Share via


Office スクリプトでのベスト プラクティス

これらのパターンとプラクティスは、スクリプトが毎回正常に実行されるように設計されています。 Excel ワークフローの自動化を開始するときに、一般的な落とし穴を避けるためにそれらを使用します。

操作レコーダーを使用して新機能を学習する

Excel では多くのことを行います。 それらのほとんどはスクリプト化できます。 操作レコーダーでは、Excel のアクションが記録され、コードに変換されます。 これは、さまざまな機能が Office スクリプトでどのように機能するかを学習する最も簡単な方法です。 特定のアクションのコードが必要な場合は、操作レコーダーに切り替えてアクションを実行し、[コードとしてコピー] を選択し、結果のコードをスクリプトに貼り付けます。

[コードとしてコピー] ボタンが強調表示された、操作レコーダー作業ウィンドウ。

重要

操作レコーダーでは、Excel on the web の外部でサポートされていない API を使用する場合があります。 他のプラットフォーム上のスクリプトのユーザーは、そのスクリプトを表示するときに警告を受けます。

オブジェクトが存在することを確認する

スクリプトは、多くの場合、ブックに存在する特定のワークシートまたはテーブルに依存します。 ただし、スクリプトの実行間に名前が変更されたり削除されたりする可能性があります。 メソッドを呼び出す前に、これらのテーブルまたはワークシートが存在するかどうかを確認することで、スクリプトが突然終了しないことを確認できます。

次のサンプル コードでは、ブックに "インデックス" ワークシートが存在するかどうかを確認します。 ワークシートが存在する場合、スクリプトは範囲を取得して続行します。 存在しない場合、スクリプトはカスタム エラー メッセージをログに記録します。

// Make sure the "Index" worksheet exists before using it.
let indexSheet = workbook.getWorksheet('Index');
if (indexSheet) {
  let range = indexSheet.getRange("A1");
  // Continue using the range...
} else {
  console.log("Index sheet not found.");
}

TypeScript ? 演算子は、メソッドを呼び出す前にオブジェクトが存在するかどうかを確認します。 これにより、オブジェクトが存在しないときに特別な操作を行う必要がない場合、コードがより合理化される可能性があります。

// The ? ensures that the delete() API is only called if the object exists.
workbook.getWorksheet('Index')?.delete();

データとブックの状態を最初に検証する

データを操作する前に、すべてのワークシート、テーブル、図形、その他のオブジェクトが存在することを確認します。 前のパターンを使用してチェック、すべてがブック内にあり、期待どおりかどうかを確認します。 データが書き込まれる前にこれを行うと、スクリプトによってブックが部分的な状態のままにならないことが保証されます。

次のスクリプトでは、"Table1" と "Table2" という名前の 2 つのテーブルが存在する必要があります。 スクリプトは最初にテーブルが存在するかどうかを確認し、return ステートメントで終わり、そうでない場合は適切なメッセージで終わります。

function main(workbook: ExcelScript.Workbook) {
  // These tables must be in the workbook for the script.
  const TargetTableName = 'Table1';
  const SourceTableName = 'Table2';

  // Get the table objects.
  let targetTable = workbook.getTable(TargetTableName);
  let sourceTable = workbook.getTable(SourceTableName);

  // Check if the tables are there.
  if (!targetTable || !sourceTable) {
    console.log(`Required tables missing - Check that both the source (${TargetTableName}) and target (${SourceTableName}) tables are present before running the script.`);
    return;
  }

  // Continue...
}

検証が別の関数で行われている場合でも、main 関数から return ステートメントを発行してスクリプトを終了する必要があります。 サブ関数から戻ってもスクリプトは終了しません。

次のスクリプトの動作は、前のスクリプトと同じです。 違いは、main 関数が inputPresent 関数を 呼び出してすべてを確認することです。 inputPresent はブール値 (true または false) を返して、必要なすべての入力が存在するかどうかを示します。 main 関数はそのブール値を使用して、スクリプトの継続または終了を決定します。

