Dans Google Spreadsheet, recherche des formules faisant référence à une valeur donnée

17

Je voudrais savoir quelles cellules ont des dépendances de formule dans une grande feuille de calcul. Je cherche un moyen de faire quelque chose comme OpenOffice

Outils> Détective> Dépendant des traces

et

Édition> Rechercher et remplacer> Rechercher dans les formules

ou un moyen de créer un déclencheur dans GAS qui est appelé lorsqu'une valeur de cellule donnée est référencée et peut identifier la source de la référence.

MetaEd
la source

Réponses:

12

Le code suivant ajoutera un menu à la feuille de calcul:

Détective> Trace Dependents

Sélectionnez cette option pour ajouter une note à la cellule active avec toutes les références de cellule dépendantes.

(ajout de la recherche de références statiques comme suggéré par Graham ci-dessous)

Vous pouvez ajouter une fonction similaire à la fonction traceDependents pour rechercher le texte dans la cellule active d'une fonction Rechercher dans les formules. Je vais laisser cela comme un exercice pour vous.

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
la source
C'est formidable. Je pense que vous pouvez supprimer la ligne supplémentaire: var output = "Dependents:";
jaredcohe
Bien attrapé. Je l'ai retiré. Merci pour les yeux d'aigle.
Tom Horwood
J'aime beaucoup ça! Est-ce que je vois bien qu'il ne prend pas en charge les plages nommées, cependant? Et si tel est le cas, serait-il simple / compliqué d'ajouter un support?
Wizek
2
Comment utiliser le code?
Ferrybig
1
pourquoi la ligne menuEntries.push({name: "Trace Dependents", functionName: "traceDependents"});apparaît-elle deux fois dans le code?
ThomasMcLeod
4

C'est super et cela m'a fait économiser beaucoup de travail - merci.
Cependant, la réponse ci-dessus ne trouve aucune référence utilisant le fixateur de ligne ou de colonne $.
La légère modification suivante du code accomplit cela:

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
la source
Merci; cela a quelque peu aidé. Comment pourrait-on le faire fonctionner sur plusieurs feuilles de calcul?
wizonesolutions du
Merci Graham - J'ai intégré vos changements. En ce qui concerne le travail entre les feuilles de calcul, le code aurait besoin d'un peu d'ajustement pour incorporer le nom de la feuille, puis parcourir chacune des feuilles
Tom Horwood