某些背景:我们有一个共享的Google表格来跟踪我们在电影院的开幕,放映和其他活动。我们有一个主选项卡(“主”),其中包含我们所有的事件以及与之相关的详细信息,还有一个用于存档的选项卡(“存档”)。
我想在Google表格中编写一个脚本,以根据日期(在E列中)检测昨天和更早的事件和放映,选择符合该条件的整行(事件),并将其粘贴到单独的“存档”标签,然后从“主”标签中删除行。
任何指向我正确方向的建议都会很有帮助。我发现了一些与此类似的响应,但它们特定于Excel / VBA,对此我并不熟悉(或者很多Javascript)。
答案 0 :(得分:0)
我建议您做一些教程以熟悉如何编写脚本。
在这个答案中,我将充实您的代码需要解决的步骤。您会在相同或相似的问题上找到许多现有的主题。这仅仅是为了使您能够更好地搜索所需的代码元素。考虑到这可能只是实现结果的一种方法。
getSheetByName(name)
将使您能够为工作表创建可重复使用的变量。getLastRow()
会有所帮助。getRange(row, column, numRows, numColumns)
,尽管这只是定义范围的5种方法之一。 getValues()
与定义的范围结合使用。 FWIW,请注意这是如何复数的,因为其中有很多值。如果只需要一个单元格,则可以使用getValue()
。您将要遍历“主”中的行,并找到日期在今天之前的那些行。 “删除电子表格中的重复行”教程显示了一种循环方式,您可以阅读基本的JavaScript“循环和迭代”。
在您的情况下,有一个循环的“障碍物”。如果采用“通常”过程,则将从第一行循环到最后一行。但是,您正在从“母版”中删除一行,并且随着每一行的删除,其余行的行号将/可能会更改;因此“常规”流程将无法执行。您需要做的两件事:第一)从范围的底部开始循环;这将确保其余行的行号永远不会改变;第二)对数据进行排序,以使最早的日期位于底部。所以...现在,您将从下往上循环,您将评估所有最旧的日期,而不会遇到当日期大于“今天”的任何风险时,不再会有日期更少的行的风险比“今天”。当然,代码完成后,您随时可以将“主”上的数据重新排序为所需的任何顺序。
if...else
语句,以便您可以根据结果定义要执行的操作。比较日期有时说起来容易做起来难。此主题与Checking if one date is greater than the other using Google Script相关,您可以在其他主题上搜索“ Google Sheets脚本日期比较”。setValues
更新新值。另一种方法是累积其他“归档”数据,并在循环完成后将其添加到“归档”中。deleteRow(rowPosition)
。 可以通过多种方式组合这些元素。 在准备上面的摘要时,我必须确保提供准确而完整的建议。因此,以下只是实现目标的一种方法。应该注意的是,我的测试数据假设A列和C列的格式分别为日期和时间。
function so5710086103() {
// set up spreadsheet and sheets
var ss = SpreadsheetApp.getActiveSpreadsheet();
var master = ss.getSheetByName("Master");
var archive = ss.getSheetByName("Archive");
// get the last row and column of Master
var masterLR = master.getLastRow();
var masterLC = master.getLastColumn();
// get the last row and column of Archive
var archiveLR = archive.getLastRow();
var archiveLC = archive.getLastColumn();
//Logger.log("DEBUG: Last Row - Master = "+masterLR+", and Archive = "+archiveLR);
//Logger.log("DEBUG: Last Column - Master = "+masterLC+", and Archive = "+archiveLC);
// create a range, sort it and get the data from "Master"
var masterRange = master.getRange(2, 1, masterLR - 1, masterLC);
// sort master based on date
masterRange.sort({
column: 1,
ascending: false
});
// Logger.log("DEBUG: Master range = "+masterRange.getA1Notation());
var masterData = masterRange.getValues();
//Logger.log("DEBUG: Length of Master data = "+masterData.length);
// create a range and get the data from "Archive"
var archiveRange = archive.getRange(1, 1, archiveLR, archiveLC);
var archiveData = archiveRange.getValues();
// create a formatted date for today
var formattedToday = Utilities.formatDate(new(Date), 'GMT+10',
'dd MMMM yyyy');
// loop through the rows
// from bottom to top
for (var i = (+masterLR - 2); i > 0; i--) {
// convert cell dates to comparable format
var DBdate = Utilities.formatDate(masterData[i][0], 'GMT+10',
'dd MMMM yyyy');
var DBtime = Utilities.formatDate(masterData[i][2], 'GMT+10',
'hh:mm a');
//Logger.log("DEBUG: i = "+i+", DBdate = "+DBdate+", Today = "+formattedToday);
// clear the temporary row array
var archivecells = [];
if (DBdate < formattedToday) {
// the table date is less than today, so archive the data
// Logger.log("DEBUG: i = "+i+", DBdate = "+DBdate+", Today = "+formattedToday+" - DB value is less than Today. ACTION: Archive this row");
// copy the row cells to temporary row array
archivecells.push(DBdate);
archivecells.push(masterData[i][1]);
archivecells.push(DBtime);
archivecells.push(masterData[i][3]);
archivecells.push(masterData[i][4]);
// copy the temporary row array to archivedata
archiveData.push(archivecells);
// delete the Master Row
master.deleteRow(i + 2);
} else {
// the table date is NOT less than today, so do nothing
// Logger.log("DEBUG: i = "+i+", DBdate = "+DBdate+", Today = "+formattedToday+" - DB value is NOT less than Today. ACTION: Do nothing");
}
// update the accumulated data to Archive.
archive.getRange(1, 1, archiveData.length, archiveLC).setValues(
archiveData);
}
}
答案 1 :(得分:0)
嗨,这真的很有用,但是运行脚本时却出现错误
该范围内的行数必须至少为1。(第29行,文件“代码”)
该代码为25[0-5]
您能帮我吗?