يستطيع HotXLS أن يضع مخططًا مباشرة على ورقة عمل، مربوطًا بمجال خلايا، بدل وضعه على ورقة مخططات مخصصة. وبمصطلحات BIFF8 هذا يعني كتابة شكل رسم بسجل OBJ من النوع 5 وإرساء التدفق الفرعي للمخطط في نهاية تدفق سجلات الورقة، وهو بالضبط التخطيط الذي ينتجه Excel وبالضبط الموضع الذي يتوقع القارئ أن يجده فيه
والتمييز يهم كل من يولّد تقارير تشغيلية. فورقة المخططات بيت جيد لمرئي رئيسي منفرد. أما تفصيل شهري إقليمي فيريد المخطط بجوار الأعداد التي يلخصها، على الورقة نفسها، بحجم مقاس لكتلة الخلايا التي ينتمي إليها، فيتمرر القارئ مرة واحدة بدل تبديل التبويبات وفقدان السياق
القراءة كانت موجودة والكتابة لم تكن
ولاتماثل يستحق التسمية لأنه يشكّل العمل. كان HotXLS يقرأ أصلًا المخططات المضمنة: حين يحوي تدفق سجلات ورقة العمل BOF موسومًا تدفقًا فرعيًا لمخطط، يبدّل المحلل السياق ويجمع سجلات المخطط، وعند EOF الختامي يسلّمها إلى شكل الرسم الذي قدّمه سجل OBJ. وتمرّن ذلك المسار على كل مصنف كتبه Excel فتحته المكتبة يومًا
والمفقود كان جانب التأليف، والنتيجة النافعة أن الكاتب الجديد كان لديه مواصفة دقيقة يصيبها: أن ينتج تخطيط البايتات الذي يعيد القارئ القائم إلحاقه أصلًا. ولا يوجد معيار قبول أفضل لميزة صيغة ثنائية من قارئ كُتب باستقلال لم تُتَح لك فرصة تغييره
مم يتكون المخطط المضمَّن
ثلاث قطع يجب أن تتفق. فطبقة الرسم تسهم شكل مضيف تحكم، وطبقة الكائن تسهم سجل OBJ تعلن بيانات الكائن المشتركة فيه نوع الكائن 5، وتدفق السجلات يسهم التدفق الفرعي للمخطط نفسه. وأعلام الخيارات على سجل OBJ هي التي يكتبها Excel لإطار مخطط: محدَّد الموضع، ومقفل، وخط تلقائي وتعبئة تلقائية، وهذا ما يجعل المخطط المضمَّن يتصرف كأصلي حين ينقره مستخدم
والمرساة تستحق ملاحظة لأنها مصدر شائع لأخطاء الانحراف بواحد. تأخذ واجهة HotXLS البرمجية أرقام صفوف وأعمدة تبدأ من واحد، مطابقة لبقية المكتبة، والمرساة العميلة المكتوبة في الملف تبدأ من صفر. ويحدث التحويل داخل AddChartObject فيبقى المستدعون في نظام الإحداثيات الذي يستخدمونه في كل مكان آخر، لكن أي من يقارن تفريغًا سداسيًا عشريًا باستدعائه الخاص يحتاج أن يتذكر أي جانب من ذلك الحد يقرأ
var
Book: TXLSWorkbook;
Sheet: TXLSWorksheet;
Series: array[0..1] of TXLSChartSeriesInfo;
begin
Book := TXLSWorkbook.Create(nil);
try
Book.LoadFromFile('regional-sales.xls');
Sheet := Book.Sheets[0];
FillChar(Series, SizeOf(Series), 0);
Series[0].Name := 'Actual';
Series[0].Categories := 'Data!$A$2:$A$13';
Series[0].Values := 'Data!$B$2:$B$13';
Series[0].DataLabels.ShowValue := True;
Series[0].HasDataLabels := True;
Series[1].Name := 'Target';
Series[1].Categories := 'Data!$A$2:$A$13';
Series[1].Values := 'Data!$C$2:$C$13';
Series[1].SecondaryAxis := True;
// مربوط إلى E2:M20 على هذه الورقة، يبدأ الترقيم من واحد
Sheet.AddChartObject(xlsChartTypeColumn, 'Regional sales',
'Month', 'Amount', Series, 2, 5, 20, 13);
Book.SaveToFile('regional-sales-charted.xls');
finally
Book.Free;
end;
end;
وFillChar على مصفوفة السلاسل ليس زينة. فـ TXLSChartSeriesInfo تحمل عدة سجلات فرعية اختيارية: ملصقات بيانات، ونمط لكل سلسلة، وخطوط اتجاه، وأشرطة خطأ، كل منها موصوم بقيمة منطقية، وسجل مهيأ جزئيًا على المكدس سيسلّم المُصدِر أعلامًا لم يضبطها أحد. صفّر المصفوفة، ثم اضبط الحقول التي تقصدها
أي مراجع سلاسل يقبلها المسار المضمَّن
مجالات طراز A1 العادية داخل المصنف نفسه، وهذا القيد متعمد لا سهو. فكل مرجع يُحل مقابل قائمة أوراق المصنف ويُحوَّل إلى فهرس المرجع الخارجي الذي تحتاجه سجلات المخطط. والمجال المسمى أو مرجع مصنف خارجي يرتد إلى عنصر نائب بتعبير محلول بطول صفري، فيُكتب المخطط بنظافة لكن تلك السلسلة بعينها بلا مصدر بيانات حتى توجهها إلى مجال
والسبب مقايضة هندسية صريحة. فمسار ترجمة المراجع الكامل موجود على طريق ورقة المخططات، ملفوفًا داخل طبقة مجموعة أوراق العمل، وانتزاعه بنظافة سيعني مضاعفة مئة سطر من منطق الحل لحالة غير شائعة في الممارسة. فالمخطط المضمَّن يرسم عادة خلايا على ورقته هو أو على ورقة بيانات شقيقة. والمراجع المسماة والخارجية مغطاة على مسار ورقة المخططات عبر AddChartSheet، فلا شيء غير متاح، بل يُبلَغ من نقطة دخول مختلفة
وكل شيء آخر في نموذج السلاسل يعمل تماثلًا على الطريقين. ربط المحور الثانوي، وأنماط الخط والتعبئة والعلامة لكل سلسلة، وخطوط الاتجاه، وأشرطة الخطأ، وملصقات البيانات، كلها جزء من TXLSChartSeriesInfo وكلها تُصدَر بالطريقة نفسها، فيستطيع تعريف مخطط أن ينتقل بين كائن مضمَّن وورقة مخططات باختلاف الاستدعاء فقط. وآليات مجموعة المحاور وراء علم المحور الثانوي مغطاة في مجموعات المحور الثانوي في كتابة BIFF
لماذا قُرئ عنوان المخطط محرفين اثنين
لأن عددًا من المحارف مُرِّر حيث كان يُتوقع عدد بايتات، وسلاسل Unicode في BIFF تجعل ذلك الخطأ سهل الكتابة عسير الرؤية. فسلسلة BIFF Unicode قصيرة تبدأ بعدد محارف وبايت أعلام، وبايت الأعلام يحمل بت البايت العالي الذي يقول هل الحمولة بايت لكل محرف أم اثنان. اقرأ حمولة 16-بت بعدد المحارف وكأنه طول بايتات وستحصل على نصف السلسلة بالضبط: سلسلة اسمها Sales تعود Sa، وعنوان مخطط يُقتطع بالطريقة نفسها لأن العناوين وملصقات السلاسل تتشارك مسار فك الترميز
وما يجعل هذا العيب جدير الذكر أنه تكرر ثلاث مرات في العائلة نفسها من السجلات: مرة في أسماء خطوط الاتجاه، ومرة في أسماء مخططات pivot، ومرة في عناوين المخططات. وكل ظهور بدا خطأ جديدًا في ميزة جديدة. والثلاثة كانت الضربَ المفقود نفسه. والقاعدة التي أغلقت الأمر في النهاية ميكانيكية وينبغي تطبيقها دون تمييز: كلما قرأت إحدى هذه السلاسل، راجع علم البايت العالي أولًا واضرب عدد المحارف في عرض الحمولة قبل أن تلمس المخزن. والتفاصيل على مستوى السجل في فك ترميز عدّادات محارف XLUnicodeString وعلم البايت العالي
// المخطط المضمَّن يشارك طبقة الرسم مع الصور والأشكال، لذا يبقى
// رسم قائم على الورقة محفوظًا. وAddChartObject تعيد فهرس
// الكائن المنشأ
var
ObjIndex: Integer;
begin
ObjIndex := Sheet.AddChartObject(xlsChartTypeLine, 'Trend',
'Week', 'Units', Series, 2, 8, 18, 16);
if ObjIndex < 0 then
raise Exception.Create('chart object was not created');
end;
موضع المخططات المضمنة مقابل البدائل
ثلاثة طرق موجودة وتجيب عن أسئلة مختلفة. فكائن مخطط مضمَّن مكانه بجوار بياناته على ورقة عمل وهو ما تريد معظم التقارير. وورقة المخططات تناسب مرئي عرض منفرد وتعطيك مسار ترجمة المراجع الكامل. أما الحفاظ على مخطط قائم من ملف محمل دون مساس فهو الجواب الصائب حين جاء المصنف من Excel بتنسيق لا يريد أحد أن تعيد مكتبة تأويله؛ وهذا السلوك العابر موصوف في ChartML المحفوظ والمخططات المركبة
ولأن المخطط المضمَّن يركب طبقة الرسم، فهو يتعايش مع الصور والأشكال على الورقة نفسها بدل أن يستبدلها، والنموذج العام لتلك الطبقة مغطى في المخططات والصور والرسومات في HotXLS. والطرق الثلاثة كلها ترد في مكوّن جداول HotXLS Delphi، فيكون الاختيار فيما يجب أن يبدو عليه التقرير لا فيما تستطيع المكتبة التعبير عنه
والنقطة المنهجية هي التي تستحق البقاء. حين يكون لميزة صيغة ثنائية قارئ قائم، ابنِ الكاتب مقابل القارئ لا مقابل قراءتك أنت للمواصفة. فالقارئ يشفّر سنوات من الاتصال بملفات أنتجتها تطبيقات حقيقية فعلًا، بما فيها الأجزاء التي تصفها المواصفة بتراخٍ، والكاتب الذي يرضيه أبعد أن يرضي Excel أيضًا