مقال تقني

HotXLS Delphi Component: data validation, AutoFilter, and worksheet tables في Delphi

تضيف المقالة أن AutoFilter يخزن تعريفاً ولا يقص الصفوف، وأن column id إزاحة لا رقم عمود. كما تشرح عقد قواعد validation، وتصحيح polarity الذي تمتصه المكتبة، وكيف تمنح الجداول النطاق schema واسماً قابلاً للتعامل

مخطط لثلاث ميزات أوراق عمل في HotXLS داخل Delphi حيث يقيد التحقق من صحة البيانات الإدخال، ويخزن AutoFilter تعريف عرض، ويفرض الجدول مخططًا
ترتبط التحقق من البيانات وAutoFilter والجداول جميعها بمدى ورقة العمل نفسه في HotXLS، مع ذلك يتجسد كل منها في لحظة مختلفة — الكتابة وفتح الملف والحفظ

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

التصفية التلقائية تخزّن تعريفًا، ولا تقصّ صفوفًا

التصفية التلقائية في ملف محفوظ سجل معايير. إخفاء الصفوف يحدث لاحقًا، عندما يفتح Excel المصنف ويقيّم المعايير مقابل البيانات. يكتب HotXLS ذلك السجل بأمانة ولا يقصّ شيئًا: كل صف صفّيته لا يزال موجودًا فعليًا في الملف. خط أنابيب يطبّق تصفية لإسقاط طلبات مرفوضة ثم يعيد قراءة المصنف سيرى كل تلك الطلبات، المرفوضة ضمنها، والكود صحيح وفق الواجهة وخاطئ وفق النموذج الذهني للمؤلف. في ورقة عمل XLSX، تعلن SetAutoFilter المنطقة المُصفّاة وتربط AddAutoFilterColumn معايير بعمود واحد منها. عندما يحتاج كود جهة الخادم النتيجة الفعلية، لعدد صفوف في ملخص أو لتمرير الصفوف المطابقة فقط، تقيّم المكتبة المعايير لك بدلًا من التظاهر بأن الملف تغيّر:

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  R, Visible: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('orders.xlsx');
    Sheet := Book.Sheets[0];

    Sheet.SetAutoFilter('A1:E500');
    // معرّف العمود 3 = العمود الرابع داخل نطاق التصفية (إزاحة تبدأ من 0)
    Sheet.AddAutoFilterColumn(3, xlsxAfOpGreaterOrEqual, '1000');

    Visible := 0;
    for R := 2 to 500 do
      if Sheet.AutoFilterRowVisible(R) then
        Inc(Visible);
    // Visible تطابق الآن ما سيعرضه Excel بعد فتح الملف

    Book.SaveAs('orders-filtered.xlsx');
  finally
    Book.Free;
  end;
end;

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

مخطط يوضح AutoFilter في HotXLS يخزن كل صف في ملف Excel المحفوظ بينما تقيّم واجهة المعاينة في Delphi أي الصفوف سيعرضها Excel، مع إزاحة معرف العمود القائمة على الصفر
يُبقي الملف المحفوظ كل صف ويسجل المعايير وحدها، بينما تخفي Excel الصفوف بعد تقييمها — ويستهدف AddAutoFilterColumn الأعمدة بإزاحة صفرية الأساس داخل المدى

معرّف العمود إزاحة، لا رقم عمود

التعليق في المقتطف أعلاه يشير إلى الفخ الذي يكلّف أكبر وقت تصحيح أخطاء في هذه الواجهة. AddAutoFilterColumn تحدد هدفها بالموضع الذي يبدأ من 0 داخل نطاق التصفية، لا بعمود ورقة العمل. لتصفية على A1:E500، نظاما الترقيم يختلفان بمقدار واحد بالصدفة، وهذا بالضبط نوع الخطأ القريب الذي ينجو من اختبار سريع وينكسر في اللحظة التي يصفّي فيها زميل عمودًا مختلفًا. لتصفية تبدأ عند العمود C، المعرّف 0 يعني العمود C، ويصبح عدم التطابق واضحًا بسرعة. عندما يُحسَب نطاق التصفية وقت التشغيل، اشتق معرّف العمود من نفس المتغير الذي بنى سلسلة النطاق، لا أبدًا من ثابت عمود ورقة عمل. كل عمود يقبل شرطًا ثانيًا عبر الحمولة الزائدة التي تأخذ عاملين، ومعيارين، وموصل and/or، وهذا يعكس مربع حوار التصفية المخصصة في Excel. واجهة XLS تغطي نفس الأرض بـSetAutoFilter مع ApplyAutoFilter، التي تتبع معاملات المعايير والعامل فيها اصطلاحات أسلوب COM الأقدم وترقّم الحقل بدءًا من 1. تبديل الواجهات يعني تبديل قواعد الفهرسة، لذا يستحق موضع الاستدعاء تعليقًا يذكر أيهما قيد الاستخدام

قواعد التحقق هي العقد الذي يحرر مستخدموك تحته

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

var
  Idx: Integer;
begin
  Idx := Sheet.AddListValidation('C2:C500', 'New,Approved,Blocked');
  Sheet.DataValidations[Idx].SetPrompt('Status',
    'Pick one of the listed states');
  Sheet.DataValidations[Idx].SetError('Invalid status',
    'Type or paste only listed values', xlsxDvErrStop);
  Sheet.DataValidations[Idx].AllowBlank := False;

  // الكميات: أعداد صحيحة، صفر أو أكثر
  Sheet.AddWholeNumberValidation('D2:D500', xlsxDvOpGreaterOrEqual, '0');
end;

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

الواجهة القديمة تقدم عائلات القواعد نفسها بفارق أرغونومي واحد. منشئات جهة XLS، وتحديدًا AddWholeNumberValidation وAddDecimalValidation وAddDateValidation وAddTimeValidation وAddTextLengthValidation وAddCustomValidation، تعيد كائن TDataValidation مباشرة بدلًا من فهرس، فتسلسل إعدادات التلميح والخطأ ينطلق من المرجع المُعاد بدلًا من بحث. تعداد العامل (xlsDvBetween وxlsDvGreaterThan وبقيتها) يعكس مجموعة XLSX، فكود بناء القواعد ينتقل بين الواجهتين باستثناء ذلك الفارق في أسلوب الإرجاع. نص التلميح نفسه يستحق تفكيرًا بقدر القاعدة. قائمة منسدلة ترفض الإدخال بمربع خطأ فارغ تعلّم المستخدمين مراسلة قسم تقنية المعلومات؛ أما التي تسمي الحالات المشروعة فتعلّمهم إصلاح الخلية والمتابعة

انقلاب قطبية واحد تمتصه المكتبة نيابة عنك

أي شخص قرأ XML الخاص بالتحقق في OOXML يدويًا يكون قد صادف سمة showDropDown المقلوبة: في ISO/IEC 29500 قيمة true تعني "أخفِ سهم القائمة المنسدلة"، عكس ما يوحي به الاسم. يقلب HotXLS هذا داخليًا، فخاصية ShowDropDown على قاعدة تحقق تعني ما تقوله بالضبط، وtrue تعرض القائمة المنسدلة. الطريقة الوحيدة للاحتراق هي خلط مستويات الحقيقة، ضبط الخاصية من الكود بينما يدقق زميل XML المحفوظ و"يصحح" السمة التي تبدو له معكوسة. قرر ما إذا كانت الخاصية أو XML الخام هي المرجع المعتمد لأدوات المراجعة، واكتب الانقلاب حيث يعيش ذلك القرار

الجداول تمنح نطاقًا مخططًا واسمًا

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

مخطط لجدول ورقة عمل HotXLS في Delphi بأعمدة موسومة بأنواع ومراجع هيكلية وأسماء فريدة للمصنف وفخ إلحاق صف الإجماليات
يلف جدول HotXLS مداه في اسم وأعمدة موصوفة النوع وتنسيق مخطط، بينما تجثم صف الإجماليات أسفل البيانات مباشرة حيث يهبط الإلحاق الساذج بآخر صف
var
  Cols: TStringList;
begin
  Cols := TStringList.Create;
  try
    Cols.CommaText := 'OrderId,Customer,Status,Amount,Owner';
    Sheet.AddTable('Orders', 'A1:E500', Cols);
  finally
    Cols.Free;
  end;
end;

في جهة XLSX، كائن الجدول الناتج يكشف StyleName (عائلة TableStyleMedium2 المدمجة وأخواتها)، ومفاتيح تبديل الأشرطة، وعلامة صف مجاميع، فتطبيق تنسيق الشركة إسناد خاصية بدلًا من تمريرة تنسيق يدوية. في ملفات ‎.xls‎ القديمة، نفس الاستدعاء يكتب سجلات جدول BIFF8، وتقدم الواجهة أيضًا AddPivotTable لعروض ملخصة مبنية من حقول صف وعمود وبيانات، تذكير بأن "الجداول" في الصيغة الأقدم تمتد أبعد مما يمتد إليه ListObject الخاص بـOOXML. سمِّ الجداول بالطريقة التي تسمي بها طرق عرض قاعدة بيانات. الكود اللاحق الذي يقرأ Orders[Amount] عبر مرجع بنيوي ينجو من إعادة ترتيب الأعمدة التي تكسر الكود الموضعي

اصطلاحان يوفران تنظيفًا لاحقًا. يشترط Excel أن تكون أسماء الجداول فريدة عبر المصنف بأكمله، فمولِّد يصدر ورقة واحدة لكل منطقة يحتاج مخططًا مثل Orders_EMEA بدلًا من إعادة استخدام Orders. التكرار لا يفشل وقت الكتابة؛ إنه يظهر كمربع حوار إصلاح عندما يفتح المستخدم الملف، وهو أسوأ مكان لاكتشافه. الاصطلاح الآخر يخص صف المجاميع: عند تفعيله، يجلس مباشرة أسفل نطاق البيانات، فأي كود يُلحق لاحقًا بـ"آخر صف مستخدم زائد واحد" يكتب في شريط المجاميع بدلًا من بعده. تتبع امتداد البيانات منفصلًا عن امتداد الجدول وستهبط الإلحاقات حيث تتوقعها

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

التحقق من الصحة، والتصفية، والجداول هي الفرق بين شحن شبكة من القيم وشحن تطبيق صغير. المرجع الكامل للقواعد والتصفية والجداول موجود على صفحة منتج HotXLS Delphi Component