Início
» Dicas para PC
»
Acelere as macros do Calc lendo e gravando dados em lotes.
Acelere as macros do Calc lendo e gravando dados em lotes.
A otimização inicial mais confiável para uma macro lenta do Calc é substituir leituras e gravações repetidas, célula por célula, por uma leitura de intervalo, um loop na memória e uma gravação de intervalo. Isso reduz as chamadas entre o Basic e o Calc; porém, não garante um ganho de velocidade fixo, pois fórmulas, formatação, tamanho do arquivo e a lógica da macro também podem impactar significativamente o tempo de execução. O exemplo abaixo altera uma coluna de status e mostra como medir a velocidade e a precisão. Os detalhes da API foram verificados com a documentação do LibreOffice 26.8 em 9 de outubro de 2026.
O que deve ser melhorado e como você vai medir isso?
Execute a macro atual em uma cópia da planilha e registre o tempo decorrido. Use uma cópia nova com os mesmos dados iniciais para as macros antiga e revisada, ou restaure a entrada entre as execuções; caso contrário, a segunda execução poderá realizar menos trabalho. Mantenha a contagem de linhas, as configurações de cálculo e as condições de saída iguais. Repita cada execução e compare o tempo típico, em vez de confiar em uma execução excepcionalmente rápida. Verifique se o resultado corresponde à regra esperada. Uma macro que termina mais rápido, mas altera as linhas erradas, não representa uma melhoria.
A função do LibreOffice Basic Timerreporta os segundos decorridos desde a meia-noite; atribua-a a Longvariáveis para obter os segundos numéricos. Para uma execução curta, registre um valor inicial e um valor final e subtraia-os. Se o valor final for menor, a execução ultrapassou a meia-noite, então adicione 86.400 segundos à diferença. O Timer reporta segundos inteiros; use o ScriptForgeserviço Timer para precisão em milissegundos. Consulte a documentação do Timer do LibreOffice Basic e a documentação do serviço Timer do ScriptForge . Mantenha a abertura, o salvamento e a inspeção manual da pasta de trabalho fora do intervalo medido, a menos que façam parte da tarefa real.
Comece com o mesmo intervalo de dados contíguos e as mesmas condições da planilha para cada execução de medição de tempo.
Por que macros grandes do Calc ficam mais lentas?
Um loop que chama getCellByPosition(), lê e escreve propriedades de células individuais repetidamente faz com que o Calc acesse a interface Basic-to-Calc para cada operação. Com muitas linhas e colunas, essas chamadas podem se acumular mesmo quando a transformação em si é simples. Um loop em uma matriz na memória ainda visita cada linha, mas evita uma chamada de API de célula separada para cada valor.
Primeiro, remova as operações que não afetam o resultado: evite selecionar ou ativar células dentro do loop, não recalcule ou formate uma célula repetidamente quando uma única operação de intervalo for suficiente e não processe colunas inteiras se apenas um bloco de dados delimitado for necessário. Essas alterações ajudam a isolar o gargalo real antes de adicionar mais controles.
Como processar um intervalo como uma matriz?
Use um intervalo retangular que contenha apenas os valores que sua macro pretende alterar. O exemplo pressupõe uma planilha chamada Data, uma linha de cabeçalho na linha 1 e valores de status na coluna C. Altere o nome da planilha e o intervalo para corresponder à sua pasta de trabalho. A API getDataArray()retorna o intervalo como linhas contendo valores; setDataArray()grava uma matriz do mesmo tamanho de volta nesse intervalo.
Leia o intervalo retangular necessário uma vez antes do loop na memória.
Sub UpdateStatuses
Dim oSheet As Object
Dim oRange As Object
Dim aData As Variant
Dim i As Long
oSheet = ThisComponent.Sheets.getByName("Data")
oRange = oSheet.getCellRangeByName("A2:C10001")
aData = oRange.getDataArray()
For i = LBound(aData) To UBound(aData)
If aData(i)(2) = "pending" Then
aData(i)(2) = "review"
End If
Next i
oRange.setDataArray(aData)
End Sub
A matriz de linhas é indexada a partir de zero: aData(i)(2)referencie a terceira coluna de cada linha. Neste caso, é a coluna C, pois o intervalo selecionado começa em A. A sequência externa da matriz representa as linhas e cada sequência interna representa as colunas. O intervalo passado para a função setDataArray()deve ter as mesmas dimensões da matriz; uma incompatibilidade gera um erro. Consulte a referência da API XCellRangeData do LibreOffice e a documentação de matrizes do LibreOffice ScriptForge .
Aplique a regra na memória e, em seguida, escreva a matriz completa no Calc em uma única chamada.
Mantenha as células com fórmulas fora de uma atualização que contenha apenas valores.
getDataArray()Retorna os valores das células como números ou strings, não o texto original da fórmula. Se você ler um intervalo contendo fórmulas e gravar essa matriz de volta com `XCellRangeFormula` setDataArray(), essas fórmulas podem ser substituídas pelos seus resultados atuais. Limite o método de matriz de valores às células de entrada/saída que devem conter valores. Quando uma macro precisa preservar ou modificar fórmulas, use os métodos de matriz de fórmulas `XCellRangeFormula` getFormulaArray()e setFormulaArray()`XCellRangeFormula`, ou trabalhe apenas no intervalo que não contém fórmulas. A documentação da API `XCellRangeFormula` descreve essa interface separada.
Quando devo alterar as configurações de cálculo ou de exibição?
Teste essas opções somente após medir a versão da matriz. Se o recálculo da fórmula representar grande parte do tempo de execução, você pode consultar o código isAutomaticCalculationEnabled(), desativar temporariamente o cálculo automático com ` enableAutomaticCalculation(False)XCalculatable.setCalculate()`, restaurar a configuração original e recalcular as células modificadas quando necessário. Coloque a restauração em um caminho de limpeza para que um erro não deixe a planilha no modo de cálculo manual. Não desative o cálculo se a macro precisar de resultados de fórmula atualizados entre as etapas. O LibreOffice documenta calculate()o recálculo de células modificadas; `XCalculatable.setCalculate()` calculateAll()força um recálculo completo e pode ser custoso. Consulte a referência da API XCalculatable .
lockControllers()É possível suspender algumas notificações usadas para atualizações de exibição enquanto uma macro altera várias células. Combine cada bloqueio com `lock` unlockControllers(), inclusive quando a macro é encerrada por meio de um manipulador de erros. Isso reduz o trabalho de atualização da exibição; não desativa o cálculo de fórmulas nem transforma a lógica por célula em uma operação em lote. Use-o para um gargalo de atualização de tela mensurável, não como um substituto para matrizes de intervalo. Consulte a referência da API XModel .
Como você verifica a alteração e sabe quando mudar de método?
Execute a macro revisada em uma cópia da planilha e registre o tempo de execução nas mesmas condições da versão de referência. Compare as linhas afetadas, as linhas não afetadas, as fórmulas e os totais principais. Salve, feche e abra novamente a cópia, caso o fluxo de trabalho de produção inclua o salvamento; isso pode revelar problemas que uma verificação visual rápida não detecta. Uma melhoria consistente deve aparecer em execuções repetidas, enquanto as verificações de saída continuarem sendo aprovadas.
Confirme os valores transformados e registre os tempos medidos sem assumir antecipadamente um aumento de velocidade.
Se a macro ainda gasta a maior parte do tempo com fórmulas complexas, formatação, entrada/saída de arquivos ou classificação, analise esse estágio separadamente; matrizes de intervalo apenas reduzem o acesso repetido a células. Para planilhas muito grandes, uma matriz completa na memória também pode usar uma quantidade substancial de memória. Processe algumas colunas por vez ou divida as linhas em blocos dimensionados se a pressão sobre a memória aumentar, verificando se cada bloco começa e termina nas linhas desejadas. Se os dados já estiverem em um banco de dados e a tarefa for filtrar, agrupar ou atualizar registros, mover esse trabalho para uma consulta ao banco de dados pode ser mais adequado do que carregar todos os registros no Calc.