复制到新的 sheet 自身倍增,并且不过滤我的结果
Copy to new sheet multiply itself loads of times, and dosent filter my result
我的代码确实会自我复制,结果中有超过 999 行行 sheet,而实际上应该只有几行。
当我创建过滤器并勾选 F
列中的“777
”时,它仍然会出现在过滤结果中。
问: 是什么导致了这种行为,我该如何解决才能使其只复制一次,并且只复制过滤后的结果?
以下是更多详细信息:
完整代码:
var partner_list = SpreadsheetApp.openByUrl(url);
var SS = partner_list.getSheetByName("Sheet 1");
var targetSheet = partner_list.getSheetByName("result");
if (SS.getFilter() != null && SS.getFilter().toString()=='Filter') {
console.log("have populated filter..", SS.getFilter());
var Avals_pre_D = SS.getFilter().getRange();
var Avals_pre = SS.getFilter().getRange().getValues();
if (targetSheet) {
partner_list.deleteSheet(targetSheet);
}
targetSheet = partner_list.insertSheet();
targetSheet.setName("result");
console.log("DATA:",Avals_pre);
Avals_pre_D.copyTo(
targetSheet.getRange('A2:R'),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL,
false);
var SS = SpreadsheetApp.openByUrl(same_url).getSheetByName("result"); // aka same.. but the result sheet.
var Avals_pre = targetSheet.getRange("A2:R").getValues();
} else {
console.log("no filter..");
var Avals_pre = SS.getRange("A2:R").getValues();
}
console.log(Avals_pre.length);
尝试复制 Avals_pre
时出现以下错误:
TypeError: Avals_pre.copyTo is not a function
avals_pre
的输出结果如下:
DATA: [
[ '','','','','','test','','','','','','','','','','','','','','','','','','','','' ],
[ 1,2,3,4,5,666,'','','',100,'','','','','','','','','','','','','','','','' ],
[ 4,23,43,44,5,777,'','','',100,'','','','','','','','','','','','','','','','' ],
[ 43,65,54,65,65,888,'','','',100,'','','','','','','','','','','','','','','','' ],]
(这包括我不想要的结果)
如果我采用 Avals_pre_D
并复制它,它的行为就像疯了一样。
其中 console.log(Avals_pre.length);
等于 999。
结果图片sheet:
修改点:
我认为您的问题可能是由于以下原因造成的。
- 当使用
SS.getFilter().getRange()
作为范围时,
- 与
copyTo
一起使用时,检索过滤后的值。通过这种方式,Avals_pre_D.copyTo(targetSheet.getRange('A2:R'), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
适用于具有过滤结果的值。似乎在这种情况下,范围内的显示值被复制了。
- 当它与
getValues
一起使用时,将检索所有值。这样,第一个 var Avals_pre = SS.getFilter().getRange().getValues();
适用于没有过滤结果的值。
- 我认为这可能是当前的规范。
而且,当我看到你的脚本时,使用了var Avals_pre = targetSheet.getRange("A2:R").getValues();
。在这种情况下,范围是“A2:R”。通过这种方式,值由 sheet 中的最大行检索。我认为这可能是您 If i take Avals_pre_D and copy that, it behaves like crazy. where console.log(Avals_pre.length); equals 999.
.
问题的原因
如果您想直接检索 sheet 上过滤结果的值,我认为 this thread 可能会有用。
当以上几点反映到你的脚本中,就变成了下面这样。
修改后的脚本:
function myFunction() {
// var url = "###"; // I'm not sure about your "url" and "same_url". So please set these variables.
// var same_url = url;
var partner_list = SpreadsheetApp.openByUrl(url);
var SS = partner_list.getSheetByName("Sheet 1");
var targetSheet = partner_list.getSheetByName("result");
if (SS.getFilter() != null && SS.getFilter().toString() == 'Filter') {
console.log("have populated filter..", SS.getFilter());
var Avals_pre_D = SS.getFilter().getRange();
// --- I added below script.
var url2 = `https://docs.google.com/spreadsheets/d/${partner_list.getId()}/gviz/tq?tqx=out:csv&gid=${SS.getSheetId()}`;
var res = UrlFetchApp.fetch(url2, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}});
var Avals_pre = Utilities.parseCsv(res.getContentText());
// ---
if (targetSheet) {
partner_list.deleteSheet(targetSheet);
}
targetSheet = partner_list.insertSheet();
targetSheet.setName("result");
console.log("DATA:", Avals_pre);
Avals_pre_D.copyTo(
targetSheet.getRange('A2:R'),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL,
false);
var SS = SpreadsheetApp.openByUrl(same_url).getSheetByName("result"); // aka same.. but the result sheet.
var Avals_pre = targetSheet.getRange("A2:R" + targetSheet.getLastRow()).getValues(); // Modified
} else {
console.log("no filter..");
var Avals_pre = SS.getRange("A2:R" + SS.getLastRow()).getValues(); // Modified
}
console.log(Avals_pre.length);
}
注:
在上面修改的脚本中,通过下面添加的脚本,过滤后的值直接检索到Avals_pre
.
var url = `https://docs.google.com/spreadsheets/d/${partner_list.getId()}/gviz/tq?tqx=out:csv&gid=${SS.getSheetId()}`;
var res = UrlFetchApp.fetch(url, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}});
var Avals_pre = Utilities.parseCsv(res.getContentText());
如果你可以使用这个脚本,我想你也可以按如下方式修改你的脚本。
var partner_list = SpreadsheetApp.openByUrl(url);
var SS = partner_list.getSheetByName("Sheet 1");
var Avals_pre;
if (SS.getFilter() != null && SS.getFilter().toString() == 'Filter') {
console.log("have populated filter..", SS.getFilter());
var url2 = `https://docs.google.com/spreadsheets/d/${partner_list.getId()}/gviz/tq?tqx=out:csv&gid=${SS.getSheetId()}`;
var res = UrlFetchApp.fetch(url2, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}});
Avals_pre = Utilities.parseCsv(res.getContentText());
} else {
console.log("no filter..");
Avals_pre = SS.getRange("A2:R" + SS.getLastRow()).getValues();
}
console.log(Avals_pre.length);
参考文献:
- getLastRow()
- 相关话题
- How to get filtered values from Filter after using setColumnFilterCriteria?
已添加:
关于以下你的附加问题,
do you know how i can get the row number? etg if 3 is filtered out, i would get 1,2,4?
在这种情况下,不能直接使用上面的方法。因此,作为一个简单的示例脚本,我添加了一个示例脚本来检索隐藏行号和显示行号。
示例脚本:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet()
var result = {hiddenRow: [], showedRow: []};
for (var r = 1; r <= sheet.getLastRow(); r++) {
result[sheet.isRowHiddenByFilter(r) ? "hiddenRow" : "showedRow"].push(r);
}
console.log(result)
}
- 在此示例脚本中,返回活动 sheet 的隐藏行号和显示行号。
参考:
我的代码确实会自我复制,结果中有超过 999 行行 sheet,而实际上应该只有几行。
当我创建过滤器并勾选 F
列中的“777
”时,它仍然会出现在过滤结果中。
问: 是什么导致了这种行为,我该如何解决才能使其只复制一次,并且只复制过滤后的结果?
以下是更多详细信息:
完整代码:
var partner_list = SpreadsheetApp.openByUrl(url);
var SS = partner_list.getSheetByName("Sheet 1");
var targetSheet = partner_list.getSheetByName("result");
if (SS.getFilter() != null && SS.getFilter().toString()=='Filter') {
console.log("have populated filter..", SS.getFilter());
var Avals_pre_D = SS.getFilter().getRange();
var Avals_pre = SS.getFilter().getRange().getValues();
if (targetSheet) {
partner_list.deleteSheet(targetSheet);
}
targetSheet = partner_list.insertSheet();
targetSheet.setName("result");
console.log("DATA:",Avals_pre);
Avals_pre_D.copyTo(
targetSheet.getRange('A2:R'),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL,
false);
var SS = SpreadsheetApp.openByUrl(same_url).getSheetByName("result"); // aka same.. but the result sheet.
var Avals_pre = targetSheet.getRange("A2:R").getValues();
} else {
console.log("no filter..");
var Avals_pre = SS.getRange("A2:R").getValues();
}
console.log(Avals_pre.length);
尝试复制 Avals_pre
时出现以下错误:
TypeError: Avals_pre.copyTo is not a function
avals_pre
的输出结果如下:
DATA: [
[ '','','','','','test','','','','','','','','','','','','','','','','','','','','' ],
[ 1,2,3,4,5,666,'','','',100,'','','','','','','','','','','','','','','','' ],
[ 4,23,43,44,5,777,'','','',100,'','','','','','','','','','','','','','','','' ],
[ 43,65,54,65,65,888,'','','',100,'','','','','','','','','','','','','','','','' ],]
(这包括我不想要的结果)
如果我采用 Avals_pre_D
并复制它,它的行为就像疯了一样。
其中 console.log(Avals_pre.length);
等于 999。
结果图片sheet:
修改点:
我认为您的问题可能是由于以下原因造成的。
- 当使用
SS.getFilter().getRange()
作为范围时,- 与
copyTo
一起使用时,检索过滤后的值。通过这种方式,Avals_pre_D.copyTo(targetSheet.getRange('A2:R'), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
适用于具有过滤结果的值。似乎在这种情况下,范围内的显示值被复制了。 - 当它与
getValues
一起使用时,将检索所有值。这样,第一个var Avals_pre = SS.getFilter().getRange().getValues();
适用于没有过滤结果的值。
- 与
- 我认为这可能是当前的规范。
- 当使用
而且,当我看到你的脚本时,使用了
问题的原因var Avals_pre = targetSheet.getRange("A2:R").getValues();
。在这种情况下,范围是“A2:R”。通过这种方式,值由 sheet 中的最大行检索。我认为这可能是您If i take Avals_pre_D and copy that, it behaves like crazy. where console.log(Avals_pre.length); equals 999.
.如果您想直接检索 sheet 上过滤结果的值,我认为 this thread 可能会有用。
当以上几点反映到你的脚本中,就变成了下面这样。
修改后的脚本:
function myFunction() {
// var url = "###"; // I'm not sure about your "url" and "same_url". So please set these variables.
// var same_url = url;
var partner_list = SpreadsheetApp.openByUrl(url);
var SS = partner_list.getSheetByName("Sheet 1");
var targetSheet = partner_list.getSheetByName("result");
if (SS.getFilter() != null && SS.getFilter().toString() == 'Filter') {
console.log("have populated filter..", SS.getFilter());
var Avals_pre_D = SS.getFilter().getRange();
// --- I added below script.
var url2 = `https://docs.google.com/spreadsheets/d/${partner_list.getId()}/gviz/tq?tqx=out:csv&gid=${SS.getSheetId()}`;
var res = UrlFetchApp.fetch(url2, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}});
var Avals_pre = Utilities.parseCsv(res.getContentText());
// ---
if (targetSheet) {
partner_list.deleteSheet(targetSheet);
}
targetSheet = partner_list.insertSheet();
targetSheet.setName("result");
console.log("DATA:", Avals_pre);
Avals_pre_D.copyTo(
targetSheet.getRange('A2:R'),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL,
false);
var SS = SpreadsheetApp.openByUrl(same_url).getSheetByName("result"); // aka same.. but the result sheet.
var Avals_pre = targetSheet.getRange("A2:R" + targetSheet.getLastRow()).getValues(); // Modified
} else {
console.log("no filter..");
var Avals_pre = SS.getRange("A2:R" + SS.getLastRow()).getValues(); // Modified
}
console.log(Avals_pre.length);
}
注:
在上面修改的脚本中,通过下面添加的脚本,过滤后的值直接检索到
Avals_pre
.var url = `https://docs.google.com/spreadsheets/d/${partner_list.getId()}/gviz/tq?tqx=out:csv&gid=${SS.getSheetId()}`; var res = UrlFetchApp.fetch(url, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}}); var Avals_pre = Utilities.parseCsv(res.getContentText());
如果你可以使用这个脚本,我想你也可以按如下方式修改你的脚本。
var partner_list = SpreadsheetApp.openByUrl(url); var SS = partner_list.getSheetByName("Sheet 1"); var Avals_pre; if (SS.getFilter() != null && SS.getFilter().toString() == 'Filter') { console.log("have populated filter..", SS.getFilter()); var url2 = `https://docs.google.com/spreadsheets/d/${partner_list.getId()}/gviz/tq?tqx=out:csv&gid=${SS.getSheetId()}`; var res = UrlFetchApp.fetch(url2, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}}); Avals_pre = Utilities.parseCsv(res.getContentText()); } else { console.log("no filter.."); Avals_pre = SS.getRange("A2:R" + SS.getLastRow()).getValues(); } console.log(Avals_pre.length);
参考文献:
- getLastRow()
- 相关话题
- How to get filtered values from Filter after using setColumnFilterCriteria?
已添加:
关于以下你的附加问题,
do you know how i can get the row number? etg if 3 is filtered out, i would get 1,2,4?
在这种情况下,不能直接使用上面的方法。因此,作为一个简单的示例脚本,我添加了一个示例脚本来检索隐藏行号和显示行号。
示例脚本:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet()
var result = {hiddenRow: [], showedRow: []};
for (var r = 1; r <= sheet.getLastRow(); r++) {
result[sheet.isRowHiddenByFilter(r) ? "hiddenRow" : "showedRow"].push(r);
}
console.log(result)
}
- 在此示例脚本中,返回活动 sheet 的隐藏行号和显示行号。