変換後のコードのエラーを修正する

マクロ変換アドオンはコンバージョン プロセスの大部分を自動化しますが、コードを完成させるには、一部の API やその他の項目を調整しなければならない場合があります。

このガイドでは、プロジェクトに追加された Apps Script ファイル(GS ファイル)について説明し、さまざまなエラータイプを解釈し、エラーを修正する方法を説明します。

プロジェクトに追加された Apps Script ファイルについて

以下の目的で、追加の GS ファイルが Apps Script プロジェクトに追加されます。

  • Apps Script に存在しない VBA 定数と値を定義します。
  • 変換されていない API を実装する。
  • バリエーションを解決します。

次の GS ファイルが Apps Script プロジェクトに追加されます。

  • Library.gs
  • Unimplemented_constructs.gs
  • Variant_resolutions.gs

Library.gs

通常、library.gs ファイル内の何も変更する必要はありません。

library.gs ファイルには、VBA コードで使用され、Apps Script に存在しない関数と定数が定義されます。これにより、新しい Apps Script コードが VBA コードに似たものになります。また、library.gs ファイルの関数や定数を使用するたびに定義を繰り返す必要もありません。

Unimplemented_constructs.gs

unimplemented_constructs.gs ファイルは、Macro Converter で変換できなかったコンストラクトまたは API に対応しています。コードが意図したとおりに動作するようにするには、このファイルを変更する必要があります。

例: Window.Activate()

以下は、Window.Activate() というサポートされていない API の例です。マクロ変換ツールは、類似した名前の新しい Apps Script 関数を作成し、unimplemented_constructs.gs ファイルで定義します。VBA 関数はサポートされていないため、新しい Apps Script 関数は例外をスローします。

新しい関数は、VBA コードで元の API が使用されているすべての場所に変換された Apps Script コードに追加されます。

元の API の動作を再現する回避策が見つかった場合は、unimplemented_constructs.gs ファイルの関数の定義を更新するだけで済みます。関数がそこで定義されると、その関数は Apps Script プロジェクト内のすべての場所に適用されます。

コードの例を次に示します。

元の VBA コード

Window.activate()

Apps Script コードを変換し、インラインに追加

_api_window_activate();

関数の定義が unimplemented_constructs.gs ファイルに追加されました

/**
 * Could not convert window.activate API. Please add relevant code in the
 * following function to implement it.
 * This API has been used at the following locations in the VBA script.
 *     module1 : line 3
 *
 * We couldn't find an equivalent API in Apps Script for this VBA API. Please
 * reconsider if this function call is critical, otherwise consider implementing
 * it in a different way.
 */
function _api_window_activate(CallingObject) {
  ThrowException("API window.activate not supported yet.");
}

Variant_resolutions.gs

オブジェクトの型を特定できない場合、variant_resolutions.gs ファイルが Apps Script プロジェクトに追加されます。これは、API に複数の戻り型がある場合や、オブジェクト自体がバリアントとして宣言されている場合など、複数の理由で発生する可能性があります。

Macro Converter は、このファイルに __handle_resolve_<api>() という新しい関数を追加します。この関数は、対象の API に代わるもので、オブジェクトのタイプを特定するのに役立ちます。

場合によっては、__handle_resolve_<api>() 関数を更新してオブジェクト タイプを手動で宣言する必要があります。サポートされていないオブジェクト タイプをご覧ください。

例: name()

VBA の多くのオブジェクト タイプは name() API を定義します。通常、Apps Script の同等の値は getName() ですが、オブジェクトの種類によっては異なります。複数の代替ケースが発生する可能性があります。

  • オブジェクトの同等の API は getName() とは異なる名前で呼ばれます。
  • オブジェクトに、名前を取得する Apps Script API がありません。
  • 同等の Apps Script オブジェクトはありません。

オブジェクト タイプが決定されていない場合、Macro Converter は variant_resolutions.gs ファイルに __handle_resolve_name という新しい関数を作成します。

コードの例を次に示します。

元の VBA コード

a = Selection.name

この場合、現在の選択に対して API name() が呼び出されます。選択は、シート オブジェクトまたはシェイプ オブジェクトのいずれかです。シート オブジェクトの場合は getName() に翻訳されますが、シェイプ オブジェクトの場合は、Apps Script に同等のオブジェクトはありません。

Apps Script コードを変換し、インラインに追加

a = __handle_resolve_name({}, getActiveSelection(), {});

以下の __handle_resolve_name() 関数は、さまざまなオブジェクト タイプを解決するために variant_resolution.gs ファイルに追加されています。この関数はオブジェクトの型をチェックし、サポートされている場合は getName() を使用し、getName() がサポートされていない場合はエラーをスローします。

関数の定義が variant_resolution.gs ファイルに追加されました

function __handle_resolve_name(ExecutionContext, CallingObject, params_map) {
  var found_api_variant = false;
  var return_value;
  if (String(CallingObject) == "Sheet") {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (CallingObject instanceof ChartInSheet) {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (!found_api_variant) {
    ThrowException("API .name not supported yet.");
  }
  return return_value;
}

エラーを検出する

変換された Apps Script コードでエラーが発生すると、エラーの種類とその場所を示すメッセージが表示されます。エラー メッセージの形式は、使用している Apps Script ランタイムによって異なります。

デフォルトの V8 ランタイムを使用している場合は、次のようなエラーが表示されます。

_api_windows_active (unimplemented_constructs:2:3)

つまり、エラーは unimplemented_constructs.gs ファイルの 2 行目 3 文字目にあります。

非推奨の Rhino ランタイムを使用している場合は、次のようなエラーが表示されます。

unimplemented_constructs:2 (_api_windows_active)

これは、エラーが unimplemented_constructs.gs ファイルの 2 行目にあることを意味します。

エラーの種類

上記の unimplemented_constructs.gs ファイルと variant_resolution.gs ファイルで発生するエラーのほとんどは修正できます。

発生する可能性のあるエラーの種類は次のとおりです。

実装されていない API

実装されていない API は、マクロ コンバーターで VBA から Apps Script に変換できない API であり、その API に対する既知の回避策はありません。

実装されていない API は通常、空の関数として(空のシグネチャ付きの場合もあります)unimplemented_constructs.gs ファイルに追加されます。オブジェクト タイプを特定できない場合、実装されていない API が variant_resolution.gs ファイルに追加されることがあります。

コンバージョン前に生成した互換性レポートでは、この API は [さらに調査が必要] とラベル付けされています。

ファイルを変換する前に VBA コードでこのタイプの API を修正しなかった場合、Apps Script プロジェクトには次のように表示されます。

/**
* Could not convert . Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*      : 
* We couldn't find an equivalent API in Apps Script for this VBA API. Please
* reconsider if this function call is critical, otherwise consider implementing
* it in a different way.
* @param param1 {}
* @param param2 {}
* ...
* @return {}
*/
function _api_<API_name>(param1, param2, ....) {
  ThrowException("API  not supported yet.");
}

実装されていない API エラーを修正する

実装されていない API を、既存の Apps Script API または JS ライブラリで定義します。そのための手順は以下のとおりです。

  1. エラーのある場所で、変換された Apps Script コードを開きます。エラーを探すをご覧ください。
  2. 関数の上に追加されたコメントを読みます。コメントに、API を Apps Script に実装する方法が示されている場合があります。
  3. Apps Script に API を実装する方法が見つからない場合は、コードから削除することを検討してください。
  4. 回避策が見つからない、またはこの API をコードから削除できないにもかかわらず、マクロでこのエラーがスローされる場合は、このマクロを変換できません。

実装されていない API エラーの例

実装されていない API のシナリオとその解決方法の例を以下に示します。

  • 同等の Apps Script がない: Apps Script に存在しない API である Chart.Protect の代替方法を示します。
  • 不明なオブジェクト タイプ: 変数であるオブジェクト タイプを処理する方法と、Apps Script で再作成できるサポートされていないオブジェクト タイプを実装する方法について説明します。
例 1: 同等の Apps Script がないか、API が不明

この例では、Google スプレッドシートでグラフを保護する方法がないため、Chart.Protect は自動的に変換されませんでした。

/**
* Could not convert chart.protect API. Please add relevant code in the following
* function to implement it.
*
* This API has been used at the following locations in the VBA script.
*     sheet1 : line 3
* You can use the following Apps Script APIs to convert it.
*
* Comments : Auto conversion of Chart.Protect is not supported yet. If the API is
* critical for the workflow the user can implement the unimplemented handler
* method in the generated code, else comment out the throw statement.
*
* @param {Object} CallingObject represents the parent object using which the API
* has been called.
* @param {string} Password
* @param {boolean} DrawingObjects
* @param {boolean} Contents
* @param {boolean} Scenarios
* @param {boolean} UserInterfaceOnly
*
*/
function _api_chart_protect(
   CallingObject, Password, DrawingObjects, Contents, Scenarios,
   UserInterfaceOnly) {
 ThrowException('API chart.protect not supported yet.');
}
グラフを保護することはできませんが、グラフのデータ範囲を保護して、データを変更できないようにすることができます。

範囲を保護する実装例を以下に示します。
/**
* Could not convert chart.protect API. Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*     sheet1 : line 3
*
* You can use the following Apps Script APIs to convert it.
* Comments : Auto conversion of Chart.Protect is not supported yet. If the API
* is critical for the workflow the user can implement the unimplemented handler
* method in the generated code, else comment out the throw statement.
*
* @param {Object} CallingObject represents the parent object using which the API
* has been called.
* @param {string} Password
* @param {boolean} DrawingObjects
* @param {boolean} Contents
* @param {boolean} Scenarios
* @param {boolean} UserInterfaceOnly
*/
function _api_chart_protect(
  CallingObject, Password, DrawingObjects, Contents, Scenarios, UserInterfaceOnly) {
var ranges = CallingObject.getChart().getRanges();
for (var i = 0; i < ranges.length; i++) {
  // Note that this does not lock the range for the document owner.
  ranges[i].protect();
}
}
例 2: サポートされていないオブジェクト タイプ

オブジェクト タイプが不明な場合、実装されていない API エラーが variant_resolution.gs ファイルに追加されます。次の例は、上記の VBA name() API の例を拡張したものです。variant_resolution.gs をご覧ください。

この例では、次のことを学習します。

  1. name() API が variant_resolution.gs ファイル内の新しい関数に変換される仕組み
  2. 変換されたコードで新しい関数が呼び出される仕組み
  3. Apps Script でサポートされていないオブジェクト タイプである CommandBar の回避策を作成する方法

1. 変換されたコードでは、name() が呼び出されるオブジェクトの正確なタイプを特定できないため、マクロ変換ツールは __handle_resolve_name という新しい関数を作成します(以下を参照)。

function __handle_resolve_name(ExecutionContext, CallingObject, params_map) {
 var found_api_variant = false;
 var return_value;
  if (String(CallingObject) == "Sheet") {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (CallingObject instanceof ChartInSheet) {
    if (!ExecutionContext.isLhs) {
      return_value = CallingObject.getName();
      found_api_variant = true;
    }
  }
  if (!found_api_variant) {
    ThrowException('API .name not supported yet.');
  }
  return return_value;
}

2. VBA コードで name() API を呼び出す PrintName() 関数を定義しているとします。VBA コードは次のとおりです。

‘Defining a function that prints the name of the object in parameter
Sub PrintName(obj as Variant)
  Debug.Print obj.Name
End Sub
「name()」は変数であるオブジェクトに対して呼び出されるため、変換されたコードでは変換時のオブジェクト型がわかりません。変換された Apps Script コードは、__handle_resolve_name 関数を呼び出します。
function PrintName(obj) {
  Logger.log(_handle_resolve_name(obj));
}

3. VBA コードで、オブジェクト タイプ CommandBarPrintName() 関数が呼び出されるとします。VBA コードは次のとおりです。

PrintName Application.CommandBars.item("Standard")
CommandBar は Apps Script ではサポートされていないため、上記の VBA コードで使用されている 2 つのメソッドもサポートされていません。
  • Application.CommandBars(): VBA では、すべての CommandBar オブジェクトのリストを返します。
  • CommandBars.item(): VBA では、特定の CommandBar オブジェクトを返します。
このオブジェクト型は Apps Script ではサポートされていないため、変換されたコードでは、定義が必要な「unimplemented_constructs.gs」ファイルに次の関数が作成されます。
  • _api_application_commandbars()
  • _api_commandbars_item()
変換されたコードでは、関数は次のように呼び出されます。
PrintName(_api_commandbars_item(_api_application_commandbars(), "Standard")))

Heres how the new functions are added to the unimplemented_construct.gs file:

function _api_application_commandbars(CallingObject) {
  ThrowException('API application.commandbars not supported yet.');
}
function _api_commandbars_item(CallingObject, index) {
  ThrowException('API commandbars.item not supported yet.');
}

新しい関数を機能させるには、次の手順を行います。

3.1 CommandBars の機能を作成する新しいオブジェクト型と、VBA に存在するものと同様の CommandBars の新しいコレクションを定義します。

3.2 新しいオブジェクト タイプに getName() メソッドを追加します。

手順 3.1 と 3.2 は次のコードに示されています。メニュー オブジェクトは、CommandBars の動作を模倣した新しいオブジェクト タイプとして作成されます。

// Our Implementation of CommandBar using Menu objects.

function CommandBar(name) {
  this.name = name;
  // Create a menu object to represent the commandbar.
  this.menu = SpreadsheetApp.getUi().createMenu(name);
  // Create methods for retrieving or updating the name of the object
  this.getName = function() {
    return this.name;
  };
  this.updateName = function(name) {
    this.name = name;
  };
  // ========================================================================
  // Implement other methods of CommandBar objects that are used in the script.
  // =====================================================================
  return this;
}
// Our implementation of the collection of CommandBars that exists in VBA
function CommandBars() {
  this.commandBars = [];
  this.getCommandBar = function(name) {
    for (var i = 0; i < this.commandBars.length; i++) {
      if (!this.commandBars[i].getName() == name) {
        return this.commandBars[i];
      }
    }
    // No commandBar with the name exists, create a new one and return.
    var commandBar = new CommandBar(name);
    this.commandBars.push(commandBar);
    return commandBar;
  };
  return this;
}
// Create a global object that represents CommandBars collection.
var GlobalCommandBars = new CommandBars();

3.3 新しいオブジェクト タイプを処理するように、variant_resolution.gs ファイルの __handle_resolve_name 関数を変更します。次のように、関数にセクションを追加します。

function __handle_resolve_name(ExecutionContext, CallingObject, params_map) {
 var found_api_variant = false;
 var return_value;
 if (String(CallingObject) == "Sheet") {
   if (!ExecutionContext.isLhs) {
     return_value = CallingObject.getName();
     found_api_variant = true;
   }
 }
 if (CallingObject instanceof ChartInSheet) {
   if (!ExecutionContext.isLhs) {
     return_value = CallingObject.getName();
     found_api_variant = true;
   }
 }
 // New section added below
 // ========================================================================
 if (CallingObject instanceof CommandBar) {
   objectExtend(params_map, {VALUETOSET: params_map.param0});
   if (ExecutionContext.isLhs) {
     // Call the setter method.
     CallingObject.updateName(params_map.VALUETOSET);
     found_api_variant = true;
   } else {
     // Getter is called, return the commandbar name,
     return_value = CallingObject.getName();
     found_api_variant = true;
   }
 }
 // ========================================================================
 // New section added above
 if (!found_api_variant) {
   ThrowException('API .name not supported yet.');
 }
 return return_value;
}

3.4 unimplemented_constructs.gs ファイルで作成した 2 つの関数(_api_application_commandbars()_api_commandbars_item())を定義します。このステップにより、関数の元の呼び出しが機能するようになります。

//This is straightforward based on the implementation of a CommandBar and the
// CommandBars collection above:
function _api_application_commandbars(CallingObject) {
 return GlobalCommandBars;
}
function _api_commandbars_item(CallingObject, index) {
 return CallingObject.getCommandBar(index);
}

実装されていない言語構文

コンストラクトは、実行フローやデータの表示を制御するコード言語の要素です。たとえば、ループ、ラベル、イベント、goto などです。すべての VBA 構文のリストをご覧ください。

マクロ変換ツールで変換できないコンストラクトは、実装されていない言語コンストラクトと見なされます。

実装されていない言語構文が存在するとマクロ変換ツールが判断した場合は、TODO コメントが挿入されます。

次の VBA 構文はサポートされていません。

実装されていない言語構文のエラーを修正

  1. サポートされていない言語構文にロジックが依存しないようにコードを更新します。
  2. エラーのある場所で、変換された Apps Script コードを開きます。エラーの検索をご覧ください。
  3. コードのロジックに基づいて、サポートされていない言語構文を必要としない方法でコードを更新します。
  4. サポートされていない言語構文を使用せずにコードを書き換える方法が見つからない場合は、このマクロを変換できません。

実装されていない言語構文エラーの例

実装されていない最も一般的な言語構文の 1 つは GoTo ステートメントです。一部の VBA GoTo ステートメントはループに置き換えることができます。以下に、GoTo ステートメントの代わりにループを使用する 2 つの例を示します。

例 1: GoToWhile Loop に置き換える

元の VBA コード
Sub Test()
 a = 0
 start: Debug.Print a
 While a < 100
   a = a + 1
   If a Mod 3 == 0
     Goto start
   End If
 Wend
End Sub
同等の Apps Script コード
function test() {
 var a = 0;
 start: do {
   console.log(a);
   while (a < 100) {
     a = a + 1;
     if (a % 3 == 0) {
       continue start;
     }
   }
   break start;
 } while (true);
}

例 2: GoTo を For ループに置き換える

元の VBA コード
Sub Test()
 a = 0
 For i = 1 to 100
   For j = 1 to 10
     a =a a + 1
     If i + j > 50
       GoTo endLoop
     End If
   Next j
 Next i
 endLoop: MsgBox a
End Sub
同等の Apps Script コード
function test() {
 var a = 0;
 endLoop: for (var i = 1; i <= 100; i++) {
    for  (var j = 0; j <=10; j++) {
      If (i + j > 50) {
        break endLoop;
      }
    }
 }
 Browser.msgBox(a);
}

   break start;
 } while (true);
}

一部サポート対象の API

一部サポート対象の API では、一部の入力パラメータは Apps Script でサポートされていますが、一部はサポートされていません。

たとえば、VBA API legend_position は、Excel グラフの凡例を定義するために使用されます。次のような複数のタイプの入力値をサポートしています。

  • xlLegendPositionBottom: 凡例をグラフの下部に配置します。
  • xlLegendPositionCorner: 凡例をグラフの隅に配置します。
  • xlLegendPositionCustom: 凡例をグラフ上のカスタム位置に配置します。

Apps Script には、これらの値の一部のみをサポートする同等のコードがあります。次の値はサポートされていません。

  • xlLegendPositionCorner
  • xlLegendPositionCustom

変換されたコードで部分的にサポートされている API のサポートされていない値にフラグを立てるには、それらの値を確認する検証条件が library.gs ファイルに追加されます。次に例を示します。

if (position == xlLegendPositionCorner ||
     position == xlLegendPositionCustom) {
   position = _handle_legend_position_error(position);
}

検証条件でサポートされていない値が検出されると、unimplemented_constructs.gs ファイルにエラーハンドラ関数 _handle_<API_name>_error が作成されます。

この関数はユーザー エラーをスローし、値をサポートされている値に置き換えません。次に例を示します。

/**
* Throw error message for unsupported legend position.
* The VBA API Legend.Position which can take values xlLegendPositionTop,
* xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight,
* xlLegendPositionCorner, xlLegendPositionCustom. It is partially supported in
* Apps Scripts that supports only a subset of the values (does not support
* xlLegendPositionCorner and xlLegendPositionCustom).
* @param {string} position
*/
function _handle_legend_position_error(position) {
// Please comment the throw statement and return a supported position value
// instead.
// Values that are supported here are xlLegendPositionTop,
// xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight.
throw new Error(
   'Google Sheets does not support legend position: ' + position);
}

