ميزات تنفيذ قوائم ديناميكية في واجهات المستخدم

صورة

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

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

خلق


تتم إضافة القوائم في النموذج في lsFusion بواسطة عبارة OBJECTS :
OBJECTS i = Item
ستتم إضافة جدول إلى النموذج ، حيث سيتم تضمين كافة كائنات فئة العنصر في الصفوف. يمكنك إضافة كائنات متعددة إلى قائمة واحدة. على سبيل المثال
OBJECTS (i = Item, s = Stock)
في هذه الحالة ، سيعرض الجدول جميع أزواج الكائنات الممكنة لفئات العناصر والأسهم.

تتم إضافة الأعمدة إلى القائمة مع بيان الخصائص :
PROPERTIES name(i), name(s), quantityOnHand(i, s)
في الجدول يمكن إضافة تفاصيل بسيطة للكائن ، وكذلك أي تعبيرات مع التجمعات ، والتقسيم ، والتكرار ، وهلم جرا.

بشكل افتراضي ، ستظهر القائمة جميع الكائنات في قاعدة البيانات. لتقييدهم ، يمكنك استخدام عبارة FILTERS :
FILTERS quantityOnHand(i, s) > 0
في حالة التصفية ، يمكنك استخدام أي تعبير يعتمد على أي كائنات في النموذج.

ملاحة


عندما يفتح المستخدم النموذج ، تحدد المنصة تلقائيًا عدد السجلات المرئية وفقًا لحجم الجدول. لسهولة العرض التقديمي ، نفترض أن هناك 50 من هذه السجلات ، وفي كل لحظة من الوقت ، ستقوم المنصة بتخزين 150 سجلًا على العميل وعلى الخادم. في هذه الحالة ، يجب أن يكون الكائن النشط الحالي في منتصف "النافذة": من السجل 50 إلى السجل 99. قد يكون هناك عدد أقل من الإدخالات إذا كان الكائن الحالي إما في البداية أو في نهاية القائمة.

إذا كنت بحاجة إلى تنشيط سجل معين عند فتح النموذج ، يتم تقديم طلبين إلى خادم قاعدة البيانات ، يقرأ كل منهما 75 سجلًا على كل جانب من السجل المطلوب. ثم يتم لصقها على قائمة عامة من نتائجها. في حالة الحاجة إلى تهيئة القائمة من البداية أو النهاية ، يتم تقديم طلب واحد لـ 100 سجل ، ويكون السجل الأول أو الأخير المستلم نشطًا. يحدث الشيء نفسه إذا ضغط المستخدم على CTRL + HOME أو CTRL + END في القائمة للانتقال إلى بداية أو نهاية القائمة.

بمجرد قيام المستخدم بإجراء تسجيل نشط خارج منتصف النافذة الحالية (قبل الخمسين أو بعد الـ 99) ، يقرأ النظام الأساسي سجلات إضافية بحيث يكون السجل الحالي في "مركز" الإطار الجديد تمامًا.

خصوصية تطبيق القائمة الديناميكية هذه هو أن الكائن الحالي لا يمكن أن يكون خارج منتصف النافذة. لذلك ، عند تمرير القائمة ، يتم نقل الكائن الحالي تلقائيًا إلى المنطقة المرئية.
صورة


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

تصفية


