我的验证脚本遇到了一些麻烦。这一切对我来说看起来不错,但现在我的验证列未加载。这是脚本...
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SG_Sheet1");
var activeCell = ss.getActiveCell();
if (activeCell.getColumn() == 1 && activeCell.getRow() > 1) {
var makes = datass.getRange(2, 1, 1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0, 1).setDataValidation(validationRule);
}
}
所以问题出在我的ValidationRange
变量上。如果我的范围不在第一行开始,那么它将无法正常工作。但是,如果我确实在第一行中将其导入,则我将不需要的数据导入到我的列中。有没有办法使此脚本起作用或隐藏不正确的数据?
答案 0 :(得分:1)
以下代码在PriceList工作表中与活动单元格相邻的行上创建一个下拉列表。
下拉数据来自Sourcedata。有趣的是,验证范围内的行数计算为(三加SourceData的最后一行)。
基于此快照,最后一行为4。验证范围声明为row = 3,column = variable,lastrownumber = 4。因此,如果该项目为“裤子”,则验证范围“应”为Column = A StartRow = 3; End Row = 7(3加4)。但是实际返回的范围是A3:A6(按预期会生成一个空白行)。但这比预期的行数少了一行。
我为PriceList表的A列创建了数据验证规则。单击此列中的单元格将触发“ OnEdit”功能,该功能会将查找插入到B列中。
以下记录器条目显示了最新条目的各种数据元素
[18-10-05 18:06:39:096 PDT] activeCell = A6
[18-10-05 18:06:39:097 PDT] Active Row =6, Active Column = 1
[18-10-05 18:06:39:210 PDT] value of the active cell = Pants
[18-10-05 18:06:39:292 PDT] last row of the data sheet = 4
[18-10-05 18:06:39:359 PDT] last column of the data sheet = 3
[18-10-05 18:06:39:429 PDT] makesrange = A2:C2
[18-10-05 18:06:39:550 PDT] makes = Pants,Tie,Basket
[18-10-05 18:06:39:551 PDT] makeIndex = 1
[18-10-05 18:06:39:621 PDT] valrange = A3:A6 being row=3, col=makeindex=1, number of rows=getLastRow=4
[18-10-05 18:06:39:684 PDT] validationRange = A3:A6
[18-10-05 18:06:39:691 PDT] validation rule applies to = B6
function onEdit() {
// declare the sheets
var s1 = "PriceList";
var s2 = "SourceData";
//declare the app and the sheets
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var pricess = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(s1);
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(s2);
//declare the active cell (must be in the Prices Sheet)
var activeCell = ss.getActiveCell();
Logger.log("activeCell = " + activeCell.getA1Notation());
// get the row and column of the active cell
var SelectRow = activeCell.getRow();
var SelectCol = activeCell.getColumn();
Logger.log("Active Row =" + SelectRow + ", Active Column = " + SelectCol);
// so if you are working on something in Column A and below row 1 (the header) t then do stuff
if (activeCell.getColumn() == 1 && activeCell.getRow() > 1) {
// Make a note of the content of the active cell
Logger.log("value of the active cell = " + activeCell.getValue());
//get the last row of data in the SourceData sheet
var lastRow = datass.getLastRow();
Logger.log("last row of the data sheet = " + lastRow);
//get the last column in the SourceData sheet
var lastColumn = datass.getLastColumn();
Logger.log("last column of the data sheet = " + lastColumn);
// declare (for reporting purposes) the 'makesrange' range (which maps to same address as "makes"
// row = 2, column = 1(A), number of rows = 1 = row 2 only, number of columns = datass.getlastcolumn = 3 (Column C); so range = A2:C2
var makesrange = datass.getRange(2, 1, 1, datass.getLastColumn()).getA1Notation();
//(row 2, col 1) = A2, (num rows = 1, num cols = 3) = C2
Logger.log("makesrange = " + makesrange);
// declare (for calculation) the 'makes' range
// row = 2, column = 1(A), number of rows = 1 = row 2 only, number of columns = datass.getlastcolumn = 3 (Column C); so range = A2:C2
var makes = datass.getRange(2, 1, 1, datass.getLastColumn()).getValues();
//getRange(row, column, numRows, numColumns) row 2, col 1, num rows=1, num cols=3
Logger.log("makes = " + makes);
// declare makeindex = converts the item selected on the Prices sheet to the relevant column on the SourceData sheet plus 1 (to account for array starting value=0)
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
Logger.log("makeIndex = " + makeIndex);
// declaring (for reporting purposes) the 'valrange' which maps to the same address as "ValidationRange
// row=3, c=makeindex==maps to column number contain product name the same as the active cell, last row of sourcedata
var valrange = datass.getRange(3, makeIndex, datass.getLastRow()).getA1Notation();
// row,col,number of rows ->row 3, col 1) = A3, (num rows = getlastrow=4) = ; so range = A3:C7, but returns as A3:C6???
Logger.log("valrange = " + valrange + " being row=3, col=makeindex=" + makeIndex + ", number of rows=getLastRow=" + lastRow);
// declare the "ValidationRange"
// documentation says "When the "numRows" argument is used, only a single column of data is returned."
//row=3, column=makeindex==maps to column number contain product name the same as the active cell, number of rows=last row# of sourcedata=4; so range = A2:C7, but returns as A3:C6???
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
// row,col, number of rows ->row=3. col=makeindex=maps to column number contain product name the same as the active cell, 1 (=A), getLastRow
Logger.log("validationRange = " + validationRange.getA1Notation()); // agrees to 'valrange'
// declare validationrue = validationrule
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
// apply the rule to the column B on PriceList(one to the right of Column A) and same row.
activeCell.offset(0, 1).setDataValidation(validationRule);
Logger.log("validation rule applies to = " + activeCell.offset(0, 1).getA1Notation());
}
}