SunFruits Exports
POWER BI · INTERMEDIO–AVANZADO
Programa Power BI para SunFruits Exports · Módulo 1 · Día 2

Sesión 2
Combinar consultas
& funciones M

Append, Merge, Reference, parámetros y funciones reutilizables

Bloque A · Combinar y reestructurar Bloque B · Lenguaje M, parámetros y funciones

2 horas · 2 bloques de 45 min · nivel intermedio–avanzado

Mapa de la sesión

🅰 Bloque A — 45 min

Combinar y reestructurar consultas

  • Reference vs Duplicate
  • Append: apilar las 4 hojas de ventas
  • Merge y los tipos de join
  • Expandir columnas y tabla de mapeo
  • Reestructurar: Unpivot / Pivot

🅱 Bloque B — 45 min

Lenguaje M, parámetros y funciones

  • Anatomía de let … in
  • Parámetros (ruta del archivo)
  • Convertir una consulta en función
  • Invocar la función sobre N hojas
  • Query folding y orden de pasos

Trabajamos sobre el mismo Excel: SunFruits_Ventas_Practica.xlsx.

Objetivos de aprendizaje

Al terminar la sesión vas a poder…

Combinar

Apilar (Append) y cruzar (Merge) consultas eligiendo el join correcto.

Reutilizar

Convertir una limpieza en una función M e invocarla sobre muchas hojas.

Parametrizar

Usar parámetros para rutas y valores, y entender el orden de pasos / folding.

💡 Idea fuerza de la sesión

Si te encuentras repitiendo los mismos pasos en varias hojas, no copies y pegues: crea una función. Una sola fuente de verdad para tu limpieza.

De dónde venimos (Sesión 1)

Ya sabes

  • Importar Excel y promover encabezados
  • Fijar tipos con locale
  • Manejar errores y filtrar basura
  • Limpiar una hoja: Ventas_2024

El problema que quedó abierto

Limpiaste una hoja. Pero hay 4: Ventas_2023, Ventas_2024, Ventas_2025 y Ventas_2026… y todas necesitan lo mismo.

¿Repetimos 10 pasos × 4? No. Hoy lo resolvemos bien.

Bloque A · 45 min

Combinar y
reestructurar consultas

Reference, Append, Merge y Unpivot

El reto de SunFruits

Tenemos las ventas separadas por año. El modelo necesita UNA tabla de hechos.

Ventas_2023
~1.150 filas
Ventas_2024
~1.300 filas
Ventas_2025
~1.150 filas
Ventas_2026
~400 filas
Ventas
~4.000 filas

Apilar (mismas columnas)

Las 4 hojas tienen el mismo formato → esto es un Append.

Enriquecer (otra tabla)

Sumar tipo de cambio, región del cliente → esto es un Merge.

Reference vs Duplicate

Antes de combinar, conviene separar la limpieza base de sus derivados.

Duplicate (duplicar)

Copia la consulta con TODOS sus pasos. Independiente: si cambias el original, la copia NO cambia.

Reference (referenciar)

Crea una consulta nueva que parte del resultado de otra. Si cambias la original, la referencia se actualiza.

Usa Reference para construir capas (staging → hechos / agregados).

Opción Reference en el menú de consulta
Clic derecho en la consulta → Reference · Microsoft Learn

Append — apilar filas

El Append une tablas una debajo de otra, combinando los encabezados por nombre (no por posición).

  • Si una tabla no tiene una columna, se rellena con null.
  • Ideal cuando las tablas comparten estructura (nuestras 4 hojas).

Por eso es clave que las 4 hojas tengan los mismos nombres de columna.

Diagrama de Append con columnas null
Append: columnas faltantes quedan en null · Microsoft Learn

Append en la práctica

Comandos Append en el ribbon Home

Anexar consultas

Agrega otras tablas a la consulta actual (la modifica).

Anexar consultas como nuevas

Crea una consulta nueva con el resultado; las originales no se tocan. Recomendado

Inicio → Combinar → Anexar consultas. Para 4 hojas usa el modo "Tres o más tablas".

Unificar las 4 hojas → tabla Ventas

Diálogo Append de 3 o más tablas
Modo "Tres o más tablas" · Microsoft Learn

Elige "Tres o más tablas", agrega las 4 consultas de ventas y Aceptar.

