简体   繁体   English

如何加快速度惊人的慢谷歌表格应用程序脚本功能,将公式从一列复制到新插入的列

[英]How to speed up surprisingly slow Google Sheets Apps Script functions that copy formulas from one column to newly inserted column

I have a workbook with multiple sheets, and the main sheet has 123 rows and 90 columns currently.我有一个包含多张工作表的工作簿,主工作表目前有 123 行和 90 列。

I've coded the following functions (which work) to define an onChange event handler for the INSERT_COLUMN event that automatically populates the cells of the newly-inserted column with the contents of the column immediately to the left.我编写了以下函数(可以工作)来为INSERT_COLUMN事件定义一个onChange事件处理程序,该事件处理程序自动将新插入的列的单元格填充为紧靠左侧的列的内容。 Then it deletes the values of the cells that are not formulas.然后它删除不是公式的单元格的值。

It's painfully slow, and I'm not sure why.它非常缓慢,我不知道为什么。

How can I speed this up?我怎样才能加快速度? Thanks.谢谢。

function getColumnLetter(a1Notation) {
  const letter = a1Notation.replace(/\d+/, ''); 
  return letter;
}

function getColumnLetterFromNumber(sheet, colNum) {
  const range = sheet.getRange(1, colNum); 
  return getColumnLetter(range.getA1Notation());
}

function forEachRangeCell(range, callback) {
  const numRows = range.getNumRows();
  const numCols = range.getNumColumns();

  for (let i = 1; i <= numCols; i+=1) {
    for (let j = 1; j <= numRows; j+=1) {
      const cell = range.getCell(j, i);

      callback(cell);
    }
  }
}

function deleteAllValuesAndNotesFromNonFormulaCells(range) {
  forEachRangeCell(range, function (cell) {
    if(!cell.getFormula()){ 
      cell.setValue(null);
      cell.clearNote();
    }
  });
}

function onInsertColumn(sheet, activeRng) {  
  if (activeRng.isBlank()) {
    const minCol = 5;
    const col = activeRng.getColumn();
    if (col >= minCol) {
      const prevCol = col - 1;    
      const colLetter = getColumnLetterFromNumber(sheet, col);    
      const prevColLetter = getColumnLetterFromNumber(sheet, prevCol);
      
      //SpreadsheetApp.getUi().alert(`Please wait while formulas are copied to the new column...`);
      const originRng = sheet.getRange(`${prevColLetter}:${prevColLetter}`);    
      originRng.copyTo(activeRng, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);    
      deleteAllValuesAndNotesFromNonFormulaCells(activeRng);
      const completeMsg = `New column ${colLetter} has formulas copied and is ready for new values (such as address, Redfin link, data, ratings).`;
      //SpreadsheetApp.getUi().alert(completeMsg);
      // SpreadsheetApp.getActiveSpreadsheet().toast(completeMsg);
    }
  }
}

function onChange(event) {   
  if(event.changeType === 'INSERT_COLUMN'){
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const sheet = ss.getActiveSheet()
    const colNumber = sheet.getSelection().getActiveRange().getColumn(); 

    const activeRng = sheet.getRange(1,colNumber,sheet.getMaxRows(),1);

    const sheetName = sheet.getName();
  
    if(sheetName === 'ratings'){
      onInsertColumn(sheet, activeRng);
    }
  }
}

Not sure if I fully understand the problem.不确定我是否完全理解这个问题。 So here is a guess.所以这里有一个猜测。

I'd try to change the function with the fancy name deleteAllValuesAndNotesFromNonFormulaCells() this way:我会尝试用这种花哨的名称deleteAllValuesAndNotesFromNonFormulaCells()更改函数:

function deleteAllValuesAndNotesFromNonFormulaCells(range) {

  // get the array with all formulas
  var formulas = range.getFormulas();

  // set all formulas back (it will clear all cells with no formula) 
  range.setFormulas(formulas);

  // get the array with all notes and
  // clear the ements of the 'notes' array that are empty in the array 'formulas'
  var notes = range.getNotes().map((x,i) => formulas[i][0] ? x : ['']);

  // set the modified array 'notes' back on the sheet
  range.setNotes(notes);
}

If you don't need to keep the notes the function can be boiled down to just one line:如果您不需要保留注释,则该功能可以归结为一行:

function deleteAllValuesAndNotesFromNonFormulaCells(range) {
  range.setFormulas(range.getFormulas()).clearNote();
}

Description描述

I don't understand the need for a lot of what the OP has developed.我不明白对 OP 开发的很多东西的需求。 But here is an example of inserting a column to the right, take the column to the left of it and copy it to the new column.但这里是一个在右侧插入一列的示例,将其左侧的列复制到新列中。 Then eliminate any values or notes leaving only the formulas.然后消除任何值或注释,只留下公式。

Since getFormulas() returns a 2D array of strings representing the formulas in the range simpy using setValues(formulas) places the formulas into the cells.由于 getFormulas() 返回代表范围内公式的二维字符串数组,因此使用 setValues(formulas) 将公式放入单元格中。

Code.gs代码.gs

function onChange(e) {
  try {
    if( e.changeType === "INSERT_COLUMN" ) {
      let spread = SpreadsheetApp.getActiveSpreadsheet();
      let sheet = spread.getActiveSheet();
      if( sheet.getName() === "Sheet1" ) {
        // assume insert column to the right
        let colNumber = sheet.getSelection().getActiveRange().getColumn();
        if( colNumber >= 5 ) {
          let activeRng = sheet.getRange(1,colNumber,sheet.getLastRow(),1);
          let originRng = sheet.getRange(1,colNumber-1,sheet.getLastRow(),1);
          originRng.copyTo(activeRng);
          let formulas = activeRng.getFormulas();
          activeRng.setValues(formulas);
          activeRng.clearNote();
        }
      }
    }
  }
  catch(err) {
    SpreadsheetApp.getUi().alert(err);
  }
}

Reference参考

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

相关问题 如何在 Google 表格上将值从一列复制到另一列? - How to copy value from one column to another on Google Sheets? 如何定位和迭代 Google 表格/应用程序脚本中的一个特定列(按列名)? - How to target and iterate through just one specific column (by column name) in Google sheets / apps script? 如何创建 Google Sheets Macro/Apps 脚本来打开新添加的文件并将数据复制到 Master? - How to create Google Sheets Macro/Apps Script to Open Newly Added File and Copy Data to Master? Google表格脚本复制值从数组到列 - Google Sheets Script Copy Values from Array to Column Google表格脚本:如何每天自动复制公式 - Google Sheets script: how to automatically copy down formulas each day 如何加速这个 Google Apps 脚本 - How to Speed Up this Google Apps Script 如何加速 Google Apps Script 运行时? - How to speed up Google Apps Script runtime? 在 Apps 脚本中将所有内容从一列复制到另一列 - Copy everything from one column to another in Apps Script Google Apps 脚本:仅复制和粘贴公式 - Google Apps Script: Copy and Paste Formulas Only 如何使用谷歌应用脚本将数组写入工作表列并将自定义公式添加到旁边的列? - How to write array to sheets column and add custom formula to column next to it using google apps script?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM