我试图编写一个Google Sheets Apps脚本函数,以检查当前活动单元格的内容,将其与另一个单元格的内容匹配,然后根据该检查结果移动光标。
以电子表格为例: https://docs.google.com/spreadsheets/d/1kpuVT1ZkK0iOSy_nGNPxvXPTFJrX-0JgNmEev6U--5c/edit#gid=0
我希望用户转到D2,输入一个值,然后按Tab,然后在活动单元格位于E2时,该功能将检查D2中的值是否与B2中的相同。如果是,请停留在E2中。 然后我们在E2中输入值,然后按Tab键,该函数检查它是否与C2相同,如果相同,则从F2向下移动两次,并两次移至D3。因此,如果正确输入所有值,则光标将在D,E和F中的单元格之间作曲折,如下所示:
我能找到的最接近的答案是下面的答案,但这每次都涉及在菜单中单击一种方法:
Move sheet rows on based on their value in a given column
我想该功能可以在编辑文档开始时触发,然后一直移动光标直到文档完成,此时可以停止该功能。
有什么想法吗?
编辑:到目前为止,我已经尝试过:
我设法将位置更改为硬编码位置“ D3”,并创建了一个可以使用以下功能向下移动的功能:
function onOpen() {
var m = SpreadsheetApp.getUi().createMenu('Move');
m.addItem('Move to D3', 'move').addToUi();
m.addItem('Move to one below', 'move2').addToUi();
m.addItem('Move down left', 'move_down_left').addToUi();
}
function move() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var range = s.getRange('D3');
s.setActiveRange(range);
}
function move2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = s.getActiveRange();
var c = r.getCell(1,1);
var target = s.getRange(c.getRow() + 1, c.getColumn());
s.setActiveRange(target);
}
function move_down_left() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var r = s.getActiveRange();
var c0 = r.getCell(1,1);
var r1 = s.getRange(c0.getRow(), c0.getColumn() - 1);
var c1 = r1.getCell(1,1);
var r2 = s.getRange(c1.getRow(), c1.getColumn() - 2);
var c2 = r2.getCell(1,1);
if (c1.getValue() == c2.getValue()) {
var target = s.getRange(c1.getRow() + 1, c1.getColumn() - 1);
s.setActiveRange(target);
}
}
答案 0 :(得分:2)
正如我在评论中提到的那样,您想使用simple trigger函数(以便该函数适用于所有用户,而无需他们首先授权该脚本)。自然有一些limitations of simple triggers,但是对于您描述的工作流程,它们并不适用。
接收on edit
触发器调用的函数的关键原理是它具有一个event object,其中包含有关已编辑单元格的数据:
- authMode : 来自
ScriptApp.AuthMode
枚举的值。- 旧值: 编辑之前的单元格值(如果有)。仅在编辑范围为单个单元格时可用。如果单元格没有以前的内容,则将是不确定的。
- 范围:
Range
对象,代表已编辑的单元格或单元格范围。- 来源:
Spreadsheet
对象,代表脚本绑定到的Google表格文件。- triggerUid : 产生此事件的触发器的ID(仅适用于可安装的触发器)。
- 用户: 一个
User
对象,代表活动用户(如果有)(取决于security restrictions的复杂集合)。- 值: 编辑后的新单元格值。仅在编辑范围为单个单元格时可用。
其中,我们将使用range
和value
。我将把处理对多个单元格范围的编辑的业务案例留给您。毕竟,堆栈溢出不是您获得统包解决方案的地方;)
function onEdit(e) {
if (!e) throw new Error("You ran this from the script editor");
const edited = e.range;
if (edited.getNumRows() > 1 || edited.getNumColumns() > 1)
return; // multicell edit logic not included.
const sheet = edited.getSheet();
if (sheet.getName() !== "your workflow sheet name")
return;
// If the user edited a specific column, check if the value matches that
// in a different, specific column.
const col = edited.getColumn(),
advanceRightColumn = 5,
rightwardsCheckColumn = 2;
if (col === advanceRightColumn) {
var checkedValue = edited.offset(0, rightwardsCheckColumn - col, 1, 1).getValue();
if (checkedValue == e.value) // Strict equality may fail for numbers due to float vs int
edited.offset(0, 1, 1, 1).activate();
else
edited.activate();
return;
}
const endOfEntryColumn = 8,
endCheckColumn = 3,
startOfEntryColumn = 4;
if (col === endOfEntryColumn) {
var checkedValue = edited.offset(0, endCheckColumn - col, 1, 1).getValue();
if (checkedValue == e.value)
edited.offset(1, startOfEntryColumn - col, 1, 1).activate();
else
edited.activate();
return;
}
}
在消化上面的内容时,您会注意到需要提供某些特定于您自己的工作流的值,例如工作表名称和适当的列。如果被编辑的列是多个列之一,则可以以相当简单的方式修改以上内容,以使用相应“ check”列的恒定偏移量或分别排列的偏移量/目标列的数组向右移动。 (这样的修改几乎可以肯定需要使用Array#indexOf
。)
我要注意的一点是,如果您的编辑是可表示为整数的数字,则严格相等===
会失败,因为Google表格会将数字存储为浮点数。严格的相等性会按定义排除类型转换,并且任何int
都不能与float
完全相同。因此,使用泛型相等性==
。上面的代码不会等同于空白的检查单元格和删除内容的结果。
方法参考: