En la hoja de cálculo de Google, encontrar qué fórmulas hacen referencia a un valor dado

17

Me gustaría saber qué celdas tienen dependencias de fórmulas en una hoja de cálculo grande. Estoy buscando una manera de hacer algo como OpenOffice

Herramientas> Detective> Seguimiento de dependientes

y

Edición> Buscar y reemplazar> Buscar en fórmulas

o una forma de crear un desencadenante en GAS que se llama cuando se hace referencia a un valor de celda determinado y puede identificar la fuente de la referencia.

MetaEd
fuente

Respuestas:

12

El siguiente código agregará un menú a la hoja de cálculo:

Detective> Rastrear dependientes

Al seleccionar esto, se agregará una nota a la celda activa con todas las referencias de celda dependientes.

(búsqueda adicional de referencias estáticas como lo sugiere Graham a continuación)

Puede agregar una función similar a la función traceDependents para buscar el texto dentro de la celda activa para una función Buscar en fórmulas. Lo dejaré como un ejercicio para ti.

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
fuente
Esto es fabuloso. Creo que puede eliminar la línea adicional: var output = "Dependents:";
jaredcohe
Bien atrapado. Lo he quitado Gracias por los ojos de águila.
Tom Horwood
¡Esto me gusta mucho! Sin embargo, ¿veo correctamente que no admite rangos con nombre? Y si ese es el caso, ¿sería simple / complicado agregar soporte?
Wizek
2
¿Cómo usar el código?
Ferrybig
1
¿Por qué la línea menuEntries.push({name: "Trace Dependents", functionName: "traceDependents"});aparece dos veces en el código?
ThomasMcLeod
4

Esto es super y me ha ahorrado mucho trabajo, gracias.
Sin embargo, la respuesta anterior no encuentra ninguna referencia que use el fijador de fila o columna $.
El siguiente ligero cambio en el código logra eso:

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
fuente
Gracias; Esto ayudó un poco. ¿Cómo se podría hacer que funcione en las hojas de trabajo?
wizonesolutions
Gracias Graham. He incorporado tus cambios. En cuanto a trabajar en hojas de trabajo, el código necesitaría un poco de ajuste para incorporar el nombre de la hoja y luego recorrer cada una de las hojas
Tom Horwood,