مقال تقني

توافق ODS في HotXLS: صيغ وقواعد يقرؤها Excel

لإنتاج ملف ODS يقرؤه Excel و LibreOffice كلاهما قراءةً صحيحة، يكتب HotXLS كل صيغة بصياغة OpenFormula تحت نطاق of: مصرَّح، ويكتب كل تنسيق شرطي من نوع قيمة أو صيغة مرتين: <style:map> على نمط كل خلية مغطاة، وهو ما لا يقرؤه Excel 16 سواه، وكتلة calcext:conditional-formats، وهي الصورة التي يثق بها LibreOffice. ويتجاهل كل تطبيق النصف الموجه لآخره، فملف يظهر صحيحاً في أحدهما لا يثبت شيئاً عن الآخر

تلك الجملة الأخيرة هي الدرس خلف ستة إصدارات من HotXLS بين v2.384.55 و v2.384.72. بدأ كل إصلاح بملف كتبه HotXLS وقرأه عائداً بإتقان وأخطأ فيه أحد التطبيقين الهدفين. وما يلي هو ما يقبله كل تطبيق فعلاً، والوسم الذي يرضيهما معاً، واستدعاءات HotXLS التي تنتجه من Delphi

لماذا يبدو ملف ODS سليماً في تطبيق ومكسوراً في الآخر؟

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

لا يبلّغ أي من التطبيقين عن خطأ. يعرض LibreOffice ‏#VALUE! في الخلايا التي لم يستطع تفسير صيغها؛ ويفتح Excel المصنف دون التنسيقات الشرطية ببساطة، أو بصيغة أُعيدت كتابتها إلى ما يقيّم #NAME? أو الثابت 0. والكاتب الذي يعيد دورة ناتجه الخاص لا يرى شيئاً من هذا. وقع HotXLS في ذلك الفخ تماماً مع نطاق الصيغ: طابق قارؤه سابقة of: نصاً صريحاً، فنجحت كل دورة ذاتية بينما عرض LibreOffice ‏#VALUE! في كل خلية صيغة

الميزةيقرؤها Excel 16يقرؤها LibreOffice 26.2
عمود كامل مكتوب A:Aتُقرأ خطأً A:(A)تُحتمل
عمود كامل مكتوب [.A:.A]نعمنعم
تنسيقات شرطية في <style:map>نعم، الصورة الوحيدة التي يقرؤهاتُتجاهل حين يوجد calcext
تنسيقات شرطية في calcext:conditional-formatsتُتجاهلنعم، المفضلة
قاعدة قيمة calcext بخاصية calcext:operatorتُتجاهلتُستورد "يساوي 0"
قاعدة صيغة calcext مهجأة is-true-formula(...)تُتجاهلتُستورد مقارنة قيمة مع 0

‏OpenFormula في ODS: صرّح النطاق ثم أحسِن الصياغة

لا تكون خلية الصيغة في ODS مقروءةً لـ LibreOffice إلا إذا تحولت سابقة of: في table:formula إلى نطاق XML مصرَّح. والسابقة ليست زخرفة. ‏of: يقابل urn:oasis:names:tc:opendocument:xmlns:of:1.2، و msoxl:، السابقة التي يستخدمها HotXLS للصيغ التي لا يصوغها مترجم OpenFormula عنده، تقابل http://schemas.microsoft.com/office/excel/formula. قبل v2.384.56 استخدم جذر content.xml السابقتين دون التصريح بهما، ولم يستطع LibreOffice تمييز نحو الصيغ أصلاً

<!-- قبل v2.384.56: سابقة مستخدمة ولم تُصرَّح قط؛ يعرض LibreOffice ‏#VALUE! -->
<office:document-content xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" ...>
  <table:table-cell table:formula="of:=SUM([.A1:.A3])" office:value-type="float" office:value="245"/>

<!-- منذ v2.384.56: كلا نطاقي الصيغ مصرَّحان على الجذر -->
<office:document-content
    xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
    xmlns:msoxl="http://schemas.microsoft.com/office/excel/formula" ...>