يمكن تصفية الإدخالات في القائمة في النموذج بناءً على الخيارات التالية:

  • إشارة في رمز الاختيار المستمر باستخدام عبارة FILTERS:
    FILTERS <>
    قد يعتمد التعبير على أي كائنات أخرى محددة حاليًا في النموذج. على سبيل المثال ، إذا كان هناك جدول أو شجرة بها مستودع في النموذج ، فعندئذٍ في التعبير عن قائمة البضائع ، يمكنك الرجوع إلى المستودع الحالي لتصفية البضائع الموجودة في الرصيد فقط.
  • الإشارة في رمز الاختيار ، والتي يمكن للمستخدم تطبيقها عند الضرورة باستخدام تعليمة FILTERGROUP :
    FILTERGROUP myFilters
    FILTER 'Filter 1' <expression> 'F5' DEFAULT
    FILTER 'Filter 2' <expression> 'F6'

    ستتم إضافة قائمة منسدلة إلى النموذج (أو مربع اختيار إذا كان هناك مرشح واحد في المجموعة) ، حيث يمكن للمستخدم اختيار أحد المرشحات التي يجب تطبيقها.
    صورة
  • التصفية المخصصة يدويًا التي قام بها المستخدم في الواجهة:
    صورة
    إذا لم يكن العمود في القائمة قابلاً للتحرير ، فعند إدخال الأحرف ، سيتم تشغيل مرشح هذا العمود تلقائيًا ، ويمكن إعادة ضبطه بضغطة واحدة على مفتاح ESC.

يراقب النظام الأساسي نفسه التغييرات في أي ظروف قد تؤثر على الفلتر الحالي (تغيير الكائنات التابعة ، وإجراءات المستخدم ، وما إلى ذلك). عند اكتشاف هذه التغييرات ، يتم تحديث القائمة تلقائيًا دون تغيير الكائن المحدد حاليًا. للقيام بذلك ، يتم تقديم طلبين ، 75 إدخالًا في كل اتجاه من الاتجاه الحالي ، وكذلك أثناء تهيئة النموذج.

الفرز


بشكل افتراضي ، يتم فرز الإدخالات الموجودة في القوائم بترتيب تصاعدي للمعرفات الداخلية للكائنات. يتم إنشاء هذه المعرفات تلقائيًا بترتيب تصاعدي عند إنشاء كائنات (في الوقت نفسه ، تكون فريدة من نوعها على مستوى العالم في جميع الفئات) ، ويتم بناء الفهارس عليها دائمًا.

يمكن تغيير التصنيف في القائمة كما يلي:

  • عن طريق الإشارة في الكود إلى الأعمدة التي يتم بها الفرز من خلال جملة ORDER :
    ORDER column1(o) DESC , column2(o)
  • النقر المزدوج على عنوان العمود من قبل المستخدم (الضغط على CTRL سيضيف الفرز "المتداخل").
    صورة

اعتمادًا على التصنيف الحالي ، عند قراءة مفاتيح السجل ، ستتم إضافة تعبيرات الأعمدة المقابلة إلى كتلة ORDER BY من الطلب. في الوقت نفسه ، تتم دائمًا إضافة المعرّف الفريد للكائن (الكائنات) إلى الفرز للتأكد من أن مفاتيح جميع السجلات فريدة.

تعبير عن النموذج: column1> value1 OR (column1 = value1 AND column2> value2) أو سيتم إضافة OR (column1 = value1 و column2 = value2 AND key> value) إلى جملة WHERE للطلب. أيضًا ، عند قراءة المفاتيح ، ستتم إضافة تعليمة LIMIT بالعدد المطلوب من السجلات القابلة للقراءة إلى الطلب. عند قراءة السجلات "للأعلى" ، سيتم "انقلب" الترتيب الموجود في ORDER BY والتعبير في WHERE وفقًا لقراءة السجلات في الاتجاه المعاكس.

تجدر الإشارة إلى أن درجة تعقيد أداء هذه الاستعلامات ستكون صغيرة نسبيًا إذا كان هناك فهرس مناسب (لأن الفهرس سيكون عدد الكيلومترات بدءًا من المفتاح الحالي لأعلى أو لأسفل فقط من خلال عدد محدد من السجلات). لذلك ، لتسريع العمل باستخدام القائمة الديناميكية عند الفرز حسب العمود 1 ، العمود 2 ، يوصى بإنشاء الفهرس التالي:
INDEX column1(Object o), column2(o), o;
إذا كان الفرز يعتمد على العمود المحسوب ، فيمكن إجراء تخزينه بشكل دائم ، كما هو موضح في هذه المقالة ، ومن ثم يمكن بناء فهرس عليه.

واحدة من ميزات هذا التطبيق هو عدم وجود شريط التمرير "صادقة". عند قراءة السجلات ، يتم قراءة العدد اللازم منها فقط. قد يؤدي طلب الحصول على العدد الإجمالي للصفوف في القائمة عبر COUNT (*) مع المرشح المطلوب إلى تشغيل كامل على الجدول أو الفهرس ، مما سيؤثر سلبًا على الأداء. سوف تحدث نفس المشكلة عند قراءة السجلات من خلال بناء OFFSET. بالإضافة إلى ذلك ، يجب أن يؤخذ في الاعتبار أنه عند التنقل في قائمة ، يمكن تغيير عدد الإدخالات فيه من قبل مستخدمين آخرين عن طريق إجراء تغييرات جديدة.

التحرير


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

لا توجد آلية محددة في lsFusion تنفذ قائمة التحرير مباشرة. يتم تنفيذ هذه الوظيفة كجزء من آلية الجلسة العامة.

يتم تخزين جميع التغييرات التي تم إجراؤها في جلسة التغيير الحالية في جداول مؤقتة. عندما يقوم المستخدم بتحرير شيء ما في النموذج (بما في ذلك القيمة في أحد الإدخالات) ، تتم كتابة القيم الجديدة في جداول مؤقتة باستخدام المفاتيح المناسبة. ثم ، عندما يقرأ الاستعلام الثاني (بعد استلام المفاتيح) قيم الأعمدة ، تتم إضافة JOIN مع الجداول المؤقتة المقابلة مع التغييرات إلى الاستعلام.

عند حفظ جلسة التغيير ، يتم تنفيذ استعلام ، والذي يقوم في إحدى المعاملات بكتابة جميع القيم من الجداول المؤقتة إلى قاعدة البيانات.

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


في كثير من الأحيان ، يحتاج المستخدم إلى تغيير قيمة العمود لجميع الكائنات المحددة في القائمة في وقت واحد. للقيام بذلك ، يوجد زر خاص في شريط الأدوات لكل قائمة (مع مفتاح الاختصار F12). عند الضغط عليه ، يتم تنشيط وضع تحرير الخلية العادي ، ولكن التغييرات لا تنطبق على السجل الحالي ، ولكن على كل المحددات.

تتيح لك هذه الآلية تحرير عدد كبير من الكائنات بسرعة وفقًا للمعايير المحددة:
صورة


وكذلك أثناء التحرير العادي ، لا يتم حفظ التغييرات فورًا في قاعدة البيانات ، ولكن يتم تسجيلها في جداول مؤقتة. ثم سيحتاج المستخدم إلى النقر فوق الزر " حفظ" لكتابته في قاعدة البيانات. قد يكون عيب هذا النهج أن المستخدم يغير عن طريق الخطأ البيانات الإضافية. ولكن هنا ، كما يقولون ، يعمل المبدأ: "مع القوة العظمى تأتي مسؤولية كبيرة".

ملخص القائمة


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


للحصول على هذه البيانات ، سيتم إنشاء طلب تلقائيًا باستخدام التعبير COUNT (*) أو SUM ، حيث سيتم إضافة تعبير التحديد الحالي. باستخدام هذه الميزة ، يمكنك الحصول بسرعة على الإجماليات من القوائم دون اللجوء إلى إنشاء تقارير.

في إصدار سطح المكتب من العميل ، من الممكن أيضًا حساب مجموع الخلايا المحددة عن طريق القياس باستخدام Excel:
صورة


نسخ / لصق


في إصدار سطح المكتب ، يتم منح المستخدم الفرصة لتمييز خلايا معينة ، واضغط على CTRL + C ، ولصق القيم منها في الحافظة:
صورة


