Precedentes y Dependientes con JavaScript vía C++

Introducción

  • Celdas precedentes son celdas a las que hace referencia una fórmula en otra celda. Por ejemplo, si la celda D10 contiene la fórmula =B5, la celda B5 es precedente a la celda D10.
  • Celdas dependientes contienen fórmulas que hacen referencia a otras celdas. Por ejemplo, si la celda D10 contiene la fórmula =B5, la celda D10 depende de la celda B5.

Para que la hoja de cálculo sea fácil de leer, es posible que desees mostrar claramente qué celdas en una hoja de cálculo se utilizan en una fórmula. Del mismo modo, es posible que desees extraer las celdas dependientes de otras celdas.

Aspose.Cells te permite rastrear celdas y averiguar cuáles están vinculadas.

Rastreo de celdas precedentes y dependientes: Microsoft Excel

Las fórmulas pueden cambiar en función de las modificaciones realizadas por un cliente. Por ejemplo, si la celda C1 depende de C3 y C4 que contienen una fórmula, y se cambia C1 (por lo que se anula la fórmula), C3 y C4, u otras celdas, necesitan cambiar para equilibrar la hoja de cálculo según las reglas empresariales.

De manera similar, suponga que C1 contiene la fórmula “=(B122)/(M2N32)”. Quiero encontrar las celdas de las que depende C1, es decir, las celdas precedentes B1, M2 y N32.

Es posible que necesite rastrear la dependencia de una celda particular respecto a otras celdas. Si las reglas empresariales están incrustadas en fórmulas, nos gustaría averiguar la dependencia y ejecutar algunas reglas basadas en ella. De manera similar, si se modifica el valor de una celda en particular, ¿qué celdas en la hoja de cálculo se ven afectadas por ese cambio?

Microsoft Excel permite a los usuarios rastrear las celdas precedentes y dependientes.

  1. En la Barra de herramientas Ver, seleccione Revisión de Fórmulas. Se mostrará el cuadro de diálogo Revisión de Fórmulas.
  2. Rastrear precedentes:
    1. Selecciona la celda que contiene la fórmula de la cual deseas encontrar las celdas precedentes.
    2. Para mostrar una flecha rastreadora a cada celda que proporciona datos directamente a la celda activa, haz clic en Rastrear precedentes en la barra de herramientas Auditoría de fórmulas.
  3. Rastrear fórmulas que hacen referencia a una celda en particular (dependientes)
    1. Selecciona la celda de la que deseas identificar las celdas dependientes.
    2. Para mostrar una flecha rastreadora a cada celda que depende de la celda activa, haga clic en Rastrear Dependientes en la barra de herramientas de Auditoría de Fórmulas.

Rastreo de celdas precedentes y dependientes: Aspose.Cells

Rastreo de Precedentes

Aspose.Cells facilita obtener celdas precedentes. No solo puede recuperar celdas que proporcionan datos a predecesores de fórmulas simples, sino que también puede encontrar celdas que proporcionan datos a predecesores de fórmulas complejas con rangos nombrados.

En el ejemplo a continuación, se utiliza un archivo de plantilla de Excel, Book1.xls. La hoja de cálculo tiene datos y fórmulas en la primera hoja de trabajo.

Aspose.Cells proporciona el método Cell.precedents() de la clase Cell que se usa para rastrear los precedentes de una celda. Retorna una colección de áreas referidas. Como se muestra arriba, en Book1.xls, la celda B7 contiene la fórmula “=SUM(A1:A3)”. Entonces, las celdas A1:A3 son las celdas precedentes de la celda B7. El ejemplo siguiente demuestra la función de rastreo de precedentes usando el archivo plantilla Book1.xls.

