Artículo técnico

Fórmulas en vivo entre libros de Excel en Delphi con HotXLS

HotXLS puede evaluar una fórmula como =[Rates.xlsx]FX!B4*C10 contra otro libro que está abierto en memoria, y no contra un valor en caché desactualizado. Usted registra el segundo libro por nombre con RegisterExternalWorkbook, y cada recálculo lee las celdas referenciadas directamente desde ese objeto. Si lo anula del registro, la evaluación vuelve a la caché de enlaces externos que el archivo ya lleva consigo

Esto cierra una brecha específica y frustrante. Los libros de Excel se referencian entre sí de forma habitual: una tabla de tasas, un catálogo de cuentas, una lista de precios que mantiene otro equipo. Cuando un archivo así lo abre una biblioteca en lugar de Excel, esas referencias normalmente se resuelven con los valores que quedaron en caché la última vez que Excel recalculó, lo cual puede tener meses de antigüedad, y ninguna cantidad de recálculos lo arregla porque los datos sencillamente no están ahí

Rutas de resolución de una fórmula entre libros de HotXLS en Delphi: un libro registrado mediante RegisterExternalWorkbook suministra celdas actualizadas en Recalculate, un libro no registrado recurre a la caché de enlaces externos, y sin caché la celda conserva su último valor calculado
El registro lee las celdas desde el objeto en vivo, la reserva a la caché mantiene segura la anulación del registro, y una referencia irresoluble deja en su lugar el último valor válido

¿Cómo se ve una referencia entre libros dentro del archivo?

Una referencia externa no se almacena como el texto que usted ve en la barra de fórmulas. El libro mantiene una tabla de libros de apoyo, cada token de fórmula apunta a un índice dentro de esa tabla, y una parte separada de valores en caché guarda el último resultado conocido para cada celda referenciada. Por eso un archivo abierto sin sus acompañantes igual muestra números

Analizar la forma de texto tiene sus propias sutilezas. El lexer trata un nombre de libro entre corchetes como parte de un solo identificador, de modo que [Book.xlsx]Sheet!A1 se convierte en un solo token en lugar de un corchete sin cerrar seguido de una referencia de hoja. Los nombres luego se normalizan para la búsqueda: las comillas, los prefijos de ruta, la extensión del archivo y la forma de índice numérico colapsan todos a un nombre base en mayúsculas, de modo que 'C:\Rates\[Rates.xlsx]FX'!B4 y [rates.xlsx]FX!B4 se resuelven al mismo libro registrado

Registrar un libro y recalcular

El registro es por nombre, y el nombre es el que aparece en las fórmulas del libro que hace la referencia:

uses
  lxHandleX;

var
  Main, Rates: TXLSXWorkbook;
begin
  Main := TXLSXWorkbook.Create;
  Rates := TXLSXWorkbook.Create;
  try
    if (Main.Open('valuation.xlsx') <> 1) or
       (Rates.Open('rates.xlsx') <> 1) then
      Exit;

    // Las fórmulas en valuation.xlsx que dicen [Rates.xlsx]... ahora leen
    // desde el objeto en vivo en lugar de los valores externos en caché
    Main.RegisterExternalWorkbook('Rates.xlsx', Rates);
    Main.Recalculate;

    Writeln(VarToStr(Main.Sheets[0].Cells[10, 3].Value));

    // Cambiar el origen y recalcular de nuevo: el nuevo valor se propaga
    Rates.Sheets[0].Cells[4, 2].Value := 1.0842;
    Main.Recalculate;
    Writeln(VarToStr(Main.Sheets[0].Cells[10, 3].Value));
  finally
    Main.UnregisterExternalWorkbook('Rates.xlsx');
    Rates.Free;
    Main.Free;
  end;
end;

El registro mantiene una referencia débil. HotXLS no toma posesión del libro registrado y no lo liberará, lo cual significa que la vida útil del objeto es responsabilidad suya, y el orden importa: anule el registro antes de liberar el libro de origen, o como mínimo no recalcule después de liberarlo

¿Qué pasa cuando un libro no está registrado?

La evaluación recurre a la caché de enlaces externos almacenada en el archivo, que es exactamente el comportamiento de un libro abierto sin sus acompañantes. Esa reserva es la razón por la que anular el registro es seguro en lugar de destructivo

El comportamiento tras anular el registro vale la pena precisarlo, porque sorprende a la gente. Cuando una referencia no se puede resolver ni desde un libro registrado ni desde la caché, la evaluación produce un error, y ese error no se escribe de vuelta en la celda. La celda conserva su último valor calculado. Vuelva a registrar el origen y recalcule, y el valor se actualiza otra vez

