افزونه Macro Converter بیشتر فرآیند تبدیل را خودکار می کند، اما ممکن است برای نهایی کردن کد خود نیاز به تنظیماتی در برخی از API ها و موارد دیگر داشته باشید.
از این راهنما برای درک فایلهای Apps Script (فایلهای GS) اضافه شده به پروژه، تفسیر انواع مختلف خطا و یادگیری نحوه رفع خطاها استفاده کنید.
فایل های Apps Script اضافه شده به پروژه شما را درک کنید
فایلهای GS اضافی به پروژه Apps Script شما اضافه میشوند تا کمک کنند:
- ثابت ها و مقادیر VBA را که در Apps Script وجود ندارند تعریف کنید.
- API های تبدیل نشده را پیاده سازی کنید.
- حل و فصل انواع
فایلهای GS زیر به پروژه Apps Script شما اضافه میشوند:
-
Library.gs
-
Unimplemented_constructs.gs
-
Variant_resolutions.gs
Library.gs
به طور کلی، شما نیازی به تغییر چیزی در فایل library.gs
ندارید.
فایل library.gs
توابع و ثابت هایی را تعریف می کند که در کد VBA شما استفاده شده است و در Apps Script وجود ندارد. این به کد Apps Script جدید کمک می کند تا بهتر شبیه کد VBA شما باشد. علاوه بر این، لازم نیست هر بار که از توابع یا ثابت های فایل library.gs
استفاده می شود، تعاریف را تکرار کنید.
Unimplemented_constructs.gs
فایل unimplemented_constructs.gs
ساختارها یا APIهایی را نشان می دهد که نمی توانند توسط مبدل ماکرو تبدیل شوند. احتمالاً باید این فایل را تغییر دهید تا کد شما همانطور که در نظر گرفته شده کار کند.
مثال: Window.Activate()
در زیر نمونه ای از یک API پشتیبانی نشده به نام Window.Activate()
است. Macro Converter یک تابع Apps Script جدید با نام مشابه ایجاد می کند و آن را در فایل unimplemented_constructs.gs
تعریف می کند. از آنجایی که تابع VBA پشتیبانی نمی شود، تابع جدید Apps Script یک استثنا ایجاد می کند.
عملکرد جدید به کد Apps Script تبدیل شده در همه جاهایی که API اصلی در کد VBA استفاده شده است اضافه می شود.
اگر راه حلی برای ایجاد مجدد رفتار 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()
نامیده می شود. - شیء دارای Apps Script API برای دریافت نام خود نیست.
- یک شیء معادل Apps Script وجود ندارد.
هنگامی که نوع شی مشخص نمی شود، تبدیل کننده ماکرو یک تابع جدید به نام __handle_resolve_name
در فایل variant_resolutions.gs
ایجاد می کند.
این مثال در کد است:
کد VBA اصلی
a = Selection.name
در این مورد، name()
API در انتخاب فعلی فراخوانی می شود. انتخاب می تواند یک شی 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 است که مبدل ماکرو نمی تواند آن را از 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_ (param1, param2, ....) { ThrowException("API not 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 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: نوع شی پشتیبانی نشده
هنگامی که نوع شی ناشناخته است، خطای API اجرا نشده به فایل variant_resolution.gs
اضافه می شود. مثال زیر بر روی مثال VBA name()
API در بالا گسترش می یابد. 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()
تعریف می کند که name()
API را فراخوانی می کند. کد VBA در زیر نشان داده شده است:
‘Defining a function that prints the name of the object in parameter Sub PrintName(obj as Variant) Debug.Print obj.Name End Subاز آنجایی که «name()» روی یک شی که یک متغیر است فراخوانی می شود، کد تبدیل شده در زمان تبدیل، نوع شی را نمی شناسد. کد Apps Script تبدیل شده تابع «__handle_resolve_name» را فراخوانی می کند:
function PrintName(obj) { Logger.log(_handle_resolve_name(obj)); }
3. فرض کنید کد VBA شما تابع 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); }
ساختارهای زبانی اجرا نشده
سازه عنصری از زبان کد است که جریان اجرا یا نمایش داده را کنترل می کند. به عنوان مثال، حلقه ها، برچسب ها، رویدادها و gotos. در اینجا لیستی از تمام ساختارهای VBA آمده است.
ساختارهایی که مبدل ماکرو نمی تواند آنها را تبدیل کند، ساختارهای زبانی اجرا نشده در نظر گرفته می شوند.
در جایی که مبدل ماکرو تشخیص می دهد که یک ساختار زبانی اجرا نشده وجود دارد، یک نظر TODO
را وارد می کند.
ساختارهای VBA زیر پشتیبانی نمیشوند:
- آدرسOf
- اعلام کنید
- DefType
- GoSub
- رفتن به
- اجرا می کند
- Lset
- باز کنید
- RaiseEvent
- نام
- رزومه
- تنظیم مجدد
- TypeOf
- کلاس
- ماژول های کلاس
رفع خطاهای ساخت زبان اجرا نشده
- کد خود را به روز کنید تا منطق شما بر ساختار زبان پشتیبانی نشده تکیه نکند.
- کد Apps Script تبدیل شده را در محل خطا باز کنید. به یافتن خطاها مراجعه کنید.
- بر اساس منطق کد، آن را به گونه ای به روز کنید که به ساختار زبان پشتیبانی نشده نیاز نداشته باشد.
- اگر نمی توانید راهی برای بازنویسی کد خود بدون ساختار زبان پشتیبانی نشده پیدا کنید، نمی توانید این ماکرو را تبدیل کنید.
نمونه هایی از خطاهای ساخت زبان اجرا نشده
یکی از رایجترین ساختارهای زبانی اجرا نشده، عبارت GoTo
است. می توانید برخی از دستورات VBA GoTo
را با حلقه ها جایگزین کنید. در زیر دو نمونه از استفاده از حلقه ها به جای دستورات 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 جایگزین کنید
کد VBA اصلیSub Test() a = 0 For i = 1 to 100 For j = 1 to 10 a =a a + 1 If i + j > 50 GoTo endLoop End If Next j Next i endLoop: MsgBox a End Sub
function test() { var a = 0; endLoop: for (var i = 1; i <= 100; i++) { for (var j = 0; j <=10; j++) { If (i + j > 50) { break endLoop; } } } Browser.msgBox(a); } break start; } while (true); }
API تا حدی پشتیبانی می شود
برای API های نیمه پشتیبانی شده ، برخی از پارامترهای ورودی در Apps Script پشتیبانی می شوند و برخی دیگر پشتیبانی نمی شوند.
به عنوان مثال، VBA API legend_position
برای تعریف افسانه در یک نمودار اکسل استفاده می شود. از چندین نوع مقادیر ورودی پشتیبانی می کند، از جمله:
-
xlLegendPositionBottom
: افسانه را در پایین نمودار قرار می دهد. -
xlLegendPositionCorner
: افسانه را در گوشه نمودار قرار می دهد. -
xlLegendPositionCustom
: افسانه را در موقعیت های سفارشی در نمودار قرار می دهد.
Apps Script یک کد معادل دارد که فقط برخی از آن مقادیر را پشتیبانی می کند. مقادیر زیر پشتیبانی نمی شوند:
-
xlLegendPositionCorner
-
xlLegendPositionCustom
برای پرچمگذاری مقادیر پشتیبانینشده از APIهای نیمهپشتیبانیشده در کد تبدیلشدهتان، یک شرط اعتبارسنجی به فایل library.gs
اضافه میشود که آن مقادیر را بررسی میکند. به عنوان مثال:
if (position == xlLegendPositionCorner || position == xlLegendPositionCustom) { position = _handle_legend_position_error(position); }
اگر شرط اعتبارسنجی یکی از مقادیر پشتیبانی نشده را پیدا کند، یک تابع کنترل کننده خطا، _handle_<API_name>_error
، در فایل unimplemented_constructs.gs
ایجاد می شود.
این تابع یک خطای کاربر ایجاد می کند و مقدار را با مقدار پشتیبانی شده جایگزین نمی کند. به عنوان مثال:
/** * Throw error message for unsupported legend position. * The VBA API Legend.Position which can take values xlLegendPositionTop, * xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight, * xlLegendPositionCorner, xlLegendPositionCustom. It is partially supported in * Apps Scripts that supports only a subset of the values (does not support * xlLegendPositionCorner and xlLegendPositionCustom). * @param {string} position */ function _handle_legend_position_error(position) { // Please comment the throw statement and return a supported position value // instead. // Values that are supported here are xlLegendPositionTop, // xlLegendPositionLeft, xlLegendPositionBottom, xlLegendPositionRight. throw new Error( 'Google Sheets does not support legend position: ' + position); }
خطاهای API تا حدی پشتیبانی شده را برطرف کنید
تابع _handle_<API_name>_error
را تعریف کنید تا مقادیر پشتیبانی نشده را با یک راه حل قابل قبول برای نیازهای شما جایگزین کنید.
- کد Apps Script تبدیل شده را در محل خطا باز کنید. به یافتن خطاها مراجعه کنید.
- نظر بالای تابع را بخوانید تا متوجه شوید کدام مقادیر پشتیبانی می شوند و کدام ها پشتیبانی نمی شوند.
- برای مقادیر پشتیبانی نشده، تعیین کنید که کدام مقادیر پشتیبانی شده می توانند به عنوان جایگزین مناسب عمل کنند.
- تابع
_handle_<API_name>_error
بهروزرسانی کنید تا یک مقدار پشتیبانی شده را به جای آن بازگردانید. - اگر نمی توانید راهی برای جایگزینی مقدار پشتیبانی نشده پیدا کنید، نمی توانید این ماکرو را تبدیل کنید.
مثالی از یک خطای API تا حدی پشتیبانی شده
مثال زیر در مورد VBA API legend_position
ذکر شده در بالا گسترش می یابد. API با پشتیبانی جزئی را ببینید.
در زیر نمونه ای از کد اصلی 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); }
نیاز به کار دستی
کار دستی مورد نیاز به این معنی است که VBA API را می توان به 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_ (param1, param2, ....) { ThrowException("API not supported yet."); }
رفع خطاهای مورد نیاز کار دستی
راهحلی برای API پیادهسازی کنید تا API طبق برنامه کار کند. 1. کد Apps Script تبدیل شده را در محل خطا باز کنید. به یافتن خطاها مراجعه کنید. 1. نظر بالای تابع را بخوانید تا بفهمید کدام API میتواند برای راهحل استفاده شود. 1. اگر نمی توانید راه حل مناسبی پیدا کنید، API را از کد خود حذف کنید. 1. اگر نتوانستید راهحلی پیدا کنید یا این API را از کد خود حذف کنید و ماکرو شما خطایی ایجاد کند، نمیتوانید این ماکرو را تبدیل کنید.
نمونه هایی از کارهای دستی به خطاهای مورد نیاز
در اینجا نمونههایی از APIهایی هستند که خطاهای مورد نیاز کار دستی را ایجاد میکنند و نحوه رفع آنها:
-
Implement a workaround for Autocorrect.Addreplacement
. -
Implement a workaround for workbook.open()
. این مثال نحوه باز کردن فایلها در Google Drive با 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.'); }
اجرای Autocorrect.Addreplacement
API در زیر نشان داده شده است:
var AUTO_CORRECTIONS = "AUTO_CORRECTIONS"; // Need to get the autocorrections set in previous sessions and use them. var savedAutoCorrections = PropertiesService.getDocumentProperties().getProperty(AUTO_CORRECTIONS); var autoCorrections = savedAutoCorrections ? JSON.parse(savedAutoCorrections) : {}; function onEdit(e) { autoCorrect(e.range); } function autoCorrect(range) { for (key in autoCorrections) { // Replace each word that needs to be auto-corrected with their replacements. range.createTextFinder(key) .matchCase(true) .matchEntireCell(false) .matchFormulaText(false) .useRegularExpression(false) .replaceAllWith(autoCorrections[key]); } } /** * Could not convert autocorrect.addreplacement API. Please add relevant code in * the following function to implement it. * This API has been used at the following locations in the VBA script. * sheet1 : line 3 * * You can use the following Apps Script APIs to convert it. * Apps Script APIs : createTextFinder , onEdit * Apps Script documentation links : https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit , createTextFinder * Comments : AutoCorrect.AddReplacement was not converted, but there is an * equivalent option you can implement manually. Use onEdit and FindReplaceRequest * APIs instead, see https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onedit * and createTextFinder. For more information on API manual implementation, see * https://developers.google.com/apps-script/guides/macro-converter/fix-conversion-errors. * * @param {Object} CallingObject represents the parent object using which the API has been called. * @param {string} What * @param {string} Replacement * * @return {string} */ function _api_autocorrect_addreplacement(CallingObject, What, Replacement) { autoCorrections[What] = Replacement; // Store the updated autoCorrections in the properties so that future executions use the correction. PropertiesService.getDocumentProperties().setProperty(AUTO_CORRECTIONS, JSON.stringify(autoCorrections)); }
مثال 2: Workbook.open()
VBA API workbook.open()
یک فایل محلی را بر اساس مسیر فایل باز می کند.
فرض کنید دو فایل در حال باز شدن توسط workbook.open()
در کد VBA وجود دارد:
- فایل 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 Drive تبدیل کنید.
شناسههای صفحه گسترده 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، کد تعریف نشده برمی گردد.
برای جلوگیری از نتایج غیرمنتظره، Macro Converter کد Apps Script را اضافه میکند که در صورت تلاش برای دسترسی به عناصر فراتر از محدوده یک آرایه، یک استثنا ایجاد میکند.
این مثال در کد زیر نشان داده شده است:
کد VBA اصلیDim arr arr = Array("apple", "orange") MsgBox arr(5) Will throw the following error: Subscript out of range
var arr; arr = ["apple", "orange"]; Browser.msgBox(arr[5]); Will return this value and not throw an error: undefined
/** * Extend the regular JS array to support VB style indexing with a get method. * @returns{*} value at the index */ Array.prototype.get = function() { var curr_res = this; for (var i = 0; i < arguments.length; i++) { if (!Array.isArray(curr_res) || curr_res.length < arguments[i]) { throw new Error(‘Converted VBA Error (Intentional Error): Subscript out of range’); } curr_res = curr_res[arguments[i]]; } return curr_res; }; var arr; arr = ["apple", "orange"]; Browser.msgBox(arr.get(5));
مقالات مرتبط
- نمای کلی افزونه Macro Converter
- تعیین کنید که آیا ماکروهای VBA سازگار هستند یا خیر
- ماکروهای VBA را به Apps Script تبدیل کنید
- به مسائل رایج رسیدگی کنید
- آموزش مبدل ماکرو را تماشا کنید
- لیستی از APIهای VBA سازگار