Вивчаємо програмування в Gupta Team Developer. Крок 4 – Списки і таблиці, Інтеграція додатків і даних, Бази даних, статті

Частина 3



Дана стаття є четвертою у циклі статей під загальною назвою “Вивчаємо програмування в Team Developer / Gupta”, в якому ми постараємося дати починаючому користувачеві програмних продуктів GUPTA всю необхідну інформацію для вивчення програмування та отримання навичок створення інформаційних систем. У ній ми розглянемо роботу зі списками і комбінованими списками, а також зі статичними і динамічними таблицями. Для успішного засвоєння матеріалу читачеві бажано познайомитися з попередніми статтями з цього циклу, які розміщені на нашому сайті.


Введення


У даній статті ми приділимо увагу питанням застосування списків і таблиць для організації програмного інтерфейсу в інформаційних системах. Для успішного освоєння даного матеріалу, який, ми дуже сподіваємося, може служити своєрідним самовчителем програмування на Centura TD, бажано познайомитися і виконати завдання статей “Крок 1”, “Крок 2″І”Крок 3”.


У спрощеному варіанті списки і таблиці можна розглядати як одномірні (списки) і багатовимірні (таблиці) масиви з можливістю автоматичного відображення у вигляді об’єктів інтерфейсу. Списки забезпечують зберігання і вибір впорядкованої, динамічно змінюваною інформації і є незамінними об’єктами віконного інтерфейсу. Масиви, крім цього, дозволяють зберігати різнорідну інформацію, забезпечують можливості її редагування, перегляд і зберігання інформації з БД. У даній статті ми розгляне базові можливості цих об’єктів, роботу ж з базами даних передбачається детально розібрати в наступній статті даного циклу.


Почнемо зі списків і комбінованих списків.


Списки і комбіновані списки


Список (List Box) – Це стандартний об’єкт віконного інтерфейсу. Списки забезпечують виконання таких операцій: зберігання символьної інформації (впорядкованої або невпорядкованою); візуальний або програмний вибір інформації з певної позиції; модифікацію збереженої інформації (додавання, видалення, очищення та зміна елементів списку), а також інші корисні операції. Список визначається як окремий фрагмент вікна, в якому забезпечується горизонтальна і вертикальна прокрутка інформації. Комбіновані списки (Combo Box) на додаток мають спеціальне поле для редагування або завдання інформації для оперативного пошуку позицій за змістом (початкові символи для пошуку). Робота зі списками та комбінованими списками дуже схожа і виконується набором спеціальних функцій. Кожна з цих функцій має префікс “SalList“. Нижче ми розглянемо роботу з цими функціями. Для роботи зі списками і комбінованими списками ми розробили спеціальний додаток (step4_list.app), роботу якого пояснимо нижче.


Списки


Вікно програми для вивчення методів роботи зі списками (у режимі роботи зі списками) представлено нижче на малюнку.

Рис. 1. Вікно програми для вивчення списків в режимі List Box


Розглянемо основні об’єкти вікна, які необхідні для вивчення списків. У правому верхньому куті розташований список, в якому висвітлений три елементи (“Л5”, “Л4” і “Л2”), причому елемент “Л4” є виділеним (selected). В даному випадку вікно знаходиться в режимі маніпулювання списками (радіокнопки “Вибір типу списку“Знаходяться в режимі List Box). Поле “Значення для заповнення“Може містити інформацію: префікса для циклічного додавання (кнопка”Заповнити List“) Або значення при одиночному додаванні (кнопка”Додати в List“). Поле”Число додаються“Визначає число елементів, що додаються в список при циклічному додаванні. Перемикач”Режим в кінець“Визначає спосіб додавання одиночних елементів (на початок або в кінець списку відповідно). Кнопка”Вибрати в List“Дозволяє вибрати третій елемент списку (Нумерації списку проводитися з 0, тому в програмі потрібно вказувати 2-й елемент). Кнопка”Очистити List“Дозволяє видалити всі елементи зі списку. Кнопка”Видалити по №“Дозволяє видалити елемент із зазначеним номером (номер задається в спеціальному полі”Номер уд.“, Причому вказується логічний номері, фізичний буде на одиницю менше). Кнопки”Встановити за номером “ і “За значенням“Дозволяють виділити елемент списку заданий номером (поле праворуч від кнопки) або заданий значенням (поле праворуч від відповідної кнопки). Кнопка”Опитування стану List“Дозволяє визначити: число елементів у списку, номер поточного обраного елемента і його значення. Поля, захищені від редагування, з відповідними назвами розташовані поруч із кнопкою опитування.


Розглянемо тепер, як програмно виконуються ці дії. Зазначимо, що після такого знайомства Ви зможете самостійно створити додаток і перевірити на практиці виконання операцій зі списками. Нижче ми наведемо текст Sal – фрагментів операцій із списками в даній програмі. Для цього на наступному малюнку ми розглядаємо перелік всіх об’єктів інтерфейсу для розробляється. Пояснимо також тут і об’єкти, необхідні для вивчення комбінованих списків.


Кнопка pbClose служить для закриття вікна та програми. Об’єкт cmbList (Тип Combo Box) Використовується для вивчення комбінованих списків. Об’єкт lbox1 (Тип List Box) Використовується для вивчення простих списків.

Рис. 2. Об’єкти вікна програми для вивчення списків


Кнопки управління (тип Pushbutton) Мають наступне призначення:



PbSelect – “Вибрати в List / Combo”
PbSelectNum – “Встановити за номером”
PbClear – “Очистити List / Combo”
pbAddList – “Додати в List / Combo”
pbTest – “Перевірка”
(Перевірка режиму додавання в список)
PbListFill – “Заповнити List / Combo”
pbSelVal – “За значенням”
pbQueryList – “Опитування стану List / Combo”
pbDelList – “Видалити по №”.


Поля інтерфейсу (тип Data Field) Мають наступне призначення:



