Дополнение Macro Converter автоматизирует большую часть процесса конвертации, но вам может потребоваться внести изменения в некоторые API и другие элементы для завершения вашего кода.
Используйте это руководство, чтобы понять файлы Apps Script (файлы GS), добавленные в ваш проект, интерпретировать различные типы ошибок и научиться исправлять ошибки.
Понимание файлов Apps Script, добавленных в ваш проект
Дополнительные файлы GS добавляются в ваш проект Apps Script, чтобы помочь:
- Определите константы и значения 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, которые не удалось преобразовать с помощью Macro Converter. Вам, вероятно, потребуется изменить этот файл, чтобы ваш код работал как задумано.
Пример: Window.Activate()
Ниже приведён пример неподдерживаемого API с именем Window.Activate()
. Macro Converter создаёт новую функцию Apps Script с похожим именем и определяет её в файле unimplemented_constructs.gs
. Поскольку функция VBA не поддерживается, новая функция Apps Script выдаёт исключение.
Новая функция добавляется в преобразованный код Apps Script везде, где в коде VBA использовался исходный API.
Если вы найдете обходной путь для воссоздания поведения исходного API, вам достаточно обновить определение функции в файле unimplemented_constructs.gs
. После того, как функция будет там определена, она будет применяться везде, где она появляется в вашем проекте Apps Script.
Вот пример в коде:
Исходный код VBA
Window.activate()
Код скрипта конвертированного приложения, добавлен в строку
_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 определяют API name()
. Обычно эквивалентом в Apps Script является getName()
, но не для всех типов объектов. Возможны различные варианты:
- Эквивалентный API объекта называется не как
getName()
. - У объекта нет API Apps Script для получения его имени.
- Эквивалентного объекта Apps Script не существует.
Если тип объекта не определен, макроконвертер создает новую функцию с именем __handle_resolve_name
в файле variant_resolutions.gs
.
Вот пример в коде:
Исходный код VBA
a = Selection.name
В этом случае для текущего выделенного элемента вызывается API name()
. Выделенный элемент может быть объектом Sheet или Shape. Для объекта Sheet перевод — getName()
, но для объекта Shape эквивалента в 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
- Требуется ручная работа
- Преднамеренная ошибка
Нереализованный API
Нереализованный API — это API, который Macro Converter не может преобразовать из VBA в Apps Script, и для такого API не существует известного обходного пути.
Нереализованные 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 или библиотек JS. Для этого выполните следующие действия:
- Откройте преобразованный код Apps Script в месте возникновения ошибки. См. раздел Поиск ошибок .
- Прочитайте добавленный комментарий над функцией. В некоторых случаях в нём даются рекомендации по реализации API в Apps Script.
- Если вы не можете найти способ реализовать API в Apps Script, рассмотрите возможность удаления его из своего кода.
- Если вы не можете найти обходной путь или удалить этот API из своего кода и ваш макрос выдает эту ошибку, вы не сможете преобразовать этот макрос.
Примеры нереализованных ошибок API
Вот примеры нереализованных сценариев API и способы их исправления:
- Эквивалентного Apps Script нет : показывает косвенный обходной путь для
Chart.Protect
— API, которого нет в Apps Script. - Неизвестный тип объекта : показано, как обрабатывать тип объекта, который является переменной, и как реализовать неподдерживаемый тип объекта, который можно воссоздать в Apps Script.
Пример 1: отсутствует эквивалентный скрипт приложения или неизвестный API
В этом примере Chart.Protect
не был автоматически преобразован, поскольку в Google Таблицах нет способа защитить диаграмму.
/** * 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». Следующий пример дополняет приведенный выше пример API VBA name()
. См. variant_resolution.gs
.
В этом примере вы узнаете:
- Как API
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()
. Код VBA показан ниже:
‘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
. Код VBA показан ниже:
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 .
Конструкции, которые макроконвертер не может преобразовать, считаются нереализованными языковыми конструкциями .
Если Macro Converter определяет, что существует нереализованная языковая конструкция, он вставляет комментарий TODO
.
Следующие конструкции VBA не поддерживаются:
- Адрес
- Заявить
- DefType
- GoSub
- Перейти к
- Инструменты
- Lset
- Открыть
- RaiseEvent
- Имя
- Резюме
- Сброс
- Тип
- Сорт
- Модули классов
Исправление ошибок нереализованных языковых конструкций
- Обновите свой код, чтобы ваша логика не полагалась на неподдерживаемую языковую конструкцию.
- Откройте преобразованный код 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 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
Исходный код 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 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, а некоторые — нет.
Например, API VBA 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
, чтобы заменить неподдерживаемые значения приемлемым решением для ваших нужд.
- Откройте преобразованный код 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, чтобы API работал как задумано. 1. Откройте преобразованный код Apps Script в месте возникновения ошибки. См. раздел Поиск ошибок . 1. Прочитайте комментарий над функцией, чтобы понять, какие API можно использовать для обходного пути. 1. Если вы не можете найти подходящий обходной путь, рассмотрите возможность удаления API из своего кода. 1. Если вы не можете найти обходной путь или удалить этот API из своего кода, и ваш макрос выдает ошибку, вы не можете преобразовать этот макрос.
Примеры ошибок, связанных с необходимостью выполнения ручной работы
Вот примеры API, которые выдают ошибки «Требуется ручная работа», и способы их исправления:
-
Implement a workaround for Autocorrect.Addreplacement
. -
Implement a workaround for workbook.open()
. В этом примере показано, как открывать файлы на Google Диске с помощью Apps Script.
Пример 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.'); }
Реализация 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()
Функция VBA API workbook.open()
открывает локальный файл на основе пути к файлу.
Предположим, что в коде VBA с помощью workbook.open()
открываются два файла:
- Файл 1:
C:\Data\abc.xlsx
- Файл 2:
C:\Data\xyz.xlsx
Ниже показано, как Macro Converter заменяет 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 Таблиц на Google Диске.
Соответствующие идентификаторы таблиц Google выделены ниже жирным шрифтом:
- Файл № 1:
C:\Data\abc.xlsx
становитсяhttps://docs.google.com/spreadsheets/d/ abc123Abc123Abc123abc
- Файл №2:
C:\Data\abc.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.
Чтобы избежать непредвиденных результатов, Macro Converter добавляет код Apps Script, который выдает исключение при попытке доступа к элементам за пределами массива.
Этот пример показан в коде ниже:
Исходный код VBADim 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 в скрипт приложений
- Решение распространенных проблем
- Посмотрите обучающие видео по Macro Converter
- Список совместимых API VBA