// Anexar las 4 hojas ya limpias
= Table.Combine({
    Ventas_2023, Ventas_2024,
    Ventas_2025, Ventas_2026
})

Resultado: ~4.000 filas en una sola consulta Ventas.

Merge — los tipos de join

El Merge cruza dos tablas por una o más columnas clave. El tipo de join define qué filas conservas.

JoinQué conservaUso típico en SunFruits
Left OuterTodo de la izquierda + coincidenciasVentas + datos de Cliente (sin perder ventas)
InnerSolo lo que coincide en ambasSolo ventas con tipo de cambio cargado
Full OuterTodo de ambasAuditar qué no cruza
Left AntiIzquierda SIN coincidenciaClientes en ventas que faltan en el maestro
Right AntiDerecha SIN coincidenciaClientes del maestro que nunca compraron

💡 Los anti joins son oro para detectar datos huérfanos antes de modelar.

Merge — el diálogo

Diálogo Merge queries con join kind
Selección de columna clave y tipo de join · Microsoft Learn

Inicio → Combinar → Combinar consultas. Elige la tabla derecha, la columna clave en ambas y el join.

// Ventas + maestro de Clientes (Left Outer)
= Table.NestedJoin(Ventas,
    {"Cliente"}, Clientes, {"Cliente"},
    "datosCliente", JoinKind.LeftOuter)

Resultado: una columna anidada lista para expandir.

Expandir + caso Tipo de Cambio

Tras el Merge, expande solo las columnas que necesitas (sin prefijo) para evitar nombres tipo Tabla.Columna.

  • Crea Periodo en Ventas (aaaa-mm) desde Fecha Pedido.
  • Merge con tblTipoCambio por Periodo.
  • Expande USD_PEN y calcula Monto en soles.
// Clave de periodo aaaa-mm
= Date.ToText([Fecha Pedido], "yyyy-MM")

// Merge por Periodo y expandir el TC
= Table.ExpandTableColumn(Cruce,
    "tc", {"USD_PEN"})

// Monto en soles
= [Monto USD (calc)] * [USD_PEN]

Append vs Merge — no los confundas

Append (anexar) ↓

Une tablas verticalmente (más filas). Mismas columnas.

"Tengo ventas 2023, 2024… las junto en una."

Merge (combinar) →

Une tablas horizontalmente (más columnas) por una clave.

"A cada venta le pego la región del cliente / el tipo de cambio."

Regla mnemotécnica: Append = apila filas · Merge = pega columnas.

Reestructurar — Unpivot / Pivot

La hoja Costos_2025 trae los meses en columnas. Para BI necesitamos formato largo.

  • Unpivot: de columnas a filas (lo que necesitamos).
  • Pivot: la operación inversa, de filas a columnas.

Selecciona las columnas fijas y "Anular dinamización de otras columnas".

// Costos: meses (Ene..Dic) -> filas
= Table.UnpivotOtherColumns(
    Costos,
    {"Centro de Costo", "Fundo"},
    "Mes", "Costo (miles USD)")

Resultado: una fila por centro/fundo/mes, listo para relacionar.

Bloque B · 45 min

Lenguaje M,
parámetros y funciones

Convierte tu limpieza en algo reutilizable

Anatomía de let … in

Advanced Editor con código M
View → Advanced Editor · Microsoft Learn

Cada consulta es un bloque let … in. Cada paso es una variable que alimenta a la siguiente.

let
  Origen = Excel.Workbook(...),
  Hoja   = Origen{[Item="Ventas_2024"]}[Data],
  Limpia = Table.Skip(Hoja, 3)
in
  Limpia

M es funcional y case-sensitive. El orden de los pasos importa.

Parámetros — adiós rutas quemadas

Un parámetro guarda un valor reutilizable. El clásico: la ruta del archivo, para no editar cada consulta al moverlo de PC.

  • Inicio → Administrar parámetros → Nuevo.
  • Tipo Texto, valor actual = ruta del .xlsx.
  • Úsalo en el paso Origen.
Diálogo Administrar parámetros
Administrar parámetros · Microsoft Learn
= Excel.Workbook(File.Contents(pRutaArchivo), null, true)

De consulta a función

Ventana Crear función
Clic derecho en la consulta → Crear función · Microsoft Learn