DfAddList – “Значення для заповнення”
dfListCount – “Кількість додаються”
dfNumDel – “Номер уд.”
dfNumSel –
номер для установки елемента (без назви)
dfValSel –
значення для встановлення елемента (без назви)
DfNumbElem – “Кількість елементів”
dfSelected – “№ вибраного”
dfSelVal – “Значення вибраного”
dfCompbo –
поле для індикації режиму комбінованих списків
dfList – Поле для індикації режиму простих списків.


Перемикачі режимів: rbCombo (Тип Radio Button) – Режим роботи для перевірки комбінованих списків, rbList (Тип Radio Button) – Режим роботи для перевірки простих списків і cbRegim (Тип Check Box) Для установки режиму додавання до списків. Об’єкти лінії, фоновий текст і об’єкти угруповання не показані на малюнку для простоти, але вони є в додатку.


Розглянемо спочатку найпростішу операцію установки в списку за номером. В даному випадку активним стає 3-й елемент списку (логічний номер). Для установки використовується спеціальна функція з двома параметрами – SalListSetSelect. Перший параметр задає ім’я об’єкта типу список, а другий параметр номер встановлюваного елемента (нагадаємо, що фізична нумерація виконується з нуля). У даному тексті показано, як використовується перемикач (rbList) Для перемикання режимів вивчення списків і комбінованих списків (оператори If – Else If мови SAL).

Рис. 3. Установка елемента списків у позиції 3-го елемента


На наступному фрагменті тексту показана установка довільного номера елемента списку з доданим контролем. Поле введення вікна dfNumSel визначає номер для установки позиції, функція для установки аналогічна. Для визначення поточного числа елементів у списку використовується функція SalListQueryCount, Яка повертає число елементів, маючи в якості єдиного параметра назву списку (lbox1).

Рис. 4. Установка елемента списку в задану позицію (dfNumSel -1)


Наступний простий фрагмент тексту SAL ілюструє використання функції очищення списків – SalListClear. Як параметр цієї функції задається ім’я об’єкта списку.

Рис. 5. Очищення списків


При додаванні до списку нових елементів можна скористатися функціями SalListAdd або SalListInsert. Нижче показано використання цих функцій. У функції SalListInsert другий параметр вказує номер нового елемента, а третьому параметрі задається значення, що додається до списку (у нашому випадку це символьне поле – dfAddList). Перемикач у вікні “Режим в кінець” (cbRegim) Визначає спосіб додавання до списку нових елементів (у початок – FALSE або в кінець – TRUE). Крім цього в даному фрагменті показано використання функції SalListQueryCount, Яка використовується для визначення поточного числа елементів у списку (повертає цілочисельне значення числа елементів у списку). Щоб додати в кінець списку може бути вказаний номер елемента наступний за останнім (нагадаємо, нумерація в списку починається з нуля). При додаванні в початок списку вказується нуль. Щоб додати в кінець списку допускається вказувати значення “-1”.

Рис. 6. Додавання елемента списку на початок (0) або в кінець (режим – cbRegim)


При додаванні в кінець списку можна скористатися функцією SalListAdd, Яка має два параметри, другий вказує додається значення. Номер в цьому випадку не задається як параметр. На фрагменті тексту, показаному на малюнку нижче, проілюстровано використання цієї функції в циклі заповнення списку. Дана процедура ініціюється після натискання кнопки pbListFil l – (“Заповнити List / Combo“). Число додаються елементів визначається полем введення dfListCount, Значення якого задається вручну у вікні. Зміст додається рядка в список визначається комбінацією значення поля dfAddList – (“Значення для заповнення“) І порядкового номера додається елемента, що задається цілочисельним лічильником циклу (nCount). Для переведення в символьне подання числа застосована стандартна функція мови SAL – SalNumberToStrX. У додатку step4_list.app передбачено заповнення при відсутності введеного значення в поле dfListCount, В цьому випадку додається фіксований число елементів (п’ять елементів). Це в даному фрагменті тексту для скорочення обсягу не показано.

Рис. 7. Заповнення списку заданим числом елементів (dfListCount)

У списках передбачається виділення рядка на основі значення заданого в програмі. Для цього використовується функція SalListSelectString, Яка містить три параметри. Фрагмент тексту вибору елемента за значенням зображений на нижньому малюнку, ця процедура активізується при натисканні кнопки – pbSelVal – (“За значенням“). В якості другого параметра задається стартовий номер пошуку (у нас 0 – початок списку), а третій параметр визначає значення для пошуку (dfValSel). Якщо шуканий елемент не знайдений, то функція повертає стандартну константу помилки – LB_Err, Яка, до речі, часто використовується для перевірки коду повернення стандартних функцій, що працюють зі списками. Якщо елемент не знайдений, то видається діагностичне повідомлення.

Рис. 8. Вибір елемента списку з заданим значенням (dfValSel)

Зворотній завдання виникає при необхідності визначення елемента, вибраного в списку. У фрагменті тексту, розташованому нижче, визначається загальна кількість елементів (dfNumbElem), Допомогою функції описаної вище (SalListQueryCount) І номер поточного елемента (dfSelected). В останньому випадку використовується функція опитування SalListQuerySelection.

Рис. 9. Визначення номера вибраного елемента у списку (dfSelected)
і загального числа елементів (dfNumbElem)


Як єдиний параметр функції опитування отримують назву списку (lbox1), А повернення для функцій визначається її типом. Якщо елемент у списку виділено (інверсія фону і тексту), то повертається номер цього елемента (dfSelected). Якщо немає вибраного елемента, то повертається константа LB_Err і видається діагностичне повідомлення. При успішному опитуванні, номер обраного елемента збільшується на одиницю, а значення елемента заноситься в поле значення елемента (dfSelVal).


Наступний фрагмент показує механізм видалення елементів зі списків. Він активізується при натисканні кнопки pbDelList – (“Видалити по №“). Для видалення використовується функція SalListDelete, Другий параметр якої визначає фізичний (на одиницю менше) номер видаляється елемента. У нашому випадку цей номер заноситься вручну попередньо в поле dfNumDel. Якщо номер невірний, то аналізується код повернення і видається повідомлення. Відзначимо, до речі, що код нормального повернення задається стандартною константою SAL – LB_Ok. Це зауваження стосується й інших функцій роботи зі списками.

Рис. 10. Видалення елемента в списку за номером (dfNumDel)


Для вибору (установки або селекції) елемента за номером в програмі передбачена кнопка PbSelectNum – (“Встановити за номером“). Фрагмент тексту, який показує цю операцію, наведено на малюнку розташованому нижче. Всі функції, використовувані для вибору елемента, були вже розглянуті вище. Полем для ручного регулювання обраного номера є поле dfNumSel. Якщо установлюваний номер не входить в діапазон номерів списку, то видається діагностичне повідомлення.

Рис. 11. Вибір елемента в списку за номером (dfNumSel)


Комбіновані списки


Різниця між списками і комбінованими списками швидше має візуальний характер. Практично всі операції з класами цих об’єктів аналогічні. Єдиним суттєвим розходженням є наявність спеціального поля введення, що дозволяє організувати швидкий пошук в комбінованому списку і введення нових значень, який повинен бути реалізований програмно. Комбінований список можна побудувати на основі комбінації об’єктів (звідси і його назва): символьне поле введення і звичайний список.


Перелік повідомлень і подій, які обробляють ці різновиди списків, ідентичні, а всі функції списків доступні для комбінованих списків.


Основні відмінності цих списків полягають у налаштуванні параметрів для етапу проектування додатку і при роботі з цими об’єктами. При налаштуванні комбінованих списків у додатки до інших властивостям списків можна вказати властивість можливості редагування поля вводу (Editable), Тип рядка (у цих списках допускаються і довгі рядки – Long String), Маска вводу даних (Input Mask) І режим постійного показу вмісту списку (Always Show List). При включенні останнього властивості необхідно передбачити вільне місце у вікні для розташування об’єкта, виключивши перекриття з іншими об’єктами. Недоступним в комбінованому списку є властивість множинної селекції елементів (Miltiple Selection).


Вікно для вивчення комбінованих списків наведено на малюнку нижче. Кнопки автоматично змінюють назви при перемиканні, це реалізовано програмно. Переглянути фрагменти тексту для маніпулювання комбінованими списками Ви можете самостійно у доданому додатку. Всі коментарі для фрагментів тексту на SAL аналогічні коментарям до фрагментів роботи зі списками.

Рис. 12. Вікно програми в режимі комбінованого списку – Combo Box


Списки і комбіновані списки підтримують режим початкового статичного опису їх со-тримання. Це початковий опис не скасовує можливостей маніпулювання списками, а дуже зручно в тих випадках, коли зміст списків фіксовано. Приклад статичного завдання (List Initialisation) Наведено для комбінованого списку на малюнку нижче. Первісне зміст списку років задається в режимі маніпулювання OUTLINE за допомогою пропозиції Text (Думаю, для створення початкових значень не потрібно додаткових пояснень.).

Рис. 13. Завдання фіксованого змісту списку (List Initialization)


Примітки:



  1. Відзначимо попутно, що комбіновані списки можуть бути визначені як дочірніх елементів у таблицях. У цьому випадку для роботи з підлеглими списками доступні функції для заповнення та зміни змісту списків, а також інші функції.
  2. У TD передбачена додаткова бібліотека для роботи зі списками і комбінованими списками – Visual Toolchest (VT), можливості якої значно ширше, зокрема організація OUTLINE – списків або використання в списках малюнків та піктограм. Цю бібліотеку ми розглянемо в одній з наступних статей даного циклу.

Для перемикання програми з режиму вивчення списків в режим комбінованих списком використовується простий перемикач у вигляді радіокнопок (rbList, rbCombo). Як це реалізовано дивіться на нижньому фрагменті тексту SAL.

Рис. 14. Управління режимами в додатку вивчення списків

В результаті вивчення першій частині даної статті Ви отримаєте додаток step4_list.app, Яке для перевірки засвоєння матеріалу можна скачати тут.


Таблиці і робота з ними


Інтерфейсні об’єкти типу таблиць займають особливе і значне місце в інтерфейсі інформаційних систем. Саме тому ми приділимо їм набагато більшу увагу.


Таблиця – Це елемент інтерфейсу, який містить інформацію порядково, причому число рядків практично не обмежена. Рядки розташовані горизонтально, а вертикально розташовуються колонки (стовпці) таблиці. Кожен зі стовпців таблиці містить інформацію певного типу, причому вона може бути і різнорідною інформацією. У цьому випадку таблицю можна спрощено розглядати як двовимірний масив, що містить різнорідну інформацію, причому має змінне число рядків і, в загальному вигляді, стовпців. Кількість стовпців у таблиці може бути фіксованим, тоді ми будемо говорити про статичних таблицях, або змінним – такі таблиці називаються динамічними.


У даній статті ми розглянемо окремо особливості роботи зі статичними і динамічними таблицями.


Безсумнівно, що найважливіше в застосуванні таблиць – це відображення інформації з бази даних. Це питання ми будемо детально вивчати в наступній статті, а тут розглянемо лише базові операції для роботи з об’єктами-таблицями.


Для вивчення програмування таблиць створимо спеціальні програми, окремо для роботи зі статичними і динамічними таблицями (назвемо їх step4_table_stat.app і step4_table_din.app відповідно).


Таблиці статичні


Статичні таблиці мають фіксоване число стовпців, що визначаються на етапі проектування. В принципі, можна досягти певної динаміки, якщо в програмі приховувати або відкривати видимість окремих стовпців, однак у цьому випадку таблиця повинна бути надмірною і, в результаті, ресурси пам’яті будуть витрачатися неефективно. Нижче представлено головне вікно програми, розроблене для вивчення статичних таблиць (step4_table_stat.app). Таблиця, роботу з якою ми будемо вивчати, має три колонки (“Ім’я“, “Оклад“І”Test“Відповідно). Колонка (стовпець) Test має допоміжне призначення і буде нами використовуватися для ілюстрації додаткових властивостей таблиць.

Рис. 15. Вікно програми для вивчення статичних таблиць

Розглянемо призначення основних об’єктів вікна. Кнопка “Очистити“Призначена для видалення всіх рядків таблиці. Кнопка”Заповнити“Використовується для циклічного додавання заданого числа записів в таблицю. Число додаються записів задається в целочисленном поле введення”Число записів:“, А значення клітинок додаються рядків обчислюється на основі інформації в полях введення”Ім’я“І”Оклад“(Далі ми познайомимося з виразами, на основі яких формуються вводяться значення). Кнопка”Сортування“Містить процедури сортування таблиці, напрямок якої задаються перемикачем”Вік.“(У порядку зростання або зменшення) і радіокнопки”Ім’я“І”Оклад“, Які визначають назву колонки для сортування.



Примітка: Робота з таблицями в чому схожа на роботу зі списками, яку ми розглянули вище. Спрощено список можна розглядати як таблицю з одного колонкою, або таблицю можна уявити пов’язаної сукупністю списків.


Перемикач “Прапори зняти“Задає режим автоматичного скидання прапорів після виконання операцій над таблицею. Прапори встановлюються функціями роботи з таблицею в спеціальному заголовному стовпці (Row Header), Який формується і змінюється автоматично. Роботу з цим стовпцем ми опишемо спільно з динамічними таблицями. Якщо прапори автоматично не скидаються, може бути використана кнопка “Скидання прапорів“. Кнопка”Додати“Використовується для додавання нового рядка на основі значень в полях”Ім’я“І”Оклад“, А кнопка”Видалити виділений“Призначена для видалення одного рядка таблиці, яка виділена в даний момент. Кнопка”Сума окладів / Середній оклад“Використовується для ілюстрації роботи спеціальних обчислювальних опцій масиву, результат їх роботи заноситися в поле”Результат“. Радіокнопки”Сума“І”Середнє“Визначають типи операції. Кнопка”Зняти виділення“Дозволяє зняти виділення довільної рядки (або довільного числа рядків) у таблиці. Кнопка”Визначити“Використовується для програмного визначення загального числа рядків (у полі”Число рядків“) І поточного елемента (поле”Контекст“). За допомогою кнопки”Встановити“Можна за номером (поле”Номер“) Встановити контекст будь-якого доступного елемента. Аналогічні дії Ви можете зробити, клацнувши одноразово мишкою на заголовній кнопці, розташованій ліворуч, будь-якого рядка таблиці. При цьому в нижніх полях “Контекст” ,”Ім’я“І”Оклад“З’являться значення, відповідні вибраному рядку. За допомогою кнопок”Число рядків“І”Кількість стовпців“Можна викликати процедури, які визначають кількість рядків (“Число“) Або стовпців (“Число колонок») В таблиці. Роботу цих функцій ми розглянемо нижче при вивченні динамічних таблиць.


Нижче на малюнку наведені основні об’єкти програми, які використовуються в цьому додатку. Пояснимо їх призначення, для того, щоб було легше орієнтуватися у фрагментах тексту програми.

Рис. 16. Об’єкти вікна програми для вивчення статичних таблиць


Кнопки програми вивчення таблиць мають такі назви:


PbClose – кнопка “Закрити” вікно
PbAddTable –
кнопка “Додати” в таблицю
PbClear –
кнопка “Очистити”
PbDelete –
кнопка “Вилучити виділений”
PbFlags –
кнопка “Скидання прапорів”
PbTblFill –
кнопка “Заповнити”
PbSort –
кнопка “Сортування”
PbSumm –
кнопка “Сума окладів / Середній оклад”
PbClearSel –
кнопка “Зняти виділення”
PbQuery –
кнопка “Визначити”
PbSetNum –
кнопка “Встановити”
PbColCount –
кнопка “Число стовпців”
PbRowCount –
кнопка “Число рядків”


Поля введення і індикації даних мають наступні назви об’єктів і відповідні їм заголовки:


dfName – полі “Ім’я” для введення
dfOklad –
полі “Оклад” для введення
dfName1 –
полі “Ім’я” для опитування
dfOklad1 –
полі “Оклад” для опитування
dfNumberToFill –
полі “Число записів:”
dfNumberSel –
полі “Номер”
dfResult –
в поле “Результат”
dfRowInTable –
поле “Число рядків “
dfCurrentRow –
полі “Контекст”
dfColNumberTable1 – “Кількість колонок”
dfNumberRows –
полі “Число”


Допоміжні перемикачі та радіокнопки мають таке назви:


CbАFlagClear – перемикач “Прапори зняти”
cbSort –
перемикач “Вік.”
rbOklad –
радіокнопка “Оклад “
rbName –
радіокнопка “Ім’я”
rbSumm –
радіокнопка “Сума” і “Середнє”
rbAver –
радіокнопка “Середнє”


Таблиця в програмі називається – tblTest, А колонки таблиці, вони розглядаються також як окремі об’єкти, мають власні назви (colName, colOklad і Test відповідно). Опис статичної таблиці в розділі OUTLINE показано на малюнку, розташованому нижче. Кожна колонка отримує своє ім’я об’єкта, формат, безліч налаштувань, включаючи маски введення даних. Можливі чотири типи полів в колонках:



  • Стандартне поле (Standart – Звичайне поле введення або перегляду) будь-якого зі стандартних типів (число, рядок, дата і т.д.)
  • Поле типу списку (Drop Down List), Описується фіксований набір значень, який, втім, може програмно змінюватися.
  • Бітове поле типу перемикач (Check Box), Яке визначається як TRUE і FALSE на заданій множині значень, у тому числі і не на {0,1}.
  • Поле для редагування багаторядкових текстів (Popup Edit), Дозволяє виводити і редагувати довгі рядки.

