独立于单元格使用 getLastRow
Use getLastRow independently of a cell
您好,我目前正在研究时间跟踪系统。使用以下代码,我可以跟踪值在单元格中的时间。这个时间记录在另一个工作表中,这是由 appendRow () 连续完成的。现在我遇到了问题,如果多个单元格具有一个值,我只会在最后一个单元格中获得日期 + 时间。无论单元格如何,它都插入最后一个值是否有效?
function onEdit(e) {
addTimestamp(e);
}
function addTimestamp(e) {
var ui = SpreadsheetApp.getUi();
var ws = "Tabellenblatt2";
var ss = e.source;
var targetSheet = ss.getSheetByName("Tabellenblatt1");
var range = targetSheet.getRange(3, 2, 1000, 1);
var currentDate = new Date();
if (e.source.getActiveSheet().getName() === ws && range != "") {
var cell = ss.getActiveCell();
var val = cell.getValue();
if (val != "") {
let rowToAdd = [val, "", currentDate, ""]
ss.getSheetByName("Tabellenblatt1").appendRow(rowToAdd);
ui.alert("Test2");
} else {
var sheet = ss.getSheetByName("Tabellenblatt1");
sheet.getRange(sheet.getLastRow(), 4).setValue(currentDate);
ui.alert("Test3");
}
}
}
为了更清楚地解释我的问题,两张脚本当前的图片运行。
如果姓名 1 (C11) 现在取消订阅,则不会在第一个工作表中为姓名 1 输入最后日期,而是为姓名 2 输入最后日期。
解释:
您可以使用 TextFinder class 搜索被删除的名称并找到特定名称的行。
- 要查找旧值,您可以使用
e.oldValue
,但这有一个限制。
解决方案:
function onEdit(e) {
addTimestamp(e);
}
function addTimestamp(e) {
var ui = SpreadsheetApp.getUi();
var ws = "Tabellenblatt2";
var ss = e.source;
var targetSheet = ss.getSheetByName("Tabellenblatt1");
var range = targetSheet.getRange(3, 2, 1000, 1);
var currentDate = new Date();
if (e.source.getActiveSheet().getName() === ws && range != "") {
var val = e.range.getValue();
if (val != "") {
let rowToAdd = [val, "", currentDate, ""]
ss.getSheetByName("Tabellenblatt1").appendRow(rowToAdd);
ui.alert("Test2");
} else {
var sheet = ss.getSheetByName("Tabellenblatt1");
var dataFinder = sheet.createTextFinder(e.oldValue);
var nameRow = dataFinder.findAll()[0].getRow();
sheet.getRange(nameRow, 4).setValue(currentDate);
ui.alert("Test3");
}
}
}
限制:
如果您删除单元格的内容,则e.oldValue
值未定义,因此上述解决方案将不起作用。
要获得旧值,您需要用空字符串替换它。为此,左键单击要删除的单元格(名称),select 公式区域中的文本:
然后按删除键删除文本。
最后但同样重要的是,该解决方案假定名称是唯一的。
问题:
由于,当直接删除单元格内容(而不是先选择它然后删除内容)时,e.oldValue
不会填充,跟踪删除了哪个值变得麻烦了。
您需要找到一种方法来跟踪源 sheet (Tabellenblatt2
) 中的哪些行对应于目标 sheet (Tabellenblatt1
) 中的哪些行).
解决方案:
您可以为此使用 PropertiesService:
- 每次向源sheet写入新项目时,使用setProperty()存储一个属性,其
key
是当前编辑行的索引, value
是附加到目标 sheet. 的行的索引
- 每次从源 sheet 中删除一个项目时,使用 getProperty(key)(使用当前行索引)在目标 sheet 中检索相应的行索引(其中应写入第二个时间戳。
- 将时间戳写入刚刚检索到的行。
代码示例:
function addTimestamp(e) {
var ui = SpreadsheetApp.getUi();
var ws = "Tabellenblatt2";
var ss = e.source;
var targetSheet = ss.getSheetByName("Tabellenblatt1");
var range = targetSheet.getRange(3, 2, 1000, 1);
var currentDate = new Date();
var scriptProperties = PropertiesService.getScriptProperties();
if (e.source.getActiveSheet().getName() === ws) {
var cell = ss.getActiveCell();
var val = cell.getValue();
var sourceRowIndex = cell.getRow();
if (val != "") {
let rowToAdd = [val, "", currentDate, ""]
targetSheet.appendRow(rowToAdd);
scriptProperties.setProperty(sourceRowIndex, targetSheet.getLastRow());
} else {
var rowIndex = Number(scriptProperties.getProperty(sourceRowIndex));
if (rowIndex) targetSheet.getRange(rowIndex, 4).setValue(currentDate);
}
}
}
注:
- 重要提示:不会为以前存在的值存储属性。手动创建这些属性,或删除所有现有值并从头开始。
- 在上面的示例中,script properties is used, but document properties and user properties 也可能是合适的,具体取决于您的当前情况。
您好,我目前正在研究时间跟踪系统。使用以下代码,我可以跟踪值在单元格中的时间。这个时间记录在另一个工作表中,这是由 appendRow () 连续完成的。现在我遇到了问题,如果多个单元格具有一个值,我只会在最后一个单元格中获得日期 + 时间。无论单元格如何,它都插入最后一个值是否有效?
function onEdit(e) {
addTimestamp(e);
}
function addTimestamp(e) {
var ui = SpreadsheetApp.getUi();
var ws = "Tabellenblatt2";
var ss = e.source;
var targetSheet = ss.getSheetByName("Tabellenblatt1");
var range = targetSheet.getRange(3, 2, 1000, 1);
var currentDate = new Date();
if (e.source.getActiveSheet().getName() === ws && range != "") {
var cell = ss.getActiveCell();
var val = cell.getValue();
if (val != "") {
let rowToAdd = [val, "", currentDate, ""]
ss.getSheetByName("Tabellenblatt1").appendRow(rowToAdd);
ui.alert("Test2");
} else {
var sheet = ss.getSheetByName("Tabellenblatt1");
sheet.getRange(sheet.getLastRow(), 4).setValue(currentDate);
ui.alert("Test3");
}
}
}
为了更清楚地解释我的问题,两张脚本当前的图片运行。
如果姓名 1 (C11) 现在取消订阅,则不会在第一个工作表中为姓名 1 输入最后日期,而是为姓名 2 输入最后日期。
解释:
您可以使用 TextFinder class 搜索被删除的名称并找到特定名称的行。
- 要查找旧值,您可以使用
e.oldValue
,但这有一个限制。
解决方案:
function onEdit(e) {
addTimestamp(e);
}
function addTimestamp(e) {
var ui = SpreadsheetApp.getUi();
var ws = "Tabellenblatt2";
var ss = e.source;
var targetSheet = ss.getSheetByName("Tabellenblatt1");
var range = targetSheet.getRange(3, 2, 1000, 1);
var currentDate = new Date();
if (e.source.getActiveSheet().getName() === ws && range != "") {
var val = e.range.getValue();
if (val != "") {
let rowToAdd = [val, "", currentDate, ""]
ss.getSheetByName("Tabellenblatt1").appendRow(rowToAdd);
ui.alert("Test2");
} else {
var sheet = ss.getSheetByName("Tabellenblatt1");
var dataFinder = sheet.createTextFinder(e.oldValue);
var nameRow = dataFinder.findAll()[0].getRow();
sheet.getRange(nameRow, 4).setValue(currentDate);
ui.alert("Test3");
}
}
}
限制:
如果您删除单元格的内容,则e.oldValue
值未定义,因此上述解决方案将不起作用。
要获得旧值,您需要用空字符串替换它。为此,左键单击要删除的单元格(名称),select 公式区域中的文本:
然后按删除键删除文本。
最后但同样重要的是,该解决方案假定名称是唯一的。
问题:
由于e.oldValue
不会填充,跟踪删除了哪个值变得麻烦了。
您需要找到一种方法来跟踪源 sheet (Tabellenblatt2
) 中的哪些行对应于目标 sheet (Tabellenblatt1
) 中的哪些行).
解决方案:
您可以为此使用 PropertiesService:
- 每次向源sheet写入新项目时,使用setProperty()存储一个属性,其
key
是当前编辑行的索引,value
是附加到目标 sheet. 的行的索引
- 每次从源 sheet 中删除一个项目时,使用 getProperty(key)(使用当前行索引)在目标 sheet 中检索相应的行索引(其中应写入第二个时间戳。
- 将时间戳写入刚刚检索到的行。
代码示例:
function addTimestamp(e) {
var ui = SpreadsheetApp.getUi();
var ws = "Tabellenblatt2";
var ss = e.source;
var targetSheet = ss.getSheetByName("Tabellenblatt1");
var range = targetSheet.getRange(3, 2, 1000, 1);
var currentDate = new Date();
var scriptProperties = PropertiesService.getScriptProperties();
if (e.source.getActiveSheet().getName() === ws) {
var cell = ss.getActiveCell();
var val = cell.getValue();
var sourceRowIndex = cell.getRow();
if (val != "") {
let rowToAdd = [val, "", currentDate, ""]
targetSheet.appendRow(rowToAdd);
scriptProperties.setProperty(sourceRowIndex, targetSheet.getLastRow());
} else {
var rowIndex = Number(scriptProperties.getProperty(sourceRowIndex));
if (rowIndex) targetSheet.getRange(rowIndex, 4).setValue(currentDate);
}
}
}
注:
- 重要提示:不会为以前存在的值存储属性。手动创建这些属性,或删除所有现有值并从头开始。
- 在上面的示例中,script properties is used, but document properties and user properties 也可能是合适的,具体取决于您的当前情况。