اذهب إلى المحتوى

معالجة مجال من الخلايا باستخدام الماكرو في ليبر أوفيس كالك


Ola Abbas

سنوضّح من خلال هذا المقال كيفية معالجة تحديد خلية ومجموعة من الخلايا التي تشكل مجالًا باستخدام الماكرو Macro في ليبرأوفيس كالك LibreOffice Calc.

هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبرأوفيس كالك، فهرس السلسلة:

معالجة خلايا محددة في كالك باستخدام الماكرو

سنوضّح آلية التحديد في خلايا ليبرأوفيس كالك LibreOffice Calc باستخدام الماكرو Macro.

الدالة getCurrentSelection()‎

يجب أولًا الحصول على مصنف Workbook كالك مفتوح باستخدام عبارة ThisComponent وإسناد الكائن المُعاد إلى متغير.

يمكنك معرفة التحديدات التي أجراها المستخدم في ورقة كالك باستخدام الدالة getCurrentSelection()‎ الخاصة بواجهة Xcomponent، حيث توفّر هذه الدالة وصولًا لقراءة التحديد الحالي إلى وحدة التحكم، وتعيد التحديد الحالي من وحدة التحكم الحالية.

Dim oDoc, oSel
oDoc = ThisComponent
oSel = oDoc.getCurrentSelection()

إن لم يكن هناك تحديد، فستعيد الدالة getCurrentSelection()‎ القيمة NULL. كما يمكنك استخدام الدالة IsNull لمعرفة إذا كان هناك شيء ما محدَّد أم لا.

لا نستطيع معرفة التحديدات باستخدام oSel فقط، حيث يجب استخدام الدالة supportService الخاصة بواجهة XServiceInfo التي تختبر ما إذا كانت الخدمة المحددة مدعومة أي يمكن تنفيذها، بحيث تعيد القيمة TRUE إذا كانت مدعومة، وإلّا فإنها تعيد القيمة FALSE. توجد قائمة بالخدمات المتاحة التي يمكن اختبارها باستخدام هذه الدالة مثل الخدمات التالية:

  • com.sun.star.sheet.SheetCell
  • com.sun.star.sheet.SheetCellRange
  • com.sun.star.sheet.SheetCellRanges

ويمكنك العثور على قائمة كاملة بالخدمات من مرجع ليبرأوفيس com.sun.star.sheet.

تحديد خلية واحدة

استخدم خدمة com.sun.star.sheet.SheetCell للتحقق من تحديد خلية واحدة. كما يمكنك الحصول على قيمة تلك الخلية المحددة باستخدام الدالة getString()‎ مع كائن التحديد.

If oSel.supportsService("com.sun.star.sheet.SheetCell") Then
    MsgBox "One Cell selected and it contains: " & oSel.getString()
End If

تحديد مجال واحد

استخدم الخدمة com.sun.star.sheet.SheetCellRange لتحديد مجال من الخلايا مثل C5:F7.

If oSel.supportsService("com.sun.star.sheet.SheetCellrange") Then
    MsgBox "One Cell Range selected"
End If

تحديد مجالات متعددة

استخدم خدمة com.sun.star.sheet.SheetCellRanges لتحديد مجالات متعددة من الخلايا.

If oSel.supportsService("com.sun.star.sheet.SheetCellRanges") Then
    MsgBox "Multiple Cell Ranges selected. Total=" & oSel.getCount()
End If

تشغيل الماكرو

أولًا، تحديد خلية واحد:

01_Single-Cell-Selection-www.debugpoint.com_.png

الخرج:

02_Single_Cell_selection_Output_www.debugpoint.com_.png

ثانيًا، تحديد مجال من الخلايا:

03_Single-Range-Selection.png

الخرج:

04_Single_Cell_Range_Output.png

ثالثًا، تحديد مجالات متعددة من الخلايا:

05_Multiple-ranges-Selection.png

الخرج:

06_Multiple_Cell_Range_Output.png

شيفرة الماكرو الكاملة

Sub Main

    Dim oDoc, oSel

    oDoc = ThisComponent
    oSel = oDoc.getCurrentSelection()

    If oSel.supportsService("com.sun.star.sheet.SheetCell") Then
        MsgBox "One Cell selected and it contains: " & oSel.getString()
    Else
        If oSel.supportsService("com.sun.star.sheet.SheetCellRange") Then
            MsgBox "One Cell Range selected"
        Else
            If oSel.supportsService("com.sun.star.sheet.SheetCellRanges") Then
                Msgbox "Multiple Cell Ranges selected. Total=" & oSel.getCount()
            Else
                Print "Somethine else is selected."
            End If
        End If
    End If  

End Sub

معالجة مجال من الخلايا باستخدام الماكرو في ليبرأوفيس كالك

نحتاج في العديد من مهام الأتمتة إلى الوصول إلى جدول البيانات باستخدام مجال Range من الخلايا لتقليل وقت المعالجة، حيث يمكن الوصول إلى كل خلية باستخدام طريقة "صف، عمود row, column" التي تُعَد طريقة مكلفة من حيث وقت المعالجة والتعقيد، وبالتالي يُفضَّل استخدام المجال على معالجة الخلية المفردة. سنتحدث فيما يلي عن كيفية معالجة "مجال Range" في تطبيق جداول البيانات ليبرأوفيس كالك من خلال الكتابة ضمن مجالات جداول البيانات.

تحديد المجال

يُحدَّد المجال باستخدام "عنوان خلية البداية: عنوان خلية النهاية startcelladdress: stopcelladdress"، حيث تُحدَّد الأعمدة في كالك باستخدام الأحرف مثل "A" و "B" و "C"، وتُحدَّد الصفوف باستخدام أرقام تبدأ من الرقم 1، وبالتالي يشير المجال "A1: D5" إلى جميع الخلايا التي تبدأ من الخلية (1,1) إلى الخلية (4,5) كما يلي:

07_A-simple-Range.png

مجال بسيط

إنشاء الماكرو

أنشئ ماكرو جديدًا في ليبرأوفيس كالك، ثم أضف دالة مثل rang_processing_demo()‎ التي تشير إلى جدول بيانات قبل أن نبدأ في معالجة المجال.

Sub range_processing_demo
      dim my_doc   as object
      Dim my_sheets as object
      Dim my_range as object
      my_doc = ThisComponent
      my_sheets = my_doc.Sheets 
End Sub

سنبدأ بتعبئة خلية واحدة باستخدام مجال، ثم ننتقل إلى معالجة مجال أكثر تعقيدًا.

ضبط خلية واحدة باستخدام مجال

يمكن ضبط المجالات باستخدام الدالة setDataArray(array)‎، فوسيط هذه الدالة هو مصفوفة ثنائية الأبعاد لها حجم المجال نفسه. إذا اخترت المجال "A1" الذي لا يمثل سوى خلية واحدة، فيجب أن يكون للمصفوفة المقابلة قيمة واحدة فقط، وبالتالي يجب تحديد مصفوفة تحتوي على عنصر واحد فقط وضبط قيمتها كما يلي:

Dim my_data(0,0)             
my_data(0,0) = "Apple"

حدّد بعد ذلك مجالًا من خلية واحدة مثل "A1"، وضع المصفوفة المحدَّدة ضمن الدالة setDataArray()‎.

my_range = ThisComponent.Sheets(0).getCellRangebyName("A1")
my_range.setDataArray(my_data)

إذا شغّلت الشيفرة السابقة، فستكون النتيجة كما يلي:

08_single-cell.png

تعبئة خلية واحدة باستخدام مجال

ضبط صف من الخلايا باستخدام مجال

نريد تعبئة صف الخلايا من A3 إلى C3 باستخدام مجال، لذلك نحتاج إلى تحديد مصفوفة أبعادها (0,2)، حيث يمثل الرقم 0 عدد الصفوف ويمثل الرقم 2 عدد الأعمدة. لاحظ أن الأعمدة تبدأ من 0، وبالتالي نريد تعبئة 3 أعمدة من 0 إلى 2.

' Set a row of cells using range
    ReDim my_data(0,2)          
    my_data(0,0) = "Apple"
    my_data(0,1) = "1000"
    my_data(0,2) = "Red"
    my_range = ThisComponent.Sheets(0).getCellRangebyName("A3:C3")
    my_range.setDataArray(my_data)  

وتكون نتيجة الشيفرة السابقة كما يلي:

09_Fill-Rows-Using-Range.png

تعبئة الصفوف باستخدام مجال

ضبط أعمدة من الخلايا باستخدام مجال

نريد تعبئة عمود واحد بعدة صفوف من خلال تحديد مصفوفة أبعادها (2,0) وكتابة الشيفرة التالية:

' Set a column of cells using range
    ReDim my_data(2,0)          
    my_data(0,0) = "Apple"
    my_data(1,0) = "1000"
    my_data(2,0) = "Red"
    my_range = ThisComponent.Sheets(0).getCellRangebyName("C1:C3")
    my_range.setDataArray(my_data)  

وتكون النتيجة كما يلي:

10_Fill-Columns-using-Range.png

تعبئة الأعمدة باستخدام مجال

ضبط صف وعمود من الخلايا بالحجم نفسه باستخدام مجال

نريد تعبئة مجالات الصفوف والأعمدة باستخدام الحجم نفسه، لذلك لنحدّد مصفوفة أبعادها (2,2) كما يلي:

' Set row and column of same size using range
    ReDim my_data(2,2)          
        my_data(0,0) = "Apple"
    my_data(0,1) = "1000"
    my_data(0,2) = "Red"

        my_data(1,0) = "Apple-1"
    my_data(1,1) = "1000-1"
    my_data(1,2) = "Red-1"

        my_data(2,0) = "Apple-2"
    my_data(2,1) = "1000-2"
    my_data(2,2) = "Red-2"

    my_range = ThisComponent.Sheets(0).getCellRangebyName("B2:D4")
    my_range.setDataArray(my_data)  

ويكون الخرج كما يلي:

11_Fill-Rows-and-Columns-of-Same-Size-using-Range.png

تعبئة الصفوف والأعمدة من الحجم نفسه باستخدام مجال

ضبط صف وعمود من الخلايا ذات أبعاد مختلفة باستخدام مجال

نريد تعبئة مجال بأبعاد مختلفة من خلال تحديد مصفوفة ذات أبعاد مختلفة كما يلي:

' Set row and column of different size using range
    ReDim my_data(3,1)          
        my_data(0,0) = "Apple"
    my_data(0,1) = "1000"

        my_data(1,0) = "Apple-1"
    my_data(1,1) = "1000-1"

        my_data(2,0) = "Apple-2"
    my_data(2,1) = "1000-2"

        my_data(3,0) = "Apple-3"
    my_data(3,1) = "1000-3"

    my_range = ThisComponent.Sheets(0).getCellRangebyName("B2:C5")
    my_range.setDataArray(my_data)

ويكون الخرج كما يلي:

Fill-Rows-and-Columns-of-Different-Size-using-Range (1)(1).png

تعبئة الصفوف والأعمدة ذات القيم المختلفة باستخدام مجال

حدّد حجم المصفوفة الخاص بك باستخدام (row, col) واستخدم الدالة setDataArray()‎ لتعبئة المجال باستخدام الماكرو.

الحصول على عنوان الخلية والمجال المحدد باستخدام الماكرو

سنوضّح كيفية الحصول على العنوان الذي يمكن قراءته الخاص بالخلايا والمجالات المحدَّدة باستخدام الماكرو.

التحديدات

يمكن تحديد خلية واحدة أو خلايا متعددة -أي مجالات- في كالك. عرّف بعض المتغيرات للاحتفاظ بنسخ من الخلية الفعّالة activeCell والتحويل Conversion كما يلي:

Dim oActiveCell
Dim oConv

استخدم الدالة getCurrentSelection للحصول على التحديد الحالي من وحدة التحكم.

oActiveCell = ThisComponent.getCurrentSelection()

يمكنك الحصول على عنوان الخلية المحدَّدة والمجال المحدَّد من خلال استخدام خدمتين مختلفتين هما:

  • com.sun.star.table.CellRangeAddressConversion
  • com.sun.star.table.CellAddressConversion

أنشئ نسخًا من هذه الخدمات باستخدام الدالة createInstance كما يلي:

oConv = ThisComponent.createInstance("com.sun.star.table.CellRangeAddressConversion")
oConv = ThisComponent.createInstance("com.sun.star.table.CellAddressConversion")

يمكنك بعد ذلك تعبئة خاصية العنوان Address من عنوان الخلية أو المجال المحدَّد باستخدام الشيفرة التالية:

oConv.Address = oActiveCell.getRangeAddress
  oConv.Address = oActiveCell.getCellAddress

ستعيد دالتان مهمتان خاصتان بكائن التحويل عنوان الخلية أو المجال الذي يمكن قراءته هما:

  • UserInterfaceRepresentation: تعيد عمود وصف الخلية، مثل A1 و B3 عند تحديد خلية واحدة، وتعيد مجالًا مثل A1: C3 و B1: E4 عند تحديد مجال
  • PersistentRepresentation: تعيد الشيء نفسه مع اسم ورقة العمل الحالية مثل Sheet1.A1 و Sheet1.B3 و Sheet1.A1:Sheet1.C3 و Sheet1.B1:Sheet1.E4، حيث تكون جميع القيم المُعادة سلسلة نصية String ويمكن معالجتها وفقًا لذلك.
msgbox  oConv.UserInterfaceRepresentation & _
          "  " & oConv.PersistentRepresentation

تشغيل الماكرو

خرج تحديد خلية واحدة:

13_getCellAddress-Demo.png

getCellAddress Demo

خرج تحديد مجال من الخلايا:

14_getRangeAddress-Demo.png

getRangeAddress Demo

شيفرة الماكرو الكاملة

الشيفرة الخاصة بالخلايا:

Sub get_cell_address

    oActiveCell = ThisComponent.getCurrentSelection()

    oConv = ThisComponent.createInstance("com.sun.star.table.CellAddressConversion")
    oConv.Address = oActiveCell.getCellAddress

    msgbox  oConv.UserInterfaceRepresentation & _
      "  " & oConv.PersistentRepresentation

End Sub

الشيفرة الخاصة بالمجالات:

Sub get_range_address

    oActiveCell = ThisComponent.getCurrentSelection()

    oConv = ThisComponent.createInstance("com.sun.star.table.CellRangeAddressConversion")
    oConv.Address = oActiveCell.getRangeAddress

    msgbox  oConv.UserInterfaceRepresentation & _
      "  " & oConv.PersistentRepresentation

End Sub

ترجمة -وبتصرُّف- للمقالات Calc Cell Selection Processing Using Macro و Range Processing using Macro in LibreOffice Calc – Part 1 و Get the Selection Cell and Range Address using Macro in LibreOffice لصاحبها Arindam.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...