No hay secretos en el Lenguaje M que se nos resistan. Aquí te ofrecemos una degustación, enfocándonos en la función List.ReplaceValuel en Lenguaje M de Power Query
Damos la bienvenida a este nuevo artículo/vídeo enfocado en la función List.ReplaceValue del Lenguaje M de Power Query, una función intrigante y con gran potencial que forma parte de la categoría genérica en el vasto conjunto de funciones de orden superior de tipo lista. Hoy, echaremos un vistazo que va más allá de lo que la documentación oficial ofrece.
Este artículo y vídeo sale directamente del curso Experto en Power Query y Lenguaje M, si deseas conocer más sobre este curso de grado Experto puedes hacerlo aquí.
Fundamentos de List.ReplaceValue en Lenguaje M
Vamos directamente al editor de Power Query del archivo asociado a este publicación (puedes descargarlo en la parte final).
Exploraremos la consulta específica: haciendo clic derecho y seleccionando Editor Avanzado, accederemos al código. En esta ocasión, trabajaremos con una lista preparada que incluye diferentes ítems, tales como textos de descuentos: Black Frida, que aparece repetidamente, Cyber Monday, Day of Full, Non, y End of Year. Nuestro objetivo inicial es sustituir ‘Cyber Monday‘ por Lunes Virtual, ofreciendo así su equivalente en español.
1 | let 2 | e6 = 3 | { 4 | "Black Friday", 5 | "Black Friday", 6 | "Black Friday", 7 | "Black Friday", 8 | "Cyber Monday", 9 | "Cyber Monday",10 | "Cyber Monday",11 | "Cyber Monday",12 | "Cyber Monday",13 | "Cyber Monday",14 | "Day Off Full",15 | "Day Off Full",16 | "Day Off Full",17 | "Day Off Full",18 | "Day Off Full",19 | "None",20 | "None",21 | "End Of Year",22 | "End Of Year",23 | "End Of Year",24 | "End Of Year"25 | }26 | in27 | e6
Fundamentos de List.ReplaceValue en Lenguaje M
En una primera instancia, nuestro objetivo es reemplazar Cyber Monday por Lunes Virtual para tener un equivalente en español. Esto lo podemos realizar fácilmente utilizando la función List.ReplaceValue
.
— Esta es su Sintaxis:
List.ReplaceValue ( list as list, oldValue as any, newValue as any, replacer as function) as list
Cuando utilizamos la función List.ReplaceValue
, el primer parámetro que necesitamos es una lista. En nuestro caso, esta es la información contenida en la variable e6
. A continuación, el segundo parámetro identifica el valor que deseamos cambiar, en este ejemplo, Cyber Monday. El tercer y crucial parámetro define el nuevo valor que reemplazará al antiguo, que en nuestro caso es Lunes Virtual. Lo interesante aquí es que este parámetro puede ser extremadamente versátil, aceptando cualquier tipo de valor, ya sea numérico, texto, fecha, null o incluso valores estructurados.
— Parámetro replacer
El cuarto parámetro en nuestra función List.ReplaceValue
es una función en sí misma. Aquí surge la pregunta: ¿cómo la utilizamos efectivamente? Para responder a esto, es útil referirse a la documentación de Microsoft en la Categoría de Funciones de Sustituo, dos funciones en particular en la categoría: Replacer.ReplaceText
y Replacer.ReplaceValue
.
Utilizamos Replacer.replaceText
para reemplazar valores de tipo texto, mientras que Replacer.replaceValue
es para otros tipos de valores, como los numéricos.
Si navegamos a la documentación especifica de la función List.ReplaceValue notaremos el único ejemplo proporcionado, al menos hasta la fecha de redacción de este artículo y creación del vídeo, indica que simplemente llamamos a la función deseada: Replacer.ReplaceText
. el cuarto parámetro de List.ReplaceValue
sin más, es decir, que nuestro ejemplo se puede manejar así:
1 | let 2 | e6 = 3 | { 4 | "Black Friday", "Black Friday", "Black Friday", "Black Friday", 5 | "Cyber Monday", "Cyber Monday", "Cyber Monday", "Cyber Monday","Cyber Monday", "Cyber Monday", 6 | "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", 7 | "None", "None", 8 | "End Of Year", "End Of Year", "End Of Year", "End Of Year" 9 | },10 | 11 | e7 =12 | List.ReplaceValue (13 | e6,14 | "Cyber Monday",15 | "Lunes Virtual",16 | Replacer.ReplaceValue17 | )18 | in19 | e7
Verificando en el área de resultados de Power Query se llega al resultado deseado:
Más Allá de la Documentación de List.ReplaceValue
Es interesante destacar que el cuarto parámetro de List.ReplaceValue
es un valor de función. Esto significa que, además de usar las funciones estándar de la librería, podríamos implementar nuestras propias funciones personalizadas. Aunque en la documentación de List.ReplaceValue
no se encuentran ejemplos de este enfoque, estamos aquí para explorar y desvelar esos secretos no documentados.
La clave para utilizar List.ReplaceValue
de manera efectiva es entender que la función de reemplazo requiere tres parámetros para operar correctamente. Estos parámetros pueden tener cualquier nombre, aunque para mayor claridad en este ejemplo los llamaremos de una manera más descriptiva.
El primer parámetro lo denominaremos texto
, que representaría el valor o texto en la iteración actual para nuestro caso específico. El tipo de valor en este parámetro podría variar dependiendo del escenario, como una lista de valores numéricos en otros casos. El segundo parámetro representa el valor antiguo
que queremos reemplazar, y el último parámetro será el nuevo valor
.
— Esta sería la firma del valor de función:
( texto, #"valor antiguo", #"nuevo valor" ) =>...
En el cuerpo de la función, podemos implementar un condicional de toda la vida, para explorar algo sencillo.
Podríamos preguntar si el valor actual de la iteración, al que nos referimos como texto
, es igual a Cyber Monday. Si es así, entonces queremos que se cambie a Lunes Virtual. En caso contrario, usamos la cláusula else
para mantener el texto original
, que corresponde al valor actual en la iteración. Nuestra expresión del Lenguaje M sería la siguiente:
1 | let 2 | e6 = 3 | { 4 | "Black Friday", "Black Friday", "Black Friday", "Black Friday", 5 | "Cyber Monday", "Cyber Monday", "Cyber Monday", "Cyber Monday","Cyber Monday", "Cyber Monday", 6 | "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", 7 | "None", "None", 8 | "End Of Year", "End Of Year", "End Of Year", "End Of Year" 9 | },10 | 11 | e7 =12 | List.ReplaceValue (13 | e6,14 | "Cyber Monday",15 | "Lunes Virtual",16 | ( texto, #"valor antiguo", #"nuevo valor" ) =>17 | if18 | texto = "Cyber Monday"19 | then20 | "Lunes Virtual"21 | else22 | texto23 | )24 | in25 | e7
Es fascinante observar cómo, dentro de este valor de función, también podemos manejar los parámetros ‘antiguo’ y ‘nuevo’, que son distintos entre sí. En nuestro primer acercamiento con la estructura if/then/else, hemos trabajado solamente con ‘texto’, que es una referencia al valor en la iteración actual. Pero, ¿qué ocurre con estos otros dos parámetros?
— Entendiendo el Parámetro replacer de List.ReplaceValue en Lenguaje M
Tomemos, por ejemplo, lo que sucede después de then
, donde originalmente especificamos el parámetro texto
. Aquí, podríamos introducir el #"valor antiguo"
. Sin embargo, para utilizarlo de esta manera, necesitamos que nuestro segundo parámetro en la función List.ReplaceValue
—el que corresponde al valor antiguo— sea también una función. Por ejemplo, si queremos transformar ese valor en mayúsculas, podríamos emplear Text.Upper
, como se muestra a continuación:
1 | let 2 | e6 = 3 | { 4 | "Black Friday", "Black Friday", "Black Friday", "Black Friday", 5 | "Cyber Monday", "Cyber Monday", "Cyber Monday", "Cyber Monday","Cyber Monday", "Cyber Monday", 6 | "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", 7 | "None", "None", 8 | "End Of Year", "End Of Year", "End Of Year", "End Of Year" 9 | },10 | 11 | e7 =12 | List.ReplaceValue (13 | e6,14 | ( #"valor antiguo" ) => Text.Upper ( #"valor antiguo" ),15 | "Lunes Virtual",16 | ( texto, #"valor antiguo", #"nuevo valor" ) =>17 | if18 | texto = "Cyber Monday"19 | then20 | "Lunes Virtual"21 | else22 | #"valor antiguo"23 | )24 | in25 | e7
Es importante notar que el #"valor antiguo"
que aparece después de else
hace referencia al segundo parámetro de la función List.ReplaceValue
. Sin embargo, este valor no es un valor estático, sino una función que requiere parámetros específicos para su evaluación. Si no proporcionamos estos parámetros, nos quedamos con una función sin evaluar.
Para comprender mejor cómo funciona, podemos ejecutar la expresión del Lenguaje M y observar cómo se define en términos de funciones. Veremos la palabra Function en varios elementos de la lista.
Entonces surge la pregunta: ¿Cómo podemos pasar un valor desde el cuerpo de la función, específicamente en la parte que sigue al else
, para que se evalúe cuando se llame la función del segundo parámetro en List.ReplaceValue
? Una solución práctica es el uso de la función Function.Invoke
.
En el primer parámetro de la función Function.Invoke
, colocamos #"valor antiguo"
, y en el segundo parámetro señalamos un valor de lista, donde cada elementos es parámetro de la función que se invoca. En nuestro ejemplo, este un sólo parámetro y es texto
(que corresponde al valor en la iteración actual).
Quedando así:.
1 | let 2 | e6 = 3 | { 4 | "Black Friday", "Black Friday", "Black Friday", "Black Friday", 5 | "Cyber Monday", "Cyber Monday", "Cyber Monday", "Cyber Monday","Cyber Monday", "Cyber Monday", 6 | "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", 7 | "None", "None", 8 | "End Of Year", "End Of Year", "End Of Year", "End Of Year" 9 | },10 | 11 | e7 =12 | List.ReplaceValue (13 | e6,14 | ( #"valor antiguo" ) => Text.Upper ( #"valor antiguo" ),15 | "Lunes Virtual",16 | ( texto, #"valor antiguo", #"nuevo valor" ) =>17 | if18 | texto = "Cyber Monday"19 | then20 | "Lunes Virtual"21 | else22 | Function.Invoke ( 23 | #"valor antiguo",24 | { texto }25 | )26 | )27 | in28 | e7
Al observar los resultados de esta operación en el área de resultado del editor de Power Query, notaremos algo interesante: ahora términos como Black Friday, Day Off Full, None, End of Year aparecen en mayúsculas.
Naturalmente, podríamos optar por incorporar toda la lógica de Text.Upper
directamente en la sección else
de nuestra función. Sin embargo, también existe la posibilidad de aprovechar al máximo las ventajas de los diferentes parámetros que nos ofrece List.ReplaceValue
en Lenguaje M.
Del mismo modo en que aplicamos una lógica específica al parámetro #"antiguo"
, también podemos emplear un enfoque similar con el parámetro #"nuevo valor"
. Asociando a Lunes Virtual. Quedaría:
1 | let 2 | e6 = 3 | { 4 | "Black Friday", "Black Friday", "Black Friday", "Black Friday", 5 | "Cyber Monday", "Cyber Monday", "Cyber Monday", "Cyber Monday","Cyber Monday", "Cyber Monday", 6 | "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", "Day Off Full", 7 | "None", "None", 8 | "End Of Year", "End Of Year", "End Of Year", "End Of Year" 9 | },10 | 11 | e7 =12 | List.ReplaceValue (13 | e6,14 | ( #"valor antiguo" ) => Text.Upper ( #"valor antiguo" ),15 | ( #"nuevo valor" ) => "Lunes Virtual",16 | ( texto, #"valor antiguo", #"nuevo valor" ) =>17 | if18 | texto = "Cyber Monday"19 | then20 | Function.Invoke ( 21 | #"nuevo valor",22 | { texto }23 | )24 | else25 | Function.Invoke ( 26 | #"valor antiguo",27 | { texto }28 | )29 | )30 | in31 | e7
Lo que hemos mostrado hasta ahora puede parecer una forma más complicada y enredada de abordar la tarea, y en cierta medida lo es. Sin embargo, la razón de usar este ejemplo sencillo es para comprender mejor la esencia de estos parámetros y cómo interactúan entre sí. En futuras publicaciones o contenidos, profundizaremos más en sus aplicaciones prácticas. Por el momento, es fundamental ir entendiendo las bases, el ABC de este proceso.
Conclusiones
En este primer análisis profundo sobre la función List.ReplaceValue
en el Lenguaje M de Power Query, podemos afirmar que esta función no solo es versátil y potente, sino que también abre un abanico de posibilidades para los usuarios avanzados. La habilidad de sustituir, manipular y transformar datos mediante parámetros personalizables y funciones reemplazantes, va más allá de la documentación estándar, ofreciendo un nuevo nivel de personalización y eficiencia. Este descubrimiento nos invita a explorar aún más las profundidades de Power Query y para eso estamos en Power Skill, desafiándonos a desentrañar y utilizar sus capacidades no documentadas para resolver problemas complejos y mejorar nuestros flujos de trabajo en todas las dimensiones de los datos.