マクロ コンバータ アドオンを使用すると、ほとんどの変換プロセスを自動化できますが、コードを確定するために、一部の API やその他の項目の調整が必要になる場合があります。
このガイドでは、プロジェクトに追加される Apps Script ファイル(GS ファイル)や、さまざまなエラーの種類の解釈、エラーの修正方法について説明します。
プロジェクトに追加された Apps Script ファイルについて
Apps Script プロジェクトには、次の GS ファイルが追加されます。
- 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
ファイルは、マクロ コンバータで変換できなかったコンストラクトまたは 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 に複数の戻り値の型がある、オブジェクトがバリアントとして宣言されているなど、複数の理由で発生します。
マクロコンバータにより、このファイルに __handle_resolve_<api>()
という新しい関数が追加されます。この関数は、問題の API を置き換え、オブジェクト タイプの判別に役立ちます。
場合によっては、__handle_resolve_<api>()
関数を更新して、オブジェクト タイプを手動で宣言する必要があります。サポートされていないオブジェクト タイプをご覧ください。
例: name()
VBA の多くのオブジェクト タイプは name()
API を定義します。通常、Apps Script で同等の機能は getName()
ですが、すべてのオブジェクト タイプに対応するわけではありません。代替となるケースは複数存在する可能性があります。
- オブジェクトと同等の API は、
getName()
とは別のものです。 - このオブジェクトには、名前を取得するための Apps Script API がありません。
- これに相当する Apps Script オブジェクトはありません。
オブジェクト タイプが確定していない場合、マクロコンバータは __handle_resolve_name
という新しい関数を variant_resolutions.gs
ファイルに作成します。
コードの例を次に示します。
元の VBA コード
a = Selection.name
この場合、現在の選択に対して API name()
が呼び出されます。選択できるのは、Sheet オブジェクトまたは Shape オブジェクトです。Sheet オブジェクトの場合、変換は getName()
になりますが、Shape オブジェクトの場合、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_ (param1, param2, ....) { ThrowException("API not supported yet."); }
未実装の API エラーを修正する
既存の Apps Script API または JS ライブラリを使用して、未実装の API を定義します。そのための手順は以下のとおりです。
- エラーのある場所にある変換済みの Apps Script コードを開きます。エラーを見つけるをご覧ください。
- 関数の上部で、追加されたコメントを確認します。コメントに Apps Script で API を実装する方法が提案されている場合もあります。
- Apps Script で API を実装する方法が見つからない場合は、コードから削除することを検討してください。
- 回避策が見つからない場合や、コードからこの 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
をご覧ください。
この例では、次のことを学びます。
variant_resolution.gs
ファイルでname()
API を新しい関数に変換する方法。- 変換後のコードで新しい関数を呼び出す方法。
- 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 コードが、オブジェクト タイプ CommandBar
に対して PrintName()
関数を呼び出しているとします。VBA コードは次のとおりです。
PrintName Application.CommandBars.item("Standard")
CommandBar
は Apps Script ではサポートされていないため、上記の VBA コードで使用されている 2 つのメソッドもサポートされていません。Application.CommandBars()
: VBA で、すべてのCommandBar
オブジェクトのリストを返します。CommandBars.item()
: VBA では、特定のCommandBar
オブジェクトを返します。
_api_application_commandbars()
_api_commandbars_item()
PrintName(_api_commandbars_item(_api_application_commandbars(), "Standard"))) Here’s 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); }
未実装の言語構造
constructは、実行フローやデータ表示を制御するコード言語の要素です。たとえば、ループ、ラベル、イベント、goto などです。詳しくは、すべての VBA 構成のリストをご覧ください。
マクロ コンバータが変換できない構文は、未実装の言語構造とみなされます。
マクロコンバータは、未実装の言語構造が存在すると判断すると、TODO
コメントを挿入します。
次の VBA 構造はサポートされていません。
未実装の言語構造エラーを修正
- サポートされていない言語構造にロジックが依存しないようにコードを更新します。
- エラーのある場所にある変換済みの Apps Script コードを開きます。エラーを見つけるをご覧ください。
- コードのロジックに基づいて、サポートされていない言語構造を必要としないようにコードを更新します。
- サポートされていない言語構造なしでコードを書き換える方法が見つからない場合は、このマクロを変換できません。
未実装の言語構成エラーの例
最も一般的な未実装言語構造の 1 つは、GoTo
ステートメントです。一部の VBA GoTo
ステートメントはループに置き換えることができます。以下に、GoTo
ステートメントの代わりにループを使用する 2 つの例を示します。
例 1: GoTo
を While 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
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
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); }
検証条件でサポートされていない値のいずれかが検出されると、エラーハンドラ関数 _handle_<API_name>_error
が 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); }
部分的にサポートされている API エラーを修正する
_handle_<API_name>_error
関数を定義して、サポートされていない値を、必要に応じて許容される回避策に置き換えます。
- エラーのある場所にある変換済みの Apps Script コードを開きます。エラーを見つけるをご覧ください。
- 関数の上にあるコメントを読み、サポートされている値とサポートされていない値を確認してください。
- サポートされていない値について、適切な置換として機能できるサポートされている値を決定します。
- サポートされている値を返すように関数
_handle_<API_name>_error
を更新してください。 - サポートされていない値を置き換える方法が見つからない場合、このマクロは変換できません。
部分的にサポートされる API エラーの例
次の例は、上記の VBA API legend_position
を拡張したものです。部分的にサポートされている API をご覧ください。
以下は、サポートされていない値 xlLegendPositionCustom
を使用している元の VBA コードの例です。
Charts(1).Legend.Position = xlLegendPositionCustom
マクロコンバータは、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 convertAPI. 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_ (param1, param2, ....) { ThrowException("API not supported yet."); }
手作業が必要なエラーを修正する
API が意図したとおりに動作するように、API の回避策を実装します。1. エラーのある場所にある変換済みの Apps Script コードを開きます。エラーを見つけるをご覧ください。1. 回避策に使用できる API を把握するには、関数の上にあるコメントをご覧ください。1. 適切な回避策が見つからない場合は、コードから API を削除することを検討してください。 1. 回避策が見つからない場合や、コードからこの API が削除され、マクロがエラーをスローする場合は、このマクロを変換できません。
「手作業が必要」エラーの例
手作業が必要エラーをスローする API の例と、その修正方法は次のとおりです。
Implement a workaround for Autocorrect.Addreplacement
.Implement a workaround for workbook.open()
。この例では、Apps Script を使用して Google ドライブでファイルを開く方法を示しています。
例 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
以下は、ファイル 1 を開くために Workbook.open()
が使用されているすべての場所で、マクロコンバータが Workbook.open()
を Apps Script に置き換える方法を示しています。
var spreadSheetId = _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx"); var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
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.xlsx
はhttps://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc
になります - ファイル 2:
C:\Data\abc.xlsx
はhttps://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ
になります
次に、次のように、ID でファイルを開くように Apps Script 関数のコードを変更します。
/** * 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
var arr; arr = ["apple", "orange"]; Browser.msgBox(arr[5]); Will return this value and not throw an error: undefined
/** * 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));
関連記事
- Macro Converter アドオンの概要
- VBA マクロに互換性があるかどうかを判断する
- VBA マクロを Apps Script に変換する
- 一般的な問題への対処
- Macro Converter のチュートリアルを見る
- 互換性のある VBA API のリスト