🔌

Conectores de Datos

Conecta Power Query a cualquier fuente de datos: Excel, CSV, Web, SQL, SharePoint y APIs REST.

Principiante Intermedio Avanzado
📁

Archivos Locales

Excel.Workbook

Principiante

Sintaxis

Excel.Workbook(fileContents as binary, optional useHeaders as nullable logical, optional delayTypes as nullable logical) as table

¿Qué hace?

Lee un archivo Excel (binario) y devuelve una tabla con las hojas, tablas y rangos con nombre disponibles. Cada fila representa un objeto del libro.

Ejemplo

// Leer una hoja específica de un Excel
let
    Origen      = File.Contents("C:\datos\ventas.xlsx"),
    Libro       = Excel.Workbook(Origen, true, true),
    Hoja_Ventas = Libro{[Item="Ventas",Kind="Sheet"]}[Data]
in
    Hoja_Ventas

// Leer tabla con nombre "TblVentas"
let
    Libro = Excel.Workbook(File.Contents("C:\datos\ventas.xlsx"), true),
    Tabla = Libro{[Item="TblVentas", Kind="Table"]}[Data]
in
    Tabla
💡 Tip kawaii: Usa Kind="Table" en lugar de Kind="Sheet" cuando los datos están formateados como tabla Excel. Las tablas Excel son más estables ante inserciones de filas y columnas.

Csv.Document

Principiante

Sintaxis

Csv.Document(source as any, optional columns as any, optional delimiter as any, optional extraValues as nullable number, optional encoding as nullable number) as table

¿Qué hace?

Parsea un contenido CSV (texto o binario) y lo convierte en tabla. El parámetro columns puede ser un número (de columnas) o un record con opciones completas incluyendo separador, encoding y manejo de cabecera.

Parámetros del record de opciones

  • Delimiter — Separador: ",", ";", "\t" (tabulador)
  • Encoding — Codificación: 1252 (Windows-1252), 65001 (UTF-8)
  • QuoteStyleQuoteStyle.Csv (por defecto)

Ejemplo

// CSV con punto y coma (formato español)
Csv.Document(
    File.Contents("C:\datos\ventas.csv"),
    [Delimiter=";", Encoding=65001, QuoteStyle=QuoteStyle.Csv]
)

// Con cabecera y tipos automáticos
let
    Origen = Csv.Document(File.Contents("C:\datos\ventas.csv"),
        [Delimiter=";", Encoding=65001]),
    ConCabecera = Table.PromoteHeaders(Origen),
    ConTipos    = Table.InferColumnTypes(ConCabecera)
in
    ConTipos

Json.Document

Intermedio

Sintaxis

Json.Document(jsonText as any, optional encoding as nullable number) as any

¿Qué hace?

Parsea un texto o binario JSON y devuelve el valor M correspondiente: un record si es objeto {}, una lista si es array [], o un valor primitivo.

Ejemplo

// Leer JSON local
let
    contenido  = File.Contents("C:\datos\config.json"),
    parseado   = Json.Document(contenido),
    servidor   = parseado[servidor],
    basedatos  = parseado[basedatos]
in [servidor = servidor, basedatos = basedatos]

// Convertir array JSON a tabla
let
    json  = Json.Document("[{""id"":1,""nombre"":""Ana""},{""id"":2,""nombre"":""María""}]"),
    tabla = Table.FromRecords(json)
in tabla
🌐

Web y APIs REST

Web.Contents

Intermedio

Sintaxis

Web.Contents(url as text, optional options as nullable record) as binary

¿Qué hace?

Hace una petición HTTP y devuelve el contenido como binario. Es el conector universal para APIs REST. Combínalo con Json.Document, Xml.Document o Csv.Document para procesar la respuesta.

Opciones principales

  • Headers — Record con cabeceras HTTP (Authorization, Content-Type, etc.)
  • Query — Record con parámetros de query string
  • Content — Binary para peticiones POST
  • RelativePath — Ruta relativa a la URL base
  • Timeout — Duración máxima de espera

