【问题标题】:Javascript custom function to extract text string from formula Google SpreadsheetsJavascript自定义函数从公式Google电子表格中提取文本字符串
【发布时间】:2015-07-09 02:35:11
【问题描述】:

我正在尝试从 Google 电子表格中的公式中提取文本字符串。具体来说,我有一列包含HYPERLINK 公式,我想从中使用自定义函数创建另一个列,其中包含提取的公式文本,以便在具有=HYPERLINK("https://twitter.com/jrosenberg6432/status/617013951184957440") 的单元格上调用该函数将返回@987654324 @ 在另一个单元格中。

我从this help forum 发现了这个非常有用的功能:

/** Extract a text string in double quotes from the formulas in selected cells
*/


function replaceFormulasWithFirstQuotedTextStringInFormula() {
  // Goes through all the cells in the active range (i.e., selected cells),
  // checks if a cell contains a formula, and if so, extracts the first
  // text  string in double quotes in the formula and stores it in the cell.
  // The formula in the cell is replaced with the text string.
  // see https://productforums.google.com/d/topic/docs/ymxKs_QVEbs/discussion

  // These regular expressions match the __"__ prefix and the
  // __"__ suffix. The search is case-insensitive ("i").
  // The backslash has to be doubled so it reaches RegExp correctly.
  // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp

  var prefix = '\\"';
  var suffix = '\\"';
  var prefixToSearchFor = new RegExp(prefix, "i");
  var suffixToSearchFor = new RegExp(suffix, "i");
  var prefixLength = 1; // counting just the double quote character (")

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var activeRange = ss.getActiveRange();
  var cell, cellValue, cellFormula, prefixFoundAt, suffixFoundAt, extractedTextString;

  // iterate through all cells in the active range
  for (var cellRow = 1; cellRow <= activeRange.getHeight(); cellRow++) {
    for (var cellColumn = 1; cellColumn <= activeRange.getWidth(); cellColumn++) {
      cell = activeRange.getCell(cellRow, cellColumn);
      cellFormula = cell.getFormula();

      // only proceed if the cell contains a formula
      // if the leftmost character is "=", it contains a formula
      // otherwise, the cell contains a constant and is ignored
      // does not work correctly with cells that start with '=
      if (cellFormula[0] == "=") {

        // find the prefix
        prefixFoundAt = cellFormula.search(prefixToSearchFor);
        if (prefixFoundAt >= 0) { // yes, this cell contains the prefix
          // remove everything up to and including the prefix
          extractedTextString = cellFormula.slice(prefixFoundAt + prefixLength);
          // find the suffix
          suffixFoundAt = extractedTextString.search(suffixToSearchFor);
          if (suffixFoundAt >= 0) { // yes, this cell contains the suffix
            // remove all text from and including the suffix
            extractedTextString = extractedTextString.slice(0, suffixFoundAt).trim();

            // store the plain hyperlink string in the cell, replacing the formula
            cell.setValue(extractedTextString);
          }
        }
      }
    }
  }
}


/** Add a custom menu to the active spreadsheet, containing a single menu item
*   for invoking the replaceFormulasWithFirstQuotedTextStringInFormula() function.
*   The onOpen() function is automatically run when the spreadsheet is opened.
*/


function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Replace formulas with text strings",
    functionName : "replaceFormulasWithFirstQuotedTextStringInFormula"
  }];
  ss.addMenu("Extract", entries);
}

但是,此函数用提取的文本替换原始单元格,而不是保留原始单元格中的内容并在另一列中返回输出。

我试图编辑代码,但我是一个 Javascript 新手,所以尽管这可能是对它的小修改,但我还是想问一下。

【问题讨论】:

    标签: javascript google-apps-script google-sheets


    【解决方案1】:

    帮助论坛上的帖子很旧。这是一个有效的解决方案。自己测试过。希望能帮助到你。如有问题,请随时给我发消息(我还没有足够的声誉发表评论,哈哈)。

    function myFunction() {
      var formulas = SpreadsheetApp.getActiveRange().getFormulas();
      var toPut = SpreadsheetApp.getActiveRange().offset(0, 1, SpreadsheetApp.getActiveRange().getNumRows(), 1);
      var extracted = [];
      for(var index in formulas){
        var array = formulas[index];
        for(var formulaIndex in array){
          Logger.log("f:" + array[formulaIndex]);
          extracted.push([array[formulaIndex].substring(array[formulaIndex].indexOf('"')+1, array[formulaIndex].lastIndexOf('"'))]);
        }
      }
    
      toPut.setValues(extracted);
    }
    
    function onOpen(e){
    
        SpreadsheetApp.getUi().createMenu("Testing").addItem("myFunc", 'myFunction').addToUi();
    }
    

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      cell = activeRange.getCell(cellRow, cellColumn);
      
      var output_cell = activeRange.getCell(cellRow, (cellColumn + 1)); 
      //Or put in the column number in which u want the output to be put
      
      cellFormula = cell.getFormula();
      .
      .
      .
      
      //(Keep the rest of the code as it is)
      

      那么,不要在你的函数中写cell.setValue(extractedTextString);, 这样做:

      output_cell.setValue(extractedTextString);
      

      所以,我在这里要做的是将新值放在原始列旁边的列中。

      希望它有效:)

      【讨论】:

      • 这看起来很有希望。我试了一下,收到了这个错误:“单元格引用超出范围”。有什么建议吗?
      • 嗯.. 在原始列旁边创建一个“虚拟列”是否可行?我认为这个错误的原因是它试图写入一个不存在的列。因此,您可以创建一个虚拟列.. 然后它可以写入.. 或者.. 您需要一个函数来创建一个单元格。所以我的意思是,只需在每个单元格中创建一个包含随机文本的列(不以 '=' 开头)
      • 刚刚试过;仍然是同样的错误——列是否可能是 A1 表示法中的索引(例如,下一列是下一个字母,而不是数字,结束)?
      • 在这种情况下,我们可以尝试创建一个var temp = ++cellColumn..,然后使用 temp 作为第二个参数
      猜你喜欢
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多