web-dev-qa-db-ja.com

何度も呼び出されたコード

私の目標は非常に単純です:列Uの値を取得し、特定の範囲内にあるかどうかを確認します。 1〜100の場合、列Aに1を入力します。101〜200の場合、列Aに2を入力します。問題は、U列にほぼ2000行の数値があることです。各セルに=function(U2)列Aの結果は

1秒間に何度も呼び出されるスクリプト

エラー、最後にUtilities.sleep(500)を追加しても解決しません。これが私のコードです。私は非常に初心者のプログラマなので、さを許してください。

function assignBoxNumber(sgNumber) {
  if(sgNumber>=1 && sgNumber<=71) {
    return "1"
  }
  if(sgNumber==72) {
    return "1 and 2"
  }
  if(sgNumber>=73 && sgNumber<=125) {
    return "2"
  }
  if(sgNumber==126) {
    return "2 and 3"
  }
  if(sgNumber>=127 && sgNumber<=202) {
    return "3"
  }
  if(sgNumber>=207 && sgNumber<=269) {
    return "4"
  }
  if(sgNumber>=270 && sgNumber<=333) {
    return "5"
  }
  if(sgNumber>=334 && sgNumber<=433) {
    return "6"
  }
  if(sgNumber>=434 && sgNumber<=497) {
    return "7"
  }
  if(sgNumber>=498 && sgNumber<=560) {
    return "8"
  }
  if(sgNumber>=561 && sgNumber<=627) {
    return "9"
  }
  if(sgNumber>=628 && sgNumber<=691) {
    return "10"
  }
  if(sgNumber>=692 && sgNumber<=791) {
    return "11"
  }
  if(sgNumber>=792 && sgNumber<=872) {
    return "12"
  }
  if(sgNumber>=874 && sgNumber<=955) {
    return "13"
  }
  if(sgNumber>=956 && sgNumber<=1019) {
    return "14"
  }
  else {
    return "Error: No box location!"
  }
  Utilities.sleep(500)
}
2
Eric

種類の式として、このスクリプトを必要としない場合があります。

=iferror(vlookup(U1,D$1:E$20,2),"Error: No box location!")  

d1:E20がこの種のテーブルである場合、スーツにコピーして提供できます。

WA66026 example

これは同じシートにある場合もありますが、そのような「参照」データを別のシートに保持するのが賢明なようです(この場合、上記の式ではシート参照の追加が必要になります)。

対処するためにダブルクリックが機能する場合、速度はユーザー定義関数の場合とほぼ同じで、さらに高速になる場合がありますが、どちらも2000行で約10秒以上かかることはありません。

3
pnuts

私はそれをそうしようとしています。

コード

function myValues(range) {
  var output = [];
  for(var i = 0, iLen = range.length; i < iLen; i++) {
    output.Push(checkValue(range[i][0]));
  }  
  return output;
}

function checkValue(value) {
  var check;
  if(value >= 1 && value <= 71) {
    check = 1;
  } else if (value == 72) {
    check = '1 and 2';
  } else if (value >= 73 && value <= 125) {
    check = 2;
  } else if (value == 126) {
    check = '2 and 3';
  } else {
    check = 'Error: No box location!';
  }
  return check.toString();
}

注意

必ず残りの基準を自分で追加してください!!

サンプルファイルを作成しました:コードの呼び出し回数が多すぎる

1

Googleのヘルプセンター says

このGoogleユーザーアカウントに対してスクリプトが1秒間に何度も呼び出されます。これは、スクリプトが短期間で何度も実行を開始したことを示しています。最も一般的には、単一のスプレッドシートで繰り返し呼び出されるカスタム関数で発生します。このエラーを回避するには、カスタム関数のガイドで説明されているように、データの範囲ごとに1回呼び出す必要があるのみになるようにカスタム関数をコーディングします。

これは、カスタム関数の呼び出しに多くのメモリが必要になるためだと考えています(既存の関数(おそらくGoogleのサーバーにある)を調べて、存在するかどうかを確認し、実行に戻る)。 2000回ではなくonceと呼ばれるようにする必要があります。 sleep()を追加したという事実は到達不能であるため何もしませんでした(そのステートメントに到達する前は常にreturningしています) '呼び出し間でスリープするのではなく、呼び出しの後にスリープします。

あなたのコードは少しおかしく、最後のelse節で特に面白かったです。範囲のパターンが見つからなかったため、すべての上限とそれぞれの出力を2つの配列に保存しました。さらに、コードを1回だけ呼び出すために、必要な範囲を選択する必要があるようにコードを作成し、配列を返します(各要素は異なる行に出力されます)。見てみな:

function assignBoxNumber(range){
  var maxes = [1, 72, 73, 126, 127, 203, 207, 270, 334, 434, 498, 561, 628, 692, 792, 873, 874, 956, 1020];
  var vals = ["", "1", "1 and 2", "2", "2 and 3", "3", "", "4", "5", "6", "7", "8", "9", "10", "11", "12", "", "13", "14"];
  //if (maxes.length != vals.length) {return "you fucked up"; }
  var length = range.length, output = new Array(length);
  var i, obj, key;
  for (var row = 0; row < length; row++)
  {
    obj = range[row][0];
    key = "";
    for (i = 0; i < maxes.length; i++)
    {
      if (obj < maxes[i]){ key = vals[i]; break;}
    }
    output[row] = (key == "") ? "Error: No box location!" : key;
  }
  return output;
};

パラメーターはrangeであることに注意してください。たとえば、<cell1>:<cell2>U1:U20の形式になりますが、NOT文字列です。最初の番号は最初のセル(例ではU1)、2番目は最後のセル(U20)です。範囲の取得に役立つ地域を選択することもできます。

enter image description here

しかし、明らかに2k行以上の場合は書き込みたいので、=assignBoxNumber(<first cell>:<last cell>)のような関数を呼び出します。

1,021行でテストし、完全に機能しました。以前に問題が発生した理由を理解しています。実際にカスタム関数を見つけるには時間がかかります。カスタム関数への呼び出しは1つだけであるため、問題はないはずです。

PDATE:配列を修正し、出力は ごちゃごちゃしたメソッドの出力と完全に同一 になりました。

0
Shahar