私は2枚のGoogleシートブックを持っています。18,000行のデータセット内のアイテムを検索するためにスクリプトが11-20秒かかる
1つは、製造元アイテム#に基づくキーを持つルックアップデータの「マスター」ソースであり、1234からA-01/234-Name_1のいずれかである可能性があります。 SpreadsheetApp.openByUrlを介して参照されるこのシートには、18,000行と13の列があります。キー列はプレーンテキストに変換され、シートはこの列でソートされます。
2番目は「マスター」に対してルックアップする必要のある項目#sを人が入力する「テンプレート」です(通常は一度に20〜1500個の項目)。
スクリプトはテンプレートにあります。それは非常に遅く、通常30分後にタイムアウトします。他の誰かによって書かれたもので、App Scriptの新機能ですが、スクリプトが何をしているのか、どこにボトルネックが発生しているのかを理解できたと思います。
それは原料の束を行いますが、これは、ルックアップの肉である:()は、iのループを通るたびに11取っていることを決定するために、私はLogger.logを使用
var numrows = master.getDataRange().getNumRows();
var masterdata = master.getDataRange().getValues();
var itemnumberlist = template.getDataRange().getValues();
var retreiveddata = [];
// iterate through the manf item number list to find all matches in the
// master and return those matches to another sheet
for (i = 1; i < template.getDataRange().getValues().length; i++) {
for (j = 0; j < numrows; j++) {
if (masterdata[j][1].toString() === itemnumberlist[i][1].toString()) {
retreiveddata.push(data[j]);
anothersheet.appendRow(data[j]);
}
}
}
から19秒、ちょうど狂っているようです。私はいくつかのGoogleの検索を行ってきたと私は別の物事のカップルを試してみた
は...
まず私は、スクリプトがすべてやってしまうので、forループの外に検出されたデータの書き込みを動かしてみました最初に読んでから大きなチャンクで書きましたが、私はそれを正しく理解できませんでした。私の2つの試みは以下の通りです。
var mycounter = 0;
for (i = 0; i < template.getDataRange().getValues().length; i++) {
for (j = 0; j < numrows; j++) {
if (masterdata[j][0].toString() === itemnumberlist[i][0].toString()) {
retreiveddata.push(masterdata[j]);
mycounter = mycounter + 1;
}
}
}
// Attempt 1
// var myrange = retreiveddata.length;
// for(k = 0; k < myrange; k++) {
// anothersheet.appendRow(retreiveddata.pop([k]);
// }
//Attempt 2
var myotherrange = anothersheet.getRange(2,1,myothercounter, 13)
myotherrange.setValues(retreiveddata);
これは金曜日にあったので、私は、確かに覚えていないことができますが、私は、両方の試みは「anothersheet」に全体のマスターファイルを作成しようとするスクリプトが生じたと思います。
私は一時的にこれを設定して、別のものを試してみることにしました。私はいくつかのサンプルスプレッドシートで問題を再現しようとしていましたが、できませんでした。同じスクリプトが、15,000行のサンプル "master"ファイルをルックアップごとに1秒未満で取得しています。私が考えることができる唯一のことは、奇妙なテキスト文字列の代わりに私のキーとして乱数を使用したことです。
これにより、マスターデータと値の両方でハッシュアルゴリズムを使用して検索することができたかもしれませんが、これは他の一連の問題を示しています。
私は別のフォーラムのポストから、これらの機能を借り:
function GetMD5Hash(value) {
var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5,
value);
var txtHash = '';
for (j = 0; j <rawHash.length; j++) {
var hashVal = rawHash[j];
if (hashVal < 0)
hashVal += 256;
if (hashVal.toString(16).length == 1)
txtHash += "0";
txtHash += hashVal.toString(16);
Utilities.sleep(100);
}
return txtHash;
}
function RangeGetMD5Hash(input) {
if (input.map) { // Test whether input is an array.
return input.map(GetMD5Hash); // Recurse over array if so.
Utilities.sleep(100);
} else {
return GetMD5Hash(input)
}
}
それは文字通り私のマスタースプレッドシート内のすべての18,000アイテムの#Sのハッシュ値を取得するために一日かかりました。 GetMD5HashもRangeGetMD5Hashも、一貫して値を返しません。私は一度にいくつかの行しかできません。時々私は "Loading ..."を無期限に取得します。 GetMD5Hashが(前の行で働いていたにもかかわらず)定義されていないというメッセージが表示されて「#Name」が表示されることがあります。そして時々私は内部エラーに関するメッセージで "#エラー"を出します。
この方法では、実際には各項目の参照時間が2〜3秒に短縮されます(これよりはるかに優れていますが、それほど優れていません)。しかし、入力データを一貫して処理するハッシュ関数を得ることはできません。
この時点では、私はこのフォーラムでスマートな人々に手を差し伸べて何らかの奇跡的な反応を期待していると思っていたので、私はとても不満を感じていました。
要約すると、私は、これらの3つの項目の提案を探しています:私は、forループの外に書き込みを移動する私の試みで、間違ってやっている何
- ?
- ハッシュ値を高速に取得する方法や、同じ目的を達成するために別の方法を使用する方法はありますか?
- スクリプトのスピードアップに役立つ他に何ができますか?
ご提供いただけるご提案があれば幸いです。
-Mandy