У нашому прикладі ми використовуємо стандартні поля і поля типу списків. З іншими варіантами пропонуємо читачеві розібратися самостійно. Поля colName і colOklad описуються стандартним типом (символьне і числове відповідно). Поле Test є списком (Drop Down List). Як показано на малюнку, для нього передбачається стандартне заповнення у списку ініціалізації (List Values), А також заповнення спеціальними функціями на етапі виконання програми при обробці повідомлення – SAM_Create, Одержуваному при створенні списку. Значення тут додаються функцією SalListAdd, Перший параметр якій вказує колонку, а другий значення, яке додається до списку. Таким чином, вміст списку може бути динамічно змінено. До даних списками застосовні й інші функції обробки списків, розглянуті вище.

Рис. 17. Опис статичної таблиці та обробки повідомлень для колонки


Як було вже зазначено, ліва колонка (сірого кольору на малюнку нижче) називається заголовної колонкою (Row Header). Вона включається в таблицю автоматично. У стандартному варіанті ця колонка служить для індикації дій, виконаних з конкретною рядком: редагування, додавання, видалення та інші. Колонка типу Row Header – Може бути відключена, а значення прапорців зупинені в нуль. Нижче ми розглянемо основні операції з заголовної колонкою.

Рис. 18. Фрагмент вікна з рядком поміченої прапором ROW_Edited.

Зокрема для скидання прапорів Додавання та редагування може бути використаний наступний фрагмент тексту. Функція SalTblSetFlagsAnyRows дозволяє скинути або встановити задані прапори для всієї таблиці.

Рис. 19. Фрагмент тесту скидання прапорів ROW_New і ROW_Edited.


У нашому прикладі скидаються прапори ROW_New (Рядок добавлена) і ROW_Edited (Рядок змінене). Дані прапори можна опитати і програмно спеціальними функціями. Для роботи тестового програми задаються початкові значення, представлені на фрагменті тексту нижче. Перемикачі сортування, поля сортування (“Ім’я“) І очищення прапорів встановлюються в положення включено, крім цього задається в полях індикації нульове число рядків і колонок, так як спочатку таблиця порожня.

Рис. 20. Початкові установки вікна програми


Додавання нового рядка ілюструється в наступному фрагменті. Для створення пустого рядка використовується функція SalTblInsertRow, Перший параметр якої визначає таблицю, а другий вказує номер рядка, після якої додається рядок. У нашому випадку це константа SAL TBL_MaxRow, Що пропонує додавання в кінець таблиці. Щоб додати до початок можна вказати 0 або іншу константу TBL_MinRow. Після додавання рядка вона ставати поточної, а це означає, що ми можемо працювати з полями цього рядка (наприклад, присвоювати значення: tblTest.colName = dfName). Для скидання прапора додавання використовується вже знайома нам функція SalTblSetFlagsAnyRows.

Рис. 21. Додавання рядка в кінець таблиці та її заповнення (dfName, dfOklad)


Для видалення рядка таблиці (дивіться нижче) використовується функція SalTblDeleteRow, Що приймає при виклику три параметри: ім’я таблиці, порядковий номер видаляється рядки (nCount) І параметр, який використовується для синхронізації видалення інформації з вибірки (Result Set). У нашому випадку поки немає БД, використовується константа SAL TBL_NoAdjust, Що виключає таку синхронізацію. Роботу з вибірками з БД ми розглянемо в наступній статті.

Рис. 22. Видалення рядка з таблиці


Для визначення номера видалення, а нашому випадку віддаляється виділена рядок, використовується функція опитування контексту таблиці – SalTblQueryContext. Ця функція повертає номер поточного рядка таблиці. Як єдиний параметра функція отримує ім’я таблиці.



Примітка: Існує тонка різниця між поняттями виділення рядка і установки контексту або фокусу. Якщо рядок виділена, то її контекст збігається з номером виділеної рядки. Рядок може бути не виділена, проте в цьому випадку мати контекст за замовчуванням. Навіть при скиданні виділення всіх рядків, одна з них має контекст. Для установки контексту без виділення може бути використана функція SalTblSetFocusRow.


Функцією SalTblQueryContext ми будемо користуватися часто в інших фрагментах даної програми. Наступний фрагмент тексту показує цикл заповнення таблиці, який активізується при натисканні кнопки “Заповнити“. Пояснимо цю програму. Цілочисельна мінлива nCount є лічильником циклу, її початкове значення задається рівним 1. Контроль інших початкових установок циклу, для спрощення, ми тут не наводимо. У циклі спочатку в таблицю додається рядок (SalTblInsertRow), Потім заповнюються значення полів (осередків рядка) за допомогою звичайного присвоєння. До імені (для колонки tblTest.colName), Заданому полем інтерфейсу dfName додається номер рядка з розділовою рискою. Значення окладу (для колонки tblTest.colOklad) Задається з урахуванням лічильника циклу. Передбачається зменшення значення від базового значення в циклі (щоразу на 10 одиниць). Це робиться для демонстрації сортування таблиці. Контроль завершення циклу виконується порівнянням лічильника і поля dfNumberToFill, Що задає число доданих рядків. Після заповнення таблиці, при необхідності скидаються прапори.


Таблиці і робота з ними

Рис. 23. Заповнення таблиці заданим числом рядків (dfNumberToFill)


Можливості сортування таблиці показані на наступному малюнку. У цьому випадку використовується універсальна функція сортування SalTblSortRows, В якій передбачено три параметри. Перший задає таблицю, другий – визначає порядковий номер колонки для сортування, а третій задає тип сортування (у порядку зростання – константа TBL_SortIncreasing або в порядку убування – константа TBL_SortDecreasing).


Номер колонки може бути заданий динамічно, тому зробити універсальну програму сортування неважко.

Рис. 24. Сортування в таблиці по імені та окладу


Для числової обробки рядків передбачені функції підрахунку суми (SalTblColumnSum) і середнього (SalTblColumnAverage). Другим параметром в них є номер колонки для обчислення (у нас – tblTest.colOklad), Третій і четвертий параметри – фільтрують рядки для обчислення залежно від включених або вимкнених прапорів. Ми встановили один параметр в 0 (жоден прапор не включено), а інший в константу TBL_RowDeleted (У всіх рядків виключений прапор видалення), для того, щоб усі записи враховувалися для розрахунку.

Рис. 25. Визначення суми та середнього по дві колонки таблиці


Можна програмним способом скинути виділення рядка або безлічі рядків (рядки виділяються інверсним кольором). Саме виділення може бути виконано програмно чи за допомогою маніпулятора миша. Для цього скористається функцією SalTblClearSelection. Зазначимо, що при знятті виділення поточний рядок – контекст зберігається (доступні в програмі клітинки рядка).

Рис. 26. Скидання виділеної рядки в таблиці


Для того, щоб програмним чином дізнатися, який рядок виділена, або на якому рядку встановлений контекст може бути використаний наступний фрагмент тексту. Ця процедура викликається при натисканні кнопки “Визначити” (pbQuery). Крім функцій вже Вам відомим тут використовується функція GetNumberRowsInTable, Яка повертає поточне число рядків у таблиці.

Рис. 27. Опитування виділеної рядки в таблиці і скидання її виділення


Якщо в програмі необхідно встановити контекст на конкретну рядок, то можна скористатися функціями SalTblSetContext і SalTblSetFocusRow, Другий параметр якої визначає номер рядка для установки фокусу. Фрагмент тексту з контролем встановлюваного номери і опитуванням встановленої рядка зображений на малюнку, розташованому нижче. Зазначимо, що нумерація рядків виконується з нуля, тому при установці базове поле введення у вікні коригується на одиницю (dfCurrentRow -1).

Рис. 28. Установка контексту в таблиці і опитування значень


Операції визначення числа колонок у таблиці ми розглянемо нижче в цій статті при вивченні процедур роботи з динамічними таблицями.


В результаті освоєння матеріалу і вправ Ви отримаєте додаток step4_table_stat.app, яке для перевірки засвоєння матеріалу можна скачати Тут.


Таблиці динамічні


Динамічні таблиці дозволяють виконувати весь набір операцій, який ми розглянули для статичних таблиць, тому ми не будемо повторюватися, а покажемо саме ті операції, які характерні для них на відміну від статичних таблиць. Нижче наведено вікно програми для вивчення можливостей динамічних таблиць. Ми розглянемо роботу з динамічними колонками і заголовної колонкою, яка, як уже було зазначено, носить назву Row Header.


Динамічні таблиці дуже зручні при організації взаємодії з БД. Залежно від виду запиту, структури таблиці БД, динамічна таблиця фактично генерується. При змінах запитів або структури БД ми не повинні повертатися до етапу проектування, а запитувана інформація надійде у вікно, що містить таку таблицю. Для вивчення основних властивостей динамічних таблиць ми розробимо спеціальний додаток – step4_table_din.app.


Вікно для вивчення динамічних таблиць показано на малюнку, розташованому нижче.


У верхній частині екрана описана динамічна таблиць, яка спочатку не містить ніяких колонок (на малюнку ми показуємо стан таблиці в процесі роботи програми). Знизу розташовані кнопки і поля для введення і індикації характеристик таблиці. Кнопка “Додати рядок” використовується для додавання рядків, що містять у першій колонці текст (поле “Текст”) І виконується нумерація рядків у заголовній колонці. Остання дія виконується, якщо відмінено режим індикації змін (прапор TBL_RowHdr_MarkEdits – Вимкнений). Для ілюстрації принципу роботи, прихована колонка – “Прихованому”, Пов’язана з заголовної (Row Header) Зараз показана на малюнку (в штатному режимі вона вимкнена). За допомогою кнопки “Додати колонку” можна в таблицю додати нову колонку з назвою, що задається в полі “Назв.”. Поля індикації “Всього рядків” і “Число колонок” динамічно висвічують зміна стану таблиці. Кнопка “Очистити таблицю” допомагає видалити всі рядки таблиці, а кнопка “Вилучити всі колонки” використовується для видалення всіх створених колонок та очищення таблиці одночасно.


Нижня частина вікна використовується для операцій зміни заголовної колонки. Кнопки “Сховати Row Header” і “Показати Row Header” використовуються для виключення і включення виводу на екран існуючої заголовної колонки. Кнопка “Опитати Row Header” використовується для визначення поточного стану заголовної колонки, а кнопка “Додати Row Header” дозволяє створити нову або задати нові властивості цієї колонки. Між перерахованими кнопками показані поля визначають властивості заголовної колонки, при опитуванні вони заповнюються при додаванні і з них зчитуються параметри настройки.

Рис. 29. Вікно програми для вивчення динамічних таблиць TD


Поле “Ім’я Row Header” визначає назву колонки, а поле “Ширина” задає її розмір. Перемикачі “Видимість” (Прапор – TBL_RowHdr_Visible), “Динам. Розмір” (Прапор – TBL_RowHdr_Sizable), “Індикація змін” (Прапор – TBL_RowHdr_MarkEdits), “Розмір рядка змінюємо” (Прапор – TBL_RowHdr_RowsSizable) І “Колір” (Прапор – TBL_RowHdr_ShareColor) Показують властивості заголовної колонки.


Об’єкти програми мають такі назви (Тут ми їх наводимо для того, щоб легше було знайомитися з фрагментами тексту). На малюнку нижче дано опис всіх основних об’єктів вікна програми. Кнопки вікна програми мають наступні назву і призначення:



pbAddCol – Кнопка “Додати колонку”
pbAddRow
– Кнопка “Додати рядок”
pbClear
– Кнопка “Очистити таблицю
pbDelCol
– Кнопка “Вилучити всі колонки”
pbAddHeader
– Кнопка “Додати Row Header”
pbQueryHeader
– Кнопка “Опитати Row Header “
pbHideHeader
– Кнопка “Сховати Row Header” і “Показати Row Header”
pbShowHeader
– Кнопка “Показати Row Header”


Поля введення і індикації вікна мають таке призначення:



dfColName – Поле “Назв.:”
dfColText
– Поле “Текст”
dfColCount
– Поле “Число колонок”
dfRowCount
– Поле “Всього рядків”
dfHeaderNameText – поле “Ім’я Row Header”
dfHeaderWitdth
– Поле “Ширина”


Перемикачі вікна мають таке призначення:



СbHeaderVis – Перемикач “Видимість”
cbMarkEdit
– Перемикач “Індикація змін”
cbColor
– Перемикач “Колір “
cbSizeChange
– Перемикач “Динам. Розмір”
cbRowsResize
– Перемикач “Розмір рядка змінюємо”

Рис. 30. Об’єкти вікна програми для вивчення динамічних таблиць TD


Таблиця tblTest2 описується без колонок і налаштувань. На малюнку, розташованому нижче, показано такий опис. Все, що пов’язано з такою таблицею, визначається в програмі динамічно.

Рис. 31. Опис таблиці tblTest2 з порожнім змістом


Перед тим як приступити до розгляду фрагментів тексту для роботи з динамічними таблицями, пояснимо механізм і призначення заголовної колонки (Row Header). Заголовна колонка присутній в таблицях TD завжди (навіть якщо вона невидима) і служить для індикації стану рядків (відображення прапорів). Значення прапорів показуються за допомогою простих піктограм, які розташовуються в цій заголовної колонці. Відображення виконується, якщо прапор самого заголовкового шпальти – TBL_RowHdr_MarkEdits встановлений в одиницю. Його установка виконується спеціальною функцією, використання якої ми розглянемо нижче. Якщо відображення змін дозволено, то при всіх операціях з рядками виконується індикація змін (наприклад, при редагуванні рядки – “v”, при додаванні рядка – “>”, при видаленні рядки – “?” і так далі). Якщо відображення змін заборонено, то заголовну колонку можна використовувати для виведення власної інформації з програми, наприклад для автоматичної нумерації рядків таблиці. У цьому випадку необхідно створити додаткову колонку в таблиці, зробити її невидимою (на малюнку вище для ілюстрації вона тимчасово зроблена видимої) і перевизначити заголовну колонку. При новому визначенні прапор TBL_RowHdr_MarkEdits повинен бути встановлений в 0. При виконанні цих вимог, інформація, що заноситься в приховану колонку, буде дублюватися в заголовній колонці (звичайно складно для реалізації, але іншого шляху немає). Хоча можна сховати заголовну колонку взагалі і використовувати звичайну колонку, але тоді не будуть доступні її властивості.


Так як у нашому прикладі повинна використовуватися заголовочная колонка (її дескриптор названий – colRowHeader), То у всіх операціях потрібно враховувати її наявність чи відсутність. Для перевірки її наявності в додатку передбачена спеціальна користувацька функція TableHasRowHeaderCol. Крім того, для динамічної таблиці ми використовуємо власну функцію GetNumberColsInTable, Що визначає поточне число колонок в таблиці з урахуванням заголовної. Дані функції ми розглянемо трохи пізніше.


У наступному прикладі виконується додавання нової колонки в таблицю. Спочатку визначається поточне число колонок у полі dfColCount, Потім перевіряється наявність заголовної колонки і, нарешті, за допомогою функції SalTblCreateColumn динамічно додається нова колонка. У цій функції крім імені таблиці вказані наступні параметри: номер додається колонки (dfColCount + 1 або dfColCount + 2 при наявності заголовної прихованої колонки), розмір нової колонки в дюймах, максимальний розмір рядка тексту в колонці і заголовок колонки. У нашому випадку назва нової колонки береться з поля dfColName. Далі визначається і коригується число колонок в таблиці (dfColCount), Що використовується для індикації.

Рис. 32. Фрагмент тексту додавання колонок з урахуванням заголовної колонки


Видалення всіх колонок виконується функцією SalTblDestroyColumns (Див. малюнок нижче), яка видаляє, на жаль, і приховану заголовну колонку. При новому побудові таблиці її ми створимо заново. Зазначу, що дана операція застосовується лише до динамічних таблиць, для статичних таблиць, при необхідності, потрібно використовувати механізм приховування колонок.

Рис. 33. Фрагмент тексту видалення всіх динамічних колонок


Наступний фрагмент показує, як можна додавати рядки в таблицю з урахуванням заголовної колонки. Спочатку ми додамо рядок стандартним способом (функція – SalTblInsertRow). У програмі, для простоти, будемо заповнювати тільки заголовну колонку і першу колонку. Тому ми отримуємо дескриптор hwndCol1 (тип – Window Handle) За допомогою функції SalTblGetColumnWindow. Фактично ми тут отримуємо дескриптор окремої клітинки таблиці. Номер колонки 2, але це перша видима колонка. Потім за допомогою функції SalSetWindowText, Ми встановлюємо значення тексту поля з поля dfColText вікна, заносимого вручну. Далі для заголовної колонки виконуємо аналогічну послідовність дії, за винятком наступного: номер колонки встановлюємо в 1, а введені значення номера рядка отримуємо за допомогою функції GetNumberRowsInTable і після переведення в символьне значення поміщаємо його в заголовну колонку. Після цих операцій коригуємо значення числа рядків.

Рис. 34. Фрагмент тексту для додавання рядків у таблицю із заповненням номера
в заголовній колонці рядка і тестами першої видимої колонки


Наступний фрагмент тексту показує, що необхідно зробити для опитування стану і параметрів заголовної колонки. Опитування виконується функцією SalTblQueryRowHeader. Ця функція має шість параметрів. Другий параметр визначає ім’я заголовної колонки (спочатку нічого). У нас воно поміщено в поле dfHeaderNameText. Третій параметр – це максимальний розмір тексту заголовка. Четвертий параметр – це розмір колонки заголовка в пікселях. П’ятий параметр – це поточне значення прапорів для заголовної колонки (і їх бітової комбінації). І, нарешті, шостий параметр – це дескриптор дублюючої прихованої колонки для заголовка. Інші дії у фрагменті тексту пов’язані з початковими і кінцевими установками перемикачів вікна, описують властивості заголовної колонки.

Рис. 35. Фрагмент тексту для опитування властивостей заголовка


Щоб додати заголовної колонки необхідно спочатку опитати її параметри, як показано вище, потім створити при необхідності приховану дублюючу колонку для введення в заголовки, і перевизначити нову заголовну колонку за допомогою функції SalTblDefineRowHeader. Ця функція має схожі параметри з функцією опитування заголовка. За умови відсутності прихованої колонки і не встановленому прапорі TBL_RowHdr_MarkEdits, Прихована колонка створюється функцією SalTblCreateColumn, Використання якої ми вже пояснювали. Колонка створюється з першим номером (переміщаємо її функцією SalTblSetColumnPos). Далі запам’ятовується її дескриптор (colRowHeader) Для того, щоб, при необхідності, динамічно перемістити її на першу позицію. Після перевизначення заголовної колонки (SalTblDefineRowHeader), Допоміжна колонка ховається функцією SalHideWindow. Після цих дій ми можемо використовувати заголовну колонку (видиму, “сіреньку”) для виведення потрібної нам інформації.

Рис. 36. Фрагмент тексту для додавання заголовної колонки


Для тимчасового приховування заголовної колонки виконуються дії, показані в тексті нижче. Спочатку опитуються прапори, і запам’ятовуються в спеціальній змінній (nFlagsHide). Далі перевизначається заголовочная колонка зі скинутим в нуль прапором TBL_RowHdr_Visible. Після цих операцій заголовочная колонка ставати невидимою.

Рис. 37. Приховування заголовної колонки colRowHeader


Відновлення видимості заголовної колонки виконується аналогічним чином, для перевизначення використовуються запомненние значення прапорів у змінній nFlagsHide. Після цих операцій заголовочная колонка ставати видимою. Опитування здійснюється для того, щоб всі параметри заголовної колонки були ідентичними.

Рис. 38. Відновлення видимості заголовної колонки colRowHeader


Нижче ми розглянемо три призначені для користувача функції (TableHasRowHeaderCol, GetNumberRowsInTable і GetNumberColsInTable), Які використовуються в додатку для наступних дій: визначення наявності заголовної колонки, а також підрахунку кількості рядків і стовпців у динамічній таблиці відповідно.


У функції перевірки наявності заголовної колонки (TableHasRowHeaderCol) Організовується цикл в таблиці по стовпчиках. Дескриптор заголовної колонки задається другим параметром функції (hWndRowHeader). Перший параметр – це дескриптор аналізованої таблиці (hWndTable). У даному циклі, представленому на малюнку нижче виконується перегляд всіх колонок і перевірка наявності в цьому списку дескриптора заголовної колонки. Функція повертає булеве значення: якщо знайдена заголовочная колонка, то TRUE, В іншому випадку FALSE. Стовпці проглядаються за номером послідовно. Якщо стовпця з даними номером немає, то це означає, що перегляд колонок закінчений, тому що всі колонки автоматично перенумеровуються у динамічній таблиці. Цикл зупиняється при отриманні нульового дескриптора колонки (стандартна системна змінна – hWndNULL).

Рис. 39. Фрагмент тексту функції визначення наявності заголовної колонки


На жаль, в SAL немає спеціальної функції для визначення числа рядків у таблиці, це пояснюється тим, що основне призначення таблиць – відображення вмісту вибірки, а для вибірки існує спеціальна функція визначення кількості записів (SqlGetResultSetCount). Можна визначити число рядків, підраховуючи їх при додаванні (наприклад, обробляючи повідомлення, що посилаються таблиці – SAM_CountRows). Ми розглянемо інший спосіб визначення числа рядків, за допомогою фіктивного додавання рядка. Такий спосіб є ефективним при великих розмірах таблиці. У функції (GetNumberRowsInTable), Представленої нижче, передбачається також збереження контексту поточного рядка, що важливо в програмах, що працюють з таблицями. Спочатку визначається і запам’ятовується контекст поточного рядка (NContext), потім в кінець таблиці додається новий рядок (SalTblInsertRow). Далі визначається її номер (у локальну змінну nRowInTable), потім фіктивна рядок видаляється (SalTblDeleteRow) І відновлюється контекст поточного рядка на основі локальної змінної функції nContext. Можливо, метод здасться комусь хитрим, але іншого пака немає.

Рис. 40. Фрагмент тексту функції для визначення числа рядків у таблиці


Наступна функція (GetNumberColsInTable) Призначена для підрахунку поточного числа видимих ​​колонок. Її особливість полягає в тому, що вона не включає до розрахунку заголовну колонку. Для такої відбракування, в якості другого параметра функції використовується дескриптор заголовної колонки, мається на увазі прихована колонка (параметр – hWndRowHeader). Першим параметром цієї функції є дескриптор таблиці (hWndTable). Цикл дуже схожий на цикл перевірки наявності заголовної колонки у функції, розглянутої вище. Тому опустимо тут його опис. Зазначимо тільки, що після циклу виконується коригування лічильника на 1 або на 2 залежно від наявності заголовної колонки.

Рис. 41. Функція визначення числа видимих ​​колонок таблиці


Існують і інші можливості роботи з таблицями: обробка повідомлення таблиць і колонок, виконання інших стандартних функцій і так далі. Ми надамо читачеві самостійно розібратися з цими можливостями, я думаю, що розглянутого матеріалу цілком достатньо для цього. У тих випадках (зокрема, в інших статтях), коли нам будуть потрібні можливості таблиць, тимчасово нами не розглянуті, то ми спеціально їх виділимо і пояснимо. Зокрема основні можливості роботи з БД будуть розглянуті в наступній статті.


У результаті узученія і вправ Ви отримаєте додаток step4_table_din.app, Яке для перевірки засвоєння матеріалу можна скачати Тут.


Висновок


У наступній статті цього циклу ми розглянемо основи роботи з БД в рамках TD. Для цього ми познайомимося з роботою вбудованого в TD програми DataBase Explorer, утиліти адміністратора БД SQLTalk та елементами SQL мови. Будуть також розглянуті можливості використання списків і таблиць для перегляду інформації з БД.

Частина 5

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*