مع النطاق مصححاً يبقى على التعبير نفسه أن يكون OpenFormula صالحاً كما يعرّفه OpenDocument 1.3 الجزء 4. والفخاخ في المواضع التي تتشابه فيها صياغة Excel مع OpenFormula ظاهرياً دون أن تكونا شيئاً واحداً:

  • مراجع الخلايا بين قوسين وبسابقة نقطة، وعلامتا $ جزء من المرجع: ‏[.$A$1] و [.A$1:.$B2] صالحتان في OpenFormula. قبل v2.384.55 أسقط كاتب HotXLS كل $، فعادت المراجع المطلقة نسبيةً ولم تخطئ إلا حين ينسخ أحد الخلية
  • الأعمدة والصفوف الكاملة يجب أن تستخدم الصورة المقوسة [.A:.A] و [.$A:.$B] و [.1:.1] و [.$1:.$2]. يحتمل LibreOffice ‏of:=SUM(A:A) العارية، لكن Excel 16 يفتحها =SUM(A:(A)) مع #NAME? ويحول مراجع الصفوف و $A:$B إلى الثابت 0. يكتب HotXLS الصورة المقوسة منذ v2.384.65
  • وسائط الدوال تفصل بـ ; لا ,
  • اتحادات المراجع تستخدم عامل ~: تصير AREAS((A1,B2)) في Excel ‏AREAS(([.A1]~[.B2])). وترجمة تلك الفاصلة إلى ; بدلاً من ذلك تحوّل وسيط اتحاد واحد إلى وسيطين
  • المصفوفات المضمّنة تفصل الأعمدة بـ ; والصفوف بـ |: تصير {1,2;3,4} في Excel ‏{1;2|3;4}. أنتج HotXLS قبل v2.384.55 ‏{1;2;3;4}، صفّاً واحداً من أربع قيم

الفاصلة هي الجزء الصعب، لأن محرف Excel الواحد يحمل ثلاثة معانٍ. منذ v2.384.55 يتتبع كاتب HotXLS كومة أقواس أثناء الترجمة: القوس ( الملاصق لاسمٍ يفتح استدعاء دالة تصير فواصله ;؛ وأي قوس آخر قوسُ تجميعٍ تصير فواصله ~؛ والفواصل داخل {} فواصل أعمدة مصفوفة. ومع ذلك وإصلاح النطاق قيّم LibreOffice 26.2 صيغ البروب الثماني كلها للمصفوفات والاتحادات قراءةً صحيحة، ومن ضمنها INDEX و AREAS فوق اتحادات

مخطط HotXLS لكومة الأقواس التي تترجم فواصل Excel إلى OpenFormula: القوس الملاصق لاسم يفتح استدعاء دالة تصير فواصله فواصل منقوطة، وأي قوس آخر قوس تجميع تصير فواصله مدّة عامل الاتحاد، والفواصل داخل الحاصرات فواصل أعمدة مصفوفة، كما في AREAS لاتحاد A1 و B2
تحمل الفاصلة ثلاثة معانٍ في صياغة Excel، وكومة الأقواس الجارية وحدها تميزها؛ ترجم فاصلة اتحادٍ إلى فاصلة منقوطة يصير الوسيط الواحد وسيطين بصمت
uses
  lxHandleX;

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
begin
  Book := TXLSXWorkbook.Create;
  try
    Sheet := Book.Sheets.Add('Orders');
    Sheet.Cells[1, 1].Value := 120;
    Sheet.Cells[2, 1].Value := 80;
    Sheet.Cells[3, 1].Value := 45;
    Sheet.Cells[1, 2].Value := 0.2;

    // تكتب ‏of:=SUM([.A:.A]) منذ v2.384.65
    Sheet.Cells[1, 4].Formula := 'SUM(A:A)';
    // تكتب ‏of:=[.A1]*[.$B$1]؛ وعلامتا $ تبقيان منذ v2.384.55
    Sheet.Cells[2, 4].Formula := 'A1*$B$1';

    Book.SaveAsODS('orders.ods');
  finally
    Book.Free;
  end;
end;

الصيغ التي لا يصوغها المترجم تتراجع إلى msoxl:= بنص Excel بلا تغيير، ولهذا يهم التصريح بـ msoxl أيضاً. في الكاتب الحالي يشمل ذلك المسار مراجع مؤهلة بورقةٍ مثل Sheet2!A1 ومراجع الجداول المهيكلة. يقرأ HotXLS صيغ msoxl: عائدةً عند الاستيراد، فتبقى دورته الذاتية تحفظ التعبير سليماً، لكن معاملة تطبيق آخر لها خارج سيطرة الكاتب. فإن خرجت صيغة يعتمد عليها مستهلكوك بسابقة msoxl:، افتح الملف في التطبيقين قبل أن تشحنه

لماذا لا يرى Excel تنسيقات شرطية كُتبت بصيغة calcext وحدها؟

لا يرى Excel 16 التنسيقات الشرطية بصيغة calcext لأنه يقرأ تنسيقات ODS الشرطية حصرياً من أبناء <style:map> لأنماط الخلايا ويتجاهل كتلة calcext:conditional-formats كلياً. والتجربة التي تحسمها قصيرة: خذ ملف ODS حفظه LibreOffice واحذف عناصر style:map، فيقرأ Excel صفر قواعد؛ واحذف كتلة calcext بدلاً منها، فيقرأ Excel القواعد كلها ما زالت. ويتصرف LibreOffice بالعكس. ‏calcext نطاق امتدادات LibreOffice، وليس جزءاً من معيار ODF، وحين توجد قاعدة calcext يأخذها LibreOffice ويتجاهل style:map

مخطط القناتين في HotXLS لتنسيقات ODS الشرطية: كل قاعدة قيمة أو صيغة تكتب خريطة نمط على نمط كل خلية مغطاة، الصورة الوحيدة التي يقرؤها Excel 16، وكقاعدة تنسيقات شرطية calcext يكون العامل فيها داخل القيمة، الصورة التي يفضلها LibreOffice، بينما يتجاهل كل تطبيق التهجئة الأخرى بصمت
يقرأ Excel خرائط الأنماط ويتجاهل calcext، ويفضل LibreOffice ‏calcext ويسقط الخرائط، ولا يعرض أي منهما خطأً؛ كتابة التهجئتين معاً من استدعاء HotXLS واحد هو الطريق الوحيد لملف يتحقق في التطبيقين

قبل v2.384.69 كتب HotXLS ‏calcext وحده، فُتح ملف ODS بتظليل سليم تماماً في Excel دون قواعد قيمة ودون قواعد صيغ على الإطلاق. يكتب HotXLS الآن الصورتين معاً. يستخدم نصف style:map نحوَ الشروط في مخطط OpenDocument ‏(ODF 1.3 الجزء 3)، بالتهجئات الدقيقة التي ينتجها Excel 16 و LibreOffice 26.2 كلاهما حين يحفظان ODS:

<!-- مبسط. النمط الحامل لكل خلية في A1:A50 ‏(قاعدتا قيمة) -->
<style:style style:name="ce3" style:family="table-cell">
  <style:map style:condition="cell-content()&gt;100"
             style:apply-style-name="CF_Hit"
             style:base-cell-address="Orders.A1"/>
  <style:map style:condition="cell-content-is-between(1,10)"
             style:apply-style-name="CF_Low"
             style:base-cell-address="Orders.A1"/>
</style:style>

<!-- النمط الحامل لكل خلية في C1:C50 ‏(قاعدة صيغة واحدة) -->
<style:style style:name="ce4" style:family="table-cell">
  <style:map style:condition="is-true-formula(COUNTIF([.$C:.$C];[.C1])&gt;1)"
             style:apply-style-name="CF_Dup"
             style:base-cell-address="Orders.C1"/>
</style:style>

المصيدة مع style:map أنه يسكن أنماط الخلايا، فهو لكل خلية. كل خلية في نطاق القاعدة يجب أن تحمل نمطاً يحوي الخريطة، والخلايا الفارغة ضمنها، وإلا فالقاعدة ببساطة لا تغطي تلك الخلية في Excel. ينسخ HotXLS نمط التنسيق القائم لكل خلية، ويُلحق الخرائط، ويُنقّي الأنماط الحاملة تكراراً بزوج النمط الأصلي ونص الخريطة، فيظل نطاق من 500 خلية بتنسيق متطابق ينتج نمطاً واحداً. ويمد الكاتب الجدول المكتوب إلى نطاق القاعدة أيضاً، أي تصدر صفوف الذيل الفارغة داخل قاعدةٍ بدل إسقاطها. ومنذ v2.384.69 يحمل styles.xml أيضاً نمط خلية Default فارغاً، فتجد style:apply-style-name="Default" هدفاً دوماً

تهجئة calcext التي يقبلها LibreOffice فعلاً

لا يقبل LibreOffice قاعدة قيمة calcext إلا إذا كان عامل المقارنة جزءاً من نص القيمة، مثل >3 أو between(1,10)، وقاعدة صيغة إلا إذا هُجئت formula-is(...). وكلتا النقطتين كلفتا HotXLS إصداراً، لأن التهجئات الخاطئة تنتج قاعدة تستورد بلا خطأ ثم تطابق الخلايا الخطأ

كان الخطأ الأول خاصية calcext:operator بجوار calcext:value. تُقرأ طبيعياً، لكنها مخترعة: لا يعرف LibreOffice تلك الخاصية، فاستورد كل قاعدة قيمة بوصفها «يساوي 0». والخطأ الثاني وضع is-true-formula(...)، تهجئة style:map، في شرط calcext، فاستورده LibreOffice مقارنةَ قيمة خلية مع 0 كذلك. شُحن إصلاح الصيغ في v2.384.66 وإصلاح القيمة في v2.384.69:

<!-- خطأ: يتجاهل LibreOffice ‏calcext:operator ويستورد «يساوي 0» -->
<calcext:condition calcext:apply-style-name="CF_Hit"
                   calcext:operator="greater-than" calcext:value="100"/>

<!-- صواب: يسافر العامل داخل القيمة -->
<calcext:condition calcext:apply-style-name="CF_Hit"
                   calcext:value="&gt;100" calcext:base-cell-address=".A1"/>
<calcext:condition calcext:apply-style-name="CF_Low"
                   calcext:value="between(1,10)" calcext:base-cell-address=".A1"/>

<!-- صواب: قواعد الصيغ تستخدم formula-is ومراجع نسبية ترسو في الخلية الأساس -->
<calcext:condition calcext:apply-style-name="CF_Dup"
                   calcext:value="formula-is(COUNTIF([.$C:.$C];[.C1])&gt;1)"
                   calcext:base-cell-address=".C1"/>
مخطط HotXLS يقابل تهجئات شرط calcext الخاطئة والصحيحة: خاصية calcext operator مخترعة وتستورد كل قاعدة قيمة كأنها يساوي 0، والعامل مكانه داخل القيمة كما في أكبر من 100 أو بين 1 و 10، وقواعد الصيغ يجب أن تقول formula-is مرساةً في خلية أساس لا تهجئة خريطة النمط is-true-formula
كلتا التهجئتين الخاطئتين تستوردان بلا خطأ ثم تطابقان الخلايا الخطأ، وقاعدة تُقرأ يساوي 0 لا تظلل شيئاً مما أردت؛ والإصلاح هو العامل داخل القيمة و formula-is للتعبيرات

الخلية الأساس هي التي تعطي المراجع النسبية معناها. يرسّي HotXLS كل قاعدة عند الخلية العلوية اليسرى من أول مساحة نطاق لها، فتُقيَّم صيغة كُتبت لـ C1 كأنها C2 و C3 وهكذا نزولاً في النطاق، تماماً كما يفعل التنسيق الشرطي الخاص بـ Excel. ويمر تعبير القاعدة عبر المترجم نفسه الذي تمر به صيغ الخلايا، فتخرج المصفوفات والاتحادات والأعمدة الكاملة وعلامات $ بالصور الموصوفة أعلاه. وعلى جانب Delphi تضيف القواعد تماماً كما تضيفها لملف .xlsx

uses
  lxHandleX;

procedure AddOrderHighlights(Book: TXLSXWorkbook; Sheet: TXLSXWorksheet);
var
  Idx: Integer;
  Opts: TODSExportOptions;
begin
  // قواعد القيمة: ‏style:map ‏cell-content()>100 مع قيمة calcext ‏">100"
  Idx := Sheet.AddConditionalFormat('A1:A50', xlsxCfOpGreaterThan, '100');
  Sheet.ConditionalFormats[Idx].Style.SetFillBgColor($00C0C0FF); // ‏BGR: أحمر فاتح

  Idx := Sheet.AddConditionalFormat('A1:A50', xlsxCfOpBetween, '1', '10');
  Sheet.ConditionalFormats[Idx].Style.SetFontBold(True);

  // قاعدة صيغة بصياغة Excel ‏(فواصل بفاصلة، نسبية إلى C1):
  // ‏style:map ‏is-true-formula(...) مع ‏calcext ‏formula-is(...)
  Idx := Sheet.AddCondFormatExpression('C1:C50', 'COUNTIF($C:$C,C1)>1');
  Sheet.ConditionalFormats[Idx].Style.SetFillBgColor($00CCFFFF); // ‏BGR: أصفر فاتح

  Opts := TODSExportOptions.Create;
  try
    Opts.Generator := 'OrderExport 3.1';
    Book.SaveAsODS('orders.ods', Opts);
  finally
    Opts.Free;
  end;
end;

قراءة ODS من Excel و LibreOffice عائدةً إلى Delphi

حين يفتح HotXLS ملف ODS يقبل قارؤه لهجتَي التنسيقات الشرطية وتهجئتي calcext معاً، ولا يعدّ قاعدةً مرتين حين يحملها الملف بالصورتين. الملفات الحقيقية تأتي من ثلاثة كاتبين، لكل منهم عاداته:

  • ‏calcext القديم والجديد. الملفات ذات خاصية calcext:operator، ومنها ODS كتبه HotXLS قبل v2.384.69، تمر عبر التحليل القديم ما زالت. وتُعرف شروط الصيغ بـ formula-is(...) أو is-true-formula(...) كليهما
  • تهجئة style:map الخاصة بـ Excel. يسوق Excel الشروط بسابقة of:، كما في of:cell-content-is-between(1,10)، ويحذف الخلية الأساس في قواعد القيمة. وكلاهما مقبول
  • الخلايا الفارغة. يضع Excel و LibreOffice كلاهما خريطة الخلايا الفارغة على النمط الافتراضي للعمود لا على خلية، فيحل القارئ الأنماط الافتراضية للأعمدة للخلايا المتكررة قبل جمع الخرائط
  • إعادة بناء النطاقات. تُجمع الخرائط لكل خلية، فبعد قراءة ورقةٍ يدمج القارئ الخلايا المتشاركة في الشرط والخلية الأساس نفسيهما نطاقاتٍ، أولاً عبر كل صفٍ ثم نزولاً في امتدادات الأعمدة المتطابقة، ويسقط أي قاعدة قُرئت سلفاً من calcext

إصلاح v2.384.72 يخص أنماط الأرقام لا القواعد. يكتب Excel 16 و LibreOffice 26.2 كلاهما تنسيق General نمطَ أرقامٍ عنصرُ number:number فيه بلا number:decimal-places، عادةً <number:number number:min-integer-digits="1"/>. عامل قارئ HotXLS العددَ المفقود عشريتين ثابتتين، فاستوردت كل قيمة في نمط Default بـ 0.00 وعُرض 1.5 بـ 1.50. ومنذ v2.384.72 يقابل عنصر العدد العاري بلا منازل عشرية ولا حد أدنى للعشريات ولا تجميع وبمحرف صحيح واحد على الأكثر تنسيقَ General، و General المنفرد يترك الخلية بلا تنسيق أرقام أصلاً. ويُحفظ النص حوله، كما في General" kg"، والأرقام المجمعة تبقي المطابقة السابقة لأن Excel لا يملك تنسيق General مجمّعاً

uses
  SysUtils, lxCondFormat, lxHandleX;

procedure DumpOdsRules(const FileName: string);
var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Rule: TXLSXConditionalFormat;
  I: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.Open(FileName) <= 0 then
      raise Exception.Create('cannot open ' + FileName);
    if Book.SourceFormat <> xlsxOpenDocumentSpreadsheet then
      raise Exception.Create('not an ODS package');

    Sheet := Book.Sheets[1]; // فهرس Sheets يبدأ من 1
    for I := 0 to Sheet.ConditionalFormats.Count - 1 do
    begin
      Rule := Sheet.ConditionalFormats[I];
      case Rule.Kind of
        cfkCellIs:
          Writeln(Rule.Range, ' value rule ', Ord(Rule.Op), ' ',
            Rule.Formula1, ' ', Rule.Formula2);
        cfkExpression:
          Writeln(Rule.Range, ' formula rule ', Rule.Formula1);
      end;
    end;

    // خلية بنمط Excel العام تعود للقراءة بلا تنسيق أرقام
    // منذ v2.384.72، بدل '0.00'
    Writeln('A2 format: "', Sheet.Cells[2, 1].NumberFormat, '"');
  finally
    Book.Free;
  end;
end;

تعود صيغ القواعد بصياغة Excel بفواصل الفاصلة، الصورة نفسها التي تمررها إلى AddCondFormatExpression، فالقاعدة التي كتبها HotXLS تعود السلسلةَ المتطابقة نفسها. وللصورة الأوسع عما يحفظه مسار استيراد ODS وما يُسقطه، راجع دليل دورة فتح وحفظ ODS في HotXLS؛ ولمعرفة كيف تُمدَّد الصفوف المتكررة من Excel و LibreOffice عند الاستيراد، راجع الصفوف المتكررة في ODS بوصفها مدّات ارتفاع صفوف

ما حدود توافق التنسيقات الشرطية في ODS مع HotXLS؟

منهج الوسم المزدوج يغطي قواعد مقارنة القيم وقواعد الصيغ، ويتوقف هناك. كل ما عداه أحادي الجانب أو لا يُكتب أصلاً:

  • سلالم الألوان وأشرطة البيانات تكتب عناصر calcext وحدها، فيعرضها LibreOffice ولا يعرضها Excel
  • أنواع القواعد الأخرى، كمجموعات الأيقونات وقواعد النص و top-N وفوق المتوسط والتكرار، ليس لها ناتج ODS في الكاتب الحالي. يمكن عادة إعادة صياغة قاعدة نص قاعدةَ صيغة، مثل ISNUMBER(SEARCH("late",B2)) فوق B2:B200، فتصل إلى التطبيقين
  • قواعد العمود الكامل والصف الكامل مثل C:C تُبسط فوق مساحة الجدول المكتوبة فعلاً فقط، لا فوق 1,048,576 صفاً كلها، فرى Excel تلك القواعد على الخلايا الموجودة في الملف وحدها
  • الملفات ذات style:map وحده. حين لا يحوي الملف كتلة calcext يفسّر HotXLS المراجع النسبية في قواعد الصيغ من الزاوية العلوية اليسرى للنطاق المعاد بناؤه، لا بالإزاحة من الخلية الأساس المذكورة
  • القواعد المتداخلة من LibreOffice. حين تغطي عدة قواعد خليةً واحدة يكتب LibreOffice خريطة القاعدة الأولى وحدها عليها. ومثل تلك الملفات لا يمكن قراءته كاملاً من style:map وحده، وهذا سبب إضافي ليفضّل القارئ calcext حين يوجد كلاهما

حد العملية أهم من كل هذه. تجاوزت العيوب خلف هذه الإصدارات دوراتٍ كتبت ODS وقرأتها عائدةً بـ HotXLS، وكان بعضها سيمر أيضاً فحصاً يدوياً في التطبيق الخطأ: صيغ الأعمدة الكاملة عملت في LibreOffice بينما عرض Excel ‏#NAME?، ومنذ v2.384.66 عملت قواعد الصيغ في LibreOffice بينما لم يعرض Excel أي قواعد حتى v2.384.69. إن كان توافق ODS متطلباً، فاختبار القبول هو فتح الملف في Excel وفي LibreOffice ومقارنة ما يعرضه كل منهما. ويسري الانضباط نفسه على الأنماط التي تشير إليها القواعد؛ تغطي مقالة التنسيق الشرطي والأنماط في HotXLS كيفية تعريف أنماط التظليل على جانب المصنف

مرجع سريع: ODS يقرؤه التطبيقان معاً

  • صرّح xmlns:of و xmlns:msoxl على جذر content.xml، وإلا عرض LibreOffice ‏#VALUE! لكل صيغة ‏(HotXLS منذ v2.384.56)
  • اكتب المراجع [.A1]، واحفظ كل $، واكتب الأعمدة والصفوف الكاملة [.A:.A] و [.1:.1] ‏(منذ v2.384.55 و v2.384.65)
  • استخدم ; للوسائط، و ~ لاتحادات المراجع، و | بين صفوف المصفوفة المضمّنة
  • اكتب كل قاعدة قيمة أو صيغة <style:map> على نمط كل خلية مغطاة لأجل Excel، وشرط calcext لأجل LibreOffice ‏(منذ v2.384.69)
  • في calcext ضع العامل داخل القيمة ‏(>3، between(1,10)) وهجئ قواعد الصيغ formula-is(...) مع خلية أساس ‏(منذ v2.384.66 و v2.384.69)
  • توقع نمط أرقام General بلا number:decimal-places عند الاستيراد؛ يقرؤه HotXLS بوصفه General منذ v2.384.72
  • تحقق من كل ملف تصدير جديد بفتح الملف في Excel و LibreOffice معاً، لا في أحدهما قط

‏HotXLS مكتبة جداول أصلية لـ Delphi و C++Builder تقرأ XLS و XLSX و ODS وتكتبها دون Excel أو LibreOffice مثبتين؛ والمصدر الكامل وقائمة المزايا والترخيص في صفحة مكوّن HotXLS Delphi للجداول الحسابية