【问题标题】:How to use Vlookup within an OnEdit function如何在 OnEdit 函数中使用 Vlookup
【发布时间】:2019-12-16 11:48:11
【问题描述】:

所以我正在尝试创建一个考勤系统。基本上我想要的是让人们能够在名为出勤的表格中输入他们的身份证号码。在该列中输入信息后,相邻列(第 2 列)将填充其名称,下一列(第三列)将填充输入时间。进入时间使用 new Date() 计算。但是,我计划让它从位于名为“列表”的工作表上的主列表中检索名称。 “列表”表在 A 列中有 ID,在 B 列中有名称。所以我要做的是让谷歌脚本通过查看最近编辑的单元格来模拟 Vlookup,然后在“列表”列 A 中搜索该值将相邻列中相应的“列表”列 B 值返回到刚刚编辑的单元格。我希望能够在整个“出勤”表中多次执行此操作。所以基本上,我们每天考勤将占据“出勤”表中的三列。

function onEdit(e) {
var sheet = e.source.getActiveSheet();
if (sheet.getName() === "Attendance") {
    var r = e.source.getActiveRange();
    if (r.getRow() != 1 && r.getColumn()%3 != 0 && r.getColumn()%3 != 2) {
    sheet.getRange(r.getRow(),r.getColumn()+2).setValue(new Date());
    var popsheet = SpreadsheetApp.getActiveSpreadsheet.GetSheetByName("list")
    var data=popsheet.getRange("A1:D100").getValues();
    for(i=0;i<data.length;++i){
    if (data[i][0]==r.GetValue()){
    sheet.getRange(r.getRow(),r.getColumn()+1).setValue(data[i][1]);
    }
    }
}

日期填充得很好,但名称没有填充。我没有收到任何错误信息。我尝试将 var popsheet = ... 之后编写的所有内容更改为仅 sheet.getRange(r.getRow(),r.getColumn()+1.setValue("test") 并且它实际上在相邻的返回“test”单元格的列已编辑。所以这让我相信问题出在我试图模拟 Vlookup 上。

【问题讨论】:

  • 首先,在最后一次调用 .setValue 之前,您似乎缺少右括号。此外,由于 data[][] 的起始索引为 0,因此您需要尝试使用 data[][1] 来获取 B 列的数据;有关更多相同内容,请参见下面的答案。
  • 我注意到您的工作表名称之一是“LIST”,而您正在调用 .getSheetByName("list")。会不会区分大小写?
  • 我尝试了几乎所有方法,但没有任何效果。我把它改回全小写以防万一
  • 很高兴为您提供进一步的帮助,但如果您还不知道如何使用 Logger.log(),您应该学习。在您的第三个“if”语句之后,您可以 Logger.log("Data: " + data[i][1]") 来查看您是否获得了正确的值。您还可以 Logger.log("All data: " + data) 来查看整个集合。如果您还没有这样做,那应该可以帮助您更接近。

标签: google-apps-script google-sheets


【解决方案1】:

试试这个:

function onEdit(e) {
  var sheet = e.source.getActiveSheet();
  if(sheet.getName()=="Attendance") {
    if (e.range.rowStart > 1 && e.range.columnStart % 3 == 1) {
      var sh=e.source.getSheetByName("list");
      e.source.toast(sh.getName());
      var data=sh.getRange(2,1,sh.getLastRow(),4).getValues();
      for(i=0;i<data.length;i++){
        if (data[i][0]==e.value){
          e.range.offset(0,1).setValue(data[i][2]);
          e.range.offset(0,2).setValue(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss"));
        }
      }
    }
  }
}

如果未找到名称,这将清除同一行的下两列。

function onEdit(e) {
  var sheet = e.source.getActiveSheet();
  if(sheet.getName()=="Attendance") {
    if (e.range.rowStart > 1 && e.range.columnStart % 3 == 1) {
      var sh=e.source.getSheetByName("list");
      e.source.toast(sh.getName());
      var data=sh.getRange(2,1,sh.getLastRow(),4).getValues();
      var found=false;
      for(i=0;i<data.length;i++){
        if (data[i][0]==e.value){
          e.range.offset(0,1).setValue(data[i][2]);
          e.range.offset(0,2).setValue(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy HH:mm:ss"));
          found=true;
        }
      }
      if(!found) {
        e.range.offset(0,1).setValue('');
        e.range.offset(0,2).setValue('');
      }
    }
  }
}

【讨论】:

  • 由于某种原因它仍然没有填充名称
  • 没有样本数据我无法调试。
  • 好的。我想我明白了。
【解决方案2】:

我相信改变这条线:

sheet.getRange(r.getRow(),r.getColumn()+1.setValue(data[i][2]);

到这里:

sheet.getRange(r.getRow(),r.getColumn()+1).setValue(data[i][1]);

应该可以解决您的问题。

data[i][2] 对应于第 i 行和第 3 列(A 列),但我相信您想要 data[i][1],即列B.

【讨论】:

  • 是的,你说得对,这些绝对是问题。但是,即使在更改它们之后,它仍然不会返回名称。我也相应地更改了我的代码。
  • @Sebastian 你知道如何使用 Logger.log() 吗?
  • 不,我对一般的日志记录很熟悉,但是,我从未在 Javascript/google 脚本中使用过日志记录。我将如何在此代码中实现日志?
  • 添加 Logger.log("Hello, world!");代码中的任何位置。运行代码后,转到“查看|日志”或只需键入 Ctrl+Enter 即可显示日志。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多