Documentação HotXLS

Referências a livros externos

Visão geral

Modelos de folhas de cálculo frequentemente obtêm dados de livros secundários utilizando fórmulas de referência cruzada; o HotXLS suporta a análise, escrita e preservação de referências a livros externos tanto em documentos BIFF8 (XLS clássico) como em OpenXML (XLSX)

Área de trabalho de livros ativos

O TXLSWorkbookWorkspace, em lxWorkbookWorkspace, é o núcleo partilhado de identidade e de registo para livros externos ativos; tanto o TXLSWorkbook como o TXLSXWorkbook expõem CreateWorkspaceWorkbook e possuem um ExternalWorkspace usado pelos respetivos avaliadores de fórmulas, enquanto um livro ODS aberto através do TXLSXWorkbook comunica o tipo de motor OpenDocument através do mesmo adaptador

var
  Host, Target: TXLSXWorkbook;
begin
  Host.ExternalWorkspace.Add(
    '..\Data\Target.xlsx',
    '..\Data\Target.xlsx',
    'C:\Models\Host.xlsx',
    Target.CreateWorkspaceWorkbook);

  // The compatibility facade maps an unambiguous name to the
  // relationship target already stored in Host.ExternalLinks
  Host.RegisterExternalWorkbook('Target.xlsx', Target);

  // The matching call revokes a facade-level registration
  Host.UnregisterExternalWorkbook('Target.xlsx');
end;

Os livros clássicos utilizam os mesmos métodos de compatibilidade com destinos TXLSWorkbook; o RegisterExternalWorkbook e o UnregisterExternalWorkbook gerem apenas o mapeamento de nomes ao nível da facade, enquanto o ExternalWorkspace.Remove e o Clear revogam os próprios registos da área de trabalho. Quem chama entre motores adiciona diretamente a ExternalWorkspace qualquer adaptador Classic, XLSX ou ODS

  • A normalização de identidade é lexical e insensível a maiúsculas e minúsculas, preserva os caminhos e as extensões, resolve os destinos relativos face à identidade de origem do proprietário, colapsa os segmentos de ponto e não efetua qualquer acesso ao sistema de ficheiros ou à rede
  • As identidades exatas e os aliases explícitos são resolvidos primeiro; a pesquisa apenas pelo nome base só tem êxito quando exatamente um registo ligado corresponde, caso contrário o Resolve devolve xlswrsConflict
  • O Add rejeita colisões de chave exata, de alias e de livro duplicado; caminhos completos distintos e extensões distintas podem coexistir
  • O Remove e o Clear revogam registos, enquanto a destruição direta de um destino Classic ou XLSX desliga o respetivo adaptador e aguarda os leitores ativos antes de o modelo ser libertado
  • As folhas externas são resolvidas pelo nome declarado antes do fallback posicional baseado em um, pelo que a ordem das folhas do livro de destino não precisa de corresponder ao diretório de ligações da origem
  • O avaliador de fórmulas lê primeiro um livro ativo resolvido e depois recorre ao fallback da cache tipada do ficheiro anfitrião; os anfitriões XLS clássicos descodificam valores XCT e CRN esparsos, enquanto os anfitriões XLSX utilizam a cache de ligações externas já detida pelo modelo de pacote
  • O OnLoadWorkbook é um pedido de recurso controlado e opcional; o valor predefinido é nil, pelo que o recálculo continua sem efetuar acesso ao sistema de ficheiros ou à rede, salvo se o código da aplicação fornecer explicitamente essa política
  • Cada identidade normalizada invoca o loader no máximo uma vez até ResetLoadAttempts; pedidos de nível superior concorrentes partilham o resultado em curso, incluindo desfechos tipados de não encontrado e de erro, em vez de abrir o mesmo recurso repetidamente
  • O MaxLoadDepth assume por predefinição o valor 16 e o MaxWorkbookCount o valor 64; a reentrada na mesma identidade, as dependências aninhadas numa identidade já em curso, a exaustão da profundidade e a exaustão da contagem de livros devolvem diagnósticos tipados sem bloquear dentro de um ciclo de carga
  • Os IRIs de origem externa ODF permanecem identidades completas ao nível lexical, incluindo esquemas URI e carateres entre aspas, mas nunca autorizam acesso implícito a ficheiros ou à rede
  • Um conflito de identidade mantém-se #REF! para que dados em cache desatualizados não possam ocultar um encaminhamento ambíguo; uma célula em cache ausente só é um valor vazio quando o ficheiro declara uma cache válida para essa folha

O Resolve efetua a pesquisa nos registos e depois a carga controlada opcional; o desfecho é um TXLSWorkspaceResolveStatus (xlswrsResolved, xlswrsNotFound, xlswrsConflict, xlswrsDisconnected, xlswrsLoadNotFound, xlswrsLoadLimit, xlswrsLoadLoop ou xlswrsLoadError), e o ResolveWithLoader devolve também um TXLSWorkspaceLoadDiagnostic que associa um TXLSWorkspaceLoadDiagnosticCode a um TXLSWorkspaceLoadResponseStatus (xlswlrsNotFound, xlswlrsResolved, xlswlrsError) para distinguir desfechos de não encontrado, erro de loader, resultado desligado, limite de profundidade ou de livros, reentrada na mesma identidade, dependência concorrente e conflito de registo. A callback de carga recebe um TXLSWorkspaceLoadRequest (identidade, profundidade, contagem de registos, limites) e responde com um TXLSWorkspaceLoadResponse

O Recalculate comunica um TXLSWorkspaceRecalcStatus, opcionalmente com uma discriminação em TXLSWorkspaceRecalcResult, e o avaliador regista a proveniência célula a célula como um TXLSWorkspaceRuntimeLookup (xlswrlInactive, xlswrlResolved, xlswrlFallbackCache ou xlswrlError), permitindo aos diagnósticos distinguir uma leitura ativa de um fallback para a cache

O adaptador IXLSWorkspaceWorkbook expõe EngineKind (tipo TXLSWorkspaceEngineKind: xlsweClassic, xlsweOpenXml ou xlsweOpenDocument), SourceIdentity, InstanceIdentity e Generation, testa se está ligado com IsConnected, lê uma célula através de TryGetCellValue (devolvendo um TXLSWorkspaceCellStatus tipado: valor, em falta, referência inválida, desligado ou erro, mais um sinalizador de fora do intervalo utilizado), atualiza o modelo com Recalculate e desanexa-se do modelo do livro com Disconnect

O registo acrescenta AddAlias para nomes extra vinculados a uma identidade registada, TryResolve como variante de pesquisa sem exceções, e BaseNameMatchCount para pré-visualizar quantos registos ligados partilham um nome base antes de escolher um destino inequívoco

Grafo de dependências entre livros

O BuildDependencyGraph tira um instantâneo de todos os adaptadores de livros registados e extrai nós de fórmulas dos modelos Classic XLS, XLSX e ODS para um único TXLSWorkspaceDepGraph; o método devolve False e nenhum grafo parcial quando algum adaptador registado não consegue fornecer metadados de dependências

  • Cada nó de fórmula mantém a identidade canónica do livro, o nome e a posição (base um) da folha de cálculo, a posição da célula (base zero), o retângulo de saída de matriz, a volatilidade e o estado de referências não resolvidas
  • As referências a células e a intervalos retangulares mantêm as identidades canónicas do livro e da folha de destino; as referências de coluna inteira, linha inteira e folha inteira permanecem um único intervalo em vez de se expandirem para milhões de células
  • Os nomes definidos locais continuam consultáveis como dependências simbólicas e também se expandem para as respetivas dependências concretas de célula ou intervalo quando a definição pode ser resolvida estaticamente
  • Os nomes definidos externos preservam o slot de ligação externa, o nome declarado, o âmbito opcional da folha de cálculo e a identidade canónica do destino, sem tratar metadados DDE, OLE ou de funções do utilizador como nomes de livros
  • O FindDependentsOfCell e a construção de arestas do grafo utilizam árvores de intervalos de linhas com poda de extremo máximo; o LastRangeCandidateChecks e o EdgeCandidateChecks expõem o número de verificações exatas de retângulos, útil para validar o desempenho
  • A extração de fórmulas corre sob leases de leitura do livro e analisa apenas objetos de fórmula materializados, pelo que o armazenamento de valores compactado se mantém compactado e a criação do grafo não modifica as gerações do livro

Recálculo agendado

O Recalculate retém o grafo partilhado e só o reconstrói quando o registo da área de trabalho ou a geração de dependências de fórmulas de um livro muda; as gerações de valores sementam uma nova passagem de pendência, e a pendência propaga-se pelas arestas de dependência entre livros

var
  RecalcInfo: TXLSWorkspaceRecalcResult;
  Status: TXLSWorkspaceRecalcStatus;
begin
  Status := Workspace.Recalculate(RecalcInfo);
  if Status <> xlswrcOk then
    HandleWorkspaceCalculation(Status, RecalcInfo);
end;
  • As componentes fortemente ligadas são calculadas sobre células de fórmulas, pelo que os livros podem ligar-se nos dois sentidos mantendo-se acíclicos quando os respetivos caminhos de dependência ao nível das células não formam um ciclo
  • Os membros reais de um ciclo e os descendentes pendentes bloqueados por um ciclo são invalidados e excluídos da ordem topológica, impedindo que valores em cache desatualizados sejam apresentados como resultados bem-sucedidos
  • As referências voláteis ou não resolvidas estaticamente forçam o comportamento conservador de pendência exigido para a correção, enquanto grafos estáveis reutilizam o trabalho de dependências anterior
  • As leituras externas dentro de uma passagem utilizam uma cache exata por instância de livro, folha de cálculo, linha e coluna; uma fórmula agendada invalida o respetivo intervalo de saída antes da avaliação, para que os dependentes posteriores observem o novo valor
  • A cache local da passagem nunca concede autoridade sobre recursos; os livros registados e o loader opcional controlado por quem chama continuam a ser as únicas fontes de resolução ativas, seguidas das caches tipadas de ficheiros e do #REF!
  • O TXLSWorkspaceRecalcResult expõe se o grafo foi reconstruído, mais as contagens de células pendentes, avaliadas, invalidadas, em ciclo, bloqueadas, com acerto de cache e com falha de cache
  • O estado distingue sucesso, adaptadores não suportados, livros desligados, referências circulares, erros de cálculo e mutação da área de trabalho durante a passagem
  • As chamadas a Recalculate na mesma área de trabalho são serializadas, pelo que duas sessões de cálculo nunca modificam concorrentemente o grafo partilhado nem as caches dos livros
  • O Remove ou o Clear podem correr enquanto uma passagem está ativa; a passagem mantém instantâneos seguros dos adaptadores e devolve xlswrcWorkspaceChanged em vez de desreferenciar um registo removido
  • Destruir uma área de trabalho aguarda que a passagem ativa termine, enquanto destruir um livro registado desliga o respetivo adaptador e faz com que resoluções posteriores falhem em segurança
  • As falhas de loader e os resultados de não encontrado permanecem em cache uma vez por identidade normalizada até ResetLoadAttempts, e um cálculo falhado retém o estado local de pendência para uma repetição explícita
  • O grafo retido torna uma passagem subsequente inalterada proporcional aos livros registados em vez da contagem de fórmulas; a análise de componentes não recursiva e as arestas de intervalo compactas mantêm os modelos profundos e largos limitados pelos metadados de fórmulas materializados

Desanexar nomes definidos externos

O ConvertExternalDefinedNamesToRefErrors disponibiliza a mesma operação pública no TXLSWorkbook e no TXLSXWorkbook; devolve o número de definições ao âmbito do livro e ao âmbito da folha de cálculo substituídas por #REF! nativo

var
  Converted: Integer;
begin
  Converted := Workbook.ConvertExternalDefinedNamesToRefErrors;
  // External-link parts and ordinary cell formulas remain intact
end;
  • A seleção em XLS clássico utiliza tokens de referência BIFF compilados e a identidade XTI do livro de suporte, pelo que as referências tridimensionais dentro do mesmo livro e os fluxos de tokens incertos permanecem inalterados
  • A seleção em XLSX utiliza slots numéricos de livros com sensibilidade à sintaxe, pela ordem do documento de relações, e aceita apenas partes de ligações externas de livros, excluindo DDE, OLE, slots não resolvidos, referências a tabelas e texto entre parênteses retos dentro de cadeias
  • Todas as substituições são preparadas antes da primeira mutação e consolidadas como uma única operação de escrita; uma segunda chamada é idempotente
  • O texto do nome, o âmbito de livro ou de folha de cálculo, a visibilidade, os comentários, os sinalizadores de macro e de incorporado, os atributos XLSX desconhecidos e o diretório de ligações externas permanecem disponíveis após a conversão e o round trip
  • As definições malformadas e não suportadas mantêm-se preservadas ao byte ou ao texto sempre que possível e adicionam diagnósticos xlsDiagnosticDefinedNameConversionSkipped em vez de serem adivinhadas
  • As fórmulas dependentes recalculam para o valor de erro correspondente do Excel, enquanto um resultado em cache válido para uma fórmula externa direta comum permanece disponível se o respetivo livro ativo se desligar mais tarde
  • A operação é específica do Excel e não reinterpreta a semântica de fórmulas de nomes do OpenDocument

Referências externas no XLS clássico

Em livros XLS clássicos, as ligações externas são armazenadas no bloco de diretório global utilizando registos EXTERNALBOOK e EXTERNNAME; o HotXLS mantém estes diretórios durante os ciclos de leitura e escrita de ficheiros, garantindo que as referências a intervalos remotos sobrevivem aos ciclos de modificação

Relações externas do XLSX

Para livros OOXML, o mapeamento de ligações externas é gerido através de partes de relacionamento; verifique os detalhes das interfaces de suporte abaixo