Дополнение Macro Converter для Google Workspace автоматизирует большую часть процесса конвертации, но для завершения работы над кодом вам может потребоваться внести корректировки в некоторые API и другие параметры.
Воспользуйтесь этим руководством, чтобы понять, как работают файлы Apps Script (GS-файлы), добавленные в ваш проект, интерпретировать различные типы ошибок и научиться их исправлять.
Разберитесь, как работают файлы Apps Script, добавленные в ваш проект.
В ваш проект Apps Script добавляются дополнительные файлы GS, которые помогут в следующем:
- Определите константы и значения VBA, которых нет в Apps Script.
- Реализуйте неконвертированные API.
- Устранить варианты.
В ваш проект Apps Script добавляются следующие файлы GS:
-
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
Ниже приведён пример неподдерживаемого API под названием Window.Activate . Макросконвертер создаёт новую функцию Apps Script с похожим именем и определяет её в файле unimplemented_constructs.gs . Поскольку функция VBA не поддерживается, новая функция Apps Script вызывает исключение.
Новая функция добавляется в преобразованный код Apps Script везде, где в коде VBA использовался исходный API.
Если вы найдете обходной путь для воспроизведения поведения оригинального 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 . Обычно в Apps Script эквивалентом является getName , но не для каждого типа объекта. Могут возникнуть различные альтернативные варианты:
- Эквивалентный метод объекта называется иначе, чем
getName. - Для получения имени объекта отсутствует API Apps Script.
- Аналогичного объекта в Apps Script не существует.
Если тип объекта не определен, макроконвертер создает новую функцию с именем __handle_resolve_name в файле variant_resolutions.gs .
Вот пример в коде:
Оригинальный код VBA
a = Selection.name
В этом случае метод name вызывается для текущего выделения. Выделение может представлять собой объект Sheet или объект Shape. Если это объект Sheet, то используется метод getName , но если это объект Shape, то в Apps Script нет эквивалента.
Код Apps Script, преобразованный в текст, добавлен непосредственно в код приложения.
a = __handle_resolve_name({}, getActiveSelection(), {});
В файл variant_resolution.gs добавлена следующая функция __handle_resolve_name для решения задач с различными типами объектов. Функция проверяет тип объекта, затем использует 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
- Требуется ручной труд
- Преднамеренная ошибка
Нереализованный API
Нереализованный API — это API, который конвертер макросов не может преобразовать из VBA в Apps Script, и для которого нет известного обходного пути.
Нереализованные API обычно добавляются в файл unimplemented_constructs.gs в виде пустых функций — иногда с пустыми сигнатурами. Если тип объекта определить не удалось, нереализованный API может быть добавлен в файл variant_resolution.gs .
В отчете о совместимости, который вы создали перед преобразованием, этот API помечен как «Требует дополнительного исследования» .
Если вы не исправите этот тип API в своем коде VBA перед преобразованием файла, он будет выглядеть в проекте 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." ); }
Исправлены ошибки, связанные с нереализованным API.
Определите нереализованный API с помощью существующих API Apps Script или библиотек JavaScript. Для этого выполните следующие шаги:
- Откройте преобразованный код Apps Script в месте возникновения ошибки. См. раздел «Поиск ошибок» .
- Над функцией ознакомьтесь с добавленным комментарием. В некоторых случаях комментарий содержит рекомендации по реализации API в Apps Script.
- Если вы не можете найти способ реализовать API в Apps Script, рассмотрите возможность удаления его из вашего кода.
- Если вы не можете найти обходное решение или удалить этот API из своего кода, и ваш макрос выдает эту ошибку, вы не сможете преобразовать этот макрос.
Примеры ошибок, связанных с нереализованным API.
Вот примеры нереализованных сценариев использования API и способы их исправления:
- В Apps Script нет эквивалентного решения : показано косвенное обходное решение для
Chart.Protect, API, которого нет в Apps Script. - Неизвестный тип объекта : Показано, как обрабатывать тип объекта, являющийся переменной, и как реализовать неподдерживаемый тип объекта, который можно воссоздать в Apps Script.
Пример 1: Нет эквивалентного Apps Script или неизвестен API.
В этом примере Chart.Protect не был преобразован автоматически, поскольку в Google Sheets нет способа защитить диаграмму.
/** * 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: Неподдерживаемый тип объекта
Если тип объекта неизвестен, в файл variant_resolution.gs добавляется ошибка "не реализован API". Следующий пример расширяет пример использования метода name в VBA. См. variant_resolution.gs .
В этом примере вы узнаете:
- Как метод
nameпреобразуется в новую функцию в файлеvariant_resolution.gs. - Как вызывается новая функция в преобразованном коде .
- Как создать обходное решение для
CommandBar, неподдерживаемого типа объектов, в Apps Script .
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 определяет функцию PrintName() , которая вызывает 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. Предположим, ваш код VBA вызывает функцию PrintName() для объекта типа CommandBar :
PrintName Application.CommandBars.item("Standard")CommandBar не поддерживается в Apps Script, и, как следствие, два метода, используемые в приведенном выше коде VBA, также не поддерживаются.-
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 , и новую коллекцию CommandBars аналогичную той, что существует в VBA.
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 Измените функцию __handle_resolve_name в файле 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; } } // 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 ( _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 см. в разделе «Операторы (VBA)» .
Конструкции, которые макроконвертер не может преобразовать, считаются нереализованными языковыми конструкциями .
Если конвертер макросов определяет наличие нереализованной языковой конструкции, он вставляет комментарий TODO .
Следующие конструкции VBA не поддерживаются:
- Адрес
- Объявить
- DefType
- GoSub
- Перейти к
- Инструменты
- Лсет
- Открыть
- RaiseEvent
- Имя
- Резюме
- Rset
- ТипОф
- Сорт
- Модули занятий
Исправлены ошибки, связанные с нереализованными языковыми конструкциями.
- Обновите свой код таким образом, чтобы ваша логика не зависела от неподдерживаемой языковой конструкции.
- Откройте преобразованный код Apps Script в месте возникновения ошибки. См. раздел «Поиск ошибок» .
- Исходя из логики кода, обновите его таким образом, чтобы не требовалась неподдерживаемая языковая конструкция.
- Если вы не можете найти способ переписать свой код без неподдерживаемой языковой конструкции, вы не сможете преобразовать этот макрос.
Примеры ошибок, связанных с нереализованными языковыми конструкциями.
Одна из наиболее распространенных нереализованных языковых конструкций — это оператор GoTo . Замените некоторые операторы GoTo в VBA циклами. В следующих примерах вместо операторов GoTo используются циклы.
Пример 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 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); }
Пример 2: Замените GoTo на цикл For.
Оригинальный код VBASub 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
Для частично поддерживаемых API некоторые входные параметры поддерживаются в Apps Script, а некоторые — нет.
Например, legend_position в API VBA используется для определения легенды на графике 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 для замены неподдерживаемых значений приемлемым обходным решением, соответствующим вашим потребностям.
- Откройте преобразованный код Apps Script в месте возникновения ошибки. См. раздел «Поиск ошибок» .
- Прочитайте комментарий над функцией, чтобы понять, какие значения поддерживаются, а какие нет.
- Для неподдерживаемых значений определите, какие поддерживаемые значения могут служить подходящей заменой.
- Обновите функцию
_handle_<API_name>_error, чтобы она возвращала поддерживаемое значение. - Если вы не можете найти способ заменить неподдерживаемое значение, вы не сможете преобразовать этот макрос.
Пример ошибки, связанной с частично поддерживаемым API.
Следующий пример расширяет возможности упомянутого ранее API VBA legend_position . См. Частично поддерживаемый API .
В следующем примере показан исходный код VBA, использующий неподдерживаемое значение xlLegendPositionCustom .
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); }
Требуется ручной труд
Необходимость ручной работы означает, что API VBA можно преобразовать в Apps Script, но для этого потребуется обходной путь.
В отчете о совместимости, который вы создали перед преобразованием, этот тип API помечен как «Поддерживается с обходными путями» .
Если вы не исправите этот тип API в своем коде VBA перед преобразованием файла, он будет выглядеть в проекте 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." ); }
Исправление ошибок, связанных с необходимостью выполнения ручной работы.
Реализуйте обходное решение для API, чтобы он работал должным образом. 1. Откройте преобразованный код Apps Script в месте возникновения ошибки. См. раздел «Поиск ошибок» . 1. Прочитайте комментарий над функцией, чтобы понять, какие API можно использовать для обходного решения. 1. Если вы не можете найти подходящее обходное решение, рассмотрите возможность удаления API из вашего кода. 1. Если вы не можете найти обходное решение или удалить этот API из вашего кода, и ваш макрос выдает ошибку, вы не можете преобразовать этот макрос.
Примеры ошибок, связанных с необходимостью выполнения ручной работы.
Вот примеры API, которые выдают ошибки "Необходима ручная работа", и способы их исправления:
Пример 1: Autocorrect.Addreplacement
В следующем примере функцию Autocorrect.Addreplacement из API VBA можно преобразовать, но для этого потребуется обходной путь. Макросконвертер предлагает способ реализации функции в комментариях к коду.
/** * 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.'); }
В следующем примере показана реализация 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)); }
Пример 2: Метод Workbook.open
Метод workbook.open в API VBA открывает локальный файл по указанному пути.
Предположим, что в коде VBA с помощью workbook.open открываются два файла:
- Файл 1:
C:\Data\abc.xlsx - Файл 2:
C:\Data\xyz.xlsx
Следующий код показывает, как конвертер макросов заменяет Workbook.open на Apps Script везде, где Workbook.open используется для открытия файла 1:
var spreadSheetId = _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx"); var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
unimplemented_constructs.gs проекта 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 '' ; }
Как указано в комментариях к предыдущему примеру, вам необходимо преобразовать целевые файлы в файлы Google Sheets на Google Диске.
Соответствующие идентификаторы электронных таблиц Google выделены в следующем списке:
- Файл №1:
C:\Data\abc.xlsxпреобразуетсяhttps://docs.google.com/spreadsheets/d/ abc123Abc123Abc123abc - Файл №2:
C:\Data\xyz.xlsxпреобразуется вhttps://docs.google.com/spreadsheets/d/ xyz456Xyz456xYz456xyZ
Затем измените код в функции 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 код возвращает undefined.
Во избежание непредвиденных результатов, конвертер макросов добавляет код Apps Script, который генерирует исключение, если вы попытаетесь получить доступ к элементам за пределами массива.
Этот пример показан в следующем коде:
Оригинальный код VBADim 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));
Статьи по теме
- Обзор дополнения Macro Converter
- Определите, совместимы ли макросы VBA.
- Преобразование макросов VBA в Apps Script
- Рассмотрите общие проблемы.
- Посмотрите обучающие видеоролики по Macro Converter.
- Список совместимых API VBA