أساسيات برمجة التطبيقات باستخدام جداول بيانات Google #3: العمل باستخدام البيانات

1. مقدمة

مرحبًا بك في الجزء الثالث من أساسيات برمجة التطبيقات مع قائمة تشغيل الدروس التطبيقية حول ترميز "جداول بيانات Google".

من خلال إكمال هذا الدرس التطبيقي حول الترميز، يمكنك معرفة كيفية استخدام معالجة البيانات والقوائم المخصّصة واسترداد بيانات واجهة برمجة التطبيقات العامة في"برمجة تطبيقات Google"لتحسين أداء"جداول بيانات Google". ستواصل العمل على دروس الدروس التطبيقية السابقة في قائمة التشغيل هذه من خلال SpreadsheetApp وSpreadsheet وSheet وRange.

ما ستتعرَّف عليه

  • كيفية استيراد البيانات من جدول بيانات شخصي أو مشترك في Drive.
  • كيفية إنشاء قائمة مخصّصة باستخدام الدالة onOpen().
  • كيفية تحليل قيم بيانات السلسلة ومعالجتها في خلايا جدول بيانات Google.
  • كيفية سحب بيانات عنصر JSON ومعالجتها من مصدر واجهة برمجة تطبيقات عام.

قبل البدء

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

  1. وحدات الماكرو والدوال المخصصة
  2. جداول البيانات وجداول البيانات والنطاقات

الأشياء التي تحتاج إليها

  • فهم المواضيع الأساسية لبرمجة التطبيقات التي تم استكشافها في الدروس التطبيقية حول الترميز السابقة لقائمة التشغيل هذه.
  • دراية أساسية بمحرِّر "برمجة تطبيقات Google"
  • إلمام أساسي بـ جداول بيانات Google
  • إمكانية قراءة تدوين A1 في "جداول بيانات Google"
  • الإلمام بأساسيات JavaScript وفئة String

2. إعداد

تتطلب التمارين في هذا الدرس التطبيقي ترميز جدول بيانات للعمل فيه. اتّبع الخطوات التالية لإنشاء جدول بيانات لاستخدامه في هذه التمارين:

  1. إنشاء جدول بيانات في Google Drive. ويمكنك إجراء ذلك من واجهة Drive عن طريق تحديد جديد &gt؛ جداول بيانات Google. سيؤدي هذا إلى إنشاء جدول البيانات الجديد وفتحه. يُحفظ الملف في مجلد Drive.
  2. انقر على عنوان جدول البيانات وغيّره من &quot؛جدول بيانات&بلا عنوان&;;&&;;&&;&;&pوفيوديوم تلاعب في البيانات وقوائم مخصصة يجب أن تبدو الورقة على النحو التالي:

545c02912de7d112.png

  1. لفتح محرِّر النص البرمجي، انقر على الإضافات > برمجة التطبيقات
  2. انقر على عنوان مشروع "برمجة التطبيقات" وغيِّره من "المشروع& دون عنوان"؛ انقر على إعادة تسمية لحفظ تغيير العنوان.

باستخدام جدول بيانات ومشروع فارغ، تكون مستعدًا لبدء الدرس التطبيقي. انتقِل إلى القسم التالي لبدء التعرّف على القوائم المخصّصة.

3- نظرة عامة: استيراد البيانات باستخدام عنصر مخصّص في القائمة

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

d6b694da6b8c6783.png

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

يتم تحديد عناصر القائمة المخصصة في الدالة onOpen() المشغّل البسيط، والتي ستعرفها في القسم التالي.

4. دالة onOpen()

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

onOpen() مثال على التشغيل البسيط. إنها سهلة الإعداد، كل ما عليك فعله هو كتابة وظيفة "برمجة التطبيقات" باسم onOpen() وتعمل "برمجة التطبيقات" على تشغيلها في كل مرة يتم فيها فتح جدول البيانات المرتبط أو إعادة تحميله:

/**
 * A special function that runs when the spreadsheet is first
 * opened or reloaded. onOpen() is used to add custom menu
 * items to the spreadsheet.
 */
function onOpen() {
 /* ... */ 
}

التنفيذ

لنبدأ قائمة مخصصة.

  1. استبدل الرمز في مشروع النص البرمجي بما يلي:
/**
 * A special function that runs when the spreadsheet is first
 * opened or reloaded. onOpen() is used to add custom menu
 * items to the spreadsheet.
 */
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Book-list')
    .addItem('Load Book-list', 'loadBookList')
    .addToUi();
}
  1. احفظ مشروع النص البرمجي.

مراجعة الرموز

لنراجع هذا الرمز لفهم آلية عمله. في onOpen()، يستخدم السطر الأول طريقة getUi() لاكتساب عنصر Ui الذي يمثل واجهة المستخدم لجدول البيانات النشط الذي يرتبط به هذا النص البرمجي.

