🔧

Funciones de Transformación

Combina, divide, compara y reemplaza con los módulos Combiner.*, Splitter.*, Comparer.* y Replacer.*.

Intermedio Avanzado
🔗

Combiner.* — Combinadores de texto

Combiner.CombineTextByDelimiter

Intermedio

Sintaxis

Combiner.CombineTextByDelimiter(delimiter as text, optional quoteStyle as nullable number) as function

¿Qué hace?

Devuelve una función que combina una lista de textos con el delimitador especificado. Los módulos Combiner.* son funciones de orden superior: devuelven funciones para usar como argumentos en otras funciones.

Ejemplo

// Crear la función combinadora
let combinador = Combiner.CombineTextByDelimiter(" | ")
in combinador({"Madrid", "Barcelona", "Valencia"})
// "Madrid | Barcelona | Valencia"

// Uso típico: en Table.CombineColumns o List.Accumulate
Table.CombineColumns(
    tabla,
    {"Nombre", "Apellido1", "Apellido2"},
    Combiner.CombineTextByDelimiter(" "),
    "NombreCompleto"
)

Combiner.CombineTextByLengths / CombineTextByPositions

Avanzado

Sintaxis

Combiner.CombineTextByLengths(lengths as list) as function
Combiner.CombineTextByPositions(positions as list) as function
Combiner.CombineTextByRanges(ranges as list) as function

¿Qué hace?

Variantes especializadas para combinar texto con longitudes fijas, posiciones o rangos. Útiles para crear formatos de ancho fijo (flat files, formatos legacy).

Ejemplo

// Combinar con longitudes fijas (rellena/trunca)
let fn = Combiner.CombineTextByLengths({3, 4, 2})
in fn({"ES", "2024", "01"})
// "ES 20240 1" (cada parte tiene longitud fija)
✂️

Splitter.* — Divisores de texto

Splitter.SplitTextByDelimiter

Intermedio

Sintaxis

Splitter.SplitTextByDelimiter(delimiter as text, optional quoteStyle as nullable number) as function

¿Qué hace?

Devuelve una función que divide un texto por el delimitador indicado. Es el equivalente modular de Text.Split para usar en Table.SplitColumn.

Ejemplo

// Crear la función divisora
let divisor = Splitter.SplitTextByDelimiter(";")
in divisor("Madrid;Barcelona;Valencia")
// {"Madrid", "Barcelona", "Valencia"}

// Uso típico: dividir columna en varias
Table.SplitColumn(
    tabla,
    "Categorias",
    Splitter.SplitTextByDelimiter(","),
    {"Cat1", "Cat2", "Cat3"}
)

Splitter.SplitTextByLengths / SplitTextByPositions

Avanzado

Sintaxis

Splitter.SplitTextByLengths(lengths as list, optional startOfNext as nullable logical) as function
Splitter.SplitTextByPositions(positions as list) as function
Splitter.SplitTextByRepeatedLengths(length as number) as function

¿Qué hace?

Divide texto de ancho fijo por longitudes o posiciones. Fundamental para procesar archivos de texto de formato fijo (mainframe, legacy systems).

Ejemplo

// Dividir por longitudes (3, 4, 2 caracteres)
let fn = Splitter.SplitTextByLengths({3, 4, 2})
in fn("ESP20240115")
// {"ESP", "2024", "01"} (los últimos 2 quedan: "15" → sólo 2 usados)

// Dividir en fragmentos de longitud repetida
let fn2 = Splitter.SplitTextByRepeatedLengths(2)
in fn2("012345")
// {"01", "23", "45"}

// Dividir por posiciones (inicio de cada parte)
let fn3 = Splitter.SplitTextByPositions({0, 3, 7})
in fn3("ESP20240115")
// {"ESP", "2024", "0115"}
💡 Tip kawaii: Los módulos Splitter.* y Combiner.* son "funciones de función": devuelven una función lista para usar. Por eso en Table.SplitColumn no llamas Splitter.SplitTextByDelimiter(",") como función, sino que se la pasas directamente como argumento.
⚖️

Comparer.* — Comparadores