Esta regla de preservar ante un fallo es deliberada. La alternativa, escribir un valor de error en cada celda dependiente en el momento en que un origen no está disponible, convertiría una tabla de tasas temporalmente ausente en un libro lleno de marcadores de error que un recálculo exitoso posterior tendría que reparar. Conservar el último valor bueno significa que un pipeline interrumpido deja un documento que todavía se puede leer con sensatez

La propagación de cambios se detiene en la frontera del libro

Editar una celda en el origen registrado no marca como sucias las celdas dependientes en el libro principal. El recálculo incremental rastrea dependencias dentro de un solo libro; no vigila a través de la frontera. Excel se comporta de la misma manera, razón por la cual sus referencias externas se actualizan al abrir o mediante una actualización explícita, y no de forma continua

La consecuencia práctica es que cambiar un valor de origen requiere un recálculo explícito del libro que hace la referencia, como en el ejemplo anterior. Si su aplicación edita ambos libros dentro de un bucle, recalcule una sola vez al final en lugar de después de cada edición; el motor incremental descrito en recálculo incremental y el grafo de dependencias entonces hace el mínimo trabajo dentro de cada libro

Tres formas en que encaja esta función

La consolidación es la obvia. Un libro principal referencia doce archivos mensuales; registre los doce, recalcule una vez, y lea las cifras consolidadas sin abrir Excel en ningún momento. El nombre de registro de cada uno debe coincidir con lo que realmente dicen las fórmulas del libro principal, lo cual vale la pena verificar contra el texto de la fórmula en lugar de asumir que coincide con el nombre del archivo

El análisis de escenarios es la segunda. Registre un origen, escriba en él un conjunto de supuestos, recalcule el modelo dependiente, registre las salidas, y repita. Como el origen es un objeto en vivo, no se escribe ningún archivo entre iteraciones, y cien escenarios cuestan cien recálculos en lugar de cien ciclos de guardar y recargar

La validación antes de la entrega es la tercera y la menos obvia. Abra un libro, registre sus acompañantes, recalcule, y compare los resultados contra los valores que ya llevaba el archivo. Una discrepancia significa que los valores en caché están desactualizados, un defecto que vale la pena detectar antes de que un cliente reciba el archivo. Esa comparación es un complemento natural de la comparación de libros descrita en comparar dos libros de Excel

Tres formas de la evaluación en vivo entre libros con HotXLS en Delphi: consolidación de doce archivos mensuales, análisis de escenarios que nunca escribe un archivo entre ejecuciones, y validación que compara los resultados recalculados contra los valores en caché que lleva un archivo
La consolidación registra cada archivo mensual y recalcula una sola vez, los bucles de escenarios nunca tocan el disco, y la validación compara resultados nuevos contra la caché que un cliente habría recibido

Higiene de referencias antes de confiar en esto

Ejecute primero un análisis de fórmulas. Reporta funciones faltantes, referencias externas y componentes de dependencia circular en un solo recorrido, lo cual le indica exactamente qué nombres de libro espera un documento antes de que usted salga a buscar los archivos:

var
  Issues: TArray<TXLSXFormulaIssue>;
  I: Integer;
begin
  Issues := Main.AnalyzeFormulaIssues;
  for I := 0 to High(Issues) do
    if Issues[I].Kind = xlsxFormulaIssueExternalReference then
      Writeln(Format('sheet %d R%dC%d needs [%s] (%s)',
        [Issues[I].Sheet, Issues[I].Row, Issues[I].Col,
         Issues[I].ExternalWorkbook, Issues[I].SourceFileName]));
end;

Otros dos hábitos ahorran tiempo. Mantenga el nombre de registro canónico: regístrelo con el nombre de archivo simple y deje que la normalización maneje las variantes entrecomilladas y con prefijo de ruta en las fórmulas. Y trate un libro que referencia archivos que usted no puede suministrar como un artefacto de solo lectura: recalcularlo preservará los valores en caché, pero cualquier edición que cambie una celda dependiente deja el documento en un estado donde algunos valores están al día y otros son históricos, sin nada en el archivo que diga cuáles son cuáles. Copiar fórmulas entre libros es una operación distinta con sus propias reglas de reenlace, cubierta en copia entre libros y reenlace de fórmulas, y los rangos con nombre agregan otra capa descrita en nombres definidos y fórmulas entre hojas

La evaluación en vivo entre libros, el recálculo incremental y el análisis de fórmulas se ejecutan sobre el mismo motor para Delphi y C++Builder; la lista completa de funciones está en la página del componente de hoja de cálculo para Delphi de HotXLS