Tiện ích bổ sung Macro Converter của Google Workspace tự động hoá hầu hết quy trình chuyển đổi, nhưng bạn có thể cần điều chỉnh một số API và các mục khác để hoàn tất mã.
Hãy sử dụng hướng dẫn này để tìm hiểu về các tệp Apps Script (tệp GS) được thêm vào dự án của bạn, diễn giải các loại lỗi khác nhau và tìm hiểu cách khắc phục lỗi.
Tìm hiểu về các tệp Apps Script được thêm vào dự án của bạn
Các tệp GS bổ sung sẽ được thêm vào dự án Apps Script của bạn để hỗ trợ:
- Xác định các hằng số và giá trị VBA không có trong Apps Script.
- Triển khai các API chưa được chuyển đổi.
- Giải quyết các biến thể.
Các tệp GS sau đây sẽ được thêm vào dự án Apps Script của bạn:
Library.gsUnimplemented_constructs.gsVariant_resolutions.gs
Library.gs
Nhìn chung, bạn không cần sửa đổi bất cứ nội dung nào trong tệp library.gs.
Tệp library.gs xác định các hàm và hằng số đã được dùng trong mã VBA của bạn nhưng không có trong Apps Script. Điều này giúp mã Apps Script mới giống với mã VBA của bạn hơn. Ngoài ra, bạn không cần lặp lại các định nghĩa mỗi khi sử dụng các hàm hoặc hằng số từ tệp library.gs.
Unimplemented_constructs.gs
Tệp unimplemented_constructs.gs đề cập đến các cấu trúc hoặc API mà Trình chuyển đổi macro không thể chuyển đổi. Bạn có thể cần sửa đổi tệp này để mã của bạn hoạt động như dự kiến.
Ví dụ: Window.Activate
Sau đây là ví dụ về một API không được hỗ trợ có tên là Window.Activate. Macro Converter sẽ tạo một hàm Apps Script mới có tên tương tự và xác định hàm đó trong tệp unimplemented_constructs.gs. Vì hàm VBA không được hỗ trợ, nên hàm Apps Script mới sẽ tạo ra một ngoại lệ.
Hàm mới sẽ được thêm vào mã Apps Script đã chuyển đổi ở mọi nơi mà API ban đầu được dùng trong mã VBA.
Nếu tìm được giải pháp thay thế để tạo lại hành vi của API ban đầu, bạn chỉ cần cập nhật định nghĩa của hàm trong tệp unimplemented_constructs.gs. Sau khi được xác định ở đó, hàm sẽ áp dụng ở mọi nơi hàm xuất hiện trong dự án Apps Script của bạn.
Sau đây là ví dụ về mã:
Mã VBA ban đầu
Window.activate()
Mã Apps Script đã chuyển đổi, được thêm vào cùng dòng
_api_window_activate();
Đã thêm định nghĩa hàm vào tệp 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
Tệp variant_resolutions.gs sẽ được thêm vào dự án Apps Script nếu không xác định được loại đối tượng. Điều này có thể xảy ra vì nhiều lý do, chẳng hạn như API có nhiều kiểu trả về hoặc đối tượng được khai báo là chính biến thể.
Macro Converter thêm một hàm mới vào tệp này có tên là __handle_resolve_<api>, thay thế API được đề cập và giúp xác định kiểu đối tượng.
Trong một số trường hợp, bạn có thể cần cập nhật hàm __handle_resolve_<api> để khai báo loại đối tượng theo cách thủ công. Xem phần Loại đối tượng không được hỗ trợ.
Ví dụ: Phương thức name
Nhiều loại đối tượng trong VBA xác định một phương thức name. Thông thường, đối tượng tương đương của Apps Script là getName, nhưng không phải cho mọi loại đối tượng. Có thể xảy ra nhiều trường hợp thay thế:
- Phương thức tương đương của đối tượng được gọi bằng một tên khác với
getName. - Đối tượng không có API Apps Script để lấy tên của đối tượng.
- Không có đối tượng Apps Script tương đương.
Khi không xác định được loại đối tượng, Macro Converter sẽ tạo một hàm mới có tên là __handle_resolve_name trong tệp variant_resolutions.gs.
Sau đây là ví dụ về mã:
Mã VBA ban đầu
a = Selection.name
Trong trường hợp này, phương thức name được gọi trên lựa chọn hiện tại. Lựa chọn có thể là đối tượng Trang tính hoặc đối tượng Hình dạng. Nếu đó là đối tượng Trang tính, thì bản dịch là getName, nhưng nếu đó là đối tượng Hình dạng, thì không có đối tượng tương đương trong Apps Script.
Mã Apps Script đã chuyển đổi, được thêm vào cùng dòng
a = __handle_resolve_name({}, getActiveSelection(), {});
Hàm __handle_resolve_name sau đây được thêm vào tệp variant_resolution.gs để giải quyết các loại đối tượng khác nhau. Hàm này kiểm tra loại đối tượng, sau đó sử dụng getName nếu được hỗ trợ hoặc gửi ra lỗi nếu getName không được hỗ trợ.
Đã thêm định nghĩa hàm vào tệp 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; }
Tìm lỗi
Khi bạn gặp lỗi trong mã Apps Script đã chuyển đổi, thông báo sẽ chỉ định loại lỗi và vị trí của lỗi. Định dạng của thông báo lỗi phụ thuộc vào thời gian chạy Apps Script mà bạn đang sử dụng.
Nếu đang ở trong thời gian chạy V8 mặc định, bạn sẽ thấy một lỗi có dạng như sau:
_api_windows_active (unimplemented_constructs:2:3)
Điều này có nghĩa là lỗi nằm trong tệp unimplemented_constructs.gs tại dòng 2, ký tự 3.
Nếu đang dùng thời gian chạy Rhino ngừng hoạt động, bạn sẽ thấy một lỗi như sau:
unimplemented_constructs:2 (_api_windows_active)
Điều này có nghĩa là lỗi nằm trong tệp unimplemented_constructs.gs ở dòng 2.
Các loại lỗi
Khắc phục hầu hết các lỗi mà bạn gặp phải trong các tệp unimplemented_constructs.gs và variant_resolution.gs được mô tả trước đó.
Các loại lỗi bạn có thể gặp phải bao gồm:
- API chưa triển khai
- Cấu trúc ngôn ngữ chưa được triển khai
- API được hỗ trợ một phần
- Cần thực hiện thao tác thủ công
- Lỗi có chủ ý
API chưa triển khai
API chưa triển khai là API mà Trình chuyển đổi macro không thể chuyển đổi từ VBA sang Apps Script và không có giải pháp thay thế nào đã biết cho API này.
Các API chưa triển khai thường được thêm dưới dạng các hàm trống (đôi khi có chữ ký trống) vào tệp unimplemented_constructs.gs. Nếu không xác định được loại đối tượng, thì API chưa triển khai có thể được thêm vào tệp variant_resolution.gs.
Trong báo cáo tương thích mà bạn đã tạo trước khi chuyển đổi, API này được gắn nhãn là Cần điều tra thêm.
Nếu bạn không sửa loại API này trong mã VBA trước khi chuyển đổi tệp, thì đây là cách loại API này xuất hiện trong dự án 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("APInot supported yet." ); }
Khắc phục lỗi API chưa triển khai
Xác định API chưa triển khai bằng các API Apps Script hiện có hoặc thư viện JS. Để thực hiện việc này, hãy làm theo các bước sau:
- Mở mã Apps Script đã chuyển đổi tại vị trí xảy ra lỗi. Xem phần Tìm lỗi.
- Ở phía trên hàm, hãy đọc nhận xét đã được thêm. Trong một số trường hợp, chú thích sẽ đề xuất cách triển khai API trong Apps Script.
- Nếu bạn không tìm được cách triển khai API trong Apps Script, hãy cân nhắc việc xoá API đó khỏi mã của bạn.
- Nếu không tìm được giải pháp hoặc xoá API này khỏi mã và macro của bạn gặp lỗi này, thì bạn không thể chuyển đổi macro này.
Ví dụ về các lỗi API chưa triển khai
Sau đây là ví dụ về các trường hợp API chưa được triển khai và cách khắc phục:
- Không có Apps Script tương đương: Cho thấy một giải pháp gián tiếp cho
Chart.Protect, một API không tồn tại trong Apps Script. - Một loại đối tượng không xác định: Cho biết cách xử lý một loại đối tượng là một biến và cách triển khai một loại đối tượng không được hỗ trợ có thể được tạo lại trong Apps Script.
Ví dụ 1: Không có Apps Script tương đương hoặc API không xác định
Trong ví dụ này, Chart.Protect không được tự động chuyển đổi vì không có cách nào để bảo vệ biểu đồ trong Google Trang tính.
/** * 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.'); }
Dưới đây là một ví dụ về cách triển khai việc bảo vệ dải ô:
/** * 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(); } }
Ví dụ 2: Loại đối tượng không được hỗ trợ
Khi loại đối tượng không xác định, lỗi API chưa triển khai sẽ được thêm vào tệp variant_resolution.gs. Ví dụ sau đây mở rộng ví dụ về phương thức name VBA. Hãy xem variant_resolution.gs.
Trong ví dụ này, bạn sẽ tìm hiểu:
- Cách phương thức
nameđược chuyển đổi thành một hàm mới trong tệpvariant_resolution.gs. - Cách gọi hàm mới trong mã đã chuyển đổi.
- Cách tạo giải pháp thay thế cho
CommandBar, một loại đối tượng không được hỗ trợ, trong Apps Script.
1. Vì mã đã chuyển đổi không thể xác định chính xác loại đối tượng mà name được gọi, nên Trình chuyển đổi macro sẽ tạo một hàm mới có tên là __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. Giả sử mã VBA xác định một hàm PrintName() gọi API name:
‘Defining a function that prints the name of the object in parameter Sub PrintName(obj as Variant) Debug.Print obj.Name End Sub
function PrintName(obj) {
Logger.log(_handle_resolve_name(obj));
}
3. Giả sử mã VBA của bạn gọi hàm PrintName() trên loại đối tượng CommandBar:
PrintName Application.CommandBars.item("Standard")CommandBar không được hỗ trợ trong Apps Script. Do đó, 2 phương thức được dùng trong mã VBA ở trên cũng không được hỗ trợ.
Application.CommandBars(): Trong VBA, phương thức này trả về danh sách tất cả các đối tượngCommandBar.CommandBars.item(): Trong VBA, phương thức này trả về một đối tượngCommandBarcụ thể.
_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.'); }
Để các chức năng mới hoạt động, hãy làm theo các bước sau:
3.1 Xác định một kiểu đối tượng mới tạo ra các chức năng của CommandBars và một tập hợp CommandBars mới tương tự như những gì có trong VBA.
3.2 Thêm phương thức getName cho loại đối tượng mới.
Các bước 3.1 và 3.2 được thể hiện trong mã sau. Các đối tượng trình đơn được tạo dưới dạng một loại đối tượng mới bắt chước hành vi của 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 Sửa đổi hàm __handle_resolve_name trong tệp variant_resolution.gs để xử lý kiểu đối tượng mới. Thêm một phần vào hàm:
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 Xác định 2 hàm được tạo trong tệp unimplemented_constructs.gs (_api_application_commandbars, _api_commandbars_item). Bước này đảm bảo các lệnh gọi ban đầu của hàm hoạt động.
//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); }
Cấu trúc ngôn ngữ chưa được triển khai
Cấu trúc là một phần tử của ngôn ngữ mã, giúp kiểm soát luồng thực thi hoặc hiển thị dữ liệu. Ví dụ: vòng lặp, nhãn, sự kiện và lệnh goto. Để biết danh sách tất cả các cấu trúc VBA, hãy xem Câu lệnh (VBA).
Các cấu trúc mà Trình chuyển đổi macro không thể chuyển đổi được coi là cấu trúc ngôn ngữ chưa triển khai.
Khi Macro Converter xác định rằng có một cấu trúc ngôn ngữ chưa được triển khai, công cụ này sẽ chèn một nhận xét TODO.
Các cấu trúc VBA sau đây không được hỗ trợ:
- AddressOf
- Khai báo
- DefType
- GoSub
- GoTo
- Triển khai
- Lset
- Mở
- RaiseEvent
- Tên
- Kích hoạt lại
- Rset
- TypeOf
- Lớp học
- Mô-đun lớp
Khắc phục lỗi cấu trúc ngôn ngữ chưa triển khai
- Cập nhật mã để logic của bạn không dựa vào cấu trúc ngôn ngữ không được hỗ trợ.
- Mở mã Apps Script đã chuyển đổi tại vị trí xảy ra lỗi. Xem phần Tìm lỗi.
- Dựa trên logic của mã, hãy cập nhật mã theo cách không yêu cầu cấu trúc ngôn ngữ không được hỗ trợ.
- Nếu không tìm được cách viết lại mã mà không có cấu trúc ngôn ngữ không được hỗ trợ, bạn sẽ không thể chuyển đổi macro này.
Ví dụ về lỗi cấu trúc ngôn ngữ chưa được triển khai
Một trong những cấu trúc ngôn ngữ chưa được triển khai phổ biến nhất là câu lệnh GoTo.
Thay thế một số câu lệnh GoTo VBA bằng các vòng lặp. Các ví dụ sau đây sử dụng vòng lặp thay vì câu lệnh GoTo.
Ví dụ 1: Thay thế GoTo bằng While Loop
Mã VBA ban đầu
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 Subfunction 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); }
Ví dụ 2: Thay thế GoTo bằng For Loop
Mã VBA ban đầuSub 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 Subfunction 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 được hỗ trợ một phần
Đối với Các API được hỗ trợ một phần, một số tham số đầu vào được hỗ trợ trong Apps Script và một số thì không.
Ví dụ: VBA API legend_position được dùng để xác định chú thích trong biểu đồ Excel. Thư viện này hỗ trợ nhiều loại giá trị đầu vào, bao gồm:
xlLegendPositionBottom: Đặt chú thích ở cuối biểu đồ.xlLegendPositionCorner: Đặt chú thích ở góc của biểu đồ.xlLegendPositionCustom: Đặt chú thích ở vị trí tuỳ chỉnh trên biểu đồ.
Apps Script có một đoạn mã tương đương chỉ hỗ trợ một số giá trị trong số đó. Các giá trị sau không được hỗ trợ:
xlLegendPositionCornerxlLegendPositionCustom
Để gắn cờ các giá trị không được hỗ trợ của API được hỗ trợ một phần trong mã đã chuyển đổi, một điều kiện xác thực sẽ được thêm vào tệp library.gs để kiểm tra các giá trị đó. Ví dụ:
if (position == xlLegendPositionCorner ||
position == xlLegendPositionCustom) {
position = _handle_legend_position_error(position);
}
Nếu điều kiện xác thực tìm thấy một trong các giá trị không được hỗ trợ, thì hàm xử lý lỗi _handle_<API_name>_error sẽ được tạo trong tệp unimplemented_constructs.gs.
Hàm này sẽ đưa ra lỗi cho người dùng và không thay thế giá trị bằng một giá trị được hỗ trợ. Ví dụ:
/** * 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); }
Khắc phục các lỗi API chỉ được hỗ trợ một phần
Xác định hàm _handle_<API_name>_error để thay thế các giá trị không được hỗ trợ bằng một giải pháp thay thế chấp nhận được cho nhu cầu của bạn.
- Mở mã Apps Script đã chuyển đổi tại vị trí xảy ra lỗi. Xem phần Tìm lỗi.
- Đọc nhận xét phía trên hàm để biết những giá trị được hỗ trợ và những giá trị không được hỗ trợ.
- Đối với các giá trị không được hỗ trợ, hãy xác định những giá trị được hỗ trợ có thể đóng vai trò là giá trị thay thế phù hợp.
- Cập nhật hàm
_handle_<API_name>_errorđể trả về một giá trị được hỗ trợ. - Nếu không tìm được cách thay thế giá trị không được hỗ trợ, bạn sẽ không thể chuyển đổi macro này.
Ví dụ về lỗi API chỉ được hỗ trợ một phần
Ví dụ sau đây mở rộng trên API VBA legend_position đã đề cập trước đó.
Xem API được hỗ trợ một phần.
Ví dụ sau đây cho thấy mã VBA gốc sử dụng một giá trị không được hỗ trợ, xlLegendPositionCustom.
Charts(1).Legend.Position = xlLegendPositionCustom
Macro Converter thêm hàm sau vào tệp 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); }
Cần thực hiện thao tác thủ công
Cần thực hiện theo cách thủ công có nghĩa là bạn có thể chuyển đổi API VBA thành Apps Script, nhưng cần có giải pháp thay thế.
Trong báo cáo tương thích mà bạn đã tạo trước khi chuyển đổi, loại API này được gắn nhãn là Được hỗ trợ bằng giải pháp.
Nếu bạn không sửa loại API này trong mã VBA trước khi chuyển đổi tệp, thì đây là cách loại API này xuất hiện trong dự án 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_<API_name>(param1, param2, ....) { ThrowException("APInot supported yet." ); }
Khắc phục lỗi cần thao tác thủ công
Triển khai một giải pháp cho API để API hoạt động như dự kiến. 1. Mở mã Apps Script đã chuyển đổi tại vị trí xảy ra lỗi. Xem phần Tìm lỗi. 1. Đọc nhận xét phía trên hàm để biết những API có thể dùng cho giải pháp tạm thời. 1. Nếu không tìm được giải pháp thay thế phù hợp, hãy cân nhắc việc xoá API khỏi mã của bạn. 1. Nếu không tìm được giải pháp hoặc xoá API này khỏi mã và macro của bạn gặp lỗi, thì bạn không thể chuyển đổi macro này.
Ví dụ về lỗi Cần có thao tác thủ công
Sau đây là ví dụ về các API gây ra lỗi Cần thực hiện thao tác thủ công và cách khắc phục các lỗi đó:
Ví dụ 1: Autocorrect.Addreplacement
Trong ví dụ sau, bạn có thể chuyển đổi API VBA Autocorrect.Addreplacement nhưng cần có giải pháp thay thế. Macro Converter đề xuất cách triển khai hàm trong phần nhận xét mã.
/** * 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.'); }
Ví dụ sau đây minh hoạ việc triển khai API Autocorrect.Addreplacement:
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)); }
Ví dụ 2: Phương thức Workbook.open
API VBA workbook.open sẽ mở một tệp cục bộ dựa trên đường dẫn.
Giả sử có 2 tệp đang được workbook.open mở trong mã VBA:
- Tệp 1:
C:\Data\abc.xlsx - Tệp 2:
C:\Data\xyz.xlsx
Đoạn mã sau đây cho biết cách Macro Converter thay thế Workbook.open bằng Apps Script ở mọi nơi Workbook.open được dùng để mở Tệp 1:
var spreadSheetId = _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx"); var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
unimplemented_constructs.gs trong dự án 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. throw new Error('Please return the spreadsheet ID corresponding to filename: ' + FileName); return '' ; }
Theo hướng dẫn trong phần nhận xét của mẫu trước, bạn cần chuyển đổi các tệp đích thành tệp Trang tính trên Drive.
Mã nhận dạng Google Trang tính tương ứng được làm nổi bật trong danh sách sau:
- Tệp 1:
C:\Data\abc.xlsxtrở thànhhttps://docs.google.com/spreadsheets/d/abc123Abc123Abc123abc - Tệp 2:
C:\Data\xyz.xlsxtrở thànhhttps://docs.google.com/spreadsheets/d/xyz456Xyz456xYz456xyZ
Sau đó, hãy sửa đổi mã trong hàm Apps Script để mở các tệp theo mã nhận dạng:
/** * 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"; }
Lỗi có chủ ý
Lỗi có chủ ý được thêm vào mã đã chuyển đổi để mô phỏng hành vi lỗi của mã VBA ban đầu. Bạn không cần sửa đổi những lỗi này.
Ví dụ về lỗi có chủ ý
Nếu bạn cố gắng truy cập vào một phần tử vượt quá giới hạn của một mảng trong VBA, thì mã sẽ trả về một ngoại lệ. Trong Apps Script, mã này sẽ trả về giá trị không xác định.
Để tránh kết quả không mong muốn, Trình chuyển đổi macro sẽ thêm mã Apps Script để tạo ra một ngoại lệ nếu bạn cố gắng truy cập vào các phần tử vượt quá giới hạn của một mảng.
Ví dụ này được minh hoạ trong mã sau:
Mã VBA ban đầuDim arr
arr = Array("apple", "orange")
MsgBox arr(5)
Will throw the following error:
Subscript out of rangevar 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));
Bài viết liên quan
- Tổng quan về tiện ích bổ sung Macro Converter
- Xác định xem macro VBA có tương thích hay không
- Chuyển đổi macro VBA sang Apps Script
- Giải quyết các vấn đề thường gặp
- Xem hướng dẫn về Macro Converter
- Danh sách các API VBA tương thích