سنوضّح من خلال هذا المقال كيفية معالجة تحديد خلية ومجموعة من الخلايا التي تشكل مجالًا باستخدام الماكرو Macro في ليبرأوفيس كالك LibreOffice Calc.
هذا المقال جزء من سلسلة مقالات حول إنشاء ماكرو في ليبرأوفيس كالك، فهرس السلسلة:
- مدخل إلى كتابة ماكرو Macro في ليبرأوفيس كالك LibreOffice Calc
- معالجة محتويات خلايا ليبرأوفيس كالك باستخدام الماكرو
- معالجة مجال من الخلايا باستخدام الماكرو في ليبرأوفيس كالك.
- استخدام عناصر التحكم بالنماذج ونافذة فتح الملفات من خلال الماكرو في ليبرأوفيس
- التعامل مع عناصر التحكم بمربع الحوار ومعالجة النماذج باستخدام الماكرو في ليبرأوفيس كالك
- أتمتة حفظ أوراق ليبرأوفيس كالك بتنسيق PDF باستعمال الماكرو
معالجة خلايا محددة في كالك باستخدام الماكرو
سنوضّح آلية التحديد في خلايا ليبرأوفيس كالك 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
تشغيل الماكرو
أولًا، تحديد خلية واحد:
الخرج:
ثانيًا، تحديد مجال من الخلايا:
الخرج:
ثالثًا، تحديد مجالات متعددة من الخلايا:
الخرج:
شيفرة الماكرو الكاملة
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) كما يلي:
مجال بسيط
إنشاء الماكرو
أنشئ ماكرو جديدًا في ليبرأوفيس كالك، ثم أضف دالة مثل 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)
إذا شغّلت الشيفرة السابقة، فستكون النتيجة كما يلي:
تعبئة خلية واحدة باستخدام مجال
ضبط صف من الخلايا باستخدام مجال
نريد تعبئة صف الخلايا من 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)
وتكون نتيجة الشيفرة السابقة كما يلي:
تعبئة الصفوف باستخدام مجال
ضبط أعمدة من الخلايا باستخدام مجال
نريد تعبئة عمود واحد بعدة صفوف من خلال تحديد مصفوفة أبعادها (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)
وتكون النتيجة كما يلي:
تعبئة الأعمدة باستخدام مجال
ضبط صف وعمود من الخلايا بالحجم نفسه باستخدام مجال
نريد تعبئة مجالات الصفوف والأعمدة باستخدام الحجم نفسه، لذلك لنحدّد مصفوفة أبعادها (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)
ويكون الخرج كما يلي:
تعبئة الصفوف والأعمدة من الحجم نفسه باستخدام مجال
ضبط صف وعمود من الخلايا ذات أبعاد مختلفة باستخدام مجال
نريد تعبئة مجال بأبعاد مختلفة من خلال تحديد مصفوفة ذات أبعاد مختلفة كما يلي:
' 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)
ويكون الخرج كما يلي:
تعبئة الصفوف والأعمدة ذات القيم المختلفة باستخدام مجال
حدّد حجم المصفوفة الخاص بك باستخدام (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
تشغيل الماكرو
خرج تحديد خلية واحدة:
getCellAddress Demo
خرج تحديد مجال من الخلايا:
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.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.