تتولّى إضافة Macro Converter في Google Workspace معظم عملية التحويل آليًا، ولكن قد تحتاج إلى إجراء تعديلات على بعض واجهات برمجة التطبيقات وعناصر أخرى لإكمال الرمز.
استخدِم هذا الدليل للتعرّف على ملفات برمجة تطبيقات (ملفات GS) التي تمت إضافتها إلى مشاريعك، وتفسير أنواع الأخطاء المختلفة، ومعرفة كيفية حل مشكلة الأخطاء.
التعرّف على ملفات "برمجة تطبيقات Google" المُضافة إلى مشروعك
تتم إضافة ملفات GS إضافية إلى مشروع "برمجة تطبيقات Google" للمساعدة في ما يلي:
- تحديد ثوابت وقيم VBA غير متوفّرة في برمجة تطبيقات
- تنفيذ واجهات برمجة التطبيقات التي لم يتم تحويلها
- حلّ خيارات المنتج
تتم إضافة ملفات GS التالية إلى مشروع "برمجة تطبيقات Google":
Library.gsUnimplemented_constructs.gsVariant_resolutions.gs
Library.gs
بشكل عام، ليس عليك تعديل أي شيء في ملف library.gs.
يحدّد الملف library.gs الدوال والثوابت التي تم استخدامها في رمز VBA
الخاص بك والتي لا تتوفّر في "برمجة تطبيقات Google". يساعد ذلك في أن يشبه رمز برمجة تطبيقات الجديد رمز VBA بشكل أفضل. بالإضافة إلى ذلك، لن تحتاج إلى تكرار التعريفات في كل مرة يتم فيها استخدام الدوال أو الثوابت من ملف library.gs.
Unimplemented_constructs.gs
يتضمّن الملف unimplemented_constructs.gs عناصر أو واجهات برمجة تطبيقات تعذّر على "أداة تحويل الماكرو" تحويلها. من المحتمل أن تحتاج إلى تعديل هذا الملف لجعل الرمز البرمجي يعمل على النحو المنشود.
مثلاً: Window.Activate
في ما يلي مثال على واجهة برمجة تطبيقات غير متوافقة باسم Window.Activate. تنشئ إضافة "محوّل الماكرو" دالة جديدة في "برمجة تطبيقات Google" تحمل اسمًا مشابهًا، وتعرّفها في الملف unimplemented_constructs.gs. بما أنّ دالة VBA غير متاحة، ستعرض دالة برمجة تطبيقات الجديدة استثناءً.
تتم إضافة الدالة الجديدة إلى رمز "برمجة تطبيقات Google" المحوَّل في كل مكان تم فيه استخدام واجهة برمجة التطبيقات الأصلية في رمز VBA.
إذا عثرت على حل بديل لإعادة إنشاء سلوك واجهة برمجة التطبيقات الأصلية، ما عليك سوى تعديل تعريف الدالة في ملف unimplemented_constructs.gs. بعد تحديد الدالة هناك، سيتم تطبيقها في كل مكان تظهر فيه الدالة في مشروع برمجة تطبيقات.
في ما يلي مثال على الرمز:
رمز VBA الأصلي
Window.activate()
رمز "برمجة تطبيقات Google" المحوّل، تمت إضافته في السطر
_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 إلى مشروعك في "برمجة تطبيقات Google" إذا تعذّر تحديد نوع أحد العناصر. يمكن أن يحدث ذلك لعدة أسباب، مثل توفّر أنواع إرجاع متعددة لواجهة برمجة التطبيقات أو تعريف العنصر كنوع متغير.
يضيف "محوّل وحدات الماكرو" دالة جديدة إلى هذا الملف باسم
__handle_resolve_<api> تحلّ محل واجهة برمجة التطبيقات المعنيّة وتساعد في تحديد
نوع العنصر.
في بعض الحالات، قد تحتاج إلى تعديل الدالة __handle_resolve_<api>
لتحديد نوع العنصر يدويًا. يُرجى الاطّلاع على نوع العنصر غير المتوافق.
مثال: طريقة name
تحدّد العديد من أنواع العناصر في VBA طريقة name. عادةً، يكون الرمز المكافئ في برمجة تطبيقات هو getName، ولكن ليس لكل نوع من أنواع العناصر. يمكن أن تحدث عدة حالات بديلة:
- يختلف اسم الطريقة المكافئة للعنصر عن
getName. - لا يحتوي العنصر على واجهة برمجة تطبيقات Apps Script للحصول على اسمه.
- لا يتوفّر عنصر مكافئ في "برمجة التطبيقات".
عندما لا يتم تحديد نوع العنصر، ينشئ Macro Converter دالة جديدة باسم __handle_resolve_name في الملف variant_resolutions.gs.
في ما يلي مثال على الرمز:
رمز VBA الأصلي
a = Selection.name
في هذه الحالة، يتم استدعاء الطريقة name على التحديد الحالي. يمكن أن يكون التحديد كائن Sheet أو كائن Shape. إذا كان كائن ورقة بيانات، تكون الترجمة getName، ولكن إذا كان كائن شكل، لا يوجد مكافئ في برمجة تطبيقات.
رمز "برمجة تطبيقات Google" المحوّل، تمت إضافته في السطر
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; }
العثور على الأخطاء
عندما تواجه خطأً في رمز برمجة تطبيقات المحوَّل، تحدّد الرسالة نوع الخطأ وموقعه. تعتمد صيغة رسالة الخطأ على وقت تشغيل "برمجة تطبيقات Google" الذي تستخدمه.
إذا كنت تستخدم وقت التشغيل التلقائي 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 الموضّحَين سابقًا
تشمل أنواع الأخطاء التي قد تواجهها ما يلي:
- واجهة برمجة تطبيقات غير منفَّذة
- بنية لغوية غير منفَّذة
- واجهة برمجة التطبيقات المتوافقة جزئيًا
- يجب اتّخاذ إجراء يدوي
- الخطأ المقصود
واجهة برمجة تطبيقات غير منفَّذة
واجهة برمجة التطبيقات غير المنفَّذة هي واجهة برمجة تطبيقات لا يمكن لـ "محوّل وحدات الماكرو" تحويلها من VBA إلى "برمجة تطبيقات Google"، ولا يتوفّر حل بديل معروف لها.
عادةً ما تتم إضافة واجهات برمجة التطبيقات غير المنفَّذة كدوال فارغة، وأحيانًا مع توقيعات فارغة، إلى الملف unimplemented_constructs.gs. إذا تعذّر تحديد نوع العنصر، قد تتم إضافة واجهة برمجة التطبيقات غير المكتملة إلى الملف variant_resolution.gs بدلاً من ذلك.
في تقرير التوافق الذي أنشأته قبل عملية التحويل، تم تصنيف واجهة برمجة التطبيقات هذه على أنّها تحتاج إلى مزيد من البحث.
إذا لم يتم إصلاح هذا النوع من واجهات برمجة التطبيقات في رمز 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." ); }
إصلاح أخطاء واجهة برمجة التطبيقات غير المنفَّذة
حدِّد واجهة برمجة التطبيقات غير المنفَّذة باستخدام واجهات برمجة التطبيقات الحالية في "برمجة التطبيقات" أو مكتبات JavaScript. لإجراء هذا، اتبع هذه الخطوات:
- افتح رمز برمجة تطبيقات المحوَّل في موقع الخطأ. يُرجى الاطّلاع على العثور على الأخطاء.
- فوق الدالة، اقرأ التعليق الذي تمت إضافته. في بعض الحالات، يقترح التعليق كيفية تنفيذ واجهة برمجة التطبيقات في "برمجة التطبيقات".
- إذا لم تتمكّن من العثور على طريقة لتنفيذ واجهة برمجة التطبيقات في "برمجة تطبيقات Google"، ننصحك بإزالتها من الرمز البرمجي.
- إذا لم تتمكّن من العثور على حلّ بديل أو إزالة واجهة برمجة التطبيقات هذه من الرمز الخاص بك وظهر هذا الخطأ في وحدة الماكرو، لن تتمكّن من تحويل وحدة الماكرو هذه.
أمثلة على أخطاء واجهة برمجة التطبيقات غير المنفَّذة
في ما يلي أمثلة على سيناريوهات غير منفَّذة لواجهة برمجة التطبيقات وكيفية حلّها:
- لا يوجد مكافئ في "برمجة التطبيقات":
تعرض هذه السمة حلاً بديلاً غير مباشر لـ
Chart.Protect، وهي واجهة برمجة تطبيقات غير متوفرة في Apps Script. - نوع عنصر غير معروف: يوضّح هذا القسم كيفية التعامل مع نوع عنصر يمثّل متغيرًا، وكيفية تنفيذ نوع عنصر غير متوافق يمكن إعادة إنشائه في "برمجة تطبيقات Google".
المثال 1: لا تتوفّر واجهة برمجة تطبيقات مكافئة أو غير معروفة في "برمجة تطبيقات Google"
في هذا المثال، لم يتم تحويل 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. يقدّم المثال التالي تفاصيل إضافية حول مثال طريقة name في VBA. يمكنك الاطّلاع على variant_resolution.gs.
في هذا المثال، سنتعرّف على ما يلي:
- طريقة تحويل طريقة
nameإلى دالة جديدة في الملفvariant_resolution.gs - كيفية استدعاء الدالة الجديدة في الرمز البرمجي المحوَّل
- كيفية إنشاء حلّ بديل لـ
CommandBar، وهو نوع عنصر غير متوافق، في "برمجة تطبيقات Google"
1. بما أنّ الرمز المحوّل لا يمكنه تحديد نوع العنصر الدقيق الذي يتم استدعاؤه، ينشئ Macro Converter دالة جديدة باسم __handle_resolve_name: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:
‘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 مع "برمجة التطبيقات"، وبالتالي لا تتوافق الطريقتان المستخدَمتان في رمز 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); }
بُنى لغوية غير منفَّذة
البنية هي عنصر من عناصر لغة الترميز يتحكّم في مسار التنفيذ أو عرض البيانات. على سبيل المثال، الحلقات والتصنيفات والأحداث وعمليات الانتقال. للاطّلاع على قائمة بجميع بنى VBA، راجِع العبارات (VBA).
تُعدّ البُنى التي لا يمكن لأداة Macro Converter تحويلها بُنى لغوية غير منفَّذة.
عندما يحدّد Macro Converter أنّ هناك بنية لغوية غير منفَّذة، يدرج تعليق TODO.
لا تتوفّر بنى VBA التالية:
- AddressOf
- التعريف
- DefType
- GoSub
- GoTo
- التنفيذ
- Lset
- افتح
- RaiseEvent
- الاسم
- استئناف
- Rset
- TypeOf
- الفئة
- وحدات الصف
إصلاح أخطاء بنية اللغة غير المتوافقة
- عدِّل الرمز البرمجي لكي لا يعتمد المنطق على بنية اللغة غير المتوافقة.
- افتح رمز برمجة تطبيقات المحوَّل في موقع الخطأ. راجِع العثور على الأخطاء.
- استنادًا إلى منطق الرمز، عدِّله بطريقة لا تتطلّب بنية اللغة غير المتوافقة.
- إذا لم تتمكّن من العثور على طريقة لإعادة كتابة الرمز بدون بنية اللغة غير المتوافقة، لن تتمكّن من تحويل هذا الماكرو.
أمثلة على أخطاء بنية اللغة غير المنفَّذة
من أكثر بنى اللغة غير المطبَّقة شيوعًا عبارة 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 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 Loop
رمز 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 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); }
واجهة برمجة التطبيقات المسموح بها جزئيًا
بالنسبة إلى واجهات برمجة التطبيقات المتوافقة جزئيًا، تتوافق بعض مَعلمات الإدخال مع Apps Script ولا تتوافق بعضها الآخر.
على سبيل المثال، يتم استخدام واجهة برمجة التطبيقات legend_position في VBA لتحديد تسمية توضيحية في رسم بياني على Excel. تتيح هذه السمة استخدام أنواع متعددة من قيم الإدخال، بما في ذلك:
-
xlLegendPositionBottom: يضع التسمية التوضيحية في أسفل الرسم البياني. xlLegendPositionCorner: تضع التسمية التوضيحية في زاوية الرسم البياني.xlLegendPositionCustom: تضع التسمية التوضيحية في مواضع مخصّصة على الرسم البياني.
يتضمّن برمجة تطبيقات رمزًا مكافئًا لا يتوافق إلا مع بعض هذه القيم. القيم التالية غير متاحة:
xlLegendPositionCornerxlLegendPositionCustom
لوضع علامة على القيم غير المتوافقة لواجهات برمجة التطبيقات المتوافقة جزئيًا في الرمز البرمجي المحوَّل، تتم إضافة شرط تحقّق إلى الملف 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); }
إصلاح أخطاء واجهة برمجة التطبيقات غير المتوافقة جزئيًا
حدِّد الدالة _handle_<API_name>_error لاستبدال القيم غير المسموح بها
بحلّ بديل مقبول يناسب احتياجاتك.
- افتح رمز برمجة تطبيقات المحوَّل في موقع الخطأ. يُرجى الاطّلاع على العثور على الأخطاء.
- اقرأ التعليق فوق الدالة لمعرفة القيم المسموح بها وغير المسموح بها.
- بالنسبة إلى القيم غير المسموح بها، حدِّد القيم المسموح بها التي يمكن أن تحلّ محلّها.
- عدِّل الدالة
_handle_<API_name>_errorلعرض قيمة متوافقة بدلاً من ذلك. - إذا لم تتمكّن من العثور على طريقة لاستبدال القيمة غير المتوافقة، لن تتمكّن من تحويل هذا الماكرو.
مثال على خطأ في واجهة برمجة تطبيقات غير متوافقة جزئيًا
يقدّم المثال التالي تفاصيل إضافية عن واجهة برمجة التطبيقات legend_position التي تم ذكرها سابقًا.
اطّلِع على واجهة برمجة التطبيقات المتوافقة جزئيًا.
يعرض المثال التالي رمز VBA أصليًا يستخدم قيمة غير متوافقة،
xlLegendPositionCustom.
Charts(1).Legend.Position = xlLegendPositionCustom
يضيف Macro Converter الدالة التالية إلى ملف 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 إلى Apps Script، ولكنّ ذلك يتطلّب حلاً بديلاً.
في تقرير التوافق الذي أنشأته قبل عملية التحويل، تم تصنيف هذا النوع من واجهات برمجة التطبيقات على أنّه متوافق مع حلول بديلة.
إذا لم يتم إصلاح هذا النوع من واجهات برمجة التطبيقات في رمز 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." ); }
إصلاح الأخطاء التي تتطلّب إجراءً يدويًا
تنفيذ حلّ بديل لواجهة برمجة التطبيقات لتعمل على النحو المطلوب 1. افتح رمز برمجة تطبيقات المحوَّل في الموقع الجغرافي الذي حدث فيه الخطأ. يُرجى الاطّلاع على العثور على الأخطاء. 1. اقرأ التعليق الذي يظهر فوق الدالة لمعرفة واجهات برمجة التطبيقات التي يمكن استخدامها كحل بديل. 1. إذا لم تتمكّن من العثور على حلّ بديل مناسب، ننصحك بإزالة واجهة برمجة التطبيقات من الرمز. 1. إذا لم تتمكّن من العثور على حلّ بديل أو إزالة واجهة برمجة التطبيقات هذه من الرمز البرمجي وظهر خطأ في وحدة الماكرو، لن تتمكّن من تحويل وحدة الماكرو هذه.
أمثلة على أخطاء تتطلّب تدخّلاً يدويًا
في ما يلي أمثلة على واجهات برمجة التطبيقات التي تعرض أخطاء "مطلوب اتّخاذ إجراء يدوي" وكيفية إصلاحها:
المثال 1: Autocorrect.Addreplacement
في المثال التالي، يمكن تحويل واجهة برمجة التطبيقات Autocorrect.Addreplacement الخاصة بلغة 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.'); }
يعرض المثال التالي عملية تنفيذ واجهة برمجة التطبيقات 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 ملفًا محليًا استنادًا إلى مسار.
لنفترض أنّه يتم فتح ملفَين بواسطة workbook.open في رمز VBA:
- الملف 1:
C:\Data\abc.xlsx - الملف 2:
C:\Data\xyz.xlsx
يوضّح الرمز التالي كيف يستبدل "مُحوّل الماكرو" Workbook.open بـ برمجة تطبيقات في كل مكان يتم فيه استخدام Workbook.open لفتح الملف 1:
var spreadSheetId = _handle_mso_excel_get_google_spreadsheet_id("C:\Data\abc.xlsx"); var spreadSheet = SpreadsheetApp.openById(spreadSheetId);
unimplemented_constructs.gs في مشروع "برمجة التطبيقات":
/** * Method to return the spreadsheet id manually. * * @param {string} FileName ID of the spreadsheet to be opened. * @return {string} return the spreadsheet id. */ function _handle_mso_excel_get_google_spreadsheet_id(FileName) { // Upload the Excel files being opened by the API to Google Drive and convert // them to Google Sheets. // Determine the spreadsheet ID of the Google Sheets file created. // Implement this method to return the corresponding spreadsheet ID when given //the original file path as parameter. throw new Error('Please return the spreadsheet ID corresponding to filename: ' + FileName); return '' ; }
وفقًا للتعليمات الواردة في التعليقات في النموذج السابق، عليك تحويل الملفات المستهدَفة إلى ملفات "جداول بيانات Google" على Drive.
يتم تمييز معرّفات جداول بيانات 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
بعد ذلك، عدِّل الرمز في دالة "برمجة تطبيقات Google" لفتح الملفات حسب رقم التعريف:
/** * 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، سيؤدي الرمز إلى طرح استثناء. في "برمجة تطبيقات Google"، يعرض الرمز القيمة غير محدّدة.
لتجنُّب نتائج غير متوقّعة، يضيف "محوّل وحدات الماكرو" رمز برمجة تطبيقات الذي يعرض استثناءً إذا حاولت الوصول إلى عناصر خارج حدود مصفوفة.
يظهر هذا المثال في الرمز التالي:
رمز VBA الأصليDim 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));
مقالات ذات صلة
- نظرة عامة على إضافة "محوّل وحدات الماكرو"
- تحديد ما إذا كانت وحدات ماكرو VBA متوافقة
- تحويل وحدات ماكرو VBA إلى "برمجة تطبيقات Google"
- معالجة المشاكل الشائعة
- مشاهدة البرامج التعليمية الخاصة بأداة Macro Converter
- قائمة بواجهات برمجة التطبيقات المتوافقة مع VBA