Cualquier consulta puede convertirse en función. Limpias una hoja "modelo" y Power Query genera la función a partir de esos pasos.

  • Crea la limpieza sobre una hoja de ejemplo.
  • Clic derecho → Crear función.
  • Si editas la consulta modelo, la función se actualiza sola.

Invocar la función sobre N hojas

Con una consulta que liste las hojas del libro, invoca la función en cada fila con Invocar función personalizada.

  • Agrega columna → Invocar función personalizada.
  • Pasa la columna Data de cada hoja.
  • Expande → todas las hojas limpias y unidas.
Diálogo Invocar función personalizada
Invocar función personalizada · Microsoft Learn

Caso SunFruits: fnLimpiarVentas

Una función que recibe la tabla de una hoja y devuelve la hoja limpia.

(hoja as table) =>
let
  Skip   = Table.Skip(hoja, 3),
  Encab  = Table.PromoteHeaders(Skip, [PromoteAllScalars=true]),
  Tipos  = Table.TransformColumnTypes(Encab,
              {{"Fecha Pedido", type date}, {"Precio USD x Kg", type number},
               {"Cajas", Int64.Type}, {"Kg Netos", type number}}, "es-PE"),
  SinTot = Table.SelectRows(Tipos, each [N Orden] <> null and [N Orden] <> ""),
  Dedup  = Table.Distinct(SinTot, {"N Orden"})
in
  Dedup

Invócala sobre las 4 hojas y haz Append → una sola limpieza, cero copy-paste.

Query folding y orden de pasos

El query folding empuja transformaciones al origen (ej. una BD) para que ejecute él, no Power Query.

  • Filtra y quita columnas temprano.
  • Operaciones que rompen folding, lo más tarde posible.
  • Con Excel no hay folding, pero el hábito de ordenar pasos te prepara para el Módulo 2 (BD).
M script y Applied Steps
Cada Applied Step = una línea de M · Microsoft Learn

Buenas prácticas de M

Estructura

  • Capas con Reference: staging → hechos → agregados
  • Parámetros para rutas y valores que cambian
  • Funciones para lógica repetida

Higiene

  • Renombra pasos con sentido
  • Agrupa consultas en carpetas
  • Desactiva carga de consultas staging
  • Documenta con descripciones

Un modelo mantenible empieza por un Power Query ordenado.

🛠 Taller de la sesión

Parte 1 — Combinar

  • Crea fnLimpiarVentas a partir de tu limpieza de la Sesión 1.
  • Invócala sobre las 4 hojas y haz Append → consulta Ventas.
  • Unpivot de Costos_2025.

Parte 2 — Enriquecer

  • Parámetro pRutaArchivo para el origen.
  • Merge de Ventas con tblTipoCambio (Periodo) y con Clientes.
  • Usa un anti join para hallar clientes huérfanos.

Resumen — puntos importantes

🅰 Combinar y reestructurar

  • Append = apila filas (mismas columnas)
  • Merge = pega columnas por clave (elige el join)
  • Reference para construir por capas
  • Unpivot para datos cruzados

🅱 M, parámetros y funciones

  • let … in: pasos encadenados, el orden importa
  • Parámetros para rutas/valores reutilizables
  • Funciones para no repetir limpieza
  • Query folding: ordena pensando en el origen

🎯 Si te llevas una sola idea: limpieza repetida = función. Una fuente de verdad, mantenible y a prueba de "otra hoja más".

Preguntas de repaso

Verifiquemos lo aprendido en esta sesión

1

¿Cuál es la diferencia entre Append y Merge, y cuándo usas cada uno?

2

Para conservar todas las ventas aunque el cliente no esté en el maestro, ¿qué tipo de join eliges?

3

¿Qué problema detecta un anti join y por qué es útil antes de modelar?

4

¿Qué ganas al convertir tu limpieza en una función en vez de repetir los pasos en cada hoja?

5

¿Para qué sirve el parámetro pRutaArchivo y qué problema evita?

Sun Fruits Exports · Programa Power BI

¡Gracias!

Gracias al equipo de SunFruits por su tiempo y participación

Edwin Barrientos Retuerto

Arquitecto de Inteligencia de Negocios & Cloud · Instructor

🌐 blog.arquitecturabi.pe

Nos vemos en la Sesión 3 — Modelado: esquema estrella

1 / 27