如何使用应用程序脚本在 Google 电子表格的单元格内添加 UI?

发布于 2024-11-27 04:01:33 字数 233 浏览 1 评论 0原文

我想向 Google 文档电子表格中的特定单元格添加按钮。 应用脚本 UI 文档介绍了如何添加新面板,但尚不清楚 UI 如何添加该面板中的内容可以附加到特定的行或单元格。

是否可以将 UI 添加到特定单元格,或者我们仅限于添加新面板?

I'd like to add buttons to specific cells in Google docs spreadsheet. The apps script UI documentation talks about how to add a new panel, but it's not clear how UI in that panel could be attached to specific rows or cells.

Is it possible to add UI to particular cells, or are we limited to adding new panels?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

无声无音无过去 2024-12-04 04:01:34

应用程序 UI 仅适用于面板。

您能做的最好的事情就是自己绘制一个按钮并将其放入电子表格中。您可以向其中添加宏。

进入“插入>绘图...”,绘制一个按钮并将其添加到电子表格中。
然后单击它并单击“分配宏...”,然后在其中插入您要执行的函数的名称。该函数必须在电子表格的脚本中定义。

或者,您也可以在其他地方绘制按钮并将其作为图像插入。

详细信息:https://developers.google.com/apps-script/guides/menus< /a>

在此处输入图像描述
在此处输入图像描述
在此处输入图像描述

The apps UI only works for panels.

The best you can do is to draw a button yourself and put that into your spreadsheet. Than you can add a macro to it.

Go into "Insert > Drawing...", Draw a button and add it to the spreadsheet.
Than click it and click "assign Macro...", then insert the name of the function you wish to execute there. The function must be defined in a script in the spreadsheet.

Alternatively you can also draw the button somewhere else and insert it as an image.

More info: https://developers.google.com/apps-script/guides/menus

enter image description here
enter image description here
enter image description here

浮华 2024-12-04 04:01:34

2018 年状态:

似乎无法将按钮(绘图、图像)放置在单元格内,以允许它们链接到 Apps 脚本功能。


话虽如此,您确实可以做一些事情:

您可以...

您可以使用 IMAGE(URL) 将图像放置在单元格内,但它们无法链接到 Apps 脚本函数。

您可以将图像放置在单元格中并使用以下方法将它们链接到 URL:
=HYPERLINK("http://example.com"; IMAGE("http://example.com/myimage.png"; 1))

您可以按照 @ 的答案中的描述创建绘图Eduardo 和它们可以链接到 Apps 脚本函数,但它们将是独立的项目,可以自由浮动在电子表格“上方”,并且不能放置在单元格中。它们无法从一个单元格复制到另一个单元格,并且它们没有脚本函数可以读取的行或列位置。

Status 2018:

There seems to be no way to place buttons (drawings, images) within cells in a way that would allow them to be linked to Apps Script functions.


This being said, there are some things that you can indeed do:

You can...

You can place images within cells using IMAGE(URL), but they cannot be linked to Apps Script functions.

You can place images within cells and link them to URLs using:
=HYPERLINK("http://example.com"; IMAGE("http://example.com/myimage.png"; 1))

You can create drawings as described in the answer of @Eduardo and they can be linked to Apps Script functions, but they will be stand-alone items that float freely "above" the spreadsheet and cannot be positioned in cells. They cannot be copied from cell to cell and they do not have a row or col position that the script function could read.

雾里花 2024-12-04 04:01:34

使用复选框(例如,在 F1 中)而不是按钮/图像。这是单元格内完整用户界面的中间版本。然后挂钩您的函数,该函数应该在单击按钮时运行到 onEdit() 触发函数。

示例脚本:

function onEdit(e){
  const rg = e.range;
  if(rg.getA1Notation() === "F1" && rg.isChecked() && rg.getSheet().getName() === "Sheet1"){
    callFunctionAttachedToImage();
    rg.uncheck();
  }
}

参考:

Use checkboxes(say, in F1) instead of buttons/Images. This is a intermediate to a full ui inside cells. Then hook your function, that is supposed to run on button click to onEdit() trigger function.

Sample script:

function onEdit(e){
  const rg = e.range;
  if(rg.getA1Notation() === "F1" && rg.isChecked() && rg.getSheet().getName() === "Sheet1"){
    callFunctionAttachedToImage();
    rg.uncheck();
  }
}

References:

感性不性感 2024-12-04 04:01:34

按钮可以作为图像添加到冻结行。将附加脚本中的函数分配给按钮可以运行该函数。说你不能的评论当然是一个非常古老的评论,可能现在情况已经改变了。

Buttons can be added to frozen rows as images. Assigning a function within the attached script to the button makes it possible to run the function. The comment which says you can not is of course a very old comment, possibly things have changed now.

牛↙奶布丁 2024-12-04 04:01:34

有一个愚蠢的技巧可以帮助您:

  1. 您可以使绘图对象与工作表一样高(以显示在工作表中的每一行)。

  2. 您可以通过以下代码使脚本影响当前单元格的值:

    SpreadsheetApp.getActiveSpreadsheet().getActiveCell().setValue(cellValue);

There is a silly trick to do something that might help you :

  1. You can make the drawing object as tall as your sheet (To appear to every row in the sheet).

  2. You can make the script affects the current cell value by the following code:

    SpreadsheetApp.getActiveSpreadsheet().getActiveCell().setValue(cellValue);

清泪尽 2024-12-04 04:01:34

我无法将图纸附加到单元格上。相反,我使用视觉错觉使单元格看起来类似于按钮,然后使用 onSelectionChange() 在单击该单元格时运行脚本。不过,您不能连续单击两次。您必须在单元格外部单击,然后再次返回。

对于视觉 3D 着色错觉,我使用粗彩色边框。我给出“按钮”单元格:

  • 厚的底部和右边框,比表格单元格的其余部分颜色更深
  • 厚的顶部和左边框,比底部/右边框浅,比其余单元格浅

一阴影“按钮”

如果我需要多个按钮彼此相邻,我会在它们之间放置一个额外的列,否则对我来说看起来不对,因为它们之间的边框只能有一种颜色。合作起来有点烦人。这里它们没有额外的列:

两个相邻的“按钮”

这里有一个额外的列:

两个“按钮” ; 它们之间有一列

应用程序脚本无法侦听某人单击单元格。不过,它可以侦听某人更改选择的单元格。当你这样做时,检查点击是否在正确的单元格中很重要:

function onSelectionChange(event) {
  // Act based on text content
  var activeCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell();
  var text = activeCell.getValue();
  console.log("text", text);  // for the debugger

  if (text === "thing 1") { function1(); }
  else if (text === "thing 2") { function2(); }
}

我有很多这样的“按钮”,当我想编辑它们时,我发现与这些单元格交互很烦人,所以我还使用了“属性”来激活和停用该交互:

function onSelectionChange(event) {
  var isActive = PropertiesService.getScriptProperties().getProperty("active")
  console.log("Cells are active", JSON.stringify(isActive));
  if ( isActive !== "true" ) { return; }
  
  // Act based on text content
  var activeCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell();
  var text = activeCell.getValue();
  console.log("text", text);  // for the debugger

  if (text === "thing 1") { function1(); }
  else if (text === "thing 2") { function2(); }
}

function activate() {
  // I think these get saved as strings even if you give
  // a boolean value, so I just gave a string
  PropertiesService.getScriptProperties().setProperty("active", "true");
  console.log("After activated", JSON.stringify(PropertiesService.getScriptProperties().getProperty("active")));
}

function deactivate() {
  PropertiesService.getScriptProperties().setProperty("active", "false");
  console.log("After deactivated", JSON.stringify(PropertiesService.getScriptProperties().getProperty("active")));
}

我确实使用绘图作为带有activatedeactivate功能的按钮而不是单元格,因为这样编程起来不那么烦人。我确实有很多细胞类型的“按钮”,所以这是值得的。

当我激活和停用它们时,我还改变了细胞的颜色。这部分有点未经测试。我的代码更适合我的情况。我正在为更大的范围着色并使用不同的颜色。

function activate() {
  PropertiesService.getScriptProperties().setProperty("active", "true");
  setStyle("#cccccc", "#000000", "A1");
}

function deactivate() {
  PropertiesService.getScriptProperties().setProperty("active", "false");
  setStyle("#b7b7b7", "#999999", "A1");  // Maybe not enough contrast for some people
}

function setStyle(backgroundColor, fontColor, cellAddress) {
  var range = SpreadsheetApp.getActiveSheet().getRange(cellAddress);
  range.setBackground(backgroundColor);
  range.setFontColor(fontColor);
}

I have been unable to attach drawings to cells. Instead, I use a visual illusion to make a cell look similar to a button, then use onSelectionChange() to run a script when that cell is clicked. You can't click twice in a row, though. You have to click outside the cell and back in again.

For the visual 3D shading illusion, I use thick colored borders. I give the "button" cell:

  • A thick bottom and right border that is a darker color than the rest of the table cells
  • A thick top and left border that is lighter than the the bottom/right border and lighter than the rest of the cells

One shaded "button"

If I need multiple buttons next to each other, I put an extra column between them or it looks wrong to me because the border between them can only have one color. It's a bit annoying to work with. Here they are without an extra column:

Two "buttons" next to each other

Here they are with an extra column:

Two "buttons" with one column in between them

App script can't listen for someone to click on a cell. It can listen for someone changing which cell is selected, though. When you do that, it's important to check that the click is in the right cell:

function onSelectionChange(event) {
  // Act based on text content
  var activeCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell();
  var text = activeCell.getValue();
  console.log("text", text);  // for the debugger

  if (text === "thing 1") { function1(); }
  else if (text === "thing 2") { function2(); }
}

I had a bunch of these "buttons" and I found it annoying to interact with those cells when I wanted to edit them, so I also used a "property" to activate and deactivate that interaction:

function onSelectionChange(event) {
  var isActive = PropertiesService.getScriptProperties().getProperty("active")
  console.log("Cells are active", JSON.stringify(isActive));
  if ( isActive !== "true" ) { return; }
  
  // Act based on text content
  var activeCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell();
  var text = activeCell.getValue();
  console.log("text", text);  // for the debugger

  if (text === "thing 1") { function1(); }
  else if (text === "thing 2") { function2(); }
}

function activate() {
  // I think these get saved as strings even if you give
  // a boolean value, so I just gave a string
  PropertiesService.getScriptProperties().setProperty("active", "true");
  console.log("After activated", JSON.stringify(PropertiesService.getScriptProperties().getProperty("active")));
}

function deactivate() {
  PropertiesService.getScriptProperties().setProperty("active", "false");
  console.log("After deactivated", JSON.stringify(PropertiesService.getScriptProperties().getProperty("active")));
}

I did use drawings as buttons with the activate and deactivate functions instead of cells because that was less annoying to program. I did have a lot of cell-type "buttons", so it was worth it.

I also changed the colors of the cells when I activated and deactivated them. This part is a bit untested. My code was much more specific to my situation. I was coloring bigger ranges and using different colors.

function activate() {
  PropertiesService.getScriptProperties().setProperty("active", "true");
  setStyle("#cccccc", "#000000", "A1");
}

function deactivate() {
  PropertiesService.getScriptProperties().setProperty("active", "false");
  setStyle("#b7b7b7", "#999999", "A1");  // Maybe not enough contrast for some people
}

function setStyle(backgroundColor, fontColor, cellAddress) {
  var range = SpreadsheetApp.getActiveSheet().getRange(cellAddress);
  range.setBackground(backgroundColor);
  range.setFontColor(fontColor);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文