一部のみサポートされている API エラーを修正する

_handle_<API_name>_error 関数を定義して、サポートされていない値をニーズに合った許容可能な回避策に置き換えます。

  1. エラーのある場所で、変換された Apps Script コードを開きます。エラーを探すをご覧ください。
  2. 関数の上にあるコメントを読んで、サポートされている値とサポートされていない値を確認します。
  3. サポートされていない値については、適切な置換として機能するサポートされている値を特定します。
  4. 関数 _handle_<API_name>_error を更新して、代わりにサポートされている値を返します。
  5. サポートされていない値を置き換える方法が見つからない場合は、このマクロを変換できません。

一部のみサポートされている API エラーの例

次の例では、前述の VBA API legend_position を拡張しています。一部サポート対象の API をご覧ください。

以下は、サポートされていない値 xlLegendPositionCustom を使用する元の VBA コードの例です。

Charts(1).Legend.Position = xlLegendPositionCustom

Macro Converter は、unimplemented_constructs.gs ファイルに次の関数を追加します。

/**
* Throw error message for unsupported legend position.
* The VBA API Legend.Position which can take values xlLegendPositionTop,
* xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight,
* xlLegendPositionCorner, xlLegendPositionCustom. It is partially supported in
* Apps Scripts that supports only a subset of the values (does not support
* xlLegendPositionCorner and xlLegendPositionCustom).
* @param {string} position
*/
function _handle_legend_position_error(position) {
// Please comment the throw statement and return a supported position value
// instead.
// Values that are supported here are xlLegendPositionTop,
// xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight.
throw new Error(
   'Google Sheets does not support legend position: ' + position);
}

手動作業が必要

手動作業が必要とは、VBA API を Apps Script に変換することはできるが、回避策が必要であることを意味します。

変換前に生成した互換性レポートでは、このタイプの API は「回避策ありでサポートされている」とラベル付けされています。

ファイルを変換する前に VBA コードでこのタイプの API を修正しなかった場合、Apps Script プロジェクトには次のように表示されます。

/**
* Could not convert  API. Please add relevant code in the following
* function to implement it.
* This API has been used at the following locations in the VBA script.
*      : 
*
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : 
* Apps Script documentation links : 
*
* @param param1 {}
* @param param2 {}
* ...
* @return {}
*/
function _api_<API_name>(param1, param2, ....) {
 ThrowException("API  not supported yet.");
}

手動作業が必要なエラーを修正する

API を意図したとおりに動作させるために、API の回避策を実装します。1. エラーのある場所で、変換された Apps Script コードを開きます。エラーを探すをご覧ください。1. 関数の上にあるコメントを読んで、回避策に使用できる API を確認します。1. 適切な回避策が見つからない場合は、コードから API を削除することを検討してください。1. 回避策が見つからない、またはこの API をコードから削除してもマクロでエラーが発生する場合、このマクロは変換できません。

手動作業が必要なエラーの例

手動作業が必要エラーをスローする API の例とその修正方法を次に示します。

例 1: Autocorrect.Addreplacement

次の例では、VBA API Autocorrect.Addreplacement は変換できますが、回避策が必要です。マクロ変換ツールは、コードコメントに関数の実装方法を提案します。

/**
* Could not convert autocorrect.addreplacement API. Please add relevant code in
* the following function to implement it.
* This API has been used at the following locations in the VBA script.
*     sheet1 : line 3
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : FindReplaceRequest , onEdit
* Apps Script documentation links :
* https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* https://developers.google.com/sheets/api/eap/reference/rest/v4/spreadsheets/request?hl=en#findreplacerequest

* Comments : AutoCorrect.AddReplacement was not converted, but there is an
* equivalent option you can implement manually. Use onEdit and FindReplaceRequest
* APIs instead, see https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* and https://developers.google.com/sheets/api/eap/reference/rest/v4/spreadsheets/request?hl=en#findreplacerequest.
* For more information on API manual implementation, see
* https://developers.google.com/apps-script/guides/macro-converter/fix-conversion-errors.

* @param {Object} CallingObject represents the parent object using which the API
* has been called.
* @param {string} What
* @param {string} Replacement
* @return {string}
*/

function _api_autocorrect_addreplacement(CallingObject, What, Replacement) {
  ThrowException('API autocorrect.addreplacement not supported yet.');

}

Autocorrect.Addreplacement API の実装は次のとおりです。

var AUTO_CORRECTIONS = "AUTO_CORRECTIONS";
// Need to get the autocorrections set in previous sessions and use them.
var savedAutoCorrections = PropertiesService.getDocumentProperties().getProperty(AUTO_CORRECTIONS);
var autoCorrections = savedAutoCorrections ? JSON.parse(savedAutoCorrections) : {};
function onEdit(e) {
autoCorrect(e.range);
}
function autoCorrect(range) {
for (key in autoCorrections) {
// Replace each word that needs to be auto-corrected with their replacements.
range.createTextFinder(key)
.matchCase(true)
.matchEntireCell(false)
.matchFormulaText(false)
.useRegularExpression(false)
.replaceAllWith(autoCorrections[key]);
}
}
/**
* Could not convert autocorrect.addreplacement API. Please add relevant code in
* the following function to implement it.
* This API has been used at the following locations in the VBA script.
* sheet1 : line 3
*
* You can use the following Apps Script APIs to convert it.
* Apps Script APIs : createTextFinder , onEdit
* Apps Script documentation links : https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit ,
createTextFinder
* Comments : AutoCorrect.AddReplacement was not converted, but there is an
* equivalent option you can implement manually. Use onEdit and FindReplaceRequest
* APIs instead, see https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit
* and createTextFinder. For more information on API manual implementation, see
* https://developers.google.com/apps-script/guides/macro-converter/fix-conversion-errors.
*
* @param {Object} CallingObject represents the parent object using which the API has been called.
* @param {string} What
* @param {string} Replacement
*
* @return {string}
*/