تنشئ الأسطر الثلاثة التالية القائمة (Book-list)، وأضِف عنصرًا إلى القائمة (Load Book-list) إلى تلك القائمة، ثم أضِف القائمة إلى واجهة جدول البيانات. ويتم هذا باستخدام الطرق createMenu(caption) وaddItem(caption, functionName) وaddToUi() على التوالي.

تنشئ الطريقة addItem(caption, functionName) اتصالاً بين تصنيف عنصر القائمة ودالة برمجة التطبيقات التي تعمل عند اختيار عنصر القائمة. في هذه الحالة، يؤدي اختيار عنصر القائمة Load Book-list إلى محاولة "جداول بيانات Google" تشغيل الدالة loadBookList() (وهي غير متوفّرة بعد).

النتائج

شغّل هذه الدالة الآن للتأكد من أنها تعمل:

  1. في "جداول بيانات Google"، أعِد تحميل جدول البيانات. ملاحظة: يؤدي هذا عادةً إلى إغلاق علامة التبويب في محرر النصوص البرمجية.
  2. أعِد فتح محرِّر النصوص البرمجية من خلال اختيار الأدوات &gt، محرِّر النصوص البرمجية.

بعد إعادة تحميل جدول البيانات، ستظهر قائمة Book-list الجديدة في شريط القوائم:

687dfb214f2930ba.png

عند النقر على قائمة الكتب، يمكنك الاطّلاع على القائمة الناتجة:

8a4a391fbabcb16a.png

ينشئ القسم التالي رمز الدالة loadBookList() ويقدّم طريقة واحدة للتفاعل مع البيانات في "برمجة التطبيقات": قراءة جداول البيانات الأخرى.

5. استيراد بيانات جدول البيانات

الآن وبعد أن أنشأت قائمة مخصّصة، يمكنك إنشاء وظائف يمكن تشغيلها من خلال النقر على عنصر القائمة.

الآن، تتضمن القائمة المخصصة Book-list عنصر قائمة واحدًا: Load Book-list. الدالة التي يتم استدعاؤها عند اختيار عنصر القائمة Load Book-list، loadBookList(), غير موجودة في النص البرمجي، لذا يؤدي اختيار قائمة الكتب &gt؛ تحميل قائمة الكتب إلى حدوث خطأ:

b94dcef066e7041d.gif

يمكنك إصلاح هذا الخطأ عن طريق تنفيذ دالة loadBookList().

التنفيذ

ترغب في أن يملأ عنصر القائمة الجديد جدول البيانات بالبيانات التي تعمل بها، لذلك ستنفِّذ loadBookList() لقراءة بيانات الكتاب من جدول بيانات آخر ونسخه في هذا الجدول:

  1. أضف الرمز التالي إلى النص البرمجي ضمن onOpen():
/** 
 * Creates a template book list based on the
 * provided 'codelab-book-list' sheet.
 */
function loadBookList(){
  // Gets the active sheet.
  var sheet = SpreadsheetApp.getActiveSheet();
  
  // Gets a different spreadsheet from Drive using
  // the spreadsheet's ID. 
  var bookSS = SpreadsheetApp.openById(
    "1c0GvbVUDeBmhTpq_A3vJh2xsebtLuwGwpBYqcOBqGvo" 
  );

  // Gets the sheet, data range, and values of the
  // spreadsheet stored in bookSS.
  var bookSheet = bookSS.getSheetByName("codelab-book-list");
  var bookRange = bookSheet.getDataRange();
  var bookListValues = bookRange.getValues();

  // Add those values to the active sheet in the current
  // spreadsheet. This overwrites any values already there.
  sheet.getRange(1, 1, bookRange.getHeight(), bookRange.getWidth()) 
    .setValues(bookListValues);
  
  // Rename the destination sheet and resize the data
  // columns for easier reading.
  sheet.setName("Book-list");
  sheet.autoResizeColumns(1, 3);
}
  1. احفظ مشروع النص البرمجي.

مراجعة الرموز

ما هي آلية عمل هذه الدالة؟ تستخدم الدالة loadBookList() طرقًا أساسية من الصفوف الدراسية Spreadsheet وSheet وRange التي تقدّمها الدروس التطبيقية السابقة حول الترميز. مع أخذ هذه المفاهيم في الاعتبار، يمكنك تقسيم رمز loadBookList() إلى الأقسام الأربعة التالية:

1: تحديد جدول البيانات

يستخدم السطر الأول SpreadsheetApp.getActiveSheet() للحصول على مرجع إلى عنصر الورقة الحالي ويخزّنه في المتغيّر sheet. هذه هي الورقة التي سيتم نسخ البيانات إليها.

2: تحديد بيانات المصدر

تنشئ الأسطر القليلة التالية أربعة متغيّرات تشير إلى بيانات المصدر التي تستردها:

  • تخزّن bookSS مرجعًا إلى جدول البيانات الذي يقرأ الرمز البيانات منه. يعثر الرمز على جدول البيانات باستخدام رقم تعريف جدول البيانات. في هذا المثال، قدّمنا معرّف جدول البيانات المصدر للقراءة منه، ونفتح جدول البيانات باستخدام طريقة SpreadsheetApp.openById(id).
  • تخزّن bookSheet مرجعًا إلى ورقة داخل bookSS تحتوي على البيانات التي تريدها. يحدِّد الرمز الورقة التي ستتم القراءة منها حسب اسمها، codelab-book-list.
  • تخزّن bookRange مرجعًا لمجموعة من البيانات في bookSheet. تعرض الطريقة Sheet.getDataRange() النطاق الذي يحتوي على جميع الخلايا غير الفارغة في الورقة. إنها طريقة سهلة للتأكد من الحصول على نطاق يغطي جميع البيانات في ورقة بدون تضمين صفوف وأعمدة فارغة.
  • bookListValues هو مصفوفة ثنائية الأبعاد تحتوي على جميع القيم التي تم الحصول عليها من الخلايا في bookRange. تُنشئ طريقة Range.getValues() هذه المصفوفة من خلال قراءة البيانات من ورقة البيانات المصدر.

3: نسخ البيانات من المصدر إلى الوجهة

ينسخ قسم الرمز التالي بيانات bookListValues إلى sheet، ثم يعيد تسمية الورقة أيضًا:

4: تنسيق الورقة المقصودة

تُستخدم Sheet.setName(name) لتغيير اسم ورقة الوجهة إلى Book-list. يستخدم السطر الأخير في الدالة Sheet.autoResizeColumns(startColumn, numColumns) لتغيير حجم الأعمدة الثلاثة الأولى في ورقة الوجهة، ما يسمح لك بقراءة البيانات الجديدة بسهولة أكبر.

النتائج

يمكنك الاطّلاع على هذه الدالة وهي تعمل. في "جداول بيانات Google"، اختَر قائمة الكتب &gt؛ تحميل قائمة الكتب لتشغيل الدالة لملء جدول البيانات:

3c797e1e2b9fe641.gif

لديك الآن ورقة تتضمن قائمة بعناوين الكتب والمؤلفين وأرقام ISBN المكوّنة من 13 رقمًا. في القسم التالي، ستتعرّف على كيفية تعديل البيانات وتعديلها في قائمة الكتب هذه باستخدام معالجة السلاسل والقوائم المخصّصة.

6- نظرة عامة: محو بيانات جدول البيانات

لديك الآن معلومات عن الكتاب في ورقة بياناتك. يشير كل صف إلى كتاب معين، ويدرج عنوانه، ومؤلفه، ورقم ISBN في أعمدة منفصلة. ومع ذلك، يمكنك أيضًا الاطلاع على بعض المشاكل المتعلقة بهذه البيانات الأولية:

  1. بالنسبة إلى بعض الصفوف، يتم وضع العنوان والمؤلف معًا في عمود العنوان، ويكون ذلك مرتبطًا بفاصلة أو السلسلة &;;&;;.
  2. بعض الكتب تفتقد إلى عنوان الكتاب أو مؤلفه.

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

7- إضافة أصناف في القائمة

يجب إنشاء ثلاثة عناصر في القائمة للتحكم في عمليات تنظيف البيانات التي ستنفذها.

التنفيذ

يجب تحديث onOpen() لتضمين عناصر القائمة الإضافية التي ستحتاج إليها. فعليك إجراء ما يلي:

  1. في مشروع النص البرمجي، عدّل رمز onOpen() لمطابقة ما يلي:
/**
 * A special function that runs when the spreadsheet is first
 * opened or reloaded. onOpen() is used to add custom menu
 * items to the spreadsheet.
 */
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Book-list')
    .addItem('Load Book-list', 'loadBookList')
    .addSeparator()
    .addItem(
      'Separate title/author at first comma', 'splitAtFirstComma')
    .addItem(
      'Separate title/author at last "by"', 'splitAtLastBy')
    .addSeparator()
    .addItem(
      'Fill in blank titles and author cells', 'fillInTheBlanks')
    .addToUi();
}
  1. احفظ مشروع النص البرمجي.
  2. في محرِّر النص البرمجي، اختَر onOpen من قائمة الدوال وانقر على تشغيل. سيؤدي هذا إلى تشغيل onOpen() لإعادة إنشاء قائمة جداول البيانات كي لا تضطر إلى إعادة تحميل جدول البيانات.

في هذا الرمز الجديد، تُنشئ طريقة Menu.addSeparator() فاصلاً أفقيًا في القائمة للحفاظ على تنظيم عناصر القائمة ذات الصلة بصريًا. بعد ذلك، تتم إضافة عناصر القائمة الجديدة التي تتضمّن التصنيفات Separate title/author at first comma وSeparate title/author at last "by" وFill in blank titles and author cells.

النتائج

في جدول البيانات، انقر على قائمة Book-list لعرض عناصر القائمة الجديدة:

580c806ce8fd4872.png

يؤدي النقر على هذه العناصر الجديدة إلى حدوث خطأ نظرًا لأنك لم تنفِّذ الوظائف المقابلة لها، لذلك دعنا نفعل ذلك بعد ذلك.

8- تقسيم النص على محدِّدات الفاصلة

تحتوي مجموعة البيانات التي تم استيرادها في جدول البيانات على بضع خلايا يتم فيها دمج المؤلف والعنوان بشكلٍ غير صحيح في خلية واحدة باستخدام فاصلة:

ca91c43c4e51d6b5.png

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

ابدأ في تنظيف بياناتك من خلال تنفيذ دالة باسم splitAtFirstComma() تقسِّم المؤلف والعنوان إلى الخلايا المناسبة عند العثور على الفواصل.

يجب أن تتخذ الدالة splitAtFirstComma() الخطوات التالية:

  1. الحصول على النطاق الذي يمثل الخلايا المحددة حاليًا.
  2. تحقّق مما إذا كانت الخلايا في النطاق تحتوي على فاصلة.
  3. في حال العثور على الفواصل، قسِّم السلسلة إلى سلسلتَين فرعيّتَين (واثنتان فقط) في موقع الفاصلة الأولى. لتبسيط الأمور، يمكنك افتراض أن أي فاصلة تشير إلى &&;;[authors], [title]" نمط سلسلة. يمكنك أيضًا افتراض ما إذا كانت الفواصل المتعددة تظهر في الخلية، سيكون من المناسب التقسيم إلى الفاصلة الأولى في السلسلة.
  4. اضبط السلاسل الفرعية على أنها المحتوى الجديد للخلايا الخاصة بالعنوان والمؤلف المعني.

التنفيذ

لتنفيذ هذه الخطوات، سيلزمك استخدام طرق خدمة جداول البيانات نفسها التي استخدمتها من قبل، ولكن ستحتاج أيضًا إلى استخدام JavaScript للتلاعب ببيانات السلسلة. اتّبِع الخطوات التالية:

  1. في محرِّر "برمجة تطبيقات Google"، أضِف الدالة التالية إلى نهاية مشروع النص البرمجي:
/**
 * Reformats title and author columns by splitting the title column
 * at the first comma, if present.
 */
function splitAtFirstComma(){
  // Get the active (currently highlighted) range.
  var activeRange = SpreadsheetApp.getActiveRange();
  var titleAuthorRange = activeRange.offset(
    0, 0, activeRange.getHeight(), activeRange.getWidth() + 1);

  // Get the current values of the selected title column cells.
  // This is a 2D array.
  var titleAuthorValues = titleAuthorRange.getValues();

  // Update values where commas are found. Assumes the presence
  // of a comma indicates an "authors, title" pattern.
  for (var row = 0; row < titleAuthorValues.length; row++){
    var indexOfFirstComma =
        titleAuthorValues[row][0].indexOf(", ");

    if(indexOfFirstComma >= 0){
      // Found a comma, so split and update the values in
      // the values array.
      var titlesAndAuthors = titleAuthorValues[row][0];

      // Update the title value in the array.
      titleAuthorValues[row][0] =
        titlesAndAuthors.slice(indexOfFirstComma + 2);

      // Update the author value in the array.
      titleAuthorValues[row][1] =
        titlesAndAuthors.slice(0, indexOfFirstComma);
    }
  }

  // Put the updated values back into the spreadsheet.
  titleAuthorRange.setValues(titleAuthorValues);
}
  1. احفظ مشروع النص البرمجي.

مراجعة الرموز

لنراجع الرمز الجديد الذي يتألف من ثلاثة أقسام رئيسية:

1: استرداد قيم العناوين التي تم تمييزها

تنشئ الأسطر الثلاثة الأولى ثلاثة متغيّرات تشير إلى البيانات الحالية في جدول البيانات:

  • تمثّل القيمة activeRange النطاق الذي ميّزه المستخدم حاليًا عند استدعاء الدالة splitAtFirstComma(). للحفاظ على سهولة هذا التمرين، يمكننا افتراض أن المستخدم لا ينفذ ذلك إلا عند تمييز الخلايا في العمود (أ).
  • تمثل titleAuthorRange نطاقًا جديدًا يغطي الخلايا نفسها مثل activeRange، ولكنه يتضمن أيضًا عمودًا آخر إلى اليسار. تم إنشاء titleAuthorRange باستخدام طريقة Range.offset(rowOffset, columnOffset, numRows, numColumns). يحتاج الرمز إلى هذا النطاق الموسّع لأنه يحتاج إلى مكان لإضافة أي مؤلفين يعثر عليهم في عمود العنوان.
  • titleAuthorValues هي مصفوفة ثنائية الأبعاد من البيانات المستخلَصة من titleAuthorRange باستخدام Range.getValues().

2: فحص كل عنوان وتقسيمه وفقًا لمحدِّد الفاصلة الأول

يفحص القسم التالي القيم في titleAuthorValues للبحث عن الفواصل. يتم استخدام JavaScript For Loop لفحص جميع القيم في العمود الأول من titleAuthorValues. عند العثور على سلسلة فرعية بفاصلة (", ") باستخدام طريقة JavaScript String indexOf()، تجري الرموز ما يلي:

  1. تم نسخ قيمة سلسلة الخلية إلى المتغير titlesAndAuthors.
  2. يتم تحديد موقع الفاصلة باستخدام الطريقة JavaScript String indexOf().
  3. يتم طلب طريقة JavaScript String string() مرتين للحصول على السلسلة الفرعية قبل محدِّد الفاصلة والسلسلة الفرعية بعد المحدِّد.
  4. يتم نسخ السلاسل الفرعية مرة أخرى إلى مصفوفة titleAuthorValues 2D، مما يؤدي إلى استبدال القيم الحالية في ذلك الموضع. وبما أنّنا'نفترض أنّه &&br;[authors], [title]" ,يتم عكس ترتيب الشريحتَين الفرعيتَين لوضع العنوان في العمود الأول والمؤلفين في العمود الثاني.

ملاحظة: عندما لا تعثر الشفرة على فاصلة، فإنها تترك البيانات في الصف بدون تغيير.

3: نسخ القيم الجديدة مرة أخرى إلى الورقة

بعد فحص جميع قيم خلايا العناوين، يتم إعادة نسخ مصفوفة titleAuthorValues 2D المعدَّلة إلى جدول البيانات باستخدام طريقة Range.setValues(values).

النتائج

يمكنك الآن الاطّلاع على تأثيرات الدالة splitAtFirstComma() أثناء استخدامها. يمكنك تشغيل العنصر عن طريق اختيار عنصر القائمة عنوان/مؤلف منفصل بعد الفاصلة...

...خلية واحدة:

a24763b60b305376.gif

...أو خلايا متعددة:

89c5c89b357d3713.gif

لقد أنشأت الآن وظيفة برمجة التطبيقات التي تعالج بيانات "جداول بيانات Google". بعد ذلك، ستنفِّذ دالة التقسيم الثانية.

9- تقسيم النص على &المحددات

عند الاطّلاع على البيانات الأصلية، يمكنك ملاحظة مشكلة أخرى. تمامًا مثل بعض عناوين البيانات والمؤلفين في خلية واحدة مثل "[authors], [title]", يبدأ تنسيق المؤلف والعنوان في الخلايا الأخرى باسم "[title] بواسطة [authors]":

41f0dd5ac63b62f4.png

التنفيذ

يمكنك حلّ هذه المشكلة باستخدام الأسلوب نفسه من القسم الأخير، ما يؤدي إلى إنشاء دالة باسم splitAtLastBy(). تؤدي هذه الدالة وظيفة مشابهة لـ splitAtFirstComma()، والفرق الوحيد هو البحث عن نمط مختلف قليلاً من النص. نفِّذ هذه الدالة عن طريق إجراء ما يلي:

  1. في محرِّر "برمجة تطبيقات Google"، أضِف الدالة التالية إلى نهاية مشروع النص البرمجي:
/** 
 * Reformats title and author columns by splitting the title column
 * at the last instance of the string " by ", if present.
 */
function splitAtLastBy(){
  // Get the active (currently highlighted) range.
  var activeRange = SpreadsheetApp.getActiveRange();
  var titleAuthorRange = activeRange.offset(
    0, 0, activeRange.getHeight(), activeRange.getWidth() + 1);

  // Get the current values of the selected title column cells.
  // This is a 2D array.
  var titleAuthorValues = titleAuthorRange.getValues();

  // Update values where " by " substrings are found. Assumes
  // the presence of a " by " indicates a "title by authors"
  // pattern.
  for(var row = 0; row < titleAuthorValues.length; row++){
    var indexOfLastBy =
        titleAuthorValues[row][0].lastIndexOf(" by ");
    
    if(indexOfLastBy >= 0){
      // Found a " by ", so split and update the values in
      // the values array.
      var titlesAndAuthors = titleAuthorValues[row][0];
      
      // Update the title value in the array.
      titleAuthorValues[row][0] =
        titlesAndAuthors.slice(0, indexOfLastBy);
      
      // Update the author value in the array.
      titleAuthorValues[row][1] =
        titlesAndAuthors.slice(indexOfLastBy + 4);
    }
  }

  // Put the updated values back into the spreadsheet.
  titleAuthorRange.setValues(titleAuthorValues);
}
  1. احفظ مشروع النص البرمجي.

مراجعة الرموز

هناك بعض الاختلافات الرئيسية بين هذا الرمز وsplitAtFirstComma():

  1. يتم استخدام السلسلة الفرعية &quot؛ by " كمحدِّد سلسلة بدلاً من &", ".
  2. في هذه الحالة، يتم استخدام طريقة JavaScript String.lastIndexOf(substring) بدلاً من String.indexOf(substring). ويعني ذلك أنّه في حال توفّر سلاسل متعدّدة من "&"، أو "by" في السلسلة الأوّلية، يُفترض أنّ جميع هذه السلاسل الفرعية باستثناء "الأخيرة"؛ by &&، كجزء من العنوان.
  3. بعد تقسيم السلسلة، يتم ضبط السلسلة الفرعية الأولى كعنوان والثاني كمؤلف (هذا هو الترتيب المقابل من splitAtFirstComma()).

النتائج

يمكنك الآن الاطّلاع على تأثيرات الدالة splitAtLastBy() أثناء استخدامها. يمكنك محاولة تشغيله من خلال تحديد عنصر القائمة عنوان أو مؤلف منفصل في نهاية الأمر&;;by" بعد تحديد...

...خلية واحدة:

ee6679e134145975.gif

...أو خلايا متعددة:

3c879c572c61e62f.gif

لقد أكملت هذا القسم من الدرس التطبيقي حول الترميز. يمكنك الآن استخدام برمجة التطبيقات لقراءة بيانات السلسلة وتعديلها في ورقة، واستخدام القوائم المخصصة لتنفيذ أوامر برمجة تطبيقات مختلفة.

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

10- نظرة عامة: الحصول على بيانات من واجهات برمجة التطبيقات المتاحة للجميع

حتى الآن، تم تحسين مجموعة بياناتك لإصلاح بعض مشاكل تنسيق العناوين والمؤلف، ولكن لا تزال مجموعة البيانات تنقصها بعض المعلومات، وقد تم تمييزها في الخلايا أدناه:

af0dba8cb09d1a49.png

لا يمكنك الحصول على البيانات المفقودة باستخدام عمليات السلسلة على البيانات المتوفرة لديك حاليًا. بدلاً من ذلك، ستحتاج إلى الحصول على البيانات المفقودة من مصدر آخر. ويمكنك إجراء ذلك في "برمجة التطبيقات" من خلال طلب المعلومات من واجهات برمجة التطبيقات الخارجية التي يمكنها توفير بيانات إضافية.

APIs هي واجهات برمجة تطبيقات. إنّه مصطلح عام، إلا أنّه في الأساس عبارة عن خدمة يُمكن لبرامجك ونصوصك البرمجية الاتصال بها لطلب معلومات أو لاتخاذ إجراءات معيّنة. في هذا القسم، إنك تطلب واجهة برمجة تطبيقات متاحة للجميع لطلب معلومات الكتاب التي يمكنك إدراجها في الخلايا الشاغرة في ورقة بياناتك.

يوضّح لك هذا القسم كيفية:

  • طلب بيانات الكتاب من مصدر واجهة برمجة تطبيقات خارجي
  • يمكنك استخراج معلومات العنوان والمؤلف من البيانات المعروضة وكتابتها في جدول البيانات.

11- استرجاع البيانات الخارجية باستخدام UrlFetch

قبل الانتقال إلى رمز يعمل مباشرةً مع جدول البيانات، يمكنك التعرّف على كيفية استخدام واجهات برمجة التطبيقات الخارجية في "برمجة التطبيقات" من خلال إنشاء دالة مساعد تحديدًا من أجل طلب معلومات الكتاب من Open Library API المتاحة للجميع.

تأخذ الدالة المساعدة، fetchBookData_(ISBN)، رقم ISBN للكتاب المكوّن من 13 رقمًا كمَعلمة وتعرض بيانات عن هذا الكتاب. فهو يتصل بالمعلومات ويستردها من واجهة برمجة التطبيقات للمكتبة المفتوحة ثم يحلل عنصر JSON المعروض.

التنفيذ

يمكنك تنفيذ هذه الوظيفة المساعدة عن طريق إجراء ما يلي:

  1. في محرِّر "برمجة تطبيقات Google"، أضِف الرمز التالي إلى نهاية النص البرمجي:
/**
 * Helper function to retrieve book data from the Open Library
 * public API.
 *
 * @param {number} ISBN - The ISBN number of the book to find.
 * @return {object} The book's data, in JSON format.
 */
function fetchBookData_(ISBN){
  // Connect to the public API.
  var url = "https://openlibrary.org/api/books?bibkeys=ISBN:"
      + ISBN + "&jscmd=details&format=json";
  var response = UrlFetchApp.fetch(
      url, {'muteHttpExceptions': true});
  
  // Make request to API and get response before this point.
  var json = response.getContentText();
  var bookData = JSON.parse(json); 
  
  // Return only the data we're interested in.
  return bookData['ISBN:' + ISBN];
}
  1. احفظ مشروع النص البرمجي.

مراجعة الرموز

ينقسم هذا الرمز إلى قسمَين رئيسيَين:

1: طلب البيانات من واجهة برمجة التطبيقات

في السطرين الأولين، يتصل fetchBookData_(ISBN) بواجهة برمجة تطبيقات Open Library العامة باستخدام نقطة نهاية عنوان URL لواجهة برمجة التطبيقات وبرمجة تطبيقات Google.

المتغير url ما هو إلا سلسلة عناوين URL، مثل عنوان ويب. وهو يشير إلى موقع جغرافي على خوادم "المكتبة المفتوحة". تتضمن أيضًا ثلاث معلّمات (bibkeys وjscmd وformat) تُعلم خوادم "المكتبة المفتوحة" بالمعلومات التي تطلبها وكيفية تنظيم الاستجابة. في هذه الحالة، تقدّم رقم ISBN للكتاب وتطلب عرض معلومات مفصّلة بتنسيق JSON.

بعد إنشاء سلسلة عنوان URL، يرسل الرمز طلبًا إلى الموقع وتلقّي ردًّا. ويتم ذلك باستخدام طريقة UrlFetchApp.fetch(url, params). تُرسِل هذه الميزة طلب معلومات إلى عنوان URL الخارجي الذي قدمته وتخزِّن الرد الناتج في المتغير response. بالإضافة إلى عنوان URL، يضبط الرمز المعلّمة الاختيارية muteHttpExceptions على true. ويعني هذا الإعداد أن الرمز لن يتوقف إذا نتج عن الطلب خطأ في واجهة برمجة التطبيقات. بدلاً من ذلك، يتم عرض استجابة الخطأ.

يعرض الطلب كائن HTTPResponse المخزّن في المتغير response. تتضمن استجابات HTTP رمز استجابة وعناوين HTTP ومحتوى الاستجابة الرئيسي. المعلومات المهمّة هنا، وهي محتوى JSON الرئيسي، لذا يجب أن يستخرج الرمز ذلك الرمز ثم يحلّل JSON لتحديد المعلومات المطلوبة وعرضها.

2: تحليل استجابة واجهة برمجة التطبيقات وعرض معلومات الاهتمام

في آخر ثلاثة أسطر من الرمز، تعرض طريقة HTTPResponse.getContentText() المحتوى الرئيسي للاستجابة كسلسلة. هذه السلسلة بتنسيق JSON، ولكن واجهة برمجة التطبيقات المفتوحة في المكتبة تحدِّد المحتوى والتنسيق بالضبط. تحوِّل الطريقة JSON.parse(jsonString) سلسلة JSON إلى كائن JavaScript، بحيث يمكن استخراج أجزاء مختلفة من البيانات بسهولة. وأخيرًا، تعرض الدالة البيانات المقابلة لرقم ISBN للكتاب.

النتائج

الآن وبعد تنفيذ fetchBookData_(ISBN)، يمكن أن تجد وظائف أخرى في رمزك معلومات عن أي كتاب باستخدام رقم ISBN. ستستخدم هذه الدالة للمساعدة على ملء الخلايا في جدول البيانات.

12- كتابة بيانات واجهة برمجة التطبيقات في جدول بيانات

يمكنك الآن تنفيذ دالة fillInTheBlanks() التي تنفّذ ما يلي:

  1. حدِّد العنوان المفقود وبيانات المؤلف ضمن نطاق البيانات النشط.
  2. يمكنك استرداد بيانات كتاب مفقود من خلال الاتصال بـ Open Library API باستخدام طريقة المساعد fetchBookData_(ISBN).
  3. تعديل قيم العنوان أو المؤلف غير المتوفرة في الخلايا المناسبة.

التنفيذ

نفِّذ هذه الدالة الجديدة عن طريق إجراء ما يلي:

  1. في محرِّر "برمجة تطبيقات Google"، أضِف الرمز التالي إلى نهاية مشروع النص البرمجي:
/**
 * Fills in missing title and author data using Open Library API
 * calls.
 */ 
function fillInTheBlanks(){
  // Constants that identify the index of the title, author,
  // and ISBN columns (in the 2D bookValues array below). 
  var TITLE_COLUMN = 0;
  var AUTHOR_COLUMN = 1;
  var ISBN_COLUMN = 2;

  // Get the existing book information in the active sheet. The data
  // is placed into a 2D array.
  var dataRange = SpreadsheetApp.getActiveSpreadsheet()
    .getDataRange();
  var bookValues = dataRange.getValues();

  // Examine each row of the data (excluding the header row).
  // If an ISBN is present, and a title or author is missing,
  // use the fetchBookData_(isbn) method to retrieve the
  // missing data from the Open Library API. Fill in the
  // missing titles or authors when they're found.
  for(var row = 1; row < bookValues.length; row++){   
    var isbn = bookValues[row][ISBN_COLUMN];
    var title = bookValues[row][TITLE_COLUMN];
    var author = bookValues[row][AUTHOR_COLUMN];
   
    if(isbn != "" && (title === "" || author === "") ){
      // Only call the API if you have an ISBN number and
      // either the title or author is missing.
      var bookData = fetchBookData_(isbn);

      // Sometimes the API doesn't return the information needed.
      // In those cases, don't attempt to update the row.
      if (!bookData || !bookData.details) {
        continue;
      }

      // The API might not return a title, so only fill it in
      // if the response has one and if the title is blank in
      // the sheet.
      if(title === "" && bookData.details.title){
        bookValues[row][TITLE_COLUMN] = bookData.details.title; 
      }

      // The API might not return an author name, so only fill it in
      // if the response has one and if the author is blank in
      // the sheet.
      if(author === "" && bookData.details.authors
          && bookData.details.authors[0].name){
        bookValues[row][AUTHOR_COLUMN] =
          bookData.details.authors[0].name; 
      }
    }
  }
  
  // Insert the updated book data values into the spreadsheet.
  dataRange.setValues(bookValues);
}
  1. احفظ مشروع النص البرمجي.

مراجعة الرموز

ينقسم هذا الرمز إلى ثلاثة أقسام:

1: قراءة معلومات الكتاب الحالية

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

2: استرجاع المعلومات المفقودة باستخدام الدالة المساعد

يتكرّر الرمز فوق كل صف في bookValues للبحث عن العناوين المفقودة أو المؤلفين. لتقليل عدد طلبات البيانات من واجهة برمجة التطبيقات مع تحسين الكفاءة، لا يطلب الرمز سوى واجهة برمجة التطبيقات في الحالات التالية:

  1. يحتوي عمود "رقم ISBN للصف" على قيمة.
  2. العنوان أو خلية المؤلف في الصف فارغة.

في حال كانت الشروط صحيحة، تطلب الرمز واجهة برمجة التطبيقات باستخدام الدالة المساعد fetchBookData_(isbn) التي تم تنفيذها سابقًا، وتخزّن النتيجة في المتغير bookData. يجب أن يحتوي الآن على المعلومات المفقودة التي تريد إدراجها في الورقة.

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

للتأكُّد من قدرة الرمز على التعامل مع أخطاء واجهة برمجة التطبيقات، يجب أن يتحقّق الرمز من استجابة واجهة برمجة التطبيقات صالحة قبل محاولة استخدامها. بعد أن يتضمّن الرمز bookData، يجري فحصًا بسيطًا للتحقّق من توفّر bookData وbookData.details قبل محاولة القراءة منه. ويعني عدم توفّر أي منهما أنّ واجهة برمجة التطبيقات لم تتضمّن البيانات التي تريدها. في هذه الحالة، يطلب الأمر continue الرمز لتخطّي هذا الصف، ولا يمكنك ملء الخلايا المفقودة، ولكن على الأقل لن يتم تعطّل النص البرمجي.

3: كتابة المعلومات المحدّثة مرة أخرى في الورقة

يحتوي الجزء الأخير من الرمز على عمليات تحقق مماثلة للتحقق من أن واجهة برمجة التطبيقات تعرض معلومات الكتاب والمؤلف. لا يعمل الرمز على تعديل صفيف bookValues إلا إذا كان العنوان الأصلي أو خلية المؤلف فارغة وعرضت واجهة برمجة التطبيقات قيمة يمكنك وضعها هناك.

يتم الخروج من الحلقة بعد فحص جميع الصفوف في الورقة. الخطوة الأخيرة هي كتابة مصفوفة bookValues المعدَّلة الآن مرة أخرى في جدول البيانات باستخدام Range.setValues(values).

النتائج

يمكنك الآن الانتهاء من تنظيف بيانات الكتاب. فعليك إجراء ما يلي:

  1. إذا لم تكن قد فعلت بعد، ميِّز نطاق A2:A15 في جدول بياناتك، ثم اختَر قائمة الكتب &gt؛ افصل بين العناوين/المؤلّفين في الفاصلة الأولى لمحو مشاكل الفاصلة.
  2. إذا لم تكن قد فعلت بعد، ميِّز نطاق A2:A15 في جدول بياناتك، ثم اختَر قائمة الكتب &gt، ثم افصل بين العناوين/المؤلِّفين أخيرًا&quot&by" لمحو المشاكل&
  3. لملء جميع الخلايا المتبقية، اختَر قائمة الكتب &gt، املأ العناوين الفارغة وخلايا المؤلف:

826675a3437adbdb.gif

13- الخلاصة

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

هل وجدت هذا الدرس التطبيقي مفيدًا؟

نعم لا

ما تعلّمته

  • كيفية استيراد البيانات من جدول بيانات Google.
  • كيفية إنشاء قائمة مخصّصة في دالة onOpen().
  • كيفية تحليل قيم بيانات السلسلة ومعالجتها.
  • كيفية استدعاء واجهات برمجة التطبيقات العامة باستخدام خدمة جلب عنوان URL.
  • كيفية تحليل بيانات عنصر JSON التي يتم استردادها من مصدر واجهة برمجة تطبيقات عام.

الخطوات التالية

يتناول الدرس التطبيقي التالي حول الترميز في قائمة التشغيل هذه كيفية تنسيق البيانات في جدول بيانات.

ابحث عن الدرس التطبيقي التالي حول الترميز في تنسيق البيانات.