簡體   English   中英

如何在 Google 電子表格中以編程方式(在 Google 應用程序腳本中)為數據驗證設置命名范圍?

[英]How to set a named range for a data validation programmatically (in Google apps script) in a Google spreadsheet?

用例

例子。 我有一個命名范圍Apples (地址“ Sheet10:B2:B ”),用於對大量工作表單元格進行數據驗證。 Apples的數據范圍可以更改(在腳本中),例如更改為“ Sheet10:D2:D ”。

它適用於 UI

我可以手動設置一個命名范圍作為數據驗證的數據源。 在這種情況下,單元格的數據驗證將始終引用已更新數據范圍的命名范圍Apples

如何在 Google Apps 腳本中制作它?

氣體限制

如果您有一個命名范圍namedRange ,則用於設置數據驗證的代碼應如下所示:

      mySheet.getRange('F5')
        .setDataValidation(
          SpreadsheetApp.newDataValidation()
            .requireValueInRange(
              namedRange.getRange()
            )
            .setAllowInvalid(false)
            .build()
        );

DataValidationBuilder.requireValueInRange()在這里不起作用,因為它只需要class Range (它無法獲取NamedRange ),並且不會使用對命名范圍的引用。

有解決方法嗎?

UPD1 - Spreadsheet.getRangeByName()不起作用

通過名稱獲取范圍沒有幫助,數據驗證將獲得實際的范圍地址。 SpreadsheetApp.getActive().getRangeByName("Apples")

UPD2 到目前為止在 GAS 中沒有辦法做到這一點

正如@TheMaster 發布的那樣,目前不可能。

請為帖子設置+1:

PS看起來唯一可行的解決方案是Google Sheets API。

我認為在您的情況下,我認為當使用 Sheets API 時,您的目標可能可以使用。

解決方法 1:

此解決方法使用表格 API。

用法:

1. 准備一份谷歌電子表格。

  1. 請創建一個新的 Google 電子表格。

  2. Example. I have a named range Apples (address "Sheet10:B2,B"). which in use for data validation for plenty of sheet cells, The data range for Apples can be changed (in a script). eg: to "Sheet10.D2 D" Example. I have a named range Apples (address "Sheet10:B2,B"). which in use for data validation for plenty of sheet cells, The data range for Apples can be changed (in a script). eg: to "Sheet10.D2 D" Example. I have a named range Apples (address "Sheet10:B2,B"). which in use for data validation for plenty of sheet cells, The data range for Apples can be changed (in a script). eg: to "Sheet10.D2 D" ,請插入一張“Sheet10”並將樣本值放入單元格“B2:B”和“D2:D”。

  3. 請將命名范圍Sheet10:B2 B設置為Apple

2. 示例腳本。

請將以下腳本復制並粘貼到電子表格的腳本編輯器中並保存腳本。 並且, 請在高級 Google 服務中啟用表格 API

function myFunction() {
  const namedRangeName = "Apple"; // Please set the name of the named range.

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("Sheet10");
  const requests = [{ updateCells: { range: { sheetId: sheet.getSheetId(), startRowIndex: 0, endRowIndex: 1, startColumnIndex: 0, endColumnIndex: 1 }, rows: [{ values: [{ dataValidation: { condition: { values: [{ userEnteredValue: "=" + namedRangeName }], type: "ONE_OF_RANGE" }, showCustomUi: true } }] }], fields: "dataValidation" } }];
  Sheets.Spreadsheets.batchUpdate({ requests }, ss.getId());
}
  • 在此請求中,命名范圍的名稱直接放入userEnteredValue

3. 測試。

當此腳本運行到上述示例電子表格時,將獲得以下結果。

在此處輸入圖像描述

當看到這個演示時,首先,您可以看到“Apple”的命名范圍,其中包含單元格“B1:B1000”。 運行腳本時,將數據驗證放入命名范圍為“Apple”的單元格“A1”中。 在這種情況下,數據有效性的值表示“B1:B1000”。 當名為范圍“Apple”的范圍從“B1:B1000”更改為“D1:D1000”並確認“A1”的數據驗證時,發現值從“B1:B1000”更改為“D1” :D1000"。

解決方法 2:

此解決方法使用 Google 電子表格服務 (SpreadsheetApp)。 在現階段,谷歌電子表格服務(SpreadsheetApp)似乎無法直接達到你的目的。 這已經在評論和TheMaster 的回答中的討論中提到過。 當您想實現這一點時,如何使用 OnChange 檢查命名范圍的范圍是否已更改,如下解決方法 2?

用法:

1. 准備一份谷歌電子表格。

  1. 請創建一個新的 Google 電子表格。

  2. Example. I have a named range Apples (address "Sheet10:B2,B"). which in use for data validation for plenty of sheet cells, The data range for Apples can be changed (in a script). eg: to "Sheet10.D2 D" Example. I have a named range Apples (address "Sheet10:B2,B"). which in use for data validation for plenty of sheet cells, The data range for Apples can be changed (in a script). eg: to "Sheet10.D2 D" Example. I have a named range Apples (address "Sheet10:B2,B"). which in use for data validation for plenty of sheet cells, The data range for Apples can be changed (in a script). eg: to "Sheet10.D2 D" ,請插入一張“Sheet10”並將樣本值放入單元格“B2:B”和“D2:D”。

  3. 請將命名范圍Sheet10:B2 B設置為Apple

2. 示例腳本。

請將以下腳本復制並粘貼到電子表格的腳本編輯器中並保存腳本。 並且, 請將 OnChange 觸發器安裝到 function onChange

首先,請運行createDataValidation 這樣,數據驗證被放入“Sheet10”的單元格“A1”。 在這種情況下,設置范圍是從命名范圍“Apple”中檢索到的范圍。 因此,在這種情況下,范圍是Sheet10:B2 B1000

下一步,請將命名范圍的范圍從Sheet10:B2 B1000更改為 Sheet10:D2 D1000 . By this, . By this,安裝的 OnChange 觸發器會自動運行 onChange` function。 由此,“A2”的數據有效性被更新。 這樣,數據驗證的值就會改變。

const namedRangeName = "Apple"; // Please set the name of the named range.
const datavalidationCell = "Sheet10!A2"; // As a sample. data validation is put to this cell.

function onChange(e) {
  if (e.changeType != "OTHER") return;
  const range = e.source.getRangeByName(namedRangeName);
  const a1Notation = `'${range.getSheet().getSheetName()}'!${range.getA1Notation()}`;
  const prop = PropertiesService.getScriptProperties();
  const previousRange = prop.getProperty("previousRange");
  if (previousRange != a1Notation) {
    const rule = SpreadsheetApp.newDataValidation().requireValueInRange(e.source.getRangeByName(namedRangeName)).setAllowInvalid(false).build();
    e.source.getRange(datavalidationCell).setDataValidation(rule);
  }
  prop.setProperty("previousRange", a1Notation);
}

// First, please run this function.
function createDataValidation() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const rule = SpreadsheetApp.newDataValidation().requireValueInRange(ss.getRangeByName(namedRangeName)).setAllowInvalid(false).build();
  ss.getRange(datavalidationCell).setDataValidation(rule);
  const prop = PropertiesService.getScriptProperties();
  const range = ss.getRangeByName(namedRangeName);
  const a1Notation = `'${range.getSheet().getSheetName()}'!${range.getA1Notation()}`;
  prop.setProperty("previousRange", a1Notation);
}

參考:

目前,這似乎是不可能的。 然而,這是一個已知問題。 +1 此功能請求,如果您希望實現此功能。

https://issuetracker.google.com/issues/143913035

跟蹤器問題創建者的解決方法:

如果驗證規則是通過 Sheets GUI 使用 NamedRange 手動創建的,則可以使用 Range.getDataValidations() 以編程方式復制它,然后用於以編程方式創建新的 DataValidations。 以這種方式創建的 DataValidation 保持與 NamedRange 的連接,並且其行為類似於手動創建的對應項。 這表明“使用”NamedRanges 數據驗證規則的功能已經可以通過 Apps 腳本實現,但不能選擇“創建”它們。

使用 getRangeByName()

function lfunko() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName("Sheet0");
  var cell = sh.getRange(1, 10);//location where datavalidation is applied
  var rule = SpreadsheetApp.newDataValidation().requireValueInRange(ss.getRangeByName("MyList")).build();
  cell.setDataValidation(rule);
}

作為一個半答案,如果您只想要驗證並且可以在沒有有效值下拉列表的情況下生存,您可以以編程方式設置引用命名范圍的自定義公式。 此對命名范圍的引用不會在 AppsScript 中擴展,因此未來對命名范圍實際范圍的更改將滲透到驗證器。 像這樣:

      mySheet.getRange('F5')
        .setDataValidation(
          SpreadsheetApp.newDataValidation()
            .requireFormulaSatisfied(
               '=EQ(F5, VLOOKUP(F5, ' + namedRange.getName() + ', 1))'
            )
            .setAllowInvalid(false)
            .build()
        );

(公式只是檢查正在測試的單元格中的值是否等於 VLOOKUP 在第一列中為該單元格找到的值——我假設命名的范圍內容已排序。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM