Javascript 在1个单元格中合并为值(格式为yyyy mm dd hh:mm的文本和日期时间)

Javascript 在1个单元格中合并为值(格式为yyyy mm dd hh:mm的文本和日期时间),javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,在谷歌表单中,我有两个临时状态的单元格 当我在下拉列表中选择一些文本时: 0(地位)| 1 | 2 | 3 | 在第一个单元格中添加当前日期时间 将状态从下拉列表添加到第二个单元格 然后我想合并(1,2)并将其作为值粘贴到第三个单元格 此公式返回我的预期结果: =IF(AR1="";"";TEXT(AR1;"mm/dd/yyyy hh:mm"))&"->"&AS1 但接下来我想复制动态范围内的这些联合状态。 如果on cell是唯一的值,那么我对它没有任何问题 但如果我尝

在谷歌表单中,我有两个临时状态的单元格

当我在下拉列表中选择一些文本时:

0(地位)| 1 | 2 | 3 |

  • 在第一个单元格中添加当前日期时间
  • 将状态从下拉列表添加到第二个单元格
  • 然后我想合并(1,2)并将其作为值粘贴到第三个单元格

    此公式返回我的预期结果:

    =IF(AR1="";"";TEXT(AR1;"mm/dd/yyyy hh:mm"))&"->"&AS1
    
    但接下来我想复制动态范围内的这些联合状态。 如果on cell是唯一的值,那么我对它没有任何问题

    但如果我尝试复制日期或公式,并不像公式那样粘贴,而是像值一样粘贴,那么脚本不会显示任何错误,但根本不起作用。 当我录制宏时,它正在工作,但当我添加一小段代码来更改事件时,它就不工作了

    也许它很简单,但我尝试了所有的方法来解决它,我不明白为什么它不起作用

    我是JavaScript新手。请给我一些建议为什么要写粘贴公式的代码

    function onChange(e) {
    
    
      var sheet = SpreadsheetApp.getActiveSheet();
      var row = sheet.getActiveRange().getRowIndex();
     var actionCol = 17;
     var mailactionCol = 15;
     var nr_id = 12
       var sourceRange = sheet.getRange(row, actionCol).getValue();
       var mailSourceRange = sheet.getRange(row, mailactionCol).getValue();
       var nr_idRange = sheet.getRange(row, nr_id).getValue();
    
        //check name of sheets
        var sheetName = sheet.getName()
        if(sheetName != "My_name_sheet"){
           return                            //exit function
        }  
    
     /
       var currentCOL = sheet.getActiveRange().getColumnIndex();
    
      switch(currentCOL) 
     {
    
    /// case is column 15
       case 15:
       //currentCOL = 15
      //id_uniq
           if(mailSourceRange == "" && nr_idRange >0) {return}
           if(mailSourceRange !== "" && nr_idRange =="")
          {
          var msr = sheet.getRange(1, 52);
          var mtr = sheet.getRange(row,12);
          msr.copyTo(mtr, {contentsOnly:true});
          }
         break;
    
      //case 17 - case is column 17
    
    
      case 17:
    
           var sourceRange1_17 = sheet.getRange(row, 17);
           var sourceRange1_19 = sheet.getRange(row, 19).getValue();
           var sourceRange1_20 = sheet.getRange(row, 20).getValue();
    
           var targetRange1_18 = sheet.getRange(row, 18);
           var targetRange1_19 = sheet.getRange(row, 19);
           var targetRange1_17 = sheet.getRange(row, 17);
           var targetRange1_20 = sheet.getRange(row, 20);
           var targetRange1_21 = sheet.getRange(row, 21);
    
    
         if(sourceRange != "wordInMyCell") {return} {
         if(sourceRange1_20 == "wordInMyCell") {return} 
         // if(sheet.getRange(row, 20).getValue() == "wordInMyCell") {return}
    
             sourceRange1_17.copyTo(targetRange1_20, {contentsOnly:true});
             targetRange1_19.setValue(new Date()).setNumberFormat('M/d/yyyy H:mm:ss'); 
    
    
    /// PROBLEMS 
    //// 1 not working those method to paste date-time
    
              targetRange1_19,copyTo(sheet.targetRange1_21, {contentsOnly: true});
    
      OR 
              sheet.getRange(row, 19).copyTo(sheet.getRange(row, 21), 
               SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
    
    
    /// 2 try to add formula to paste on cell not as current row but form recorder 
    ///    In recorder its works but when i add here to my code it doesn't.
    
    
              //       sheet.getRange(row, 18).setFormulaR1C1('=CONCATENATE(U2&" 
                        ";X2&" ";AA2&" ";AD2&" ";AG2&" ";AJ2)');
    
              var ss2 = SpreadsheetApp.getActiveSpreadsheet();
              var sheet2 = ss2.getSheets()[0];
                var cell2 = sheet2.getRange("U2");
                cell2.setFormula('=IF(V2="";"";W2&TEXT(V2;"mm/dd/yyyy hh:mm"))');     
      }}}
    

    您选择使用onChange()触发器,但我建议:

    • 使用onEdit(e)触发器
    • 通过在单个单元格中捕获所有历史记录(R列),可以简单地显示状态历史记录。这会产生连锁反应,简化代码;特别是它减少了
      getValue
      语句的数量
    你会注意到:

    • 状态值和日期的连接是通过简单地用“+”连接来实现的。实际上,我添加了一个分号以更好地区分状态和日期

    • 我在每一行中添加了一个换行符,这样状态历史记录更容易阅读。这样做的一个缺点是行高度增加。您可以同样轻松地删除换行符和/或增加Status History列的宽度

    • 如果愿意,可以保留状态历史记录的存档列,但每套只需要一列

    与往常一样,可能有几种方法可以实现这一结果。把这个答案看作是这样做的一种方式。



    屏幕截图


    更新-确保状态代码的一次性使用

    可以从Q列的下拉列表中选择所有状态代码,并且可以多次选择状态代码。但是,状态历史记录只应记录一次状态代码。因此,脚本应检测所选状态代码是否已被使用,如果已被使用,则不应更新状态历史记录

    这是通过只添加几行代码来实现的

    • var statusExist=historyvalue.indexOf(eValue)
      这使用javascript“String”
      indexOf()
      方法,该方法“返回调用字符串对象中第一次出现指定值的索引……如果找不到该值,则返回-1。”
    • 如果(状态存在!=-1){

      如果该方法返回-1,则状态代码以前从未使用过;任何其他值都表明状态代码位于“ALL_Status_history”字段中


    编辑2019年8月13日
    允许在多个授权工作表上进行编辑-通过使用开关实现,代码更改最少

    • 前面的第5行和第6行-(
      var sheetname
      &
      getSheetByName
      )已删除
    • 在第27至43行插入开关。-分配
      var sheetname
      ,其中“CASE”名称有效;易于添加/删除/编辑有效名称
    • 如果在第46行插入;则有条件地执行
      getSheetByName
    • 第55行注释-轻微编辑
    • 对代码或逻辑没有进一步的更改


    请共享您的电子表格副本(无私人或机密数据),但显示成功的结果。感谢您Tedinoz的关注。我创建了一个简单的文件来显示我的问题。稍微修改一点声明,现在我可以粘贴公式。但我希望在计算后>。选择范围(19列)然后像值一样粘贴。我可以澄清一下;请纠正我。您有一张名为“MAIN”的表。Q列(“状态”)是当前状态,由下拉列表填充。R列(所有状态历史记录)是状态值和日期的串联记录,包括分配给Q列的当前值。共有6组单独的历史状态(颜色:S,T,U;V,W,X;Y,Z,AA;AB,AC,AD;AE,AF,AG&AH,AI,AJ)但如果代码有效工作,这些是多余的。目标:当Q列中的状态发生更改时,当前日期和状态应添加到R列中的历史记录中。您好,Tedinoz。谢谢您的解决方案,但我有一个小问题。在我工作表中的所有历史记录中,代码粘贴值加倍。“AAA 08/05/2019 08:31 AAA 08/05/2019 08:31”“BBB 08/05/2019 08:31 BBB 08/05/2019 08:31”我删除跳跳虎,它工作正常:)谢谢你,Tedinoz.ps,我想请你帮个小忙。我的代码是非覆盖的。对我来说,修改你的解决方案,使其无法在第行再次添加相同的状态是很重要的。非常感谢你的帮助。@Gregory_Ame我可以澄清一下吗;如果我错了,请纠正我?所有状态代码都可以从Co中的下拉单元格中选择列Q,可以多次选择状态代码。例如:first=AAA、second=BBB、third=AAA(第二次)等。但是,状态历史记录只应记录一次状态代码。因此,脚本应检测所选状态代码是否已被使用(详细信息见“ALL_status_History”)如果是这样的话,就不应该更新状态历史记录。我回到你的代码Tedinoz,我想问一些事情。是的,Tedinoz。我仍在编写你的精彩代码。:)谢谢你的回答。我只是尝试指定我想问的内容。好的。我只是尝试参考这个过程,不仅是主表,而且我还想在主、AAA、B中使用BB,CCC,但不在DDD表中。名称。当我
    function onEdit(e) {
      // 5731586703
    
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheetname = "MAIN";
      var sheet = ss.getSheetByName(sheetname);
    
      // get a list of the event objects
      // Logger.log(JSON.stringify(e));
    
    
      // get the event source data
      var editedCell = e.range;
      var editRow = editedCell.getRow();
      var editCol = editedCell.getColumn();
      var eValue = e.value;
      var editedSheet = editedCell.getSheet().getName();
      //Logger.log("DEBUG: the cell = "+editedCell.getA1Notation()+", the column = "+editCol+", the row is "+editRow+", the value is "+eValue+", the edited sheet is "+editedSheet);
    
    
      // create some variables for column and row range  
      var statusColumn = 17; // Column Q
      var minstatusRow = 2; // row 2
    
    
      // test for a change in column Q, row 2 and higher on Sheet MAIN
      if (editedSheet === sheetname && statusColumn === editCol && editRow>=minstatusRow && eValue.length !=0 ){
    
    
        // set the range and value for Column R - ALL_status_history
        var historyrange = sheet.getRange(e.range.rowStart,e.range.columnStart).offset(0,1);
        var historyvalue = historyrange.getValue();
        // Logger.log("DEBUG: The history range = "+historyrange.getA1Notation()+", value = "+historyvalue+", length = "+historyvalue.length);
    
        // get the modified value of the STATUS cell from the event object
        // Logger.log("DEBUG: The Status  value = "+e.value);
    
        // get the date of the change
        var changeDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(),  "MM/dd/yyyy hh:mm") ;
        //Logger.log("DEBUG: The change date is "+changeDate);
    
        // build the value of the modified status and the change date
        var statusHistory = e.value+" "+changeDate;
        // Logger.log("DEBUG: the statusHistory is "+statusHistory);
    
        // if historyvalue is blank
        if (historyvalue.length !=0){
          // there's already some history so insert a blank line
          //Logger.log("DEBUG: there's existing history - insert a line");
          var newhistory = historyvalue+"\n"+statusHistory;
          // Logger.log("DEBUG: the new status history = "+newhistory)
        }
        else
        {
          // this is the first entry
          Logger.log("DEBUG: there's no existing history just insert data");
          var newhistory = statusHistory;
          // Logger.log("DEBUG: the new status history = "+newhistory)
        }
    
        // Update the status history
        historyrange.setValue(newhistory);
    
      }
      else
      {
      // the edited cell wasn't in row2 or higher in Column Q
      // do nothing
    
      }
    
    }
    
    function onEdit(e) {
      // 5731586704
    
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheetname = "MAIN";
      var sheet = ss.getSheetByName(sheetname);
    
      // get a list of the event objects
      // Logger.log(JSON.stringify(e));
    
    
      // get the event source data
      var editedCell = e.range;
      var editRow = editedCell.getRow();
      var editCol = editedCell.getColumn();
      var eValue = e.value;
      var editedSheet = editedCell.getSheet().getName();
      //Logger.log("DEBUG: the cell = "+editedCell.getA1Notation()+", the column = "+editCol+", the row is "+editRow+", the value is "+eValue+", the edited sheet is "+editedSheet);
    
    
      // create some variables for column and row range  
      var statusColumn = 17; // Column Q
      var minstatusRow = 2; // row 2
    
    
      // test for a change in column Q, row 2 and higher on Sheet MAIN
      if (editedSheet === sheetname && statusColumn === editCol && editRow>=minstatusRow && eValue.length !=0 ){
    
    
        // set the range and value for Column R - ALL_status_history
        var historyrange = sheet.getRange(e.range.rowStart,e.range.columnStart).offset(0,1);
        var historyvalue = historyrange.getValue();
        // Logger.log("DEBUG: The history range = "+historyrange.getA1Notation()+", value = "+historyvalue+", length = "+historyvalue.length);
    
        // test for an existing Status code in the historyvalue
        var statusExist = historyvalue.indexOf(eValue);
        //Logger.log("DEBUG: The status code: " + eValue + " returned " + statusExist); // if -1 = does not exist, any other value = does not exist
    
        if (statusExist !=-1){
          // do nothing, the statusCode already exists
          Logger.log("DEBUG: do nothing, the Status Code:"+eValue+" has already been used");
        }
        else
        {
          Logger.log("DEBUG: the Status Code:"+eValue+" hasn't been registered yet, so proceed");
          // the status code hasn't been registered yet, so proceed
    
          // get the modified value of the STATUS cell from the event object
          // Logger.log("DEBUG: The Status  value = "+e.value);
    
          // get the date of the change
          var changeDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(),  "MM/dd/yyyy hh:mm") ;
          //Logger.log("DEBUG: The change date is "+changeDate);
    
          // build the value of the modified status and the change date
          var statusHistory = e.value+" "+changeDate;
          // Logger.log("DEBUG: the statusHistory is "+statusHistory);
    
          // if historyvalue is blank
          if (historyvalue.length !=0){
            // there's already some history so insert a blank line
            //Logger.log("DEBUG: there's existing history - insert a line");
            var newhistory = historyvalue+"\n"+statusHistory;
            // Logger.log("DEBUG: the new status history = "+newhistory)
          }
          else
          {
            // this is the first entry
            Logger.log("DEBUG: there's no existing history just insert data");
            var newhistory = statusHistory;
            // Logger.log("DEBUG: the new status history = "+newhistory)
          }
    
          // Update the status history
          historyrange.setValue(newhistory);
    
       }
    
      }
      else
      {
      // the edited cell wasn't in row2 or higher in Column Q
      // do nothing
    
      }
    
    }
    
    function onEdit(e) {
      // 5731586706
      var ss = SpreadsheetApp.getActiveSpreadsheet();
    
      // get a list of the event objects
      // Logger.log(JSON.stringify(e));  
    
      // get the event source data
      var editedCell = e.range;
      var editRow = editedCell.getRow();
      var editCol = editedCell.getColumn();
      var eValue = e.value;
      var editedSheet = editedCell.getSheet().getName();
      //Logger.log("DEBUG: the cell = "+editedCell.getA1Notation()+", the column = "+editCol+", the row is "+editRow+", the value is "+eValue+", the edited sheet is "+editedSheet);
    
      // create some variables for column and row range  
      var statusColumn = 17; // Column Q
      var minstatusRow = 2; // row 2
    
      switch (editedSheet) {
        case "MAIN":
          var sheetname = "MAIN";
          break;
        case "AAA":
          var sheetname = "AAA";
          break;
        case "BBB":
          var sheetname = "BBB";
          break;
        case "CCC":
         var sheetname = "CCC";
          break;
        default:
          var sheetname = "";
          break;
      }
    
      if (sheetname.length !=0){
        // Logger.log("DEBUG: the name of the edited sheet = "+sheetname);
        var sheet = ss.getSheetByName(sheetname);
      }
      else{
        // Logger.log("DEBUG: the name of the edited sheet was not on the list");
      }
    
      // test for a change in column Q, row 2 and higher on a valid sheet
      if (editedSheet === sheetname && statusColumn === editCol && editRow>=minstatusRow && eValue.length !=0 ){
    
        // set the range and value for Column R - ALL_status_history
        var historyrange = sheet.getRange(e.range.rowStart,e.range.columnStart).offset(0,1);
        var historyvalue = historyrange.getValue();
        // Logger.log("DEBUG: The history range = "+historyrange.getA1Notation()+", value = "+historyvalue+", length = "+historyvalue.length);
    
        // test for an existing Status code in the historyvalue
        var statusExist = historyvalue.indexOf(eValue);
        //Logger.log("DEBUG: The status code: " + eValue + " returned " + statusExist); // if -1 = does not exist, any other value = does not exist
    
        if (statusExist !=-1){
          // do nothing, the statusCode already exists
          Logger.log("DEBUG: do nothing, the Status Code:"+eValue+" has already been used");
        }
        else
        {
          Logger.log("DEBUG: the Status Code:"+eValue+" hasn't been registered yet, so proceed");
          // the status code hasn't been registered yet, so proceed
    
          // get the modified value of the STATUS cell from the event object
          // Logger.log("DEBUG: The Status  value = "+e.value);
    
          // get the date of the change
          var changeDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(),  "MM/dd/yyyy hh:mm") ;
          //Logger.log("DEBUG: The change date is "+changeDate);
    
          // build the value of the modified status and the change date
          var statusHistory = e.value+" "+changeDate;
          // Logger.log("DEBUG: the statusHistory is "+statusHistory);
    
          // if historyvalue is blank
          if (historyvalue.length !=0){
            // there's already some history so insert a blank line
            //Logger.log("DEBUG: there's existing history - insert a line");
            var newhistory = historyvalue+"\n"+statusHistory;
            // Logger.log("DEBUG: the new status history = "+newhistory)
          }
          else
          {
            // this is the first entry
            Logger.log("DEBUG: there's no existing history just insert data");
            var newhistory = statusHistory;
            // Logger.log("DEBUG: the new status history = "+newhistory)
          }
          // Update the status history
          historyrange.setValue(newhistory);
       }   
      }
      else
      {
      // the edited cell wasn't in row2 or higher in Column Q
      // do nothing
      }
    }