【问题标题】:An Array to copy and paste from one sheet to another用于从一张纸复制并粘贴到另一张纸的数组
【发布时间】:2019-11-17 16:52:35
【问题描述】:

Java 脚本新手,因此寻求帮助,我正在设计一个包含两张工作表的假日电子表格

  • 包含每个部门团队成员的主表(表 4)
  • 假期表,用户可以输入他们的团队假期 (Sheet5)。

我找到了一个脚本,可以在表 4 和表 5 中插入一行或删除一行,但我现在需要一个脚本来复制表 4 中新插入的行的内容并将数据粘贴到新的在工作表 5 中插入的行与工作表 4 位于同一行。

例如,如果我在表 4 的 A10 中添加一行,并在 A10 中输入大写“Y”,我希望将 B10 到 I10 的数据复制到 A10 到 NJ10 行的表 5。 我试图找到解决方案,但无法使用 Copyto 命令使其正常工作。

有人对此有解决方案吗?

function onEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet5 = ss.getSheetByName('Sheet5');
  var sheet4 = ss.getSheetByName("Sheet4");
  var values1 = sheet4.getRange("A:A").getValues();
  var values2 = sheet4.getRange("A:A").getValues();
  var values3 = sheet4.getRange("A:A").getValues();
  // This starts off the remove and Insert Row Code
  var deleteRow = new Array(); // Part of remove and Insert Row Code
  var insertRow = new Array(); // Part of remove and Insert Row Code
  var copyPaste = new Array(); // Copies to Sheet5  
  for (var i = 0; i < values1.length; i++) {
    if (values1[i] == 'D') {
      deleteRow.push(i + 1); // This line was added for debugging purposes.
      var X = sheet4.getRange(i + 1, "2").getValues();
      var response = Browser.msgBox('WARNING!!  You are about to Delete the record for', X, Browser.Buttons.YES_NO);
      Logger.log(response);
      if (response == "yes") {

      } else {
        sheet4.getRange('A:A').clearContent();
        Browser.msgBox('Cancelled', 'The operation has been cancelled', Browser.Buttons.OK);
      }
    }
  }
  for (var i = deleteRow.length - 1; i >= 0; i--) {
    sheet4.deleteRow(deleteRow[i]);
  }
  for (var i = deleteRow.length - 1; i >= 0; i--) {
    sheet5.deleteRow(deleteRow[i]);
  }
  for (var k = 0; k < values2.length; k++) {
    if (values2[k] == 'I') {
      insertRow.push(k + 1); // This line was added for debugging purposes.        
      sheet4.getRange('A:A').clearContent(); //Removes "I" to stop code repeating
    }
  }

  for (var k = insertRow.length - 1; k >= 0; k--) {
    sheet4.insertRowAfter(insertRow[k]);
  }
  for (var k = insertRow.length - 1; k >= 0; k--) {
    sheet5.insertRowAfter(insertRow[k]);
  }
  for (var m = 0; m < values3.length; m++) {
    if (values3[m] == 'Y') {
      copyPaste.push(m + 1); // This line was added for debugging    purposes.        
      sheet4.getRange('A:A').clearContent(); //Removes "Y" to stop code repeating
    }
  }
  for (var m = copyPaste.length - 1; m >= 0; m--) {
    sheet4.copyTo('B2:I13')(copyPaste[m]);
  }
  for (var m = copyPaste.length - 1; m >= 0; m--) {
    sheet4.copyTo('B2:J13')(copyPaste[m]);
  }
}
 //----------------------------------------------------------------------------

function onEdit(e) {
 // so 56930421_04
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();
  var mastername = "Sheet4";
  var master = ss.getSheetByName(mastername);
  var hols = ss.getSheetByName('Sheet5');

  // get the range for Master and the data also
  var masterLR = master.getLastRow();
  var masterRange = master.getRange(4,2,masterLR-3,8);
  Logger.log("DEBUG: MASTER range = "+masterRange.getA1Notation());
  var masterData = masterRange.getValues();

  // get the last Column for hols for use in setting the update range
  var holsLC = hols.getLastColumn();
   Logger.log("DEBUG: the last column on Hols = "+holsLC);

  // display event objects - two mwthods displayed here
  // Method#1
   Logger.log(JSON.stringify(e))

  // Method#2
  // var debug_e = {authMode:  e.authMode,range:  e.range.getA1Notation(),source:  e.source.getId(),user:  e.user,value:  e.value,oldValue: e. oldValue};
   //Logger.log("DEBUG: AuthMode: "+debug_e.authMode+", Range: "+debug_e.range+", source: "+debug_e.source+", user: "+debug_e.user+", value: "+debug_e.value+", old value: "+debug_e.oldValue);

  // get the column, row and sheet name of the edited cell
  var editColumn = e.range.getColumn();
  var editRow = e.range.getRow();
  var editSheet = e.range.getSheet().getSheetName();
  Logger.log("DEBUG: editted Column = "+editColumn+", editted Row = "+editRow+", edited Sheet = "+editSheet);

  // set variable
  var firstdatarow = 4;

  // create if statement
  // iF the edited row is between firstdatarow and the last row
  // AND
  // IF the edited column is Column#1  (Column A)
  // AND
  // IF the edited sheet is Master
  if (firstdatarow < editRow && editRow < masterLR && editColumn == 1 && e.value == "Y" && editSheet == mastername) {

    // do something
     Logger.log("DEBUG: do something");

    // get the employee name
    var empname = masterData[(+editRow-4)][0];
    Logger.log("DEBUG: The employee name is "+empname);


    // create an alert to confirm
    var result = ui.alert(
      'WARNING!!  You are about to Update the holiday record for '+empname,
      'Are you sure you want to continue?',
      ui.ButtonSet.YES_NO);

    // Process the user's response.
    if (result == ui.Button.YES) {
      // User clicked "Yes".
      ui.alert('Confirmation received.');


      // build the data to be pasted to Sheet5
      var holsData = [];
      for (var i = 1; i<54;i++){ 
        for (var x = 1; x<8;x++){
          holsData.push(masterData[(+editRow-1)][x]);
        }
        Logger.log("DEBUG: hols = "+holsData+", length = "+holsData.length);
      }
      Logger.log("DEBUG: Progressive holsData = "+holsData+", length = "+holsData.length);


      // create the range for Sheet5
      var target = hols.getRange(editRow,2,1,(+holsLC-1));
      Logger.log("DEBUG: the target range = "+target.getA1Notation());

      // update the values to Sheet5
      target.setValues([holsData]);

      //Removes "Y" to stop code repeating
      master.getRange(editRow,editColumn).clearContent();


    } else {

      // User clicked "No" or X in the title bar.
      ui.alert('Permission denied.');

      //Removes "Y" to stop code repeating
      master.getRange(editRow,editColumn).clearContent(); 
    }
  }
  else
  {
    // don't do anything
    Logger.log("don't do anything");
  }  
}




【问题讨论】:

  • 您可能忘记提及您使用的是什么库?例如 PHPExcel。看起来不像你在使用普通的 vsnilla js。
  • 我还不太明白代码。但是需要更改 if 语句。试试: values1[i][0] == 'D' values2[k][0] == 'I' values3[m][0] == 'Y'
  • 感谢您的回复,我正在使用 Google 表格工作 Zim84,但对于应用程序的编码方面非常陌生。
  • ADW,我已经对我的 IF 语句进行了更改。我认为问题在于最后两个 For 循环,没有任何内容复制到 Sheet5,但我也没有收到错误消息,脚本也没​​有崩溃。
  • 欢迎。你能澄清一些事情吗? 1)“找到一个脚本,将在表 4 和表 5 中插入一行或删除一行”这是您问题中的 onEdit(e) 吗? 2) 你使用这个 OnEdit(e),还是打算作为开发新代码的基础?例如。代码删除行,您确认要从“Sheet4”中删除行吗? 3)“从 B10 到 I10 [复制到] A10 到 NJ10 行中的表 5 的数据”。 “B10”和“I10”之间有8列,但“A10”和“NJ10”之间有更多。请确认“sheet5”的目标范围。

标签: google-apps-script google-sheets


【解决方案1】:

事件对象虽然您选择使用onEdit 触发器,但您没有使用任何由onEdit() 自动生成的事件对象。这将使您能够简化代码并创建明确的IF 语句来验证是否在正确的列、行和工作表中输入了“Y”。

代码开发 您显然在开发代码时重新定义了目标;包括(最终)删除、插入和追加行的不必要步骤。这会使您的代码复杂化,例如为 sheet4.getRange("A:A").getValues(); 创建的三个相同变量

推送数组值 当您开始将值推送到临时数组时,您找到了更新“Sheet5”的正确策略。在这个答案中,我创建了两个嵌套循环来构建必要的值。第一个循环为 53 周,第二个循环为 7 天 - 因此该数组是每周构建的,持续 53 周。

