Google apps script 在函数中实现vlookup和match

Google apps script 在函数中实现vlookup和match,google-apps-script,google-sheets,google-sheets-formula,Google Apps Script,Google Sheets,Google Sheets Formula,我试图在工作表中创建一个函数,它结合了我经常使用的“Vlookup”和“Match”组合 我想用我的函数“Rates”来接受1个参数并返回一个Vlookup和Match的组合,它总是使用相同的值 Vlookup(参数,定义范围(始终保持相同的定义范围),match(A1(始终为单元格A1),不同的定义范围,0),FALSE) 我曾尝试创建一个脚本,但没有编码经验,我收到一个错误“vlookup未定义” 实际结果:#错误 ReferenceError:“vlookup”未定义。(第2行) vloo

我试图在工作表中创建一个函数,它结合了我经常使用的“Vlookup”和“Match”组合

我想用我的函数“Rates”来接受1个参数并返回一个Vlookup和Match的组合,它总是使用相同的值

Vlookup(参数,定义范围(始终保持相同的定义范围),match(A1(始终为单元格A1),不同的定义范围,0),FALSE)

我曾尝试创建一个脚本,但没有编码经验,我收到一个错误“vlookup未定义”

实际结果:
#错误

ReferenceError:“vlookup”未定义。(第2行)


vlookup不是可以在脚本的函数中使用的东西,它是一个电子表格公式

Google脚本使用JavaScript,所以您需要用JS编写代码,然后将其输出到相关单元格

如果您能分享您的工作表/脚本,我们可以帮助您解决问题。

