Вы находитесь на страницах старой версии сайта.
Переходите на новую версию Interface.Ru

СТАТЬЯ
08.01.03


Предыдущая часть

Изучаем программирование
в Team Developer/Gupta

Шаг 4. Списки и таблицы . Часть 2.

© Большаков С. А., к.т.н.,
технический консультант Interface Ltd.

Таблицы и работа с ними

Рис. 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 языка. Будут также рассмотрены возможности использования списков и таблиц для просмотра информации из БД.

Следующая часть

Дополнительная информация

За дополнительной информацией обращайтесь в компанию Interface Ltd.

Обсудить на форуме Gupta Technologies

Рекомендовать страницу

INTERFACE Ltd.
Телефон/Факс: +7 (495) 925-0049
Отправить E-Mail
http://www.interface.ru
Rambler's Top100
Ваши замечания и предложения отправляйте редактору
По техническим вопросам обращайтесь к вебмастеру
Дата публикации: 08.01.03