调用GAS中的sheet函数

2024-04-12

有没有办法在 google-app-script 中调用工作表函数?

我想调用 MATCH()、IMPORTRANGE() 和 INDEX() 函数来计算函数定义中的返回值,如下所示。

function abc(foo, bar) {
  a = MATCH(foo, IMPORTRANGE("address of sheet", "A:A"),0)
  b = MATCH(bar, IMPORTRANGE("address of sheet", "B:B"),0)

  return INDEX(IMPORTRANGE("address of sheet", "C:Z"),a,b)
}

应用@Tanaike 提供的示例

function doGet(e) {
  const [sheet1, sheet2, sheet3] = [e.parameter.url1, e.parameter.url2, e.parameter.url3].map(f => SpreadsheetApp.openByUrl(f).getSheets()[0]);
  const a = sheet1.getRange("A:A").createTextFinder(e.parameter.foo).findNext().getRow();
  const b = sheet2.getRange("B:B").createTextFinder(e.parameter.bar).findNext().getRow();
  const res = sheet3.getRange("C:Z").offset(a - 1, b - 1).getValue();
  return ContentService.createTextOutput(res);
}

function abc(foo, bar) {
  const url1 = "https://docs.google.com/spreadsheets/d/###/edit";
  const url2 = "https://docs.google.com/spreadsheets/d/###/edit";
  const url3 = "https://docs.google.com/spreadsheets/d/###/edit";
  const baseUrl = "https://script.google.com/a/###/macros/s/###/exec";
  
  const res = UrlFetchApp.fetch(`${baseUrl}?url1=${encodeURIComponent(url1)}&url2=${encodeURIComponent(url2)}&url3=${encodeURIComponent(url3)}&foo=${foo}&bar=${bar}`);
  console.log(res.getContentText())
  return res.getContentText();
}

上面基本上是示例的副本,abc 函数返回 #VALUE 错误,长度为 50,000 个字母。
控制台日志如下所示开始。

Logging output too large. Truncating output. 
<!DOCTYPE html>
<html lang="en">
  <head>
  <meta charset="utf-8">
  <meta content="width=300, initial-scale=1" name="viewport">

这个答案怎么样?

