首页 > 解决方案 > GAS 中 DeveloperMetadata 的实际用例

问题描述

我最近发现了与DeveloperMetadata相关的已发布的新电子表格类和方法,并且我正在寻找显示此类数据结构实际使用的代码示例。

我试图掌握元数据的概念,但到目前为止它对我来说太混乱了。

让我们假设这种情况 - 我正在为电子表格开发一些自动化。有一个带有订单的表格(日期、客户名称、销售商品名称、价格等)。在有界脚本中,我处理这样的价格列sheet.getRange("H:H")(硬编码)。但是,当工作表的用户在其他地方更改“H”列的位置时,脚本将停止正常工作 - 除非我将代码“H”更改为新的列字母。

我正在寻找一些真正的 GAS 代码(不是高级工作表服务),它们将显示如何轻松处理这种情况。

我在想象这样的事情(伪代码):

sheet.getRange("H:H").setMatadata("columnName","price"); //First set column identification

var priceColumnRange = sheet.getMetadaDataByKey("price").getRange(); //Then retrieve column range by its identification

我找到了一种如何将元数据设置为范围的方法,但我没有找到一种如何轻松检索(搜索/查找)这些数据的方法。从文档中看起来真的很难,而且我仍然不知道如何使用元数据来完成如此简单的任务。

标签: google-apps-scriptgoogle-sheetsgoogle-sheets-api

解决方案


  • 您想使用类 DeveloperMetadata 从行和列中搜索和检索 DeveloperMetadata。
    • 您需要上述情况的示例脚本。

如果我的理解是正确的,那么这个示例脚本怎么样?我试图考虑这种情况,因为这对我的情况也很有用。我认为您的情况有几个示例脚本。因此,请将此视为其中之一。

示例脚本 1:

在此示例脚本中,所有 DeveloperMetadata 都是从工作表名称为“Sheet1”的工作表中检索的。

var s = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var v = s.getRange(1, 1, s.getMaxRows(), s.getMaxColumns()).createDeveloperMetadataFinder().onIntersectingLocations().find();
var res = v.map(function(e) {
  var loc = e.getLocation();
  var obj = loc.getLocationType() === SpreadsheetApp.DeveloperMetadataLocationType.COLUMN ? {range: loc.getColumn().getA1Notation()} :
    loc.getLocationType() === SpreadsheetApp.DeveloperMetadataLocationType.ROW ? {range: loc.getRow().getA1Notation()} : {};
  obj[e.getKey()] = e.getValue();
  return obj;
});
Logger.log(res)
  • 作为示例情况,在将 DeveloperMetadata 设置为列“A”后,当它移动到列“B”时,此脚本会检索列“B”的键和值。
  • 例如,如果要使用 key 和 value 进行搜索,还可以使用以下脚本。
    • var v = s.getRange(1, 1, s.getMaxRows(), s.getMaxColumns()).createDeveloperMetadataFinder().onIntersectingLocations().withKey("key1").find();
    • var v = s.getRange(1, 1, s.getMaxRows(), s.getMaxColumns()).createDeveloperMetadataFinder().onIntersectingLocations().withValue("value").find();
    • var v = s.getRange(1, 1, s.getMaxRows(), s.getMaxColumns()).createDeveloperMetadataFinder().onIntersectingLocations().withKey("key1").withValue("value1").find();
  • 这是一个示例脚本。因此,请根据您的情况进行修改。

结果:

{key1: "value1"}当和的2 个 DeveloperMetadata{key2: "value2"}设置为第 1 行 A 列时,得到如下结果。

[
  {
    "range": "1:1",
    "type": "ROW",
    "key1": "value1"
  },
  {
    "range": "A:A",
    "type": "COLUMN",
    "key2": "value2"
  }
]

示例脚本 2:

作为另一种方式,您还可以使用 Sheets API 搜索 DeveloperMetadata,如下所示。当您使用 Sheets API 时,请在 Advanced Google Services 和 API 控制台中启用 Sheets API。您可以在此处了解如何启用 Sheets API 。

var resource = {"dataFilters": [{"developerMetadataLookup": {"metadataKey": "key1"}}]}; // Search by key
// var resource = {"dataFilters": [{"developerMetadataLookup": {"metadataValue": "value1"}}]}; // Search by value
// var resource = {"dataFilters": [{"developerMetadataLookup": {"metadataKey": "key1", "metadataValue": "value1"}}]}; // Search by key and value
var res = Sheets.Spreadsheets.DeveloperMetadata.search(resource, spreadsheetId);

参考:

如果这不是你想要的,我很抱歉。

编辑:

对于你的第二个问题。

  1. 将元数据添加到“H:H”作为“columnName”的键和“price”的值。
  2. 如果移动了“H”列,则需要使用元数据的值检索新范围。

如果我的理解是正确的,那又如何呢?

添加元数据

为了向“H”列添加元数据,您可以使用以下脚本。因为没有方法setMatadata(),请使用addDeveloperMetadata()

var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("H:H").addDeveloperMetadata("columnName", "price");

使用值检索范围

此示例脚本使用元数据值检索范围。在此脚本中,envn 如果移动了“H”列,则可以检索使用元数据值的新范围。

var sheet = SpreadsheetApp.getActiveSheet();
var value = "price";
var v = sheet.getRange(1, 1, 1, sheet.getMaxColumns())
  .createDeveloperMetadataFinder()
  .onIntersectingLocations()
  .withValue(value)
  .find();
var ranges = v.map(function(e) {return e.getLocation().getColumn()}); // "ranges" is one dimensional array.

推荐阅读