Google 文档脚本:在编辑时将单元格移动到另外两个工作表,但没有重复项
Google Docs Script: Move cell to two other sheets onEdit but no duplicates
我很了解 Google Sheet 公式,但不会编写脚本。
我从堆栈溢出中借用了别人的代码,进行了修补,结果失败了。
基本上,我想要做的是当我在 1 sheet 的 A 列的单元格中键入文本时,我希望它将该文本移动到下一个可用的,或者(+1 从最后一行)在另外两个 sheet 中,都列为 As。我还需要它来检查重复项,如果文本与另一个单元格完全匹配,则根本不将文本添加到 sheet。
这是我一直在修改的代码。
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "AddMember" && r.getColumn() == 27 && r.getValue() == "y") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("InputVPData");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
var targetSheet2 = ss.getSheetByName("InputSoulData");
var target = targetSheet2.getRange(targetSheet2.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
s.deleteRow(row);
}
}
此脚本有时将我的单元格移动到两个 sheet,有时它只将它添加到一个 sheet,有时它两次将单元格添加到同一个 sheet,有时它只是删除了我原来的单元格,并没有对它做任何事情。
此外,我真的不喜欢在 AA 列中键入 "y" 来移动它,最大的问题是它还会将 AA 列移动到另一个 sheet s 也是,这在某些时候将是一个大问题。
此脚本也不检查重复项。有一个 Google Sheet 数据验证功能可以做到这一点,但出于某种原因,到目前为止,当与脚本结合使用时,它充其量是参差不齐的,实际上 95% 的功能都不起作用时间.
这是我的 Spreadsheet 的副本,它是为 link 的任何人设置的,可以编辑。我认为此脚本不需要它,但请随时查看我正在使用的内容,因为它是一个副本,我不介意它损坏。
已更新 Link(2017 年 3 月 1 日)
我的职业是狗美容师,所以我不喜欢编写此脚本,当然 google sheet 公式只是一种爱好,当然还有游戏。 :)
编辑:(2017 年 3 月 1 日)
下面是我的新脚本。我添加了几个新的 sheet 并且脚本运行良好。我还更新了上面的 spreadsheet link 以再次包含一个具有完全编辑权限的新副本。
不过我有一个新问题。我该如何撤消此操作?例如,假设我要添加一个名为 "RemoveMember"?
的新 sheet
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
/*var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();*/
// Nothing wrong with using event.source, It is easier to debug with the below code.
var s = ss.getActiveSheet()
var r = ss.getActiveRange()
// The reason your previous code was checking for column AA was due to the following code r.getColumn() == 27 and r.getValue() == 'y'
if(s.getName() == "AddMember" && r.getColumn() == 1) {
var targetSheet = ss.getSheetByName("InputVPData");
var tlastRow = targetSheet.getLastRow()
// targetMembers gets the previous members you have in the inputVpData
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
//RemoveDuplicates removes if any duplicates are found.
var newMembers = removeDuplicates(r.getValues(),targetMembers)
//check and see if you have any new entry before entering the data
//important because getRange cannot have 0 as argument.
if(newMembers.length != 0){
targetSheet.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet2 = ss.getSheetByName("InputSoulData");
tlastRow = targetSheet2.getLastRow()
targetSheet2.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet3 = ss.getSheetByName("InputDonatedData");
tlastRow = targetSheet3.getLastRow()
targetSheet3.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet4 = ss.getSheetByName("InputWonData");
tlastRow = targetSheet4.getLastRow()
targetSheet4.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet5 = ss.getSheetByName("InputCapturedData");
tlastRow = targetSheet5.getLastRow()
targetSheet5.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet6 = ss.getSheetByName("InputDefendedData");
tlastRow = targetSheet6.getLastRow()
targetSheet6.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet7 = ss.getSheetByName("InputLostData");
tlastRow = targetSheet7.getLastRow()
targetSheet7.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
}
r.clear()
}
}
function removeDuplicates(newMembers, targetMembers){
var uniqueMembers = []
var counter =0
for( var i=0; i< newMembers.length; i++)
{
var isunique = true;
for(var j=0 ; j < targetMembers.length; j++) {
if(newMembers[i][0].trim() == targetMembers[j][0].trim())
{
isunique = false;
}
}
if(isunique){
uniqueMembers[counter] = []
uniqueMembers[counter][0] = newMembers[i][0]
counter++
}
}
return uniqueMembers
}
这应该可以解决问题:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
/*var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();*/
// Nothing wrong with using event.source, It is easier to debug with the below code.
var s = ss.getActiveSheet()
var r = ss.getActiveRange()
// The reason your previous code was checking for column AA was due to the following code r.getColumn() == 27 and r.getValue() == 'y'
if(s.getName() == "AddMember" && r.getColumn() == 1) {
var targetSheet = ss.getSheetByName("InputVPData");
var tlastRow = targetSheet.getLastRow()
// targetMembers gets the previous members you have in the inputVpData
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
//RemoveDuplicates removes if any duplicates are found.
var newMembers = removeDuplicates(r.getValues(),targetMembers)
//check and see if you have any new entry before entering the data
//important because getRange cannot have 0 as argument.
if(newMembers.length != 0){
targetSheet.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet2 = ss.getSheetByName("InputSoulData");
tlastRow = targetSheet2.getLastRow()
targetSheet2.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
}
r.clear()
}
}
function removeDuplicates(newMembers, targetMembers){
var uniqueMembers = []
var counter =0
for( var i=0; i< newMembers.length; i++)
{
var isunique = true;
for(var j=0 ; j < targetMembers.length; j++) {
if(newMembers[i][0].trim() == targetMembers[j][0].trim())
{
isunique = false;
}
}
if(isunique){
uniqueMembers[counter] = []
uniqueMembers[counter][0] = newMembers[i][0]
counter++
}
}
return uniqueMembers
}
您在正确的轨道上,刚刚添加了一个名为 remove Duplicates 的函数来检查重复项,然后再在这两个 sheet 中输入值。但是请注意,我只检查来自 InputVPData 的数据是否重复。如果愿意,您可以对 InputSoulData sheet 执行相同的操作。
编辑: 如何在第二个 sheet 中查找重复项。诀窍在于这些代码:
var targetSheet = ss.getSheetByName("InputVPData");
var tlastRow = targetSheet.getLastRow()
// targetMembers gets the previous members you have in the inputVpData
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
//RemoveDuplicates removes if any duplicates are found.
var newMembers = removeDuplicates(r.getValues(),targetMembers)
这段代码的作用是获取名为 "InputVPData" 的 sheet,然后找出最后一行有数据的行。然后获取第一列中从第 8 行到最后一行 - 7 的所有值:
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
getRange(StartRow,StartColumn,NoofRows,noOfColumns)=> Get the range
getValues() => Get the value of said range
同样,我们使用 r.getValues() 获取输入数据的值并将其传递给此函数
removeDuplicates(r.getValues(),targetMembers)
它从输入的数据 (r.getValues) 中删除重复项,并且 returns 它到变量 newMembers,就像这样
var newMembers = removeDuplicates(r.getValues(),targetMembers)
然后使用 setValues 函数将此 newMember 添加到您的 targetSheet,如下所示:
targetSheet.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
您需要做的就是在 r.getValues 和 targetSheet2 成员上使用 removeduplicates 函数后,复制上述代码以获得一组新的 newMembers2。
再次获得该列表后,使用 setValues 从变量 newMembers2.
中设置新 sheet 中的值
我很了解 Google Sheet 公式,但不会编写脚本。
我从堆栈溢出中借用了别人的代码,进行了修补,结果失败了。
基本上,我想要做的是当我在 1 sheet 的 A 列的单元格中键入文本时,我希望它将该文本移动到下一个可用的,或者(+1 从最后一行)在另外两个 sheet 中,都列为 As。我还需要它来检查重复项,如果文本与另一个单元格完全匹配,则根本不将文本添加到 sheet。
这是我一直在修改的代码。
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "AddMember" && r.getColumn() == 27 && r.getValue() == "y") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("InputVPData");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
var targetSheet2 = ss.getSheetByName("InputSoulData");
var target = targetSheet2.getRange(targetSheet2.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
s.deleteRow(row);
}
}
此脚本有时将我的单元格移动到两个 sheet,有时它只将它添加到一个 sheet,有时它两次将单元格添加到同一个 sheet,有时它只是删除了我原来的单元格,并没有对它做任何事情。
此外,我真的不喜欢在 AA 列中键入 "y" 来移动它,最大的问题是它还会将 AA 列移动到另一个 sheet s 也是,这在某些时候将是一个大问题。
此脚本也不检查重复项。有一个 Google Sheet 数据验证功能可以做到这一点,但出于某种原因,到目前为止,当与脚本结合使用时,它充其量是参差不齐的,实际上 95% 的功能都不起作用时间.
这是我的 Spreadsheet 的副本,它是为 link 的任何人设置的,可以编辑。我认为此脚本不需要它,但请随时查看我正在使用的内容,因为它是一个副本,我不介意它损坏。
已更新 Link(2017 年 3 月 1 日)
我的职业是狗美容师,所以我不喜欢编写此脚本,当然 google sheet 公式只是一种爱好,当然还有游戏。 :)
编辑:(2017 年 3 月 1 日)
下面是我的新脚本。我添加了几个新的 sheet 并且脚本运行良好。我还更新了上面的 spreadsheet link 以再次包含一个具有完全编辑权限的新副本。
不过我有一个新问题。我该如何撤消此操作?例如,假设我要添加一个名为 "RemoveMember"?
的新 sheetfunction onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
/*var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();*/
// Nothing wrong with using event.source, It is easier to debug with the below code.
var s = ss.getActiveSheet()
var r = ss.getActiveRange()
// The reason your previous code was checking for column AA was due to the following code r.getColumn() == 27 and r.getValue() == 'y'
if(s.getName() == "AddMember" && r.getColumn() == 1) {
var targetSheet = ss.getSheetByName("InputVPData");
var tlastRow = targetSheet.getLastRow()
// targetMembers gets the previous members you have in the inputVpData
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
//RemoveDuplicates removes if any duplicates are found.
var newMembers = removeDuplicates(r.getValues(),targetMembers)
//check and see if you have any new entry before entering the data
//important because getRange cannot have 0 as argument.
if(newMembers.length != 0){
targetSheet.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet2 = ss.getSheetByName("InputSoulData");
tlastRow = targetSheet2.getLastRow()
targetSheet2.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet3 = ss.getSheetByName("InputDonatedData");
tlastRow = targetSheet3.getLastRow()
targetSheet3.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet4 = ss.getSheetByName("InputWonData");
tlastRow = targetSheet4.getLastRow()
targetSheet4.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet5 = ss.getSheetByName("InputCapturedData");
tlastRow = targetSheet5.getLastRow()
targetSheet5.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet6 = ss.getSheetByName("InputDefendedData");
tlastRow = targetSheet6.getLastRow()
targetSheet6.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet7 = ss.getSheetByName("InputLostData");
tlastRow = targetSheet7.getLastRow()
targetSheet7.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
}
r.clear()
}
}
function removeDuplicates(newMembers, targetMembers){
var uniqueMembers = []
var counter =0
for( var i=0; i< newMembers.length; i++)
{
var isunique = true;
for(var j=0 ; j < targetMembers.length; j++) {
if(newMembers[i][0].trim() == targetMembers[j][0].trim())
{
isunique = false;
}
}
if(isunique){
uniqueMembers[counter] = []
uniqueMembers[counter][0] = newMembers[i][0]
counter++
}
}
return uniqueMembers
}
这应该可以解决问题:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
/*var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();*/
// Nothing wrong with using event.source, It is easier to debug with the below code.
var s = ss.getActiveSheet()
var r = ss.getActiveRange()
// The reason your previous code was checking for column AA was due to the following code r.getColumn() == 27 and r.getValue() == 'y'
if(s.getName() == "AddMember" && r.getColumn() == 1) {
var targetSheet = ss.getSheetByName("InputVPData");
var tlastRow = targetSheet.getLastRow()
// targetMembers gets the previous members you have in the inputVpData
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
//RemoveDuplicates removes if any duplicates are found.
var newMembers = removeDuplicates(r.getValues(),targetMembers)
//check and see if you have any new entry before entering the data
//important because getRange cannot have 0 as argument.
if(newMembers.length != 0){
targetSheet.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
var targetSheet2 = ss.getSheetByName("InputSoulData");
tlastRow = targetSheet2.getLastRow()
targetSheet2.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
}
r.clear()
}
}
function removeDuplicates(newMembers, targetMembers){
var uniqueMembers = []
var counter =0
for( var i=0; i< newMembers.length; i++)
{
var isunique = true;
for(var j=0 ; j < targetMembers.length; j++) {
if(newMembers[i][0].trim() == targetMembers[j][0].trim())
{
isunique = false;
}
}
if(isunique){
uniqueMembers[counter] = []
uniqueMembers[counter][0] = newMembers[i][0]
counter++
}
}
return uniqueMembers
}
您在正确的轨道上,刚刚添加了一个名为 remove Duplicates 的函数来检查重复项,然后再在这两个 sheet 中输入值。但是请注意,我只检查来自 InputVPData 的数据是否重复。如果愿意,您可以对 InputSoulData sheet 执行相同的操作。
编辑: 如何在第二个 sheet 中查找重复项。诀窍在于这些代码:
var targetSheet = ss.getSheetByName("InputVPData");
var tlastRow = targetSheet.getLastRow()
// targetMembers gets the previous members you have in the inputVpData
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
//RemoveDuplicates removes if any duplicates are found.
var newMembers = removeDuplicates(r.getValues(),targetMembers)
这段代码的作用是获取名为 "InputVPData" 的 sheet,然后找出最后一行有数据的行。然后获取第一列中从第 8 行到最后一行 - 7 的所有值:
var targetMembers = targetSheet.getRange(8,1,tlastRow - 7,1).getValues()
getRange(StartRow,StartColumn,NoofRows,noOfColumns)=> Get the range
getValues() => Get the value of said range
同样,我们使用 r.getValues() 获取输入数据的值并将其传递给此函数
removeDuplicates(r.getValues(),targetMembers)
它从输入的数据 (r.getValues) 中删除重复项,并且 returns 它到变量 newMembers,就像这样
var newMembers = removeDuplicates(r.getValues(),targetMembers)
然后使用 setValues 函数将此 newMember 添加到您的 targetSheet,如下所示:
targetSheet.getRange(tlastRow + 1, 1,newMembers.length, 1).setValues(newMembers);
您需要做的就是在 r.getValues 和 targetSheet2 成员上使用 removeduplicates 函数后,复制上述代码以获得一组新的 newMembers2。 再次获得该列表后,使用 setValues 从变量 newMembers2.
中设置新 sheet 中的值