function main(workbook: ExcelScript.Workbook) {

  // Get the table objects.
  if (!inputPresent(workbook)) {
    return;
  }

  // Continue...
}

function inputPresent(workbook: ExcelScript.Workbook): boolean {
  // These tables must be in the workbook for the script.
  const TargetTableName = 'Table1';
  const SourceTableName = 'Table2';

  // Get the table objects.
  let targetTable = workbook.getTable(TargetTableName);
  let sourceTable = workbook.getTable(SourceTableName);

  // Check if the tables are there.
  if (!targetTable || !sourceTable) {
    console.log(`Required tables missing - Check that both the source (${TargetTableName}) and target (${SourceTableName}) tables are present before running the script.`);
    return false;
  }

  return true;
}

throw ステートメントを使用する場合

throw ステートメントは、予期しないエラーが発生したことを示します。 コードはすぐに終了します。 ほとんどの場合、スクリプトから throw する必要はありません。 通常、スクリプトは、問題が原因でスクリプトの実行に失敗したことをユーザーに自動的に通知します。 ほとんどの場合、エラー メッセージと main 関数の return ステートメントでスクリプトを終了するだけで十分です。

ただし、スクリプトが Power Automate フローの一部として実行されている場合、フローの続行を停止することが必要となる可能性があります。 throw ステートメントはスクリプトを停止し、フローにも停止するように指示します。

次のスクリプトは、テーブルチェックの例で throw ステートメントを使用する方法を示しています。

function main(workbook: ExcelScript.Workbook) {
  // These tables must be in the workbook for the script.
  const TargetTableName = 'Table1';
  const SourceTableName = 'Table2';

  // Get the table objects.
  let targetTable = workbook.getTable(TargetTableName);
  let sourceTable = workbook.getTable(SourceTableName);

  // Check if the tables are there.
  if (!targetTable || !sourceTable) {
    // Immediately end the script with an error.
    throw `Required tables missing - Check that both the source (${TargetTableName}) and target (${SourceTableName}) tables are present before running the script.`;
  }
  

try...catch ステートメントを使用する場合

try...catch ステートメントは、API 呼び出しが失敗したかどうかを検出し、スクリプトの実行を続行する方法です。

範囲に対して大規模なデータ更新を実行する次のスニペットを考えてみましょう。

range.setValues(someLargeValues);

someLargeValuesExcel on the web の処理能力を超える場合setValues() 呼び出しは失敗します。 その後、スクリプトはランタイム エラーでも失敗します。 try...catch ステートメントを使用すると、スクリプトはすぐにスクリプトを終了して既定のエラーを表示することなく、スクリプトでこの条件を認識できます。

スクリプト ユーザーに優れたエクスペリエンスを提供するためのアプローチの 1 つは、カスタム エラー メッセージを表示することです。 次のスニペットは、読み手に役立つより多くのエラー情報をログに記録する try...catch ステートメントを示しています。

try {
    range.setValues(someLargeValues);
} catch (error) {
    console.log(`The script failed to update the values at location ${range.getAddress()}. Please inspect and run again.`);
    console.log(error);
    return; // End the script (assuming this is in the main function).
}

エラーを処理するためのもう 1 つのアプローチは、エラー ケースを処理するフォールバック動作行うことです。 次のスニペットでは、catch ブロックを使用して、別の方法で更新プログラムをより小さな部分に分割し、エラーを回避します。

ヒント

大規模な範囲を更新する方法の完全な例については、「大規模なデータセットの書き込み」を参照してください。

try {
    range.setValues(someLargeValues);
} catch (error) {
    console.log(`The script failed to update the values at location ${range.getAddress()}. Trying a different approach.`);
    handleUpdatesInSmallerBatches(someLargeValues);
}

// Continue...
}

注:

ループの内部または周囲で try...catch を使用すると、スクリプトの速度が低下します。 パフォーマンスの詳細については、「try...catch ブロックの使用を避ける」を参照してください。

関連項目