我正在查看“网络”标签,以查看是否将重做/撤消数据发送到Google表格中的服务器,似乎不是-似乎是本地用户/设备正在修改信息。
数据结构如何实现撤消/重做功能?我的猜测是它将是一个堆栈(即数组),最后一个可撤消的操作被推入堆栈,如下所示:
actions = [
action_1,
action_2
]
但是,对于每个操作而言,实际的数据结构将是什么样?我猜想可以对单元格进行基本修改,但可以存储文本,但是Google表格中有太多可能要做的事情,因此看起来“动作”几乎是无限复杂的。
最佳答案
您想要实现Google Spreadsheet的撤消和重做功能。
您可以使用Google Apps脚本。
我可以像上面那样理解。为此,该示例脚本如何?因此,请仅将此作为几种可能的答案之一。
用法:
请执行以下流程以使用示例脚本。
创建新的电子表格并打开脚本编辑器。
如果第一个选项卡不是Sheet1
的名称,请将其更改为Sheet1
。在此示例脚本中,作为测试情况,撤消和重做功能将运行到活动电子表格中的Sheet1
表。请注意这一点。
将以下示例脚本复制并粘贴到脚本编辑器,然后保存脚本。
将可安装的OnEdit事件触发器安装到函数installedOnEdit
。
您可以在here上查看有关此操作的文档。请设置installedOnEdit
作为OnEdit事件触发器。
安装可安装的OnEdit事件触发器时,将打开授权屏幕。因此,请授权范围。
请关闭电子表格,然后重新打开电子表格。这样,onOpen()
由简单触发器运行。并且offset
被清除。然后,请打开脚本编辑器。
在电子表格上,手动将“ foo”放入单元格“ A1”。
这样,将logSpreadsheet
的电子表格创建到根文件夹。这用作日志。
因此,只有这一次,请等待创建电子表格。
在根文件夹中确认创建的电子表格后,将“栏”手动放在单元格“ A1”中。
手动将“ baz”放入单元格“ A1”。
这时,当您看到日志电子表格时,可以在单元格“ A1:A3”中看到以下值。这用于撤消和重做功能。
{"range":"A1","value":"foo","oldValue":""}
{"range":"A1","value":"bar","oldValue":"foo"}
{"range":"A1","value":"baz","oldValue":"bar"}
在脚本编辑器上运行功能
undo
。这样,单元格“ A1”的值从
baz
更改为bar
。在脚本编辑器上运行功能
undo
。这样,单元格“ A1”的值从
bar
更改为foo
。在脚本编辑器上运行功能
undo
。这样,单元格“ A1”的值从
foo
更改为空。因为最初的情况是空的。在脚本编辑器上运行功能
redo
。这样,单元格“ A1”的值从
foo
更改为bar
。在脚本编辑器上运行功能
redo
。这样,单元格“ A1”的值从
bar
更改为baz
。在脚本编辑器上运行功能
redo
。这样,单元格“ A1”的值不变。因为这种情况是最新的。
示例脚本:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var prop = PropertiesService.getScriptProperties();
function onOpen() {
prop.setProperty("offset", "0");
}
function getSheet() {
var logId = prop.getProperty("logSpreadsheetId");
if (logId) {
return SpreadsheetApp.openById(logId).getSheets()[0];
}
throw new Error("Please edit a cell in the Spreadsheet. By this, the Spreadsheet for logging is created.");
}
// Undo function
function undo() {
var logsheet = getSheet();
var offset = Number(prop.getProperty("offset"));
var lastRow = logsheet.getLastRow();
if (lastRow + offset > 0) {
var log = logsheet.getRange(lastRow, 1).offset(offset, 0).getValue();
var obj = JSON.parse(log);
sheet.getRange(obj.range).setValue(obj.oldValue);
prop.setProperty("offset", offset - 1);
}
}
// Redo function
function redo() {
var logsheet = getSheet();
var offset = Number(prop.getProperty("offset")) + 1;
var lastRow = logsheet.getLastRow();
if (lastRow + offset <= lastRow) {
var log = logsheet.getRange(lastRow, 1).offset(offset, 0).getValue();
var obj = JSON.parse(log);
sheet.getRange(obj.range).setValue(obj.value);
prop.setProperty("offset", offset);
}
}
// Please set the installable OnEdit event trigger to this function.
function installedOnEdit(e) {
var logId = prop.getProperty("logSpreadsheetId")
var ss;
if (logId) {
ss = SpreadsheetApp.openById(logId);
} else {
ss = SpreadsheetApp.create("logSpreadsheet");
prop.setProperty("logSpreadsheetId", ss.getId());
}
var log = {range: e.range.getA1Notation(), value: "value" in e ? e.value : "", oldValue: "oldValue" in e ? e.oldValue : ""};
ss.getSheets()[0].appendRow([JSON.stringify(log)]);
}
注意:
这是一个简单的示例脚本。不幸的是,复杂的动作可能无法使用。例如,在当前脚本中不能使用来编辑多个单元格。我对此深表歉意。当您想添加更复杂的操作时,需要针对每种情况修改脚本。请注意这一点。
在当前阶段,当通过单击删除按钮删除单元格值时,旧值不包括在事件对象中。因此,当您要测试值的删除时,请单击该单元格,然后使用Backspace按钮删除该单元格中的每个字符。这样,旧值将包含在事件对象中。请注意这一点。
我认为,如果要执行更复杂的操作,使用修订数据覆盖电子表格可能是合适的。 Ref
参考:
Installable Triggers
关于javascript - Google表格撤消/重做功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59078734/