<!DOCTYPE html>
<html>
    <head>
        <title>Aspose.Cells Example</title>
    </head>
    <body>
        <h1>Get Cell Precedents Example</h1>
        <input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
        <button id="runExample">Run Example</button>
        <a id="downloadLink" style="display: none;">Download Result</a>
        <div id="result"></div>
    </body>

    <script src="aspose.cells.js.min.js"></script>
    <script type="text/javascript">
        const { Workbook, SaveFormat } = AsposeCells;

        AsposeCells.onReady({
            license: "/lic/aspose.cells.enc",
            fontPath: "/fonts/",
            fontList: [
                "arial.ttf",
                "NotoSansSC-Regular.ttf"
            ]
        }).then(() => {
            console.log("Aspose.Cells initialized");
        });

        document.getElementById('runExample').addEventListener('click', async () => {
            const fileInput = document.getElementById('fileInput');
            if (!fileInput.files.length) {
                document.getElementById('result').innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
                return;
            }

            const file = fileInput.files[0];
            const arrayBuffer = await file.arrayBuffer();

            // Instantiate workbook from uploaded file
            const workbook = new Workbook(new Uint8Array(arrayBuffer));

            // Access first worksheet's cells
            const cells = workbook.worksheets.get(0).cells;

            // Get cell B4
            const cell = cells.get("B4");

            if (cell) {
                // Get precedents (converted from getPrecedents)
                const ret = cell.precedents;

                if (!ret.isNull() && ret.count > 0) {
                    const area = ret.get(0);

                    const sheetName = area.sheetName;
                    const startAddress = AsposeCells.CellsHelper.cellIndexToName(area.startRow, area.startColumn);
                    const endAddress = AsposeCells.CellsHelper.cellIndexToName(area.endRow, area.endColumn);

                    console.log(sheetName);
                    console.log(startAddress);
                    console.log(endAddress);

                    document.getElementById('result').innerHTML = `<pre>Sheet: ${sheetName}\nStart: ${startAddress}\nEnd: ${endAddress}</pre>`;
                } else {
                    document.getElementById('result').innerHTML = '<p style="color: red;">No precedents found for the cell.</p>';
                }
            } else {
                document.getElementById('result').innerHTML = '<p style="color: red;">Cell B4 is null.</p>';
            }
        });
    </script>
</html>

Rastreo de Dependientes

Aspose.Cells le permite obtener las celdas dependientes en hojas de cálculo. Aspose.Cells no solo puede recuperar las celdas que proporcionan datos respecto a una fórmula simple, sino también encontrar las celdas que proporcionan datos a dependientes de fórmulas complejas con rangos con nombre.

Aspose.Cells proporciona el método Cell.dependents(boolean) de la clase Cell que se usa para rastrear las dependientes de una celda. Por ejemplo, en Book1.xlsx existen fórmulas: “=A1+20” y “=A1+30” en las celdas B2 y C2 respectivamente. El ejemplo siguiente demuestra cómo rastrear las dependientes de la celda A1 usando el archivo plantilla Book1.xlsx.

<!DOCTYPE html>
<html>
    <head>
        <title>Aspose.Cells Example</title>
    </head>
    <body>
        <h1>Aspose.Cells - Get Cell Dependents Example</h1>
        <input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
        <button id="runExample">Run Example</button>
        <a id="downloadLink" style="display: none;">Download Result</a>
        <div id="result"></div>
    </body>

    <script src="aspose.cells.js.min.js"></script>
    <script type="text/javascript">
        const { Workbook, SaveFormat, Worksheet, Cell } = AsposeCells;

        AsposeCells.onReady({
            license: "/lic/aspose.cells.enc",
            fontPath: "/fonts/",
            fontList: [
                "arial.ttf",
                "NotoSansSC-Regular.ttf"
            ]
        }).then(() => {
            console.log("Aspose.Cells initialized");
        });

        document.getElementById('runExample').addEventListener('click', async () => {
            const fileInput = document.getElementById('fileInput');
            const resultDiv = document.getElementById('result');

            if (!fileInput.files.length) {
                resultDiv.innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
                return;
            }

            const file = fileInput.files[0];
            const arrayBuffer = await file.arrayBuffer();

            // Loads the workbook which contains hidden external links
            const workbook = new Workbook(new Uint8Array(arrayBuffer));
            const cells = workbook.worksheets.get(0).cells;
            const cell = cells.get("B2");
            // Ensure dependents is accessed as a property (converted from getDependents)
            const dependents = cell.dependents;

            if (Array.isArray(dependents)) {
                let out = '<p>Dependents found:</p><ul>';
                for (const c of dependents) {
                    console.log(c.name);
                    out += `<li>${c.name}</li>`;
                }
                out += '</ul>';
                resultDiv.innerHTML = out;
            } else {
                console.error("Dependents is not an array");
                resultDiv.innerHTML = '<p style="color: red;">Dependents is not an array</p>';
            }
        });
    </script>
</html>

Rastreo de celdas precedentes y dependientes según la cadena de cálculo

Las API anteriores para rastrear precedentes y dependientes se basan en la propia expresión de la fórmula. Simplemente proporcionan una manera conveniente para que los usuarios rastreen las interdependencias de algunas fórmulas. Si hay un gran número de fórmulas en el libro de trabajo y el usuario necesita rastrear precedentes y dependientes para cada celda, podrían tener un rendimiento pobre. Para tal situación, el usuario debería considerar usar los métodos Cell.precedentsInCalculation() y Cell.dependentsInCalculation(boolean). Estos dos métodos rastrean dependencias según la cadena de cálculo. Por lo tanto, para usarlos, primero debes habilitar la cadena de cálculo con FormulaSettings.enableCalculationChain(). Luego debes realizar un cálculo completo del libro de trabajo con Workbook.calculateFormula(). Después de eso, puedes rastrear precedentes o dependientes para todas esas celdas que necesitas.

Para algunas fórmulas, los precedentes resultantes pueden ser diferentes para precedentes y precedentesInCalculation, y los dependientes resultantes pueden ser diferentes para dependents y dependentsInCalculation. Por ejemplo, si la fórmula de la celda A1 es “=IF(TRUE,B2,C3)”, los precedentes serán B2 y C3 como precedentes de A1. En consecuencia, B2 y C3 tienen como dependiente a A1 cuando se verifica con dependientes. Sin embargo, para el cálculo de esta fórmula, es obvio que solo B2 puede afectar el resultado calculado. Por lo tanto, precedentsInCalculation no proporcionará C3 para A1, y dependentsInCalculation no proporcionará A1 para C3. A veces, los usuarios solo necesitan rastrear esas interdependencias que realmente afectan el resultado calculado de las fórmulas según los datos actuales del libro de trabajo, entonces también deben usar dependentsInCalculation/precedentsInCalculation en lugar de dependents/precedents.

El siguiente ejemplo demuestra cómo rastrear los precedentes y dependientes según la cadena de cálculo para las celdas:

<!DOCTYPE html>
<html>
    <head>
        <title>Aspose.Cells Example</title>
    </head>
    <body>
        <h1>Aspose.Cells Example</h1>
        <input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
        <button id="runExample">Run Example</button>
        <a id="downloadLink" style="display: none;">Download Result</a>
        <div id="result"></div>
    </body>

    <script src="aspose.cells.js.min.js"></script>
    <script type="text/javascript">
        const { Workbook, SaveFormat } = AsposeCells;

        AsposeCells.onReady({
            license: "/lic/aspose.cells.enc",
            fontPath: "/fonts/",
            fontList: [
                "arial.ttf",
                "NotoSansSC-Regular.ttf"
            ]
        }).then(() => {
            console.log("Aspose.Cells initialized");
        });

        document.getElementById('runExample').addEventListener('click', async () => {
            const fileInput = document.getElementById('fileInput');
            const resultDiv = document.getElementById('result');
            resultDiv.innerHTML = '';
            if (!fileInput.files.length) {
                resultDiv.innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
                return;
            }

            const file = fileInput.files[0];
            const arrayBuffer = await file.arrayBuffer();

            // Instantiating a Workbook object by opening the uploaded file
            const workbook = new Workbook(new Uint8Array(arrayBuffer));

            // Accessing the first worksheet and its cells
            const cells = workbook.worksheets.get(0).cells;

            // Setting formulas
            cells.get("A1").formula = "=B1+SUM(B1:B10)+[Book1.xls]Sheet1!B2";
            cells.get("A2").formula = "=IF(TRUE,B2,B1)";

            // Enable calculation chain
            workbook.settings.formulaSettings.enableCalculationChain = true;

            // Calculate formulas
            workbook.calculateFormula();

            // Collect output
            let output = '';

            let en = cells.get("B1").dependentsInCalculation;
            output += "B1's calculation dependents:\n";
            if (en && en.length !== undefined) {
                for (var cell of en) {
                    output += (cell.name || '') + "\n";
                }
            } else if (en) {
                // If it's an iterable but doesn't have length
                for (var cell of en) {
                    output += (cell.name || '') + "\n";
                }
            }
            output += "\n";

            en = cells.get("B2").dependentsInCalculation;
            output += "B2's calculation dependents:\n";
            if (en && en.length !== undefined) {
                for (var cell of en) {
                    output += (cell.name || '') + "\n";
                }
            } else if (en) {
                for (var cell of en) {
                    output += (cell.name || '') + "\n";
                }
            }
            output += "\n";

            en = cells.get("A1").precedentsInCalculation;
            output += "A1's calculation precedents:\n";
            if (en && en.length !== undefined) {
                for (var area of en) {
                    output += area.toString() + "\n";
                }
            } else if (en) {
                for (var area of en) {
                    output += area.toString() + "\n";
                }
            }
            output += "\n";

            en = cells.get("A2").precedentsInCalculation;
            output += "A2's calculation precedents:\n";
            if (en && en.length !== undefined) {
                for (var area of en) {
                    output += area.toString() + "\n";
                }
            } else if (en) {
                for (var area of en) {
                    output += area.toString() + "\n";
                }
            }

            resultDiv.innerHTML = '<pre>' + output.replace(/</g, '&lt;') + '</pre>';

            // Save the modified workbook and provide download link
            const outputData = workbook.save(SaveFormat.Xlsx);
            const blob = new Blob([outputData]);
            const downloadLink = document.getElementById('downloadLink');
            downloadLink.href = URL.createObjectURL(blob);
            downloadLink.download = 'output.xlsx';
            downloadLink.style.display = 'block';
            downloadLink.textContent = 'Download Modified Excel File';
        });
    </script>
</html>