当前位置: 首页 > 知识库问答 >
问题:

使用"or"逻辑使用Apps脚本创建Google Sheets FILTER/SEARCH公式

公羊浩气
2023-03-14

示例页链接:https://docs.google.com/spreadsheets/d/1Sqt7_Ev9iagbE9CZT1F2lAUJqc1fX4WfbyaOBGEfqyQ/edit?usp=sharing

由于对上一个问题的回答,当关键字输入到资源数据库的输入单元格时,我有应用脚本自动更新谷歌表格中的公式。目前,公式使用“和”逻辑(即结果必须满足所有条件)。

=FILTER(resources!B2:B,SEARCH(B2,resources!J2:J),SEARCH(B3,resources!K2:K))

是否有一个公式使用多个SEARCH公式作为使用或逻辑(即,至少满足一个条件)的FILTER公式中的条件?

我尝试在条件中添加外括号并使用"",但它返回相同的结果。

=FILTER(resources!B2:B,(SEARCH(B2,resources!J2:J))+(SEARCH(B3,resources!K2:K)))

如果是这样,如何添加什么脚本来返回公式?我希望有一个细胞与数据验证与

// global variables
const ss = SpreadsheetApp.getActiveSpreadsheet();
const fcSheet = ss.getSheetByName('filterCode');
  const fcOption = fcSheet.getRange('B1').getValue();
  const fcInput = fcSheet.getRange('B2:B5').getValues();
const frSheet = ss.getSheetByName('resources');

var fcTabs = ['filterCode'];
var frTabs = ['resources']


// set simpleFilter formulas on edit
function onEdit(e) {
  var activeSheet = e.source.getActiveSheet();

  if (fcTabs.indexOf(activeSheet.getName()) !== -1 &&
    e.range.columnStart == 2 &&
    e.range.columnEnd == 2 &&
    e.range.rowStart >= 2 &&
    e.range.rowEnd <= 6) {
    var cell = e.range;

    if (ss.getActiveSheet().getRange("B2").getValue() != "") {
      var b2 = 'SEARCH(B2,resources!J2:J)'
    }
    else { var b2 = "" }

    if (ss.getActiveSheet().getRange("B3").getValue() != "") {
      var b3 = 'SEARCH(B3,resources!K2:K)'
    }
    else { var b3 = "" }

    if (ss.getActiveSheet().getRange("B4").getValue() != "") {
      var b4 = 'SEARCH(B4,resources!L2:L)'
    }
    else { var b4 = "" }

    if (ss.getActiveSheet().getRange("B5").getValue() != "") {
      var b5 = 'SEARCH(B5,resources!M2:M)'
    }
    else { var b5 = "" }

     if (ss.getActiveSheet().getRange("B6").getValue() != "") {
      var b6 = 'SEARCH(B6,resources!Q2:Q)'
    }
    else { var b6 = "" }

    if (b2 == '' && b3 == '' && b4 == '' && b5 == '' && b6 == '') {
      fcSheet.getRange(['C2']).setValue(' ⭠ set at least one search key');
      fcSheet.getRange(['A8:C8']).clearContent()
    }

    else {
      var fcInputList = [b2, b3, b4, b5, b6]
      var concatenated = fcInputList.filter(Boolean).join(',');
      fcSheet.getRange(['A8:C8']).setFormulas([['=FILTER(resources!B2:B,' + concatenated + ')', '=FILTER(resources!H2:H,' + concatenated + ')', '=FILTER(resources!I2:I,' + concatenated + ')']]);
      fcSheet.getRange(['C2']).clearContent();
    }
  }
}

更新的代码试图使用基于C6的单独的simpleAnd和simpleOR函数。

// global variables
const ss = SpreadsheetApp.getActiveSpreadsheet();
const fcSheet = ss.getSheetByName('filterCode');
  const fcOption = fcSheet.getRange('B1').getValue();
  const fcInput = fcSheet.getRange('B2:B5').getValues();
const frSheet = ss.getSheetByName('resources');

var fcTabs = ['filterCode'];
var frTabs = ['resources']


// set simpleFilter formulas on edit
function onEdit(e) {
  var activeSheet = e.source.getActiveSheet();

  if (fcTabs.indexOf(activeSheet.getName()) !== -1 && 
        e.range.columnStart == 2 && e.range.columnEnd == 2 &&
        e.range.rowStart >= 2 && e.range.rowEnd <= 6) {
    var cell = e.range;
    if (fcTabs.indexOf(activeSheet.getName()) !== -1 &&
    e.range.columnStart == 2 &&
    e.range.columnEnd == 2 &&
    e.range.rowStart >= 2 &&
    e.range.rowEnd <= 6 ) {
    var cell = e.range;
      if (fcSheet.getRange('C6') == 'OR') {
      simpleOr();
      }
    else simpleAnd();
    }
  }
}

function simpleAnd() {
  if (ss.getActiveSheet().getRange("B2").getValue() != "") {
    var b2 = 'SEARCH(B2,resources!J2:J)'
    }
    else { var b2 = "" }

    if (ss.getActiveSheet().getRange("B3").getValue() != "") {
      var b3 = 'SEARCH(B3,resources!K2:K)'
    }
    else { var b3 = "" }

    if (ss.getActiveSheet().getRange("B4").getValue() != "") {
      var b4 = 'SEARCH(B4,resources!L2:L)'
    }
    else { var b4 = "" }

    if (ss.getActiveSheet().getRange("B5").getValue() != "") {
      var b5 = 'SEARCH(B5,resources!M2:M)'
    }
    else { var b5 = "" }

     if (ss.getActiveSheet().getRange("B6").getValue() != "") {
      var b6 = 'SEARCH(B6,resources!Q2:Q)'
    }
    else { var b6 = "" }

    if (b2 == '' && b3 == '' && b4 == '' && b5 == '' && b6 == '') {
      fcSheet.getRange(['C2']).setValue(' ⭠ set at least one search key');
      fcSheet.getRange(['A8:C8']).clearContent()
    }

    else {
      var fcInputList = [b2, b3, b4, b5, b6]
      var concatenated = fcInputList.filter(Boolean).join(',');
      fcSheet.getRange(['A8:C8']).setFormulas([['=FILTER(resources!B2:B,' + concatenated + ')', '=FILTER(resources!H2:H,' + concatenated + ')', '=FILTER(resources!I2:I,' + concatenated + ')']]);
      fcSheet.getRange(['C2']).clearContent();
  }
}


function simpleOr() {
const activeSheet = e.source.getActiveSheet();
  const rangeReferences = [ // Attach input cells to columns
      { source: "B2", column: "J" },
      { source: "B3", column: "K" },
      { source: "B4", column: "L" },
      { source: "B5", column: "M" },
      { source: "B6", column: "Q" }
    ];
    let fcInputList = rangeReferences.map(reference => { // Loop through input cells
      const ref = reference.source;
      const col = reference.column;
      if (activeSheet.getRange(ref).getValue() != "") {
        return col + "='\"&" + ref + "&\"'"; // Build formula: eg. K='"&B3&"'
      } else return '';
    });
    const c2 = fcSheet.getRange('C2');
    if (fcInputList.every(input => input == "")) {
      c2.setValue(' ⭠ set at least one search key');
      fcSheet.getRange(['A8:C8']).clearContent()
    } else {
      fcInputList = fcInputList.filter(Boolean);
      const formula = '=QUERY(resources!B2:P26, "SELECT B,H,I WHERE ' + fcInputList.join(" OR ") + '")'; // Build rest of formula
      fcSheet.getRange("A8").setFormula(formula);
      c2.clearContent();
  }
}

共有1个答案

荆运诚
2023-03-14

您可以使用QUERY函数代替,使用其中和逻辑运算符。例如,如果填满了B2B3B5,则在A8中的公式可以是:

=QUERY(resources!B2:P26, "SELECT B,H,I WHERE J='"&B2&"' OR K='"&B3&"' OR M='"&B5&"'")

正如您所看到的,这个公式的一个优点是,您只需要为所有三个输出列调用它一次。

有趣的是,将替换为将生成一个使用运算符的公式,如您所愿。您只需检查相应的单元格(C6)是否具有值,并在构建公式时使用该信息:

=QUERY(resources!B2:P26, "SELECT B,H,I WHERE J='"&B2&"' AND K='"&B3&"' AND M='"&B5&"'")

然后,为了在onEdit函数中动态构建和设置此公式,您可以执行以下操作:

function onEdit(e) {
  const cell = e.range;
  const activeSheet = e.source.getActiveSheet();
  const OR_AND_CELL = "C6";
  if (fcTabs.indexOf(activeSheet.getName()) !== -1 && 
        ((e.range.columnStart == 2 && e.range.columnEnd == 2 &&
        e.range.rowStart >= 2 && e.range.rowEnd <= 6) ||
        cell.getA1Notation() === OR_AND_CELL)) {
    const OR_AND = activeSheet.getRange(OR_AND_CELL).getValue(); // Retrieve OR or AND
    const rangeReferences = [ // Attach input cells to columns
      { source: "B2", column: "J" },
      { source: "B3", column: "K" },
      { source: "B4", column: "L" },
      { source: "B5", column: "M" },
      { source: "B6", column: "P" }
    ];
    let fcInputList = rangeReferences.map(reference => { // Loop through input cells
      const ref = reference.source;
      const col = reference.column;
      if (activeSheet.getRange(ref).getValue() != "") {
        return col + "='\"&" + ref + "&\"'"; // Build formula: eg. K='"&B3&"'
      } else return '';
    });
    const c2 = fcSheet.getRange('C2');
    if (fcInputList.every(input => input == "")) {
      c2.setValue(' ⭠ set at least one search key');
      fcSheet.getRange(['A8:C8']).clearContent()
    } else {
      fcInputList = fcInputList.filter(Boolean);
      const formula = '=QUERY(resources!B2:P26, "SELECT B,H,I WHERE ' + fcInputList.join(" " + OR_AND + " ") + '")'; // Build rest of formula
      fcSheet.getRange("A8").setFormula(formula);
      c2.clearContent();
    }
  }
}
  • 你会注意到我已经简化了你的代码,减少了重复的数量。例如,用于指定哪些单元格(B2...B6)连接到哪些列(JKL等)。这样,您可以在循环中执行相应的操作。我希望这对你有用。

 类似资料:
  • 创建和使用脚本 游戏对象的行为由绑定的 组件 所控制。尽管 Unity 内置的组件非常灵活多样,但是你很快就会发现它们提供的功能远远不够,为了实现你所要的游戏功能,你需要超越它们才行。Unity 支持通过 脚本 创建属于你自己的组件。在组件中,随着时间的推移,你可以触发游戏事件、修改组件属性,还可以以任何你喜欢的方式来响应用户输入。 Unity 内置支持两种编程语言: C# 一种工业标准语言,类似

  • 当我逻辑删除数据库中代码为“U1”的实体时,我创建了代码为“Ü1”的新实体,出现异常“重复条目”。Hibernate是否有注释来解决此问题? 编辑: 当我插入一个具有相同代码的新实体时,错误如下: 组织。postgresql。util。PSQLException:错误:重复的键值违反唯一约束“country_pkey”详细信息:键(代码)=(AA)已存在。 表格如下:

  • 我尝试了一个简单的Java命令行应用程序,它向GoogleApps脚本执行API发出请求。大概是这样的:https://developers.google.com/apps-script/guides/rest/quickstart/java#prerequisites.但它不起作用。 谷歌应用程序脚本编辑器: Java错误:

  • 创建组件脚本 在 Cocos Creator 中,脚本也是资源的一部分。你可以在资源编辑器中通过点击"创建"按钮来添加并选择 JavaScript 或者 TypeScript 来创建一份组件脚本。此时你会在你的资源编辑器中得到一份新的脚本: 一份简单的组件脚本如下: cc.Class({ extends: cc.Component, properties: { },

  • 问题内容: 是否可以将Angular.js用作通过Google Apps脚本中的HtmlService服务的网络应用程序的一部分? 我还 按照以下链接中所述更改了文件。如何在GoogleApps脚本提供的HTML网站中使用Angular.js? 但是没有成功。 源代码 : 我进入控制台的输出: 解析“ sandbox”属性时出错:“ allow-modals”,“ allow-popups to