验证脚本问题

时间:2018-09-27 18:00:00

标签: google-apps-script google-sheets

我的验证脚本遇到了一些麻烦。这一切对我来说看起来不错,但现在我的验证列未加载。这是脚本...

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变量上。如果我的范围不在第一行开始,那么它将无法正常工作。但是,如果我确实在第一行中将其导入,则我将不需要的数据导入到我的列中。有没有办法使此脚本起作用或隐藏不正确的数据?

1 个答案:

答案 0 :(得分:1)

以下代码在PriceList工作表中与活动单元格相邻的行上创建一个下拉列表。

下拉数据来自Sourcedata。有趣的是,验证范围内的行数计算为(三加SourceData的最后一行)。
SourceData snapshot
基于此快照,最后一行为4。验证范围声明为row = 3,column = variable,lastrownumber = 4。因此,如果该项目为“裤子”,则验证范围“应”为Column = A StartRow = 3; End Row = 7(3加4)。但是实际返回的范围是A3:A6(按预期会生成一个空白行)。但这比预期的行数少了一行。

我为PriceList表的A列创建了数据验证规则。单击此列中的单元格将触发“ OnEdit”功能,该功能会将查找插入到B列中。
Screenshot PriceList sheet

以下记录器条目显示了最新条目的各种数据元素

[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());
    }
}