1

私は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ループの外に書き込みを移動する私の試みで、間違ってやっている何

  1. ハッシュ値を高速に取得する方法や、同じ目的を達成するために別の方法を使用する方法はありますか?
  2. スクリプトのスピードアップに役立つ他に何ができますか?

ご提供いただけるご提案があれば幸いです。

-Mandy

答えて

0

あなたはappendRow()ループの外に呼び出しを移動しようとすると、右のアプローチに打つように聞こえます。スプレッドシートを読んでいたり、スプレッドシートに書き込んだりしているときは、個々のコールに1~2秒かかりますので、マッチすると時間がかかります。マッチを配列に格納して一度にすべて書き込むことは、方法です。

私が気づくもう一つのことは、スクリプトが実際のforループ条件文でgetValues()を呼び出すことです。条件文はループの各反復で毎回実行されるため、一致しない場合でも多くの時間を無駄にする可能性があります。

最終的な調整は、ご希望の動作に応じて役に立つ場合があります。最初の試合を気にしたり、試合が1つしかないとわかっている場合は、多くの繰り返しを節約することができます。これを行うには、retreiveddata.push(masterdata[j]);の直後に "break"と入力します。

for (i = 1; i < template.getDataRange().getValues().length; i++) { 

for (i = 1; i < itemnumberlist.length; i++) { 

そしてappendRowの問題と一緒にその修正、およびブレークコールを含む:にgetValuesの問題、変更を修正するには

for (i = 1; i < itemnumberlist.length; i++) { 
    for (j = 0; j < numrows; j++) { 
    if (masterdata[j][0].toString() === itemnumberlist[i][0].toString()) { 
     retreiveddata.push(masterdata[j]); 
     break; //stop searching after first match, move on to next item 
    } 
    } 
} 

//make sure you have data to write before trying to write it. 
if(retreiveddata.length > 0){ 
    var myotherrange = anothersheet.getRange(2,1,retreiveddata.length, retreiveddata[0].length); 
    myotherrange.setValues(retreiveddata); 
} 

各実行時に同じシートを別のシートに再使用している場合は、新しい結果を書き込む前に既存のデータを消去してください。

文字列を比較している文字列を比較しているので、ハッシュや実際の部品番号であっても、大きな違いは見込めません。

関連する問題