function findRate(){
function findRate() {
  var accountName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(1,1).getValue(); //determine the account name to use in the horizontal search
  var rateTab = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Rates'); //hold the name of the rate tab for further dissection
  var rateNumColumns =rateTab.getLastColumn(); //count the number of columns on the rate tab so we can later create an array
  var rateNumRows = rateTab.getLastRow(); //count the number of rows on the rate tab so we can create an array
  var rateSheet = rateTab.getRange(1,1,rateNumRows,rateNumColumns).getValues(); //create an array based on the number of rows & columns on the rate tab
  var currentRow = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell().getRow(); //gets the current row so we can get the name of the rate to search
  var rateToSearch = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(currentRow,1).getValue(); //gets the name of the rate to search on the rates tab
  for(rr=0;rr<rateSheet.length;++rr){
    if (rateSheet[rr][0]==rateToSearch){break} ;// if we find the name of the 
      }
  for(cc=0;cc<rateNumColumns;++cc){
    if (rateSheet[0][cc]==accountName){break};
      }
  var rate = rateSheet[rr][cc] ; //the value of the rate as specified by rate name and account name
  return rate;
}
var accountName=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(1,1).getValue();//确定要在水平搜索中使用的帐户名 var rateTab=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Rates');//保留rate选项卡的名称以便进一步分析 var rateNumColumns=rateTab.getLastColumn();//计算rate选项卡上的列数,以便稍后创建数组 var rateNumRows=rateTab.getLastRow();//计算rate选项卡上的行数,以便创建数组 var rateSheet=rateTab.getRange(1,1,rateNumRows,rateNumColumns)。getValues();//根据rate选项卡上的行数和列数创建一个数组 var currentRow=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell().getRow();//获取当前行,以便获取要搜索的速率的名称 var rateToSearch=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(currentRow,1.getValue();//获取要在“速率”选项卡上搜索的速率的名称 对于(rr=0;rr优化点:

  • 永远不要忘记使用
    var
    const
    let
    rr
    cc
    )。如果省略关键字,变量将是全局变量,会给您带来很多麻烦(因为它们在循环完成后不会重置)。最好的方法是使用块作用域
    let
  • 遵循#1,不要依赖范围外变量(
    rateSheet[rr][cc]
  • 您不需要多次调用
    SpreadsheetApp.getActiveSpreadsheet()
    ,这就是变量的用途。调用一次,然后重用
  • getRange(1,1,,)
    相当于一次调用
  • 使用或方法避免冗长的循环
  • 应用这些点后,您可以使用一个干净且优化的函数:

    const findRate=()=>{
    const ss=SpreadsheetApp.getActiveSpreadsheet();
    const accountName=ss.getActiveSheet().getRange(1,1.getValue();
    const rateTab=ss.getSheetByName(“费率”);
    const rates=rateTab.getDataRange().getValues();
    const currentRow=ss.getActiveSheet().getActiveCell().getRow();
    var rateToSearch=ss.getActiveSheet().getRange(currentRow,1.getValue();
    const rr=rates.findIndex((rate)=>rate==rateToSearch);
    常数[第一速率]=速率;
    const cc=firstRates.findIndex((rate)=>rate==accountName);
    回报率[rr][cc];
    };
    


    请注意,
    “vlookup”未定义
    错误表示作用域中没有
    vlookup
    变量/函数声明。显然是这样,因为没有内置的Google Apps脚本
    vlookup
    函数。

    您无法从自定义函数访问随机范围,因此您必须向函数提供数据,包括其他函数这里使用get-active spreadsheet的解决方案不会作为自定义函数工作,我猜这是OP正在寻找的,这里有一个脚本的示例,可以这样做,但在你走这条路之前,警告一句,自定义函数比内置函数慢得多,所以这样做会比vlookup和match慢得多,如果是的话您在工作表中只有几个这样的函数,这样就可以了,但是如果您构建了包含几十行的大型表,并且使用自定义函数,则会大大降低您的速度

    // Combines VLOOKUP and MATCH into a single function
    // equivalent to VLOOKUP(rowValue, tableData, MATCH(columnName, tableHeader))
    // but in this version tableData includes tableHeader
    function findInTable(tableData, columnName, rowValue) {
      if (rowValue === "") {
        return "";
      }
      if (tableData.length == 0) {
        return "Empty Table";
      }
      const header = tableData[0];
      const index = header.indexOf(columnName);
      if (index == -1) {
        return `Can't find columnName: ${columnName}`;
      }
    
      const row = tableData.find(row => row[0] == rowValue);
      if (row === undefined) {
        return `Can't find row for rowValue: ${rowValue}`;
      }
      return row[index];
    }
    
    我建议您做的另一个优化是使用命名范围,它允许您转换如下内容:
    =VLOOKUP(C5,‘其他工作表’!A2:G782,匹配(“列名’,‘其他工作表’!A1:G1))
    更易于阅读和查看:
    =VLOOKUP(C5,someTableData,MATCH(“列名”,someTableHeader))

    对于自定义函数窗体,其如下所示:
    =findInTable(A1:G782,“列名”,C5)
    请注意,我通过合并数据和标题缩短了参数列表,这对表结构做出了一些假设,例如,有一个标题行,查找值在第一列中,但这使它更简短,更易于阅读。 但正如前面提到的,这是以速度变慢为代价的。 由于VLOOKUP和MATCH是内置函数,所以速度非常慢,速度也非常快,我最终放弃了使用它来满足我的需求

    // Combines VLOOKUP and MATCH into a single function
    // equivalent to VLOOKUP(rowValue, tableData, MATCH(columnName, tableHeader))
    // but in this version tableData includes tableHeader
    function findInTable(tableData, columnName, rowValue) {
      if (rowValue === "") {
        return "";
      }
      if (tableData.length == 0) {
        return "Empty Table";
      }
      const header = tableData[0];
      const index = header.indexOf(columnName);
      if (index == -1) {
        return `Can't find columnName: ${columnName}`;
      }
    
      const row = tableData.find(row => row[0] == rowValue);
      if (row === undefined) {
        return `Can't find row for rowValue: ${rowValue}`;
      }
      return row[index];
    }