Google apps script 在函数中实现vlookup和match
我试图在工作表中创建一个函数,它结合了我经常使用的“Vlookup”和“Match”组合 我想用我的函数“Rates”来接受1个参数并返回一个Vlookup和Match的组合,它总是使用相同的值 Vlookup(参数,定义范围(始终保持相同的定义范围),match(A1(始终为单元格A1),不同的定义范围,0),FALSE) 我曾尝试创建一个脚本,但没有编码经验,我收到一个错误“vlookup未定义” 实际结果: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
#错误代码>
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];
}