【问题标题】:Vlookup at Google Apps Script with for loop [duplicate]带有 for 循环的 Google Apps 脚本中的 Vlookup [重复]
【发布时间】:2020-12-07 13:51:08
【问题描述】:

我需要你的帮助。我想做一个 for 循环或其他类似公式 =Vlookup 的东西

我有两张床单。在 Sheet1(概述)中,A 列中有 1000、1002、1003、...、100X 等 ID;

Sheet2 是表单响应表(Response),您需要在其中输入您的 ID 和带有“Ok”和“Nok”的 Action。我输入的 ID 出现在 Sheet2 Column B 中,而 Action (Ok/Nok) 出现在 Sheet2 Column C 中。

现在我想使用 onFormSubmit 函数将 Ok/Nok 复制到概览表中具有相同 ID 的行。

例如。 ID 为 1005 的人员使用“Ok”操作做出表单响应。现在应该将“确定”复制到 B 列中的概览表和确切的行中(在本例中:ID 为 1005 的行)。

这是我的功能。但我不想在表格中有公式。所以我寻求另一种解决方案。

 function vlookup() {

   var ss = SpreadsheetApp.getActiveSpreadsheet();
   var sheet = ss.getSheets()[0];

   var cell = sheet.getRange(1,5);
    cell.setFormula('=ARRAYFORMULA(IFS(ROW(Response!B:B)=1,"Action from 
    User",Response!B:B="","",TRUE,IFERROR(VLOOKUP(A:A,Response!B:C,2,0),"Waiting for Response")))');
 }

希望有人可以帮助我。 提前感谢您的帮助!

乔纳斯

【问题讨论】:

标签: arrays for-loop google-apps-script match vlookup


【解决方案1】:

感谢您提供所有这些答案。我尝试了 stackoverflow.com/questions/60255775 中的代码 - TheMaster,效果很好!

但对于编程初学者来说,它看起来非常复杂。特别是带有“哈希”的部分。 如果在表单中使用 Nok,我还添加了第二个比较和复制以从原因中获取数据。

const ss = SpreadsheetApp.getActive();
/**
 * @param {GoogleAppsScript.Spreadsheet.Sheet} fromSht -Sheet to import from
 * @param {GoogleAppsScript.Spreadsheet.Sheet} toSht -Sheet to import to
 * @param {Number} fromCompCol -Column number of fromSht to compare
 * @param {Number} toCompCol -Column number of toSht to compare
 * @param {Number} fromCol -Column number of fromSht to get result
 * @param {Number} toCol -Column number of toSht to get result
 */
function copyToOverview(e,response,
  fromSht = ss.getSheetByName('Response'),
  toSht = ss.getSheetByName('Overview'),
  fromCompCol = 2,
  toCompCol = 1,
  fromCol = 3,
  toCol = 2,
  fromColRej = 4,
  toColRej = 3
  
) {
  const toShtLr = toSht.getLastRow();
  const toCompArr = toSht.getRange(2, toCompCol, toShtLr - 1, 1).getValues();
  const fromArr = fromSht.getDataRange().getValues();
  fromCompCol--;
  fromCol--;
  fromColRej--;

  /*Create a hash object of fromSheet*/
  const obj1 = fromArr.reduce((obj, row) => {
    let el = row[fromCompCol];
    el in obj ? null : (obj[el] = row[fromCol]);
    return obj;
  }, {});
  
    /*Create a second hash object of fromSheet to copy the Reason why it is Nok (also from filling out the Form) */
  const obj3 = fromArr.reduce((obj2, row) => {
    let el1 = row[fromCompCol];
    el1 in obj2 ? null : (obj2[el1] = row[fromColRej]);
    return obj2;
  }, {});





  //Paste to column  first toSht copy the "ok/nok" second toSht for the Reason why Nok
  toSht
    .getRange(2, toCol, toShtLr - 1, 1)
    .setValues(toCompArr.map(row => (row[0] in obj1 ? [obj1[row[0]]] : [null])));
    
    toSht
    .getRange(2, toColRej, toShtLr - 1, 1)
    .setValues(toCompArr.map(row => (row[0] in obj3 ? [obj3[row[0]]] : [null])));
    
    
}

我还尝试了“Michiel the Temp”中的代码,它接缝,它也可以工作。

“Mateo Randwolf”的代码看起来很简单,我也试过了。效果也很好! 我已经对其进行了一些修改,它可以像我希望的那样工作!我想我会使用这段代码。

function onFormSubmit(e) {
  // Get the sheet where the form responses are submitted and the one where we want to check the IDs
  var formSheet = SpreadsheetApp.getActive().getSheetByName('Response');
  var destinationSheet = SpreadsheetApp.getActive().getSheetByName('Overview');
  
  // Get the new incoming data (ID and Ok/Nok) with each form submit by accessing  
  // the trigger object e which is the submited and new form response row
  var submittedId = formSheet.getRange(e.range.getRow(), 2).getValue();
  var submittedValue = formSheet.getRange(e.range.getRow(), 3).getValue();
  var submittedValueReason = formSheet.getRange(e.range.getRow(), 4).getValue();

  
  
  // get all the ID values we have in the sheet we want to check them. flat will convert all the returning
  // 2D array of values in a 1D array with all the IDs
  var idRange = destinationSheet.getRange(1, 1, destinationSheet.getLastRow(),1).getValues().flat();
  
  // iterate over all your IDs
  for(i=0;i<idRange.length;i++){
    // if one ID is the same as the incoming one from the form response
    if(idRange[i] == submittedId){
      // set its value to the one submitted by the form
      destinationSheet.getRange(i+1, 2).setValue(submittedValue);
    }        
    
    if(idRange[i] == submittedId){
    
      destinationSheet.getRange(i+1, 3).setValue(submittedValueReason);
      destinationSheet.getRange(i+1, 2).getValue() == "Nok" ? destinationSheet.getRange(i+1, 4).setValue("Closed") : destinationSheet.getRange(i+1, 4).setValue("Open");
    }   
      
  }
  
}

感谢大家的帮助,你们太棒了!

所以我可以通过更新表单中的复选框来完成项目中的下一步。

【讨论】:

    【解决方案2】:

    我没有使用触发器对此进行测试,但这应该可以工作

     function vlookup() {
       var ssOverview = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Overview");
       var ssOverviewLr = ssOverview.getLastRow();
       var ssOverviewData = ssOverview.getRange(2, 1, ssOverviewLr, 1).getValues(); //assuming you have a header in the first row
       
       var ssResponse = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Response");
       var ssResponseLr = ssResponse.getLastRow();
       var newResponse = ssResponse.getRange(ssResponseLr, 2, 1, 2).getValues(); 
       
       var Ids = ssOverviewData.map(function (r){return r[0];});
       
       
       for(var i = 0; i < newResponse.length; i++) 
       {
         var row = newResponse[i];
         var id = row[0];
         var action = row[1];
         
         var index = Ids.indexOf(id);
         
         if(index == -1)
         {
           SpreadsheetApp.getActiveSpreadsheet().toast("No matches", "Be aware")
         }
         else
         {
         ssOverview.getRange(index + 2, 2).setValue(action); //this puts the action in column B
         }
       }
     }
    

    【讨论】:

      【解决方案3】:

      为了在每次提交新表单时检查 ID 并相应地更改 ID 表中的数据,您需要使用installable triggers。具体来说,您应该使用FormSubmit trigger,它会在每次提交表单时触发该功能。除了这个触发器,您还将使用它的event object

      要添加可安装的触发器,请在您的 Apps 脚本编辑器中转到 编辑 -> 当前项目的触发器,然后点击 Add trigger 创建一个新触发器。确保选择 On form submit 作为事件类型并选择下面显示的函数(因此请在创建触发器之前先复制/粘贴下面的函数)。

      以下函数使用此触发事件将传入数据与您的 ID 列 A 进行比较并检查是否匹配,如果匹配,则添加相关的 Ok/Nok 信息。它有不言自明的 cmets:

      function onFormSubmit(e) {
        // Get the sheet where the form responses are submitted and the one where we want to check the IDs
        var formSheet = SpreadsheetApp.getActive().getSheetByName('Form Responses 1');
        var destinationSheet = SpreadsheetApp.getActive().getSheetByName('Check');
        
        // Get the new incoming data (ID and Ok/Nok) with each form submit by accessing  
        // the trigger object e which is the submited and new form response row
        var submittedId = formSheet.getRange(e.range.getRow(), 2).getValue();
        var submittedValue = formSheet.getRange(e.range.getRow(), 3).getValue();
        
        // get all the ID values we have in the sheet we want to check them. flat will convert all the returning
        // 2D array of values in a 1D array with all the IDs
        var idRange = destinationSheet.getRange(1, 1, destinationSheet.getLastRow(),1).getValues().flat();
        
        // iterate over all your IDs
        for(i=0;i<idRange.length;i++){
          // if one ID is the same as the incoming one from the form response
          if(idRange[i] == submittedId){
            // set its value to the one submitted by the form
            destinationSheet.getRange(i+1, 2).setValue(submittedValue);
          }
        }
        
      }

      【讨论】:

        猜你喜欢
        • 2018-05-26
        • 1970-01-01
        • 1970-01-01
        • 2023-01-03
        • 2013-10-04
        • 2023-03-16
        • 2019-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多