(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Изучаем программирование в 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

Ссылки по теме


 Распечатать »
 Правила публикации »
  Обсудить материал в конференции Gupta/Centura (Gupta Technologies) »
Написать редактору 
 Рекомендовать » Дата публикации: 08.01.2003 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Traffic Inspector GOLD 5 Учетных записей
FastReport.Mono Single License
Комплект Dr.Web «Универсальный», 1 год, 5 ПК
ABBYY Lingvo x6 Европейская Домашняя версия, электронный ключ
EMS Data Export for PostgreSQL (Business) + 1 Year Maintenance
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Каждый день новые драйверы для вашего компьютера!
Windows и Office: новости и советы
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Ищу программиста для написания программы (76)
Ищу программиста ,владеющего Вижуал Бэйсик и программированием в Экселе, для написания...
 
Симулятор рулетки без графики. Обязятельно на VB6, Требуется сделать симулятор игры в рулетку по опр (4)
Здравствуйте! Задача такая: Требуется сделать симулятор игры в рулетку по определённой...
 
Realme Narzo 50A (1)
Посмотрела вчера характеристики нового смартфона Realme Narzo 50A...
 
Онлайн покер (6)
Подскажите, пожалуйста, где можно научиться играть в покер в интернете и зарабатывать на этом?
 
Опытная и сработанная команда разработчиков ищет новые проекты (4)
Опытная и сработанная команда разработчиков ищет новые проекты. Работаем вместе уже почти 10...
 
 
 



    
rambler's top100 Rambler's Top100