使用 TextFinder 搜索范围比搜索整个工作表慢

Searching through a Range with TextFinder is slower than searching the entire Sheet

提问人:IMTheNachoMan 提问时间:6/10/2019 最后编辑:sinarahenebaIMTheNachoMan 更新时间:6/10/2019 访问量:14997

问:

我有一张纸,上面有很多行——几千行。我想在特定列中搜索文本。我正在使用,但它超时了。如果工作表只有 4 行数据,它甚至会超时。Range.createTextFinder

// This is very slow
var found = sheet.getRange("A:A").createTextFinder("dog").matchCase(false).findNext();

如果我搜索整个工作表,它的速度非常快,但我只想检查特定的列。

// This works faster but it searches the entire sheet
var found = sheet.createTextFinder("dog").matchCase(false).findNext();

有没有更快的方法来查找特定列中包含字符串的第一行?

更新:以下是执行记录:

[19-06-09 14:16:48:430 EDT] Starting execution
[19-06-09 14:16:48:513 EDT] SpreadsheetApp.openById([redacted]) [0.071 seconds]
[19-06-09 14:16:48:513 EDT] Spreadsheet.getSheetByName([Sheet2]) [0 seconds]
[19-06-09 14:16:48:514 EDT] Sheet.createTextFinder([b]) [0 seconds]
[19-06-09 14:16:48:514 EDT] TextFinder.matchCase([false]) [0 seconds]
[19-06-09 14:16:48:595 EDT] TextFinder.findNext() [0.08 seconds]
[19-06-09 14:16:48:596 EDT] Sheet.getRange([A:A]) [0 seconds]
[19-06-09 14:16:48:596 EDT] Range.createTextFinder([b]) [0 seconds]
[19-06-09 14:16:48:597 EDT] TextFinder.matchCase([false]) [0 seconds]
[19-06-09 14:17:21:064 EDT] TextFinder.findNext() [32.467 seconds]
[19-06-09 14:17:21:072 EDT] Execution failed: Service error: Spreadsheets (line 103, file "main") [32.626 seconds total runtime]
google-apps-script 谷歌表格

评论

0赞 TheMaster 6/10/2019
显示执行脚本。
1赞 sinaraheneba 6/10/2019
在TextFinder出现之前,这样做的方法是使用for循环将值与搜索字符串进行比较。这当然会起作用,但我想知道您的问题是否可能是由使用 A1 表示法引起的。如果你使用会怎样?.getValues()"A:A"getRange(1,1, sheet.getLastRow())
0赞 IMTheNachoMan 6/10/2019
@TheMaster我添加了执行记录。
0赞 IMTheNachoMan 6/10/2019
@Altigraph 是的,这似乎更快。我创建了一个有 8000 行的测试表并进行了搜索,它似乎很快就找到了。你会认为自己足够聪明,只能搜索到最后一行。TextFinder
2赞 sinaraheneba 6/10/2019
如果搜索整个工作表的速度比搜索范围快,它可能只搜索到“最后一行”——在工作表上返回包含内容的最后一行,范围内的 getLastRow() 返回该范围内的最后一行。getLastRow()

答:

8赞 sinaraheneba 6/10/2019 #1

此处的 Range 设置为整个 A 列,包括数千个空行。TextFinder 似乎基于或非常相似的东西进行搜索。对于工作表,返回包含内容的最后一行的值,但在某个范围内,它返回该范围内的最后一行getLastRow()getLastRow()

有两种方法可以解决这个问题: 在创建 TextFinder 之前指定一个更窄的范围

var found = sheet.getRange(1,1,sheet.getLastRow()).createTextFinder("dog").matchCase(false).findNext();

这将只搜索第一列,从第一行开始,到最后一行结束内容。

或者,您可以使用循环而不是 TextFinder,例如

var column = sheet.getRange("A:A").getValues();
var foundIndex;
for (var i = 0; i < column.length; i++){
  if (column[i][0] === "dog") {
    foundIndex = i;
    break;
  }
}

评论

2赞 Juan Salcedo 3/24/2020
第二个选项是否需要更长的时间,或者TextFinder是否针对这种搜索/替换过程进行了优化?