简体   繁体   English

工作表的谷歌脚本不复制单元格内的公式,只复制值

[英]Google script for sheets not copying formulas inside cells, only the values

I found this excellent script by --Hyde on support.google.com called moveRowsFromSpreadsheetToSpreadsheet , which enables the transfer of Google Sheet rows between a target sheet and a destination sheet, based on a value set in a dropdown cell for each row in the target sheet.我在support.google.com 上找到了这个名为 moveRowsFromSpreadsheetToSpreadsheet优秀脚本,它可以根据目标中每一行的下拉单元格中设置的值,在目标工作表和目标工作表之间传输 Google 工作表行床单。

The challenge i'm facing is that the script is copying & pasting values only for each cell, not the formulas inside those cells .我面临的挑战是脚本仅为每个单元格复制和粘贴值而不是这些单元格中的公式

My spreadsheet contains cells with =IMAGE() formulas and =HYPERLINK() formulas and these cells are transferred either empty (in cells where I have =IMAGE() formulas) or non-hyperlinked values only (in cells where I have =HYPERLINK() formulas).我的电子表格包含带有=IMAGE()公式和=HYPERLINK()公式的单元格,并且这些单元格被转移为空(在我有=IMAGE()公式的单元格中)或仅非超链接值(在我有=HYPERLINK()公式)。

My hope is, if at all possible, to find a way to modulate the script so it will copy & paste the rows as they are, with formulas and all , and not just values only for each cell.我的希望是,如果可能的话,找到一种方法来调整脚本,以便它可以按原样复制和粘贴行,包括公式和所有内容,而不仅仅是每个单元格的值。 Similar to the manual copying & pasting of cell ranges.类似于单元格范围的手动复制和粘贴。

I'm guessing it has to do with the targetRange.setValues([values]);我猜它与targetRange.setValues([values]);有关class in line 269 which probably should have used the targetRange.copyTo(destination, options);第 269 行中的 class 可能应该使用targetRange.copyTo(destination, options); class. I tried to change the class but it returned the following error: "The parameters (number[]) don't match the method signature for SpreadsheetApp.Range.copyTo. Code line 270" class。我尝试更改 class 但它返回以下错误:“参数 (number[]) 与 SpreadsheetApp.Range.copyTo 的方法签名不匹配。代码行 270”

Here is the script:这是脚本:

try {
  // START Modifiable parameters
  var sheetsToWatch =       ['Incoming'];
  var columnsToWatch =      ['Review'];
  var valuesToWatch =       ['ignore','threat','defamatory'];
  var targetSheets =        ['Ignored','Threats','Defamation'];
  var targetSpreadheets =   ['18Cj0oSroQJ_c_4exPK03ubqUd3Fpr8o1M1lzebsyD9g','18Cj0oSroQJ_c_4exPK03ubqUd3Fpr8o1M1lzebsyD9g','18Cj0oSroQJ_c_4exPK03ubqUd3Fpr8o1M1lzebsyD9g'];
  var targetIdColumn =      ['Review'];
  var targetValues =        [];
  var copyInsteadOfMove =   [false, false, false];
  var numColumnsToMove =    [];
  var changeColumnOrderTo = [];
  var sheetsToSort =        [];
  var columnToSortBy =      [];
  var sortAscending =       [];
  // END modifiable parameters
} catch (error) {
  showAndThrow_(error);
}

