الدوال المخصصة في "جداول بيانات Google"

يوفر تطبيق "جداول بيانات Google" مئات الوظائف المضمَّنة، مثل AVERAGE وSUM وVLOOKUP. عندما لا تكون هذه متطلباتك كافية، يمكنك استخدام "برمجة تطبيقات Google" لكتابة دوال مخصصة — مثل، تحويل الأمتار إلى أميال أو جلب محتوى مباشر من الإنترنت — ثم استخدامها في "جداول بيانات Google" كوظيفة مضمّنة.

البدء

يتم إنشاء الدوال المخصصة باستخدام جافا سكريبت القياسية. إذا كنت حديث العهد باستخدام جافا سكريبت، فإن Codecademy تقدم دورة تدريبية رائعة للمبتدئين. (ملاحظة: لم يتم تطوير هذه الدورة التدريبية بواسطة Google وليست مرتبطة بها.)

إليك دالة مخصّصة بسيطة اسمها DOUBLE تضرب قيمة الإدخال في 2:

/**
 * Multiplies an input value by 2.
 * @param {number} input The number to double.
 * @return The input multiplied by 2.
 * @customfunction
*/
function DOUBLE(input) {
  return input * 2;
}

إذا كنت لا تعرف كيفية كتابة جافا سكريبت وليس لديك وقت كافٍ لتعلمها، يمكنك مراجعة متجر الإضافات لمعرفة ما إذا كان هناك شخص آخر قد أنشأ الدالة المخصصة التي تحتاج إليها.

إنشاء دالة مخصصة

لكتابة دالة مخصصة:

  1. إنشاء جدول بيانات في "جداول بيانات Google" أو فتحه.
  2. حدد عنصر القائمة الإضافات > برمجة التطبيقات.
  3. احذف أي رمز في محرِّر النص البرمجي. بالنسبة إلى الوظيفة DOUBLE أعلاه، ما عليك سوى نسخ الرمز ولصقه في محرر النص البرمجي.
  4. في أعلى الصفحة، انقر على "حفظ" .

يمكنك الآن استخدام الدالة المخصّصة.

الحصول على دالة مخصصة من Google Workspace Marketplace

يقدم Google Workspace Marketplace العديد من الدوال المخصصة كإضافات لجداول بيانات Google. لاستخدام هذه الإضافات أو استكشافها:

  1. إنشاء جدول بيانات في "جداول بيانات Google" أو فتحه.
  2. في أعلى الصفحة، انقر على الإضافات > الحصول على إضافات.
  3. بعد فتح Google Workspace Marketplace، انقر على مربّع البحث في أعلى يسار الصفحة.
  4. اكتب "دالة مخصصة" واضغط على Enter.
  5. إذا عثرت على إضافة وظائف مخصّصة تهتم بها، انقر على تثبيت لتثبيتها.
  6. قد يخبرك مربع حوار بأن الإضافة تتطلب تفويضًا. إذا كان الأمر كذلك، فاقرأ الإشعار بعناية، ثم انقر على سماح.
  7. تصبح الإضافة متاحة في جدول البيانات. لاستخدام الإضافة في جدول بيانات مختلف، افتح جدول البيانات الآخر، وفي أعلى الصفحة، انقر على الإضافات > إدارة الإضافات. ابحث عن الإضافة التي تريد استخدامها وانقر على رمز الخيارات > استخدام في هذا المستند.

استخدام دالة مخصصة

بعد كتابة دالة مُخصَّصة أو تثبيت دالة من Google Workspace Marketplace، يمكن استخدامها بسهولة كدالة مضمَّنة:

  1. انقر على الخلية التي تريد استخدام الدالة فيها.
  2. اكتب علامة يساوي (=) متبوعة باسم الدالة وأي قيمة إدخال - على سبيل المثال، =DOUBLE(A1) - واضغط على Enter.
  3. ستعرض الخلية Loading... بعد لحظات، ثم تعرض النتيجة.

إرشادات الدوال المخصصة

قبل كتابة الدالة المخصصة بنفسك، هناك بعض الإرشادات الواجب معرفتها.

التسمية

بالإضافة إلى الاصطلاحات القياسية لتسمية دوال جافا سكريبت، يجب الانتباه إلى ما يلي:

  • يجب أن يكون اسم الدالة المخصصة مختلفًا عن أسماء الدوال المضمنة مثل SUM().
  • لا يمكن أن ينتهي اسم الدالة المخصصة بشرطة سفلية (_)، والتي تشير إلى دالة خاصة في برمجة التطبيقات.
  • يجب إعلان اسم الدالة المخصّصة باستخدام البنية function myFunction()، وليس var myFunction = new Function().
  • الكتابة بالأحرف الكبيرة غير مهمة، على الرغم من أن أسماء دوال جداول البيانات عادةً ما تكون بالأحرف الكبيرة.

الوسيطات

مثل الدالة المدمجة، يمكن للدالة المخصصة أن تأخذ وسيطات كقيم إدخال:

  • إذا تم استدعاء الدالة مع مرجع إلى خلية واحدة كوسيطة (مثل =DOUBLE(A1))، فستكون الوسيطة قيمة الخلية.
  • إذا تم استدعاء الدالة مع الإشارة إلى نطاق من الخلايا كوسيطة (مثل =DOUBLE(A1:B10))، فستكون الوسيطة مصفوفة ثنائية الأبعاد لقيم الخلايا. على سبيل المثال، في لقطة الشاشة أدناه، يتم تفسير الوسيطات في =DOUBLE(A1:B2) بواسطة برمجة التطبيقات كـ double([[1,3],[2,4]]). تجدر الإشارة إلى أن نموذج الرمز لـ DOUBLE من أعلاه يجب تعديله لقبول مصفوفة كإدخال.


  • يجب أن تكون وسيطات الدالة المخصّصة محددة. وهذا يعني أن دوال جداول البيانات المدمجة التي تعرض نتيجة مختلفة في كل مرة يتم حسابها، مثل NOW() أو RAND()، غير مسموح بها كوسيطات لدالة مخصّصة. إذا حاولت دالة مخصّصة عرض قيمة استنادًا إلى إحدى هذه الدوال المضمّنة المتغيرة، ستعرض Loading... بدلاً منها.

عرض القيم

يجب أن تعرض كل دالة مخصصة قيمة لعرضها، بحيث:

  • إذا كانت الدالة المخصصة تعرض قيمة، يتم عرض القيمة في الخلية التي تم استدعاء الدالة منها.
  • إذا كانت دالة مخصصة تعرض صفيفًا ثنائي الأبعاد من القيم، فيتم تجاوز القيم إلى الخلايا المجاورة طالما أن هذه الخلايا فارغة. إذا كان ذلك سيؤدي إلى صفيف بدلاً من محتويات الخلايا الحالية، ستعرض الدالة المخصّصة خطأ بدلاً من ذلك. للاطّلاع على مثال، راجع القسم الذي يتناول تحسين الدوال المخصّصة.
  • لا يمكن للدالة المخصّصة التأثير في خلايا بخلاف الخلايا التي تعرض قيمة لها. بمعنى آخر، لا يمكن للدالة المخصّصة تعديل الخلايا العشوائية، بل فقط الخلايا التي تستدعي منها والخلايا المجاورة لها. لتعديل الخلايا العشوائية، استخدم القائمة المخصصة لتشغيل دالة بدلاً من ذلك.
  • يجب أن يتم استدعاء الدالة المخصصة في غضون 30 ثانية. وإذا لم يحدث ذلك، ستعرض الخلية خطأ: Internal error executing the custom function.

أنواع البيانات

تخزّن "جداول بيانات Google" البيانات بتنسيقات مختلفة بناءً على طبيعة البيانات. وعند استخدام هذه القيم في دوال مخصصة، يتعامل معها برمجة التطبيقات على أنها نوع البيانات المناسبة في جافا سكريبت. إليك الجوانب الأكثر شيوعًا من الالتباس:

  • تصبح الأوقات والتواريخ في "جداول البيانات" كائنات التاريخ في "برمجة التطبيقات". إذا كان جدول البيانات والنص البرمجي يستخدمان مناطق زمنية مختلفة (مشكلة نادرة)، فستحتاج الدالة المخصصة إلى التعويض.
  • وتصبح قيم المدة في "جداول البيانات" أيضًا كائنات Date، إلا أن العمل معها يمكن أن يكون معقدًا.
  • تصبح قيم النسبة المئوية في "جداول بيانات Google" أرقامًا عشرية في "برمجة التطبيقات". على سبيل المثال، تصبح قيمة الخلية 10% هي 0.1 في "برمجة التطبيقات".

الإكمال التلقائي

تدعم جداول بيانات Google الإكمال التلقائي للدوال المخصصة تمامًا مثل الوظائف المضمّنة. أثناء كتابة اسم دالة في خلية، ستظهر لك قائمة بالدوال المخصصة والمخصّصة التي تطابق ما أدخلته.

ستظهر الدوال المخصّصة في هذه القائمة إذا كان النص البرمجي يتضمّن علامة JsDoc @customfunction، كما في المثال DOUBLE() أدناه.

/**
 * Multiplies the input value by 2.
 *
 * @param {number} input The value to multiply.
 * @return The input multiplied by 2.
 * @customfunction
 */
function DOUBLE(input) {
  return input * 2;
}

مزايا متقدّمة

استخدام خدمات برمجة تطبيقات Google

يمكن أن تطلب الدوال المخصّصة بعض خدمات "برمجة تطبيقات Google" لتنفيذ مهام أكثر تعقيدًا. على سبيل المثال، يمكن لدالة مخصصة استدعاء خدمة اللغة لترجمة عبارة باللغة الإنجليزية إلى الإسبانية.

بخلاف معظم الأنواع الأخرى من النصوص البرمجية للتطبيقات، فإن الدوال المخصصة لا تطلب من المستخدمين مطلقًا السماح بالدخول إلى البيانات الشخصية. وبالتالي، لا يمكنهم سوى استدعاء الخدمات التي لا يمكنها الوصول إلى البيانات الشخصية، وعلى وجه التحديد ما يلي:

الخدمات المتوافقة ملاحظات
ذاكرة التخزين المؤقت يعمل، ولكنه غير مفيد بشكل خاص في الدوال المخصّصة
HTML يمكن إنشاء HTML، ولكن لا يمكن عرضه (نادرًا ما يكون مفيدًا)
JDBC
اللغة
قفل يعمل، ولكنه غير مفيد بشكل خاص في الدوال المخصّصة
الخرائط إمكانية حساب الاتجاهات، ولكن ليس عرض الخرائط
المواقع يحصل getUserProperties() على خصائص مالك جدول البيانات فقط. لا يمكن لمحرري جداول البيانات تعيين خصائص المستخدمين في وظيفة مخصصة.
جدول بيانات للقراءة فقط (يمكن استخدام معظم طرق get*()، وليس set*()).
لا يمكن فتح جداول بيانات أخرى (SpreadsheetApp.openById() أو SpreadsheetApp.openByUrl()).
جلب عنوان URL
برامج الخدمات
XML

إذا كانت الدالة المخصصة تعرض رسالة الخطأ You do not have permission to call X service.، فإن الخدمة تتطلب تفويض المستخدم، وبالتالي لا يمكن استخدامها في دالة مخصصة.

لاستخدام خدمة بخلاف تلك المذكورة أعلاه، أنشئ قائمة مخصصة تشغّل دالة برمجة التطبيقات بدلاً من كتابة دالة مخصصة. ستطلب الدالة التي يتم تشغيلها من إحدى القوائم من المستخدم التفويض إذا لزم الأمر، ومن ثم يمكن أن تستخدم جميع خدمات "برمجة التطبيقات".

تتمّ مشاركة الأرباح

تبدأ الدوال المخصّصة بربط جدول البيانات الذي تم إنشاؤها فيه. وهذا يعني أنه لا يمكن استخدام وظيفة مخصصة مكتوبة في جدول بيانات واحد في جداول بيانات أخرى ما لم تستخدم إحدى الطرق التالية:

  • انقر على الإضافات > برمجة التطبيقات لفتح محرر النصوص البرمجية، ثم انسخ نص النص البرمجي من جدول البيانات الأصلي والصقه في محرر النص البرمجي لجدول بيانات آخر.
  • أنشئ نسخة من جدول البيانات الذي يحتوي على الوظيفة المخصصة بالنقر على ملف > إنشاء نسخة. عند نسخ جدول بيانات، يتم أيضًا نسخ أي نصوص برمجية مرفقة به. تتوفر إمكانية نسخ النص البرمجي لأي شخص لديه إمكانية الوصول إلى جدول البيانات. (لا يمكن للمتعاونين الذين لديهم إمكانية الدخول للعرض فقط فتح محرر النص البرمجي في جدول البيانات الأصلي. ومع ذلك، عندما ينشئون نسخة، يصبحون مالكي النسخة ويمكنهم الاطّلاع على النص البرمجي).
  • انشر النص البرمجي كـ إضافة محرر في جداول بيانات Google.

التحسين

في كل مرة يتم فيها استخدام دالة مخصصة في جدول بيانات، تُجري "جداول بيانات Google" استدعاءً منفصلاً لخادم برمجة التطبيقات. إذا كان جدول البيانات يحتوي على عشرات (أو مئات أو آلاف) استدعاءات الوظائف المخصصة، يمكن أن تكون هذه العملية بطيئة جدًا.

وبالتالي، إذا كنت تخطط لاستخدام دالة مخصصة عدة مرات على نطاق كبير من البيانات، يمكنك تعديل الدالة بحيث تقبل نطاقًا كإدخال في شكل مصفوفة ثنائية الأبعاد، ثم عرض مصفوفة ثنائية الأبعاد يمكن أن تتدفق إلى الخلايا المناسبة.

على سبيل المثال، يمكن إعادة كتابة الدالة DOUBLE() الموضحة أعلاه لقبول خلية واحدة أو نطاق من الخلايا على النحو التالي:

/**
 * Multiplies the input value by 2.
 *
 * @param {number|Array<Array<number>>} input The value or range of cells
 *     to multiply.
 * @return The input multiplied by 2.
 * @customfunction
 */
function DOUBLE(input) {
  return Array.isArray(input) ?
      input.map(row => row.map(cell => cell * 2)) :
      input * 2;
}

يستخدم الأسلوب أعلاه طريقة map لكائن Array في JavaScript لاستدعاء DOUBLE بشكل متكرر في كل قيمة في المصفوفة ثنائية الأبعاد من الخلايا. وتعرض صفيفًا ثنائي الأبعاد يحتوي على النتائج. بهذه الطريقة، يمكنك استدعاء DOUBLE مرة واحدة فقط ولكن مع حسابها لعدد كبير من الخلايا في وقت واحد، كما هو موضّح في لقطة الشاشة أدناه. (يمكنك إنجاز الأمر نفسه باستخدام عبارات if مدمجة بدلاً من طلب map).

وبالمثل، تجلب الدالة المخصّصة أدناه المحتوى المباشر بكفاءة من الإنترنت، وتستخدم مصفوفة ثنائية الأبعاد لعرض عمودَين من النتائج باستدعاء وظيفة واحدة فقط. إذا تطلبت كل خلية استدعاء الدالة الخاص بها، فستستغرق العملية وقتًا أطول بكثير، نظرًا لأن خادم برمجة التطبيقات سيضطر إلى تنزيل خلاصة XML وتحليلها في كل مرة.

/**
 * Show the title and date for the first page of posts on the
 * Developer blog.
 *
 * @return Two columns of data representing posts on the
 *     Developer blog.
 * @customfunction
 */
function getBlogPosts() {
  var array = [];
  var url = 'https://gsuite-developers.googleblog.com/atom.xml';
  var xml = UrlFetchApp.fetch(url).getContentText();
  var document = XmlService.parse(xml);
  var root = document.getRootElement();
  var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
  var entries = document.getRootElement().getChildren('entry', atom);
  for (var i = 0; i < entries.length; i++) {
    var title = entries[i].getChild('title', atom).getText();
    var date = entries[i].getChild('published', atom).getValue();
    array.push([title, date]);
  }
  return array;
}

يمكن تطبيق هذه التقنيات تقريبًا على أي دالة مخصصة يتم استخدامها بشكل متكرر عبر جدول بيانات، على الرغم من أن تفاصيل التنفيذ ستختلف اعتمادًا على سلوك الدالة.