此答案中描述的代码只是一种方法。您可能还有其他方法可以实现您的目标。我还在代码中留下了一些Logger.log() 语句;您可能希望在函数的不同阶段使用这些标识值。


function onEdit(e) {

  // so 56930421_04
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();
  var mastername = "Sheet4";
  var master = ss.getSheetByName(mastername);
  var hols = ss.getSheetByName('Sheet5');

  // get the range for Master and the data also
  var masterLR = master.getLastRow();
  var masterRange = master.getRange(4,2,masterLR-3,8);
  //Logger.log("DEBUG: MASTER range = "+masterRange.getA1Notation());
  var masterData = masterRange.getValues();

  // get the last Column for hols for use in setting the update range
  var holsLC = hols.getLastColumn();
  // Logger.log("DEBUG: the last column on Hols = "+holsLC);

  // display event objects - two mwthods displayed here
  // Method#1
  // Logger.log(JSON.stringify(e))

  // Method#2
  // var debug_e = {authMode:  e.authMode,range:  e.range.getA1Notation(),source:  e.source.getId(),user:  e.user,value:  e.value,oldValue: e. oldValue};
  // Logger.log("DEBUG: AuthMode: "+debug_e.authMode+", Range: "+debug_e.range+", source: "+debug_e.source+", user: "+debug_e.user+", value: "+debug_e.value+", old value: "+debug_e.oldValue);

  // get the column, row and sheet name of the edited cell
  var editColumn = e.range.getColumn();
  var editRow = e.range.getRow();
  var editSheet = e.range.getSheet().getSheetName();
  //Logger.log("DEBUG: editted Column = "+editColumn+", editted Row = "+editRow+", edited Sheet = "+editSheet);

  // set variable
  var firstdatarow = 4;

  // create if statement
  // iF the edited row is between firstdatarow and the last row
  // AND
  // IF the edited column is Column#1  (Column A)
  // AND
  // IF the edited sheet is Master
  if (firstdatarow <= editRow && editRow <= masterLR && editColumn == 1 && e.value == "Y" && editSheet == mastername) {

    // do something
    // Logger.log("DEBUG: do something");

    // get the employee name
    var empname = masterData[(+editRow-4)][0];
    //Logger.log("DEBUG: The employee name is "+empname);


    // create an alert to confirm
    var result = ui.alert(
      'WARNING!!  You are about to Update the holiday record for '+empname,
      'Are you sure you want to continue?',
      ui.ButtonSet.YES_NO);

    // Process the user's response.
    if (result == ui.Button.YES) {
      // User clicked "Yes".
      ui.alert('Confirmation received.');


      // build the data to be pasted to Sheet5
      var holsData = [];
      for (var i = 1; i<54;i++){ 
        for (var x = 1; x<8;x++){
          holsData.push(masterData[(+editRow-4)][x]);
        }
        //Logger.log("DEBUG: hols = "+holsData+", length = "+holsData.length);
      }
      //Logger.log("DEBUG: Progressive holsData = "+holsData+", length = "+holsData.length);


      // create the range for Sheet5
      var target = hols.getRange(editRow,2,1,(+holsLC-1));
      //Logger.log("DEBUG: the target range = "+target.getA1Notation());

      // update the values to Sheet5
      target.setValues([holsData]);

      //Removes "Y" to stop code repeating
      master.getRange(editRow,editColumn).clearContent();


    } else {

      // User clicked "No" or X in the title bar.
      ui.alert('Permission denied.');

      //Removes "Y" to stop code repeating
      master.getRange(editRow,editColumn).clearContent(); 
    }
  }
  else
  {
    // don't do anything
    Logger.log("don't do anything");
  }  
}

【讨论】:

  • 您好,我收到以下错误 var editColumn = e.range.getColumn();错误消息说 Type error:Cannot read property "Range" form yndefined (line 29,File "code"
  • 这是您手动运行onEdit(e) 函数(从脚本编辑器)时遇到的错误。 onEdit 旨在在用户更改电子表格DocsDocs 中的值时运行。单击“关闭”以消除错误消息,然后跳转到电子表格的 Sheet4 并在其中一个员工姓名旁边的 A 列中键入“Y”(大写字母)。
  • 您好,非常感谢您的帮助。我有一段我会经常使用的代码。显然,我还有很多东西要学,但我现在可以继续我需要做的其他事情。再次感谢您的所有帮助 Col
猜你喜欢
  • 2020-06-12
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
相关资源
最近更新 更多