Na Planilha do Google, encontrar quais fórmulas referenciam um determinado valor

17

Gostaria de descobrir quais células têm dependências de fórmula em uma planilha grande. Estou procurando uma maneira de fazer algo como o OpenOffice

Ferramentas> Detetive> Rastrear dependentes

e

Editar> Localizar e substituir> Pesquisar em fórmulas

ou uma maneira de criar um gatilho no GAS que é chamado quando um determinado valor de célula é referenciado e pode identificar a origem da referência.

MetaEd
fonte

Respostas:

12

O código a seguir adicionará um menu à planilha:

Detetive> Rastrear dependentes

Selecionar isso adicionará uma nota à célula ativa com todas as referências de célula dependentes.

(pesquisa adicionada por referências estáticas, conforme sugerido por Graham abaixo)

Você pode adicionar uma função semelhante à função traceDependents para procurar o texto na célula ativa por uma função Pesquisar em Fórmulas. Vou deixar isso como um exercício para você.

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = []
  menuEntries.push({name: "Trace Dependents", functionName: "traceDependents"});
  ss.addMenu("Detective", menuEntries);
}

function traceDependents(){
  var dependents = []
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var currentCell = ss.getActiveCell();
  var currentCellRef = currentCell.getA1Notation();
  var range = ss.getDataRange();

  var regex = new RegExp("\\b" + currentCellRef + "\\b");
  var formulas = range.getFormulas();

  for (var i = 0; i < formulas.length; i++){
    var row = formulas[i];

    for (var j = 0; j < row.length; j++){
      var cellFormula = row[j].replace(/\$/g, "");
      if (regex.test(cellFormula)){
        dependents.push([i,j]);
      }
    }
  }

  var dependentRefs = [];
  for (var k = 0; k < dependents.length; k ++){
    var rowNum = dependents[k][0] + 1;
    var colNum = dependents[k][1] + 1;
    var cell = range.getCell(rowNum, colNum);
    var cellRef = cell.getA1Notation();
    dependentRefs.push(cellRef);
  }
  var output = "Dependents: ";
  if(dependentRefs.length > 0){
    output += dependentRefs.join(", ");
  } else {
    output += " None";
  }
  currentCell.setNote(output);
}
Tom Horwood
fonte
Isso é fantástico. Eu acho que você pode remover a linha extra: var output = "Dependents:";
precisa saber é o seguinte
Bem pego. Eu o removi. Obrigado pelos olhos de águia.
precisa
Gosto muito disto! No entanto, vejo corretamente que não suporta intervalos nomeados? E se for esse o caso, seria simples / complicado adicionar suporte?
Wizek 6/04
2
Como usar o código?
precisa saber é o seguinte
11
por que a linha menuEntries.push({name: "Trace Dependents", functionName: "traceDependents"});aparece duas vezes no código?
25418 Thomas
4

Isso é super e me salvou muito trabalho - obrigado.
No entanto, a resposta acima não encontra nenhuma referência que use o fixador de linha ou coluna $.
A seguinte pequena alteração no código realiza isso:

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = []
  menuEntries.push({name: "Trace Dependents", functionName: "traceDependents"});
  ss.addMenu("Detective", menuEntries);
}

function traceDependents(){
  var dependents = []
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var currentCell = ss.getActiveCell();
  var currentCellRef = currentCell.getA1Notation();
  var range = ss.getDataRange();

  var regex = new RegExp("\\b" + currentCellRef + "\\b");
  var formulas = range.getFormulas();

  for (var i = 0; i < formulas.length; i++){
    var row = formulas[i];

    for (var j = 0; j < row.length; j++){
      var cellFormula = row[j].replace(/\$/g, "");
        if (regex.test(cellFormula)){
          dependents.push([i,j]);
      }
    }
  }

  var dependentRefs = [];
  for (var k = 0; k < dependents.length; k ++){
    var rowNum = dependents[k][0] + 1;
    var colNum = dependents[k][1] + 1;
    var cell = range.getCell(rowNum, colNum);
    var cellRef = cell.getA1Notation();
    dependentRefs.push(cellRef);
  }
  var output = "Dependents: ";
  if(dependentRefs.length > 0){
    output += dependentRefs.join(", ");
  } else {
    output += " None";
  }
  currentCell.setNote(output);
}
Graham
fonte
Obrigado; isso ajudou um pouco. Como alguém faria isso funcionar entre as planilhas?
Wizonesolutions
Obrigado Graham - incorporei suas alterações. Quanto ao trabalhar em planilhas, o código seria necessário um pouco de ajuste para incorporar o nome da folha e, em seguida, percorrer cada uma das folhas
Tom Horwood