修改要点:

  • 不幸的是,现阶段,Spreadsheet 的内置函数无法与 Google Apps Script 一起使用。
  • 当我在伪脚本中看到你的公式时,我认为MATCH(foo, IMPORTRANGE("address of sheet", "A:A",0)可能MATCH(foo, IMPORTRANGE("address of sheet", "A:A") ,0).
  • So, in order to convert your formulas to Google Apps Script, it is required to use openByUrl for achieving IMPORTRANGE("address of sheet", "A:A",0). If you want to use this converted script as the custom function, in this case, the custom function cannot use openByUrl due to the permission. So in this case, it is required to run the script using the script editor, the custom menu and the button in Spreadsheet. This is the current specification at Google side. Please be careful this.
    • 从你的问题来看,我无法理解你想如何运行脚本以及address of sheet。因此,在这个答案中,我想建议使用脚本编辑器运行脚本。

当上述几点反映到您问题中的伪脚本时,它会变成如下所示。该样本的流程如下。

Flow:

  1. 取回床单。
  2. Retrieve values of a and b.
    • 在本例中,我使用了 TextFinder。
  3. 使用检索结果值a and b.

示例脚本:

请将以下脚本复制并粘贴到电子表格的脚本编辑器中。并且,请设置变量url1, url2 and url3, foo and bar。当您运行脚本时,请运行以下函数myFunction使用脚本编辑器。这样,您就可以在控制台看到检索到的值,并且该值也将作为示例放入活动单元格中。

function abc(foo, bar) {
  const url1 = "https://docs.google.com/spreadsheets/d/###/edit"; // Please set this.
  const url2 = "https://docs.google.com/spreadsheets/d/###/edit"; // Please set this.
  const url3 = "https://docs.google.com/spreadsheets/d/###/edit"; // Please set this.

  // 1. Retrieve sheets.
  const [sheet1, sheet2, sheet3] = [url1, url2, url3].map(e => SpreadsheetApp.openByUrl(e).getSheets()[0]);  // Modified

  // 2. Retrieve values of `a` and `b`.
  const a = sheet1.getRange("A:A").createTextFinder(foo).findNext().getRow();
  const b = sheet2.getRange("B:B").createTextFinder(bar).findNext().getRow();
  
  // 3. Retrieve the result value using `a` and `b`.
  return sheet3.getRange("C:Z").offset(a - 1, b - 1).getValue();
}

// Please run this function.
function myFunction() {
  const foo = "###"; // Please set this.
  const bar = "###"; // Please set this.
  const res = abc(foo, bar);
  console.log(res)
  
  SpreadsheetApp.getActiveRange().setValue(res); // Heare, the value is put to the active cell.
}
  • 不幸的是,从你的问题来看,我无法理解是否每个address of sheet是相同的 URL。因此,在上面的示例脚本中,可以使用 3 个不同的 URL。另外,可以使用相同的 3 个 URL。
  • const a = sheet1.getRange("A:A").createTextFinder(foo).findNext().getRow(); and const b = sheet2.getRange("B:B").createTextFinder(bar).findNext().getRow(); are a = MATCH(foo, IMPORTRANGE("address of sheet", "A:A",0) and b = MATCH(bar, IMPORTRANGE("address of sheet", "B:B",0), respectively.
    • IMPORTRANGE("address of sheet", "A:A")表示第一个选项卡的“A:A”address of sheet.
  • return sheet3.getRange("C:Z").offset(a - 1, b - 1).getValue(); is return INDEX(IMPORTRANGE("address of sheet", "C:Z"),a,b).

Note:

  • 当所有的值address of sheet在你的伪脚本中是活动的电子表格,abc可以修改如下。在这种情况下,您可以将此函数用作自定义函数,例如=abc(foo, bar).

      function abc(foo, bar) {
        const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
        const a = sheet.getRange("A:A").createTextFinder(foo).findNext().getRow();
        const b = sheet.getRange("B:B").createTextFinder(bar).findNext().getRow();
        return sheet.getRange("C:Z").offset(a - 1, b - 1).getValue();
      }
    
  • 请在启用 V8 的情况下使用此脚本。

参考:

  • Google 表格中的自定义函数 https://developers.google.com/apps-script/guides/sheets/functions
  • 文本查找器 https://developers.google.com/apps-script/reference/spreadsheet/text-finder

Added:

与其他方法一样,为了使用openByUrl在自定义功能中,我建议使用Web Apps。

Usage:

请执行以下流程。

1. 准备脚本。

Web Apps 的示例脚本是 Google Apps 脚本。请将以下脚本(Google Apps 脚本)复制并粘贴到脚本编辑器中。该脚本适用于 Web 应用程序。并请设置 URL。关于baseUrl,请在Web Apps部署后进行设置。

function doGet(e) {
  const [sheet1, sheet2, sheet3] = [e.parameter.url1, e.parameter.url2, e.parameter.url3].map(f => SpreadsheetApp.openByUrl(f).getSheets()[0]);
  const a = sheet1.getRange("A:A").createTextFinder(e.parameter.foo).findNext().getRow();
  const b = sheet2.getRange("B:B").createTextFinder(e.parameter.bar).findNext().getRow();
  const res = sheet3.getRange("C:Z").offset(a - 1, b - 1).getValue();
  return ContentService.createTextOutput(res);
}

function abc(foo, bar) {
  const url1 = "https://docs.google.com/spreadsheets/d/###/edit";
  const url2 = "https://docs.google.com/spreadsheets/d/###/edit";
  const url3 = "https://docs.google.com/spreadsheets/d/###/edit";
  const baseUrl = "https://script.google.com/macros/s/###/exec";
  
  const res = UrlFetchApp.fetch(`${baseUrl}?url1=${encodeURIComponent(url1)}&url2=${encodeURIComponent(url2)}&url3=${encodeURIComponent(url3)}&foo=${foo}&bar=${bar}`);
  return res.getContentText();
}

2. 部署 Web 应用程序。

  1. 在脚本编辑器上,通过“发布”->“部署为 Web 应用程序”打开一个对话框。
  2. Select "Me" for "Execute the app as:".
    • 这样,脚本就会以所有者身份运行。
  3. Select “任何人,甚至匿名” for “谁有权访问该应用程序:”.
  • 在这种情况下,不需要请求访问令牌。我认为我建议使用此设置来测试此解决方法。
  • 当然,您也可以使用访问令牌。当您使用访问令牌时,请包含 Drive API 的范围之一,例如https://www.googleapis.com/auth/drive.readonly.
  • 而且,我认为键值可以用作查询参数而不是访问令牌。
  1. 单击“部署”按钮作为新的“项目版本”。
  2. Automatically open a dialog box of "Authorization required".
    1. 单击“查看权限”。
    2. 选择自己的帐户。
    3. 单击“此应用程序未经验证”处的“高级”。
    4. 点击“转到###项目名称###(不安全)”
    5. 单击“允许”按钮。
  3. 单击“确定”。
  4. Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
    • 当您修改 Google Apps 脚本时,请重新部署为新版本。这样,修改后的脚本就会反映到Web Apps中。请小心这一点。

3. 使用自定义函数测试Web Apps。

请将您的 Web 应用程序的 URL 设置为baseUrl上述 Google Apps 脚本并将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。

并且,作为该脚本的测试,请输入=abc(foo, bar)到一个细胞。至此,函数abc运行并使用 UrlFetchApp 检索结果值。

Note:

  • 当您修改Web Apps的脚本时,请将Web Apps重新部署为新版本。这样,最新的脚本就会反映到Web Apps中。请小心这一点。

参考:

  • Web Apps https://developers.google.com/apps-script/guides/web
  • 通过 Google Apps 脚本利用 Web Apps https://github.com/tanaikech/taking-advantage-of-Web-Apps-with-google-apps-script
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用GAS中的sheet函数 的相关文章

  • 图像未显示在从 HTML 创建的 PDF 上

    我想动态创建 PDF 这意味着我将从 Google Drive 获取文件 然后将它们放入 HTML 代码中 并尝试从中创建 PDF 一切工作正常 除了图像没有显示 我现在正在做的是 从 HTML 字符串创建 HtmlOutput 获取该 H
  • 如何使用 OnChange() 触发器

    我有一个电子表格以及该电子表格的主副本 每次用户将数据输入单元格时 它都会获取新数据并放入主副本中 然而最近 我注意到一个用户创建了一个新列 该列未被 OnEdit 捕获 于是我查了一下 看到了去年实现的OnChange 但是 我不知道如何
  • 谷歌表格根据今天的日期隐藏行

    在 Google Sheets 中 当 A 列中的日期等于或早于今天的日期时 我需要一个脚本来自动隐藏工作表 1 中的行 因此 如果今天是 2018 年 8 月 29 日 单元格 A3 中的日期是 2018 年 8 月 28 日 则第 3
  • 根据单元格值隐藏列

    在我的谷歌电子表格 A 中 我使用 TRANSPOSE 和 IMPORTRANGE 公式的组合从日历电子表格 B 导入数据 以便填写事件的工作时间表 因为每个日期都有 3 个事件空位 但这些空位并不总是被填满 所以我收到了很多过时的列 表格
  • BigQuery REGEXP_MATCH 和重音:边界通配符失败?

    在 GAS 中 我可以正确地将重音符号与具有边界字符的正则表达式相匹配 例如 b b 仅当字符 是单独的单词时才匹配 这在 GAS 中有效 function test regExp var str la s ance est Paris v
  • Google Apps 脚本:连接日期和时间

    更新 要使用 AppsScript 创建 Google 日历事件 我们可以使用以下简单方法createEvent eventName startTime endTime 我已经使用过这个并且没有任何问题 但我使用的唯一日期格式是谷歌表格中的
  • 如何求Google电子表格中每列的最大值之和?

    我有一个谷歌数字电子表格 如何从每列中获取最大值 并仅使用one公式 没有临时单元 没有脚本 1 2 1 0 1 3 0 2 0 对于上表 结果应为 6 1 2 3 每列的最大值 但我想要一个也适用于更大的表的解决方案 作为一个更普遍的问题
  • 使用 Promise 对 Google 表格进行多次查询

    我是一名初学者编码器 需要一些帮助来加快我的 Google 表格查询速度 我环顾四周 找不到解决方案 我正在尝试快速对 Google 表格运行 25 个查询 这就是我的尝试方式 对 Google 工作表运行查询 将结果推送到数组 运行不同的
  • 查询新的谷歌电子表格

    我使用谷歌可视化创建了一个折线图 该代码查询谷歌电子表格 当我使用普通电子表格 第 1 行 时 它可以工作 当我使用新的谷歌电子表格 第 2 行的 URL 时 出现以下错误 Error in query request time out 我
  • Google Sheets 自定义数字格式、颜色规范

    我有一个自定义的百分比数字格式 这是代码 Green 0 0 Red 0 0 输出预览 Positive 123 456 0 Green Negative 123 456 0 Red 我想要绿色更深一些 我已经尝试过了 Dark Green
  • 如何像函数一样使用 google.script.run

    在 Google Apps 脚本中 我有以下脚本 function doGet return HtmlService createHtmlOutputFromFile mypage function writeSomething retur
  • 如何使用基于时间的触发器每小时运行一个脚本,仅在工作日的整点运行?

    我只需要在工作日每小时运行一个 Google App Script 脚本 两者之一似乎很容易做到 但将其结合起来我不确定 每小时触发 ScriptApp newTrigger RefreshRates timeBased inTimezon
  • 当 Google 任务标记为“已完成”时如何触发 Google 脚本

    Google Apps 脚本允许由各种事件触发脚本 看here https developers google com apps script guides triggers 当用户将任务标记为已完成 在 Google 任务中 时 我想更新
  • 自动递增 ID 号 Google Apps 脚本

    我想在向工作表添加新值时自动增加 ID 我尝试从当前的 ID 列表创建一个列表 但它只计数到 5 因此当自动递增时 它只会到达一个点并为每个输入保存该数字 以下是我尝试获取 ID 号列表的方法 但它没有获取整个列表 我缺少什么 var ss
  • 如何在多个文档中使用 Google Apps 脚本

    我有一个谷歌应用程序脚本 我想在多个文档中使用它 我也可能想稍后在这些文档中更改它 因此我必须使用same所有这些文档中的脚本 而不是该脚本的副本 我知道以下问题可能属于重复问题 但我不愿意接受它的答案 Google Apps 脚本 如何在
  • 在 Google 表格脚本中设置活动单元格的值

    我想创建一个公式 在某个单元格更改上创建时间戳 下面的代码就可以了 我现在想做的是将公式转换为纯文本 将该时间戳锚定到工作表上 如果您手动执行此操作 您将选择时间戳 复制它们并将它们粘贴为值 我不想手动执行此操作 因此我创建了下面的脚本 它
  • 为什么我们使用 SpreadsheetApp.flush()?

    我的理解是 flush https developers google com apps script reference spreadsheet spreadsheet app flush有助于在功能发生时执行这些功能 而无需将它们捆绑在
  • 我们可以使用 Google Spreadsheet 作为后端数据库吗

    我正在尝试开发一个应用程序 在其中从与某些事务相关的多个客户端获取数据 现在我想使用 Google Spreadsheet 进行一些分析 有什么方法可以使用 ASP Net MVC 使用 C 实现此目的 Google 提供 OAuth 当我
  • 如何使用 Google Sheets (v4) API 修改依赖于特定单元格的特定数据行?

    我想找到一种使用 Google API 根据我提供的条件修改特定行数据的方法 类似于 SQL 的东西 UPDATE Customers SET ContactName Alfred Schmidt City Frankfurt WHERE
  • 有没有办法导入/导出容器绑定脚本

    我有一个插件 它使用 appscripts gs 以及 html js 和 css 文件 目前我们所做的是我们有一个参考 Google 文档 其中有一个脚本项目包含所有这些源代码 但是除了手动复制和粘贴之外 没有办法在 GIT 中保留源代码

随机推荐

  • Laravel Passport tokensExpireIn 似乎不起作用

    我正在使用 Laravel 5 4 Passport 来创建 SPA 应用程序 但是 我能够使身份验证工作 但访问令牌始终是短期令牌 过期时间为 600 秒 我无法通过以下方式增加过期时间 Passport tokensExpireIn C
  • 如何在 pandas groupby 直方图中显示标签名称

    我可以使用 pandas 在单个图中绘制多个直方图 但缺少一些东西 如何给出标签 我只能绘制一个图形 如何将其更改为layout 3 1 或其他内容 另外 在图1中 所有的垃圾箱都填充了纯色 很难知道哪个是哪个 那么如何用不同的标记 例如十
  • 有没有有效的方法来禁用 HTML 表单中的自动完成功能?

    当使用xhtml1 transitional dtddoctype 使用以下 HTML 收集信用卡号
  • Play2 如何从服务层而不是动作层管理事务?

    我正在使用 Play2 1 1 Java 和 JPA2 0 以及 hibernate 实现 通过代码控制事务而不是像下面那样使用 transactional 是正常的 JPA 代码风格 有没有办法在 Play 上像下面这样工作 或者如何使用
  • 在 p5js 中将画布导出为 GIF/PNG

    I use 原子编辑器 我要实现20 秒 GIF用我的画布 saveFrames 有一个限制 我猜 即使我输入 它也可以将 png 文件保存为短 gif 3 5 秒 saveFrames aa png 15 22 我发现了 CCapture
  • 如何组织大型代码文件?

    我越来越意识到 任何单个文件中的代码通常可以很容易地跨越数百行 尽管我知道实现可能是合理的 但它仍然感觉混乱和无组织 我知道在某些情况下需要大量代码 但是组织所有代码的最佳方法是什么 我考虑过将变量与方法分开 privates from p
  • Dart 中的函数类型定义/函数类型别名是什么?

    我已经阅读了描述 我明白它是一个函数类型别名 typedef 或函数类型别名为函数类型提供一个名称 您可以在声明字段和返回类型时使用该名称 当将函数类型分配给变量时 typedef 会保留类型信息 http www dartlang org
  • 如何知道两个线程中哪个线程首先完成执行

    我有两个线程 A 和 B 如果 A 先完成 那么我必须执行 function1 否则如果 B 先完成 我需要执行 function 2 我如何知道两个线程中哪一个先完成执行 您可以使用以下内容 仅当先前的值为空时才会设置该内容 即使只有一个
  • 未收到 ACTION_MY_PACKAGE_REPLACED

    我正在使用 ACTION MY PACKAGE REPLACED 来接收我的应用程序更新或重新安装的信息 我的问题是该事件永远不会被触发 我尝试了 Eclipse 和真实设备 这就是我所做的 显现
  • Python:将原始字符串转换为字节字符串而不添加转义字符

    我有一个字符串 BZh91AY SYA xaf x82 r x00 x00 x01 x01 x80 x02 xc0 x02 x00 x00 x9ah3M x07 lt xc9 x14 xe1BA x06 xbe x084 而且我要 b BZ
  • Android EditText 具有固定的最大行数且无滚动

    我想创建一个文本输入 1 始终显示3行 2 不允许用户输入超过 3 行可用空间的文本 3 如果用户输入的文本超过 3 行 则不可滚动 从技术上讲 我允许用户输入最多 500 个字符以保存到数据库 但我并不期望输入的文本量接近这个数量 因此
  • 在Java 8中以静态方式获取类名[重复]

    这个问题在这里已经有答案了 这是后续更一般和类似的问题 答案 https stackoverflow com questions 1696551 how to get the name of the calling class in jav
  • java中的计算器[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 最近我在研究可以加 减 乘 除的简单计算器 public static void main String arr double num1
  • 如何在 Init 状态下访问提供者值

    如何从 init 函数或解决方法访问提供程序模型中的值 基本上 当我的应用程序加载时 我会在提供程序模型中保存一些值 一个值是一个搜索变量 然后我被重定向到加载页面 我需要该值来获取数据并呈现列表 我正在 init 方法中检索数据 我的主要
  • Ruby 中的安全整数解析

    我有一根绳子 比如说 123 我想将它转换为整数123 我知道你可以简单地做some string to i 但这会转换 lolipops to 0 这不是我想要的效果 当我试图用一种美好而痛苦的方式转换一些无效的东西时 我希望它在我脸上爆
  • 格式化 Fitnesse RowFixture 中的数据

    我有一个 Fitnesse RowFixture 它返回业务对象列表 该对象有一个浮点数字段 表示 0 到 1 之间的百分比 consumer业务对象的内容将是来自设计者的网页或报告 因此百分比的格式将由设计者而不是业务对象决定 如果页面能
  • 如何从 tomcat 提供静态内容

    我有一个目录 其中包含许多静态文件 png css 等 我认为 也许是错误的 只需在应用程序的 WEB INF 文件中创建一个目录就足够了 我只需按名称引用这些文件即可访问它们 Ex 我的目录结构如下 WEB INF static styl
  • 在 IntelliJ 中重新排序 Java 类方法的简单方法?

    在 IntelliJ 中 是否有比手动剪切和粘贴代码更简单的方法来重新排序类源文件中的方法 现在我在重构遗留代码时经常需要这个 例如将源代码中的相关方法移至彼此靠近的位置 在 Eclipse AFAIK 中 有一个类似于 IntelliJ
  • 获取gridview中选中记录的超链接字段值

    我的 Gridview 在其列上有一个超链接字段 每行都有复选框 我们可以通过选中复选框来选择任何记录 问题是 我无法获取超链接字段记录 执行此操作的代码是 for int i 0 i lt GridView1 Rows Count i C
  • 调用GAS中的sheet函数

    有没有办法在 google app script 中调用工作表函数 我想调用 MATCH IMPORTRANGE 和 INDEX 函数来计算函数定义中的返回值 如下所示 function abc foo bar a MATCH foo IM