function _api_autocorrect_addreplacement(CallingObject, What, Replacement) {
autoCorrections[What] = Replacement;
// Store the updated autoCorrections in the properties so that future executions use the correction.
PropertiesService.getDocumentProperties().setProperty(AUTO_CORRECTIONS, JSON.stringify(autoCorrections));
}

例 2: Workbook.open()

VBA API workbook.open() は、ファイルパスに基づいてローカル ファイルを開きます。

VBA コードで workbook.open() によって開かれているファイルが 2 つあるとします。

  • ファイル 1: C:\Data\abc.xlsx
  • ファイル 2: C:\Data\xyz.xlsx

以下は、Workbook.open() を使用して File 1 を開くすべての場所で、Macro Converter が Workbook.open() を Apps Script に置き換える方法を示しています。

var spreadSheetId =
   _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx");
var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
Apps Script プロジェクトの unimplemented_constructs.gs ファイルに、次のエラーが追加されます。
/**
* Method to return the spreadsheet id manually.
*
* @param {string} FileName ID of the spreadsheet to be opened.
* @return {string} return the spreadsheet id.
*/
function _handle_mso_excel_get_google_spreadsheet_id(FileName) {
 // Upload the Excel files being opened by the API to Google Drive and convert
 // them to Google Sheets.
 // Determine the spreadsheet ID of the Google Sheets file created.
 // Implement this method to return the corresponding spreadsheet ID when given
 //the original file path as parameter.
 throw new Error('Please return the spreadsheet ID corresponding to filename: ' + FileName);
 return '';
}

上のサンプルのコメントに記載されているように、対象ファイルを Google ドライブの Google スプレッドシート ファイルに変換する必要があります。

対応する Google スプレッドシート ID は太字で示されています。

  • ファイル 1: C:\Data\abc.xlsxhttps://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc に変更されます
  • ファイル 2: C:\Data\abc.xlsxhttps://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ に変更されます

次に、Apps Script 関数のコードを変更して、ID でファイルを開くようにします。

/**
* Method to return the spreadsheet id manually.
*
* @param {string} FileName ID of the spreadsheet to be opened.
* @return {string} return the spreadsheet id.
*/
function _handle_mso_excel_get_google_spreadsheet_id(FileName) {
 // Upload the Excel files being opened by the API to Google Drive and convert
 //them to Google Sheets.
 // Determine the spreadsheet ID of the Google Sheets file created.
 // Implement this method to return the corresponding spreadsheet ID when given
 //the original file path as parameter
 if (Filename.indexOf("abc.xlsx") >= 0) {
   return "abc123Abc123Abc123abc";
 } else if (Filename.indexOf("xyz.xlsx") >= 0) {
   return "xyz456Xyz456xYz456xyZ";
 }

意図的な誤り

変換されたコードには、元の VBA コードのエラー動作を模倣するために意図的なエラーが追加されます。これらのエラーは変更する必要はありません。

意図的なエラーの例

VBA で配列の範囲外の要素にアクセスしようとすると、コードが例外をスローします。Apps Script では、コードは未定義を返します。

予期しない結果を回避するため、マクロ変換ツールは、配列の範囲外の要素にアクセスしようとすると例外をスローする Apps Script コードを追加します。

次のコードに、この例を示します。

元の VBA コード
Dim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of range
変換された Apps Script コード(例外エラーが追加される前)
var arr;
arr = ["apple", "orange"];
Browser.msgBox(arr[5]);
Will return this value and not throw an error:
undefined
例外エラーをスローする Apps Script コードを追加
/**
* Extend the regular JS array to support VB style indexing with a get method.
* @returns{*} value at the index
*/
Array.prototype.get = function() {
 var curr_res = this;
 for (var i = 0; i < arguments.length; i++) {
   if (!Array.isArray(curr_res) || curr_res.length < arguments[i]) {
     throw new Error(Converted VBA Error (Intentional Error): Subscript out of range);
   }
   curr_res = curr_res[arguments[i]];
 }
 return curr_res;
};
var arr;
arr  = ["apple", "orange"];
Browser.msgBox(arr.get(5));