Ejemplo

// GET básico a API REST
let
    respuesta = Web.Contents("https://api.ejemplo.com/ventas"),
    datos     = Json.Document(respuesta)
in datos

// GET con parámetros de query y cabecera de autorización
let
    respuesta = Web.Contents(
        "https://api.ejemplo.com/datos",
        [
            Headers = [Authorization = "Bearer " & token,
                       #"Content-Type" = "application/json"],
            Query   = [anyo = "2024", region = "ES"]
        ]
    ),
    datos = Json.Document(respuesta)
in datos

// POST con body JSON
let
    body = Json.FromValue([filtro = "activos", limit = 100]),
    respuesta = Web.Contents(
        "https://api.ejemplo.com/consulta",
        [Content = body,
         Headers = [#"Content-Type" = "application/json"]]
    ),
    datos = Json.Document(respuesta)
in datos
⚠️ Ojo con esto: Para que Power BI Service pueda actualizar datos de Web.Contents, la URL base debe ser fija (no dinámica). Si construyes la URL dinámicamente, usa RelativePath y Query para la parte variable — así PBI puede hacer query folding y gestionar la autenticación correctamente.

Patrón: API paginada con List.Generate

Avanzado

¿Qué hace?

Las APIs REST suelen devolver datos paginados. El patrón con List.Generate itera automáticamente por todas las páginas hasta obtener todos los datos.

Ejemplo

let
    baseUrl = "https://api.ejemplo.com/registros",
    pageSize = 100,

    // Función que obtiene una página
    obtenerPagina = (pagina as number) =>
        let
            resp  = Web.Contents(baseUrl,
                [Query = [page = Text.From(pagina), size = Text.From(pageSize)]]),
            json  = Json.Document(resp)
        in json,

    // Generar páginas hasta que venga vacía
    todasLasPaginas = List.Generate(
        () => [pagina = 1, datos = obtenerPagina(1)],
        each List.Count(_[datos]) > 0,
        each [pagina = _[pagina] + 1, datos = obtenerPagina(_[pagina] + 1)],
        each _[datos]
    ),

    // Combinar todo en una tabla
    combinado = Table.FromRecords(List.Combine(todasLasPaginas))
in
    combinado
📌 Buena práctica: Añade siempre un límite máximo de páginas para evitar bucles infinitos si la API tiene un bug: each _[pagina] <= 50 and List.Count(_[datos]) > 0.
🗄️

Bases de Datos

Sql.Database / Sql.Databases

Intermedio

Sintaxis

Sql.Database(server as text, database as text, optional options as nullable record) as table
Sql.Databases(server as text, optional options as nullable record) as table

¿Qué hace?

Conecta a SQL Server y devuelve una tabla con todos los objetos de la base de datos (tablas, vistas). Cada fila contiene el nombre y los datos del objeto en una columna [Data].

Ejemplo

// Conectar y leer tabla específica
let
    bd     = Sql.Database("servidor\instancia", "BaseDatos"),
    ventas = bd{[Schema="dbo",Item="Ventas"]}[Data]
in ventas

// Con query SQL nativa
let
    resultado = Sql.Database("servidor", "BaseDatos",
        [Query = "SELECT * FROM dbo.Ventas WHERE Anyo = 2024"])
in resultado

// Con timeout personalizado
Sql.Database("servidor", "bd", [CommandTimeout = #duration(0,0,5,0)])
⚠️ Ojo con esto: Las queries SQL nativas (Query = "SELECT...") deshabilitan el query folding en pasos posteriores. Úsalas sólo para lógica que M no puede expresar eficientemente (CTEs complejas, funciones de ventana).

Otros conectores de base de datos

Intermedio

Conectores disponibles

// PostgreSQL
PostgreSQL.Database(server as text, database as text) as table

// MySQL
MySQL.Database(server as text, database as text) as table

// Oracle
Oracle.Database(server as text, optional options as nullable record) as table

// ODBC genérico
Odbc.DataSource(connectionString as text) as table

// OLE DB
OleDb.DataSource(connectionString as text) as table

¿Qué hace?

Conectores para diferentes motores de base de datos. Todos siguen el mismo patrón: devuelven una tabla navegable con los objetos de la base de datos.

Ejemplo

// PostgreSQL
let
    bd    = PostgreSQL.Database("localhost", "mi_bd"),
    tabla = bd{[Schema="public", Item="clientes"]}[Data]
in tabla
☁️

SharePoint y OneDrive

SharePoint.Files / SharePoint.Tables

Intermedio

Sintaxis

SharePoint.Files(url as text, optional options as nullable record) as table
SharePoint.Tables(url as text, optional options as nullable record) as table

¿Qué hace?

SharePoint.Files devuelve todos los archivos de una biblioteca de SharePoint como tabla (con columnas Name, Content, etc.). SharePoint.Tables devuelve las listas de SharePoint.

Ejemplo

// Leer todos los Excel de una carpeta de SharePoint
let
    archivos  = SharePoint.Files("https://empresa.sharepoint.com/sites/Datos/"),
    soloExcel = Table.SelectRows(archivos, each Text.EndsWith([Name], ".xlsx")),
    contenido = Table.AddColumn(soloExcel, "Datos",
        each Excel.Workbook([Content], true)),
    expandido = Table.ExpandTableColumn(contenido, "Datos",
        {"Name", "Data"}, {"Hoja", "TablaHoja"}),
    soloSheet = Table.SelectRows(expandido, each [Hoja] = "Datos")
in soloSheet

// Leer lista de SharePoint
SharePoint.Tables("https://empresa.sharepoint.com/sites/Datos/")
💡 Tip kawaii: El patrón "leer carpeta + expandir Excel" es uno de los más potentes de Power Query. Te permite combinar automáticamente todos los archivos Excel de una carpeta en una sola tabla, sin modificar la consulta cuando añades nuevos archivos.
📁

Carpeta de Archivos

Folder.Files / Folder.Contents

Intermedio

Sintaxis

Folder.Files(path as text) as table
Folder.Contents(path as text, optional options as nullable record) as table

¿Qué hace?

Folder.Files devuelve todos los archivos de una carpeta (recursivo). Folder.Contents devuelve el contenido no recursivo (archivos y subcarpetas). Ambas incluyen columna Content con el binario de cada archivo.

Ejemplo

// Combinar todos los CSV de una carpeta
let
    archivos  = Folder.Files("C:\datos\informes\"),
    soloCSV   = Table.SelectRows(archivos, each [Extension] = ".csv"),
    parseados = Table.AddColumn(soloCSV, "Tabla",
        each Csv.Document([Content], [Delimiter=";", Encoding=65001])),
    cabecera  = Table.TransformColumns(parseados, {"Tabla",
        each Table.PromoteHeaders(_)}),
    combinado = Table.Combine(cabecera[Tabla])
in combinado
⚙️

Parametrizar Conexiones

Parámetros para conexiones dinámicas

Avanzado

¿Qué hace?

Puedes crear parámetros de Power Query (tipo Parámetro) o leer valores de una tabla de configuración para hacer las conexiones dinámicas y fácilmente configurables sin tocar el código M.

Ejemplo — Tabla de parámetros

// 1. Crear tabla de parámetros en el modelo:
//    Nombre         | Valor
//    Servidor       | prodserver\sql2022
//    BaseDatos      | ventas_prod
//    RutaArchivos   | C:\datos\

// 2. Convertir a record
let
    tablaParams = Parametros,  // nombre de la consulta de parámetros
    config      = Record.FromTable(tablaParams)
in
    // 3. Usar en conexión
    Sql.Database(config[Servidor], config[BaseDatos])
📌 Buena práctica: Usa siempre una tabla de parámetros para servidores, rutas y configuración de entorno. Así puedes cambiar de entorno DEV → PRO modificando sólo una tabla, sin tocar ninguna consulta.
🚀 ¡Conectada a todo! Explora las Funciones Binarias para trabajar directamente con datos en formato binario.