如何在整个列中使用indexOf?

时间:2019-09-03 05:36:33

标签: google-apps-script google-sheets

我正在创建一个具有下拉列表的列(A列),该下拉列表取决于同一行的G列中的相邻值。下拉列表的内容位于另一个工作表(OE名称)中,在其中对其进行索引以选择正确的值列表。

此处仅包含相关脚本和列的工作表示例:https://docs.google.com/spreadsheets/d/1bligSkSDr0dtU3Zwj1c-SasvKbHqX-QhbM8zysIvM-Q/edit?usp=sharing

我尝试过的代码是:

function DropDowns() {

var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();;
var OEsheet = ss.getSheetByName("OE names");
var SOsheet = ss.getSheetByName("Sales Order");
var OEcolumn = SOsheet.getRange("A2:A");
var Bcolumn = SOsheet.getRange("G2:G");

  OEcolumn.clearContent().clearDataValidations();

  var OEnames = OEsheet.getRange(1, 1, 1, OEsheet.getLastColumn()).getValues();

  var OEnamesIndex = OEnames[0].indexOf(Bcolumn.getValue()) + 1;

  if(OEnamesIndex != 0){
 var validationRange = OEsheet.getRange(2, OEnamesIndex, OEsheet.getLastRow());
 var validationRule = app.newDataValidation().requireValueInRange(validationRange).build();

 OEcolumn.setDataValidation(validationRule);

}
  }

此代码没有执行所需的操作,因为它创建了下拉列表,但它们似乎仅来自OE名称表的第一列,因此与列G中的值不匹配。问题似乎是索引整个列并不会索引该列下的每个单独的值。我将如何进行这项工作?

谢谢

2 个答案:

答案 0 :(得分:3)

  • 您要将数据验证规则放在“销售订单”页面上的“ A”列。
  • 您要使用“ OE名称”表中下拉列表的内容。
  • 例如,在共享的电子表格中,单元格“ G1”和“ G2”的值分别为LachhmangarhBeawar。在这种情况下,您要分别使用“ OE名称”表中“ A”和“ B”列的内容。
  • 您想使用Google Apps脚本实现这一目标。

如果我的理解是正确的,那么该修改如何?修改后的脚本的流程如下。

流量:

  1. 从“ OE名称”表中检索值
  2. 创建一个用于创建数据验证规则的对象。
  3. 在“销售订单”表的“ A”列中清除值和数据验证规则。
  4. 从“销售订单”表上的“ G”列中检索值。
  5. 根据检索到的值和对象创建数据验证规则。
  6. 将创建的数据验证规则设置到“销售订单”表的“ A”列。

修改后的脚本:

function DropDowns() {
  var app = SpreadsheetApp;
  var ss = app.getActiveSpreadsheet();
  var OEsheet = ss.getSheetByName("OE names");
  var SOsheet = ss.getSheetByName("Sales Order");

  // Retrieve values from the sheet of "OE names"
  var OEnames = OEsheet.getRange(1, 1, 1, OEsheet.getLastColumn()).getValues()[0];

  // Create an object for using to create the data validation rules.
  var obj = OEnames.reduce(function(o, e, i) {
    o[e.toUpperCase()] = OEsheet.getRange(2, i + 1, OEsheet.getLastRow());
    return o;
  }, {});

  // Clear values and data validation rules at the column "A" of the sheet of "Sales Order".
  var OEcolumn = SOsheet.getRange("A2:A" + SOsheet.getLastRow());
  OEcolumn.clearContent().clearDataValidations();

  // Retrieve values from the column "G" on the sheet of "Sales Order".
  // Create the data validation rules from the retrieved values and the object.
  var Bcolumn = SOsheet.getRange("G2:G" + SOsheet.getLastRow());
  var rules = Bcolumn.getValues().map(function(e) {return e[0].toUpperCase() in obj ? [app.newDataValidation().requireValueInRange(obj[e[0].toUpperCase()]).build()] : [null]});

  // Set the created data validation rules to the column "A" of the sheet of "Sales Order".
  OEcolumn.setDataValidations(rules);
}

注意:

  • 在“销售订单”工作表的“ G”列的值中,有BariBARI的值,并且在“ OE名称”中不存在值。
    • 在此脚本中,BariBARI用作相同的值。
    • 关于不存在的值,未设置数据验证规则。

参考文献:

如果我误解了您的问题,而这不是您想要的结果,我深表歉意。

答案 1 :(得分:1)

这是我的解决方案版本,可以通过以下方式实现:

  1. 建立验证者范围
  2. 将A列中的值设置为G。
  3. 构建验证规则并将其应用于A。

(此外,我还可以自由地在上面共享的文件中解决问题。您可能需要重置它。)

---
- hosts: all
  become: True
  roles:
    - gluster.infra
  vars:
    gluster_infra_fw_state: disabled
    gluster_infra_volume_groups:
      - vgname: 'storage_vg'
        pvname: '/dev/vdb'
    gluster_infra_thick_lvs:
      - vgname: 'storage_vg'
        lvname: 'storage_lv'
        pvs: '/dev/vdb'
        size: '100%FREE'
    gluster_infra_mount_devices:
      - path: '/mnt/brick'
        vgname: 'storage_vg'
        lvname: 'storage_lv'