Comparer.Ordinal / OrdinalIgnoreCase

Intermedio

Sintaxis

Comparer.Ordinal(x as any, y as any) as number
Comparer.OrdinalIgnoreCase(x as any, y as any) as number
Comparer.FromCulture(culture as text, optional ignoreCase as nullable logical) as function

¿Qué hace?

Los comparadores definen cómo comparar dos valores. Devuelven -1 (x menor), 0 (iguales) o 1 (x mayor). Se usan en funciones de ordenación, búsqueda y agrupación.

Ejemplo

// Búsqueda insensible a mayúsculas
List.Contains({"Madrid", "BARCELONA"}, "barcelona", Comparer.OrdinalIgnoreCase)
// true

// Ordenar con cultura española (ñ ordenada correctamente)
List.Sort({"zebra", "ñoño", "abeja"}, Comparer.FromCulture("es-ES"))
// {"abeja", "ñoño", "zebra"}

// En Table.Sort
Table.Sort(tabla, {{"Nombre", Comparer.FromCulture("es-ES")}})
⚠️ Ojo con esto: Comparer.Ordinal ordena por código Unicode, por lo que la "Ñ" puede quedar en posición incorrecta. Usa siempre Comparer.FromCulture("es-ES") para ordenación alfabética correcta en español.
✏️

Replacer.* — Reemplazadores

Replacer.ReplaceValue / ReplaceText

Intermedio

Sintaxis

Replacer.ReplaceValue(value as any, old as any, new as any) as any
Replacer.ReplaceText(value as any, old as text, new as text) as any

¿Qué hace?

Funciones reemplazadoras modulares para usar en Table.ReplaceValue. ReplaceValue reemplaza valores exactos (de cualquier tipo). ReplaceText reemplaza subcadenas de texto.

Ejemplo

// Reemplazar valor exacto null por 0 en columna "Ventas"
Table.ReplaceValue(tabla, null, 0, Replacer.ReplaceValue, {"Ventas"})

// Reemplazar subcadena en columna de texto
Table.ReplaceValue(tabla, "S.A.", "SA", Replacer.ReplaceText, {"Empresa"})

// Reemplazar en múltiples columnas
Table.ReplaceValue(tabla, "N/D", null, Replacer.ReplaceValue,
    {"Ciudad", "Pais", "Region"})
📌 Buena práctica: Usa Table.ReplaceValue con Replacer.* para reemplazos masivos en columnas específicas. Es más eficiente que aplicar Table.TransformColumns con Text.Replace columna por columna.
🏷️

Value.* — Funciones de Valor

Value.Is / Value.Type / Value.As

Avanzado

Sintaxis

Value.Is(value as any, type as type) as logical
Value.Type(value as any) as type
Value.As(value as any, type as type) as any

¿Qué hace?

Value.Is comprueba si un valor es de un tipo determinado. Value.Type devuelve el tipo de un valor. Value.As lanza un error si el valor no es del tipo esperado (aserción de tipo).

Ejemplo

Value.Is(42, type number)     // true
Value.Is("hola", type text)   // true
Value.Is(null, type number)   // false

Value.Type(42)        // type number
Value.Type("texto")   // type text
Value.Type(#date(2024,1,1))  // type date

// Asegurar tipo antes de operar
Value.As([Importe], type number)  // error si no es number

Value.NativeQuery / Value.Metadata

Avanzado

Sintaxis

Value.Metadata(value as any) as record
Value.ReplaceMetadata(value as any, metaRecord as record) as any

¿Qué hace?

Accede o establece los metadatos asociados a un valor. Los metadatos son records opcionales que M adjunta a cualquier valor para transportar información adicional sin afectar al valor en sí.

Ejemplo

// Asignar metadatos
let
    valor = "Kawaii BI" meta [Fuente = "Manual", Version = 1],
    metadatos = Value.Metadata(valor)
in metadatos[Fuente]   // "Manual"

// Los metadatos no afectan al valor
valor = "Kawaii BI"   // el texto sigue siendo el mismo
🚀 ¡Transformaciones dominadas! Explora las Funciones de Tipo para entender el sistema de tipos de M.