بنفس الطريقة ، يمكنك لصق الجدول من الحافظة في أي قائمة قابلة للتحرير بأي شكل:
صورة

مثل هذه الفرصة غالبًا ما تكون بديلاً لتطوير الواردات المتخصصة.

إعداد الجدول


في أي قائمة ، يمكنك تغيير بعض معالمها:
صورة

يمكنك تغيير تركيبة الأعمدة وأحجامها وعناوينها وأقنعةها ، وما إلى ذلك. يمكنك حفظ إعدادات الجدول لكل من المستخدم الحالي ولجميع المستخدمين (إذا كان المستخدم الحالي لديه الحقوق اللازمة).

لاحظ الخيار حجم الصفحة. باستخدامه ، يمكنك تغيير حجم "النافذة" الموضحة في بداية المقال. على سبيل المثال ، بدلاً من 50 إدخال تلقائي ، يمكنك تحديد قيمة أكبر. بعد ذلك ، سيتم تنزيل كمية أكبر من البيانات إلى العميل والخادم ، ولكن الطلبات ستحدث بشكل أقل تكرارًا. سيؤدي تعيين قيمة هذه المعلمة إلى 0 إلى جعلها طبيعية من أي قائمة ديناميكية ، أي سيتم دائمًا قراءة جميع الإدخالات في القائمة. يمكن أيضًا تحديد حجم الإطار مباشرةً في الكود باستخدام معلمة pageSize لبيان DESIGN .

تصدير إلى Excel


لأي قائمة ، يمكن تحميل جميع سجلاتها في Excel. للقيام بذلك ، فقط انقر فوق الزر التالي:
صورة

هذا يأخذ في الاعتبار التحديدات الحالية ، والفرز ، وكذلك الأعمدة المرئية المحددة في إعدادات الجدول.

التمحور


بشكل افتراضي ، يتم عرض أي قائمة كجدول. ولكن هناك إمكانية للتبديل إلى وضع عرض خاص حيث يمكن للمستخدم إنشاء تقارير ورسوم بيانية مختلفة:
صورة


مع وجود عدد صغير من الإدخالات في القائمة ، سيتم معالجة البيانات مباشرة على العميل. بمجرد أن يتجاوز حجم البيانات حدًا معينًا ، سيتم استخدام استعلامات قاعدة البيانات التي تم إنشاؤها تلقائيًا على الخادم لتجميع البيانات.

البديل


يطرح سؤال معقول. كيفية حل مشكلة تحرير القوائم الديناميكية في الأنظمة الأساسية حيث لا يتم دعم هذه الميزة. في معظم الأحيان ، يقومون بإنشاء قائمة بسيطة ، مما يجبر المستخدم على تحديد عدد الإدخالات من خلال بعض التحديدات (على سبيل المثال ، تحديد عوامل تصفية حسب الفئة أو المورد أو الدلائل الأخرى ذات الصلة).

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

استنتاج


إن تنفيذ قائمة ديناميكية في التطوير الحديث ليس بالمهمة الأكثر تافهة ، حيث يتم إشراك كل من أجزاء العميل والخادم. هناك عدد غير قليل من المكتبات مفتوحة المصدر ذات ترخيص مفتوح في العالم تتيح لك تنفيذ هذه الوظيفة بسرعة وسهولة.

في النظام الأساسي المفتوح والمجاني lsFusion ، يتم إنشاء قوائم ديناميكية في عدة سطور من التعليمات البرمجية وتزويد المستخدم بعدد كبير من فرص العمل معهم. بالاقتران مع القدرة على تحرير هذه القوائم ، يتيح لك النظام الأساسي العمل بسرعة مع المستندات على مئات الآلاف من الخطوط ، وتنظيم عمل مناسب لتحديد السجلات في المستندات ، وتنفيذ تغييرات المجموعة على الأدلة ، وأكثر من ذلك بكثير.

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

Source: https://habr.com/ru/post/ar484648/


All Articles