function moveRowsFromSpreadsheetToSpreadsheet_(e) {
  if (!e || !e.range) {
    return;
  }
  var sourceSheet = e.range.getSheet();
  var sourceSheetName = sourceSheet.getName();
  if (sheetsToWatch.indexOf(sourceSheetName) === -1) {
    return;
  }
  var columnLabelRow = sourceSheet.getFrozenRows() || 1;
  var numSheetColumns = sourceSheet.getLastColumn();
  var columnLabels = sourceSheet.getRange(columnLabelRow, 1, 1, numSheetColumns).getValues()[0];
  if (targetIdColumn.length && targetValues.length) {
    var targetIdColumnNumber = columnLabels.indexOf(targetIdColumn[0]) + 1;
    if (!targetIdColumnNumber) {
      throw new Error('Could not find a column named "' + String(targetIdColumn[0]) + '".');
    }
  }
  for (var i = 0, numValuesToWatch = valuesToWatch.length; i < numValuesToWatch; i++) {
    valuesToWatch[i] = String(valuesToWatch[i]).toLowerCase();
  }
  var values = e.range.getDisplayValues();
  var rowsToDelete = [];
  var numRowsMoved = 0;
  var messageOnDisplay = false;
  for (var row = 0, numRows = values.length; row < numRows; row++) {
    for (var column = 0, numColumns = values[row].length; column < numColumns; column++) {
      if (e.range.rowStart + row <= columnLabelRow) {
        continue;
      }
      var columnLabel = columnLabels[e.range.columnStart - 1 + column];
      if (columnsToWatch.indexOf(columnLabel) === -1) {
        continue;
      }
      var valueLowerCase = values[row][column].toLowerCase();
      var valuesToWatchIndex = valuesToWatch.indexOf(valueLowerCase);
      if (valuesToWatchIndex === -1) {
        continue;
      }
      if (targetIdColumn.length && targetValues.length) {
        var valueInTargetIdColumn = sourceSheet.getRange(e.range.rowStart + row, targetIdColumnNumber).getValue();
        var targetIndex = targetValues.indexOf(valueInTargetIdColumn);
      } else {
        targetIndex = valuesToWatchIndex;
      }  
      if (targetIndex === -1) {
        continue;
      }
      // all checks done, there is at least one row to move
      var movedRowIndex = e.range.rowStart + row;
      if (!messageOnDisplay) {
        showMessage_('Moving rows...', 30);
        messageOnDisplay = true;
      }
      var sourceRange = sourceSheet.getRange(e.range.rowStart + row, 1, 1, numSheetColumns);
      var rowValuesInOriginalOrder = sourceRange.getValues()[0];
      if (numColumnsToMove[targetIndex] !== undefined) {
        var rowValues = rowValuesInOriginalOrder.slice(0, numColumnsToMove[targetIndex]);
      } else {
        rowValues = rowValuesInOriginalOrder.slice();
      }
      for (var changeIndex = 0; changeIndex < changeColumnOrderTo.length; changeIndex++) {
        if (changeColumnOrderTo[changeIndex] !== undefined) {
          rowValues[changeIndex] = rowValuesInOriginalOrder[changeColumnOrderTo[changeIndex]];
        } else if (rowValues[changeIndex] === undefined) {
          rowValues[changeIndex] = null;
        }
      }
      if (targetSpreadheets[targetIndex]) {
        try {
          var targetSpreadsheet = SpreadsheetApp.openById(targetSpreadheets[targetIndex]);
        } catch (error) {
          var ssIdShortened = String(targetSpreadheets[targetIndex]).slice(0, 5) + '...' + String(targetSpreadheets[targetIndex]).slice(-5);
          throw new Error("Could not find the target spreadsheet with ID '" + ssIdShortened + "'.");
        }
      } else {
        targetSpreadsheet = sourceSheet.getParent();
      }
      var targetSheet = targetSpreadsheet.getSheetByName(targetSheets[targetIndex]);
      if (!targetSheet) {
        throw new Error("Could not find the target sheet '" + targetSheets[targetIndex] + "'.");
      }
      var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1, 1, rowValues.length);
      targetRange.setValues([rowValues]);
      numRowsMoved += 1;
      if (!copyInsteadOfMove[targetIndex]) {
        rowsToDelete.push(e.range.rowStart + row);
      }
    } // column
  } // row
  if (messageOnDisplay) {
    var message = (rowsToDelete.length ? 'Moved ' : 'Copied ') + numRowsMoved + (numRowsMoved === 1 ? ' row.' : ' rows.');
    showMessage_('Moving rows... done. ' + message);
  }
  if (rowsToDelete.length) {
    for (var i = rowsToDelete.length - 1; i >= 0; i--) {
      sourceSheet.deleteRow(rowsToDelete[i]);
    }
  }
  return { sourceSheet: sourceSheet, targetSheet: targetSheet };
}

function installOnEditTrigger() {
  ScriptApp.newTrigger('moveRowsAndSortSheet_')
  .forSpreadsheet(SpreadsheetApp.getActive())
  .onEdit()
  .create();  
}

From the question从问题

I tried to change the class but it returned the following error: "The parameters (number[]) don't match the method signature for SpreadsheetApp.Range.copyTo. Code line 270"我尝试更改 class 但它返回以下错误:“参数 (number[]) 与 SpreadsheetApp.Range.copyTo 的方法签名不匹配。代码行 270”

The error means that the first argument is an Array of numbers but SpreadsheetApp.Range.copyTo requires a Class Range object.该错误意味着第一个参数是数字数组,但SpreadsheetApp.Range.copyTo需要 Class 范围 object。

The solution to this error is to pass an appropiate object. By the other hand, the copyTo method should be applied to the source range instead of the target range.此错误的解决方案是传递一个适当的 object。另一方面,应该将copyTo方法应用于源范围而不是目标范围。

Instead of代替

targetRange.copyTo(destination, options);

try尝试

sourceRange.copyTo(targetRange, options);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM