Google 脚本:当复选框为真时,将行从 sheet A 复制到 sheet B。当复选框为假时,从 sheet B 中删除复制的行
Google Scripts: When checkbox true, copy row from sheet A to sheet B. When checkbox false, delete copied row from sheet B
我是 Google 脚本的新手,真的应该先学习基础知识,但直接跳到试图为朋友解决问题。在网上找到了这段代码,它是我想要实现的完美解决方案,但是,以下代码片段似乎导致了问题并且没有执行其预期的功能:
} else if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == "") {
// Remove the row from "Tab2" when the checkbox in "Tab1" is unchecked
var prop = PropertiesService.getDocumentProperties();
var targetRow = prop.getProperty(row);
ss.getSheetByName("Tab2").deleteRow(targetRow);
Logger.log("Deleted the " + targetRow + "row from " + s.getName());
prop.deleteProperty(row);
完整代码见下:
function onEdit(event) {
// assumes source data in sheet named "Tab1"
// target sheet of move to named "Tab2"
// getColumn with check-boxes is currently set to colu 1 or C
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
var row = r.getRow();
var numColumns = s.getLastColumn();
Logger.log(r.getValue());
if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == true) {
// Create the record in "Tab2"
var prop = PropertiesService.getDocumentProperties();
var targetSheet = ss.getSheetByName("Tab2");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 2);
s.getRange(row, 2, 1, numColumns).copyTo(target, { contentsOnly: true });
// Insert checkbox cell (already checked)
targetSheet.getRange(target.getRow(), 1).insertCheckboxes().check();
prop.setProperty(row, target.getRow());
} else if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == "") {
// Remove the row from "Tab2" when the checkbox in "Tab1" is unchecked
var prop = PropertiesService.getDocumentProperties();
var targetRow = prop.getProperty(row);
ss.getSheetByName("Tab2").deleteRow(targetRow);
Logger.log("Deleted the " + targetRow + "row from " + s.getName());
prop.deleteProperty(row);
} else if (s.getName() == "Tab2" && r.getColumn() == 1 && r.getValue() == false) {
// Remove the row from "Tab2" when the checkbox is unchecked and unchecks in "Tab1"
var prop = PropertiesService.getDocumentProperties();
s.deleteRow(row);
// Look the corresponding row in "Tab1"
var keys = prop.getKeys();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (prop.getProperty(key) == row) {
ss.getSheetByName("Tab1").getRange(key, 1).setValue(false);
prop.deleteProperty(key)
break;
}
}
}
}
一切都完全按照我的预期工作(请参阅下面的用例),除了当 Tab1 中的复选框在第 X 行上未选中并且 Tab2 中的关联行(通过 PropertiesService)未被删除时...但它应该是。
用例:
- Tab1 中第 X 行的复选框为真 - 将行复制到下一个可用行的 Tab2 [在上面的代码中工作]
- 然后将 Tab1 中第 X 行的复选框设置为假(该行已被复制到 Tab2 中)- 删除 Tab2 中的关联行[在上面的代码中不起作用]
- Tab2 中第 X 行的复选框设为 false - 删除 Tab2 中的行并将 Tab1 中关联行的复选框设为 false [在上面的代码中工作]
理想情况下,上面的代码会更聪明,每一行都有一个唯一的标识符(例如,这可以添加到 A 列中)并且更像关系数据库,因此代码不依赖于顺序维护的行数,例如如果用户将来想在现有行之间插入新行。
提前感谢您的帮助!
我正在尝试重现该问题,是的,我也遇到了您所指的问题。现在,在对代码进行了一些修改之后,我似乎无法修改它并使其工作。甚至修改最后一个条件并将其作为您的第二个条件。
对我有用的是:
} else if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == false) {
sourceRow = ss.getSheetByName("Tab1").getRange(r.getRow(), 1, 1, ss.getSheetByName("Tab1").getLastColumn()).getValues();
destData = ss.getSheetByName("Tab2").getDataRange().getValues();
destData.forEach(function(item, index){
tempRow = sourceRow[0];
tempRow[0] = true;
if(JSON.stringify(tempRow) === JSON.stringify(item)) {
ss.getSheetByName("Tab2").deleteRow(index + 1);
}
});
所以我确实手动访问了两张纸上的数据。将 Tab2 中的所有行与 Tab1 中的选定行进行比较。
而且由于选中的行在捕获后已经取消选中,所以我确实创建了一个临时变量来存储勾选的行值。然后在 Tab2 中查找。如果相同则删除Tab2中的行
另外,请注意上面的 r.getValue()
条件已更新为与 false
值而不是空白进行比较。
我是 Google 脚本的新手,真的应该先学习基础知识,但直接跳到试图为朋友解决问题。在网上找到了这段代码,它是我想要实现的完美解决方案,但是,以下代码片段似乎导致了问题并且没有执行其预期的功能:
} else if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == "") {
// Remove the row from "Tab2" when the checkbox in "Tab1" is unchecked
var prop = PropertiesService.getDocumentProperties();
var targetRow = prop.getProperty(row);
ss.getSheetByName("Tab2").deleteRow(targetRow);
Logger.log("Deleted the " + targetRow + "row from " + s.getName());
prop.deleteProperty(row);
完整代码见下:
function onEdit(event) {
// assumes source data in sheet named "Tab1"
// target sheet of move to named "Tab2"
// getColumn with check-boxes is currently set to colu 1 or C
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
var row = r.getRow();
var numColumns = s.getLastColumn();
Logger.log(r.getValue());
if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == true) {
// Create the record in "Tab2"
var prop = PropertiesService.getDocumentProperties();
var targetSheet = ss.getSheetByName("Tab2");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 2);
s.getRange(row, 2, 1, numColumns).copyTo(target, { contentsOnly: true });
// Insert checkbox cell (already checked)
targetSheet.getRange(target.getRow(), 1).insertCheckboxes().check();
prop.setProperty(row, target.getRow());
} else if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == "") {
// Remove the row from "Tab2" when the checkbox in "Tab1" is unchecked
var prop = PropertiesService.getDocumentProperties();
var targetRow = prop.getProperty(row);
ss.getSheetByName("Tab2").deleteRow(targetRow);
Logger.log("Deleted the " + targetRow + "row from " + s.getName());
prop.deleteProperty(row);
} else if (s.getName() == "Tab2" && r.getColumn() == 1 && r.getValue() == false) {
// Remove the row from "Tab2" when the checkbox is unchecked and unchecks in "Tab1"
var prop = PropertiesService.getDocumentProperties();
s.deleteRow(row);
// Look the corresponding row in "Tab1"
var keys = prop.getKeys();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (prop.getProperty(key) == row) {
ss.getSheetByName("Tab1").getRange(key, 1).setValue(false);
prop.deleteProperty(key)
break;
}
}
}
}
一切都完全按照我的预期工作(请参阅下面的用例),除了当 Tab1 中的复选框在第 X 行上未选中并且 Tab2 中的关联行(通过 PropertiesService)未被删除时...但它应该是。
用例:
- Tab1 中第 X 行的复选框为真 - 将行复制到下一个可用行的 Tab2 [在上面的代码中工作]
- 然后将 Tab1 中第 X 行的复选框设置为假(该行已被复制到 Tab2 中)- 删除 Tab2 中的关联行[在上面的代码中不起作用]
- Tab2 中第 X 行的复选框设为 false - 删除 Tab2 中的行并将 Tab1 中关联行的复选框设为 false [在上面的代码中工作]
理想情况下,上面的代码会更聪明,每一行都有一个唯一的标识符(例如,这可以添加到 A 列中)并且更像关系数据库,因此代码不依赖于顺序维护的行数,例如如果用户将来想在现有行之间插入新行。
提前感谢您的帮助!
我正在尝试重现该问题,是的,我也遇到了您所指的问题。现在,在对代码进行了一些修改之后,我似乎无法修改它并使其工作。甚至修改最后一个条件并将其作为您的第二个条件。
对我有用的是:
} else if (s.getName() == "Tab1" && r.getColumn() == 1 && r.getValue() == false) {
sourceRow = ss.getSheetByName("Tab1").getRange(r.getRow(), 1, 1, ss.getSheetByName("Tab1").getLastColumn()).getValues();
destData = ss.getSheetByName("Tab2").getDataRange().getValues();
destData.forEach(function(item, index){
tempRow = sourceRow[0];
tempRow[0] = true;
if(JSON.stringify(tempRow) === JSON.stringify(item)) {
ss.getSheetByName("Tab2").deleteRow(index + 1);
}
});
所以我确实手动访问了两张纸上的数据。将 Tab2 中的所有行与 Tab1 中的选定行进行比较。
而且由于选中的行在捕获后已经取消选中,所以我确实创建了一个临时变量来存储勾选的行值。然后在 Tab2 中查找。如果相同则删除Tab2中的行
另外,请注意上面的 r.getValue()
条件已更新为与 false
值而不是空白进行比较。