17 abril, 2024

REALIZAR UNA CONSULTA LEFT JOIN CON TYPESCRIPT

Hola a todos,

Hace tiempo que no publico sobre typescript, pero es que como ya sabéis estoy muy centrado en Power Apps y esto me deja muy poco tiempo para desarrollar scripts. Pero en esta ocasión era necesario usar typescript, de hecho estoy trabajando para incluirlo en un Power Automate como una de las fases.

En concreto lo que quiero resolver es cómo poder hacer un left join en excel online entre los datos de dos hojas.

Vemos las dos hojas:

Primera hoja (PERSONAS), con ID y Nombre:

Y otra hoja que se llama ATRIBUTOS con una serie de características como: NACIMIENTO, SEXO, ESTUDIOS, etc.

Y toda esta información necesito cruzarla con un left join, es decir, todos los de la primera hoja y solo los que crucen con los de la segunda.

La información la pasaremos a la hoja CRUCE utilizando el siguiente script:

async function main(workbook: ExcelScript.Workbook) {
    // CARGAMOS HOJAS PERSONAS Y ATRIBUTOS
    let personasSheet = workbook.getWorksheet("PERSONAS");
    let atributoSheet = workbook.getWorksheet("ATRIBUTOS");
    // VERIFICAMOS QUE EXISTE CRUCE
    let fusionSheet = workbook.getWorksheet("CRUCE");
    if (!fusionSheet) {
        throw new Error("La hoja de trabajo 'CRUCE' no existe.");
    }
    // SI CRUCE TIENE DATOS LIMPIAMOS CONTENIDO
    let valorA2 = fusionSheet.getRange("A2").getValue();
    if (valorA2 !== null && valorA2 !== "") {
        fusionSheet .getRange("2:2").getExtendedRange(ExcelScript.KeyboardDirection.down).delete(ExcelScript.DeleteShiftDirection.up);}
    // OBTENEMOS ENCABEZADOS
    let personasHeaders = personasSheet.getRange("A1").getResizedRange(0, personasSheet.getUsedRange().getColumnCount() - 1).getValues();
    let atributosHeaders = atributoSheet.getRange("A1").getResizedRange(0, atributoSheet.getUsedRange().getColumnCount() - 1).getValues();
    // COMBINAMOS ENCABEZADOS
    let combinadHeaders = [...personasHeaders[0], ...atributosHeaders[0].slice(1)];
    // LEEMOS DATOS
    let personasData = await personasSheet.getRange("A2").getResizedRange(personasSheet.getUsedRange().getRowCount() - 1, personasSheet.getUsedRange().getColumnCount() - 1).getValues() as (string | number | boolean)[][];
    let atributosData = await atributoSheet.getRange("A2").getResizedRange(atributoSheet.getUsedRange().getRowCount() - 1, atributoSheet.getUsedRange().getColumnCount() - 1).getValues() as (string | number | boolean)[][];
    // CREAMOS ARRAY PARA ALMACENAR ENCABEZADOS
    let combinadosData: (string | number | boolean)[][] = [combinadHeaders];
    // CRUZAMOS INFO Y COMPARAMOS
    personasData.forEach(personasRow => {
        let personasID = personasRow[0];
        let foundMatch = false;
        for (let atributosRow of atributosData) {
            if (personasID === atributosRow[0]) {
                combinadosData.push([...personasRow, ...atributosRow.slice(1)]);
                foundMatch = true;
                break;
            }
        }
        //SI NO HAY CRUCE AÑADIMOS UN NULO
        if (!foundMatch) {
            combinadosData.push([...personasRow, ...Array(atributosHeaders[0].length - 1).fill(null)]);
        }
    });
    // PASAMOS DATOS A CRUCE
    let fusionRange = fusionSheet.getRangeByIndexes(0, 0, combinadosData.length, combinadosData[0].length);
    fusionRange.setValues(combinadosData);
}

Una vez que se ejecuta se muestra el cruce correctamente realizado:

Además vamos a poder ejecutarlo también con Power Automate:

Con el mismo resultado, obviamente.

  • Nota, en cruces muy extensos tipo 20 mil filas contra otras 20 mil, no se llega a ejecutar el script, de momento estoy investigando, pero creo que se debe a limitaciones en tipo de licencia y tiempo de ejecución.

Espero que sea de utilidad.

Comparte este post

Si te ha gustado o tienes alguna duda, puedes dejar aquí tu comentario.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies