您必须使用 Google Apps 脚本。
试试这个:
- 首先,转到工具并点击脚本编辑器。
- 删除Code.gs中的代码
- 粘贴下面提供的代码并保存
- 刷新您的电子表格,自定义菜单将在菜单中弹出
- 转到自定义菜单并点击更新排序表
首次执行需要用户授权。授权脚本后,请确保重新运行自定义菜单。
下面的代码将在您的电子表格中创建一个自定义菜单。单击自定义菜单将执行一个函数,该函数将更新排序表并保留其复选框值。
我还加了cmets来解释代码中每一行的作用。
代码:
function updateSorted() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Import_range");
var sortedSh = ss.getSheetByName("Sorted");
/* Use this if the Import_range is from different spreadsheet
var iSS = SpreadsheetApp.openById("Insert Sheet ID here");
var sh = iSS.getSheetByName("Insert Sheet name here");
and comment the var sh = ss.getSheetByName("Import_range"); above*/
/*
Check if the Sorted Sheet has data.
If true, compare Sorted Sheet and Import_range data
else, copy Import_range data to Sorted Sheet.
*/
if(sortedSh.getLastRow() > 1){
var sData = sortedSh.getRange(2, 1, sortedSh.getLastRow()-1, 5).getValues(); //remove unnecessary data
var sDataFiltered = sData.filter(e => e[4]); //get Date column of Sorted sheet
var sDates = sortedSh.getRange(2, 5, sortedSh.getLastRow()-1, 1).getValues().flat();
var sDatesFiltered = sDates.filter((a) => a); //remove unnecessary data
var importDates = sh.getRange(2, 4, sh.getLastRow()-1, 1).getValues().flat(); //get Date column of Import_range
//convert dates to String format
var arr1 = sDatesFiltered.map( dateString => String(dateString))
var arr2 = importDates.map( dateString => String(dateString))
var difference = arr2.filter(x => !arr1.includes(x)); //get the difference between arr1 and arr2
difference.forEach(dates => {
var index = arr2.indexOf(dates); //get new entry position in Import_range
var newEntry = sh.getRange(index+2, 1, 1, 4).getValues().flat(); //get row data of new entry from Import_range
newEntry.unshift(false); //append false in the beggining of the array
sDataFiltered.push(newEntry); //append new entry to sDataFiltered array
})
var range = sortedSh.getRange(2, 1, sDataFiltered.length, 5);
range.setValues(sDataFiltered); //set the values of Sorted sheet using the sDataFiltered array as data
sortedSh.getRange(2, 1, sDataFiltered.length, 1).insertCheckboxes(); //get the checkbox range and insert checkbox
range.sort({column: 5, ascending: false}); //sort the data by Date column
}else{
var range = sh.getRange(2, 1, sh.getLastRow()-1, 4);
var data = range.getValues();
data.forEach(row => {
row.unshift(false)
})
var sortedRange = sortedSh.getRange(2, 1, data.length, 5);
sortedRange.setValues(data);
sortedSh.getRange(2, 1, data.length, 1).insertCheckboxes();
sortedRange.sort({column: 5, ascending: false});
}
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Update Sorted Sheet', 'updateSorted')
.addToUi();
}
示例:
填充空排序表:
更新 Import_range 工作表,单击复选框并更新 Sorted Sheet:
实现时间驱动触发器:
- 打开您的 Apps 脚本项目。
- 点击左侧的触发警报。
- 点击右下角的添加触发器。
- 选择并配置您要创建的触发器类型。
- 点击保存。
对于时间驱动,您的触发器设置应如下所示:
上面的示例触发器将每分钟更新一次工作表。使用时间驱动触发器的缺点是配额限制。 Gmail 帐户的总运行时间限制为 90 分钟。超出配额将导致错误。见Quotas for Google Services。
使用按钮:自定义菜单的替代方案
在您的工作表中创建一个用户友好的按钮
- 转到插入 -> 绘图
- 绘制所需的按钮形状和样式。
- 点击保存并关闭
- 将按钮移至所需位置
- 右键单击,单击三个垂直点并选择分配脚本
- 输入 updateSorted 并点击 确定
- 点击按钮运行
注意:如果您决定使用按钮并想删除工作表中的自定义菜单,只需删除您的 Apps 脚本中的 onOpen 函数即可。
参考资料: