Изучаем программирование в Gupta Team Developer. Шаг 6 - Отладка, выборка и работа с записями

Большаков С. А.

Часть 5

Данная статья является шестой в цикле статей под общим названием "Изучаем программирование в TD/GUPTA", в котором мы постараемся дать начинающему пользователю программных продуктов GUPTA всю необходимую информацию для изучения программирования и получения навыков создания информационных систем. В ней мы рассмотрим механизмы работы с записями и таблицами БД на основе двух подходов. Первый основывается на визуальном объекте TD - таблице, а второй на непосредственной работе с выборкой (Result Set). Кроме того, мы поясним возможности отладки программ в TD (программы стали сложнее, и настало для этого время) и способы диагностики ошибок при работе с SQL СУБД. Для успешного усвоения этого материала читателю желательно познакомиться с предыдущими статьями из данного цикла, которые размещены на нашем сайте.

Введение

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

Как любые системы программирования TD имеет весь необходимый набор средств для отладки программного обеспечения, поэтому, первоначально, кратко их рассмотрим. Кроме этого в начале статьи мы акцентируем внимание читателей на том, как получить и выдать пользователю программ информацию об ошибках при работе с БД. Такие ошибки не всегда удается исключить в программе, некоторые из них (например, доступ к серверу или конкретной БД) зависят от окружения информационной системы.

Далее будут рассмотрены унифицированные механизмы выборки из БД в визуальную таблицу и способы работы с отдельными записями. Затем остановимся на варианте работы с выборкой из БД (традиционно называемой Result Set - RS) без создания визуальных объектов, и, наконец, покажем, как можно обеспечить навигацию по записям в случае работы с визуальной таблицей и сформированной предварительно выборкой данных из БД.

Для успешного и самостоятельного освоения материала данной статьи, который, мы очень надеемся, может служить своеобразным самоучителем программирования на Gupta TD, желательно познакомиться с материалом и выполнить задания предыдущих статей "Шаг 1-5".

Отладка программ в Team Developer

Team Developer имеет все необходимые средства для отладки информационных систем. Предусмотрены режимы трассировки программ, просмотра переменных, задание точек останова, анимации выполнения программы и останова работы программы. Ниже, на рисунке 1, показаны основные элементы управления отладкой: панель инструментов отладки и меню для управления отладкой. Панель инструментов (Dеbug) становиться доступной при запуске программы. Здесь расположены элементы: запуска и приостановки программы, операции пошагового выполнения программы с входом во вложенную процедуру и без , а также кнопки вызова специальных окон отладки. Эти окна служат для: просмотра переменных, просмотра стека вызова процедур, просмотра управляющих сообщений и просмотра вычислимых выражений. Эти окна мы рассмотрим чуть позже.

Рис. 1 Панель инструментов и меню отладки TD

Меню для управления отладкой содержит следующие позиции: запуск программы в режиме отладки (Go - клавиша F7), останов процесса отладки (Stop - клавиши Shift+F7), приостановка процесса отладки (Break), шаг по программе со входом в процедуры (Step Into - клавиша F10) и с обходом процедур (Step Over - клавиши Ctrl + F10), подменю управления точками останова (Breakpoints) и режимы анимации (No Animate , Slow Animate , Fast Animate). В подменю управления точками останова (на рисунках не показано) предусмотрены следующие возможности: установить точку останова (Toggle - клавиша F9), убрать точку останова (тоже F9), убрать все точки останова (Clear All), временного включения и отключения точек останова (Disable All и Enable All соответственно).

Примечание: 1. Для того чтобы перейти в режим отладчика необходимо первоначально установить одну точку останова, в противном случае программа будет выполняться в автоматическом режиме. Такая точка останова может быть установлена в том месте, где целесообразно начать режим отладки.

2. В отличие от других систем программирования в TD нет необходимости устанавливать специальные переключатели отладки. Так как под управлением TD программа всегда выполняется в режиме интерпретации, то объектных модулей не создается. Ранее мы уже показали ("Шаг 1…") как можно создать исполнимый модуль (*.EXE).

Режимы анимации используются в тех случаях, когда трудно проследить процесс выполнения программы и локализовать ошибки. Применяя этот режим на медленной (Slow) или высокой скорости (Fast) вы можете просматривать последовательность выполняемых операторов SAL и остановить программу в любом месте.

В процессе отладки, находясь в режиме приостановки выполнения программы или при выполнении по шагам, программист может вызвать окно просмотра переменных, показанное ниже. Это окно, помимо вызова его из линейки инструментов, может быть вызвано с помощью комбинации клавиш Alt+5, или посредством меню Tools->Variables.

Рис. 2 Окно просмотра переменных отладчика TD

Окно представляет собой таблицу, в которой даны имена переменных и их значения. Любые изменения переменных в ходе отладки оперативно будут отражаться в этом окне. В нашем примере выводятся переменные: frmPrimer.dfDBName - имя БД, frmPrimer.dfFamReplace - поле окна с фамилией и т.д. Системная переменная lParam содержит информацию передаваемую в процедуру обработки сообщений.

С помощью специальной кнопки (+/-) из этого окна вызывается окно настройки переменных, выводимых в окно просмотра. Это окно показано на рисунке, расположенном ниже. Окно выбора переменных для просмотра имеет интуитивно понятный интерфейс. Оно содержит: три окна списков, одно поле ввода имен переменных и кнопки управления. В двойном списке "Select Watch Variables" устанавливаются области просмотра переменных (окна, процедуры, области OUTLINE и так далее) и конкретные переменный доступные в этих областях. С помощью кнопок "Add" и "Add All", а также двойным щелчком, вы можете переместить переменные в третий список "Current Watch Variables", в котором представлен список переменных, подлежащих выводу в данный момент. Этот список можно очистить полностью (Clear All), или удалить из него одну выделенную строку (Clear). Если идентификатор переменной (можно и без квалифицированной ссылки) вводится вручную в поле "Edit Watch Variable", то после нажатия кнопки "Add" ее имя тоже можно разметить в списке вывода. При необходимости можно отредактировать имя выделенной переменной, для этого используется кнопка "Change". Если вы хотите отказаться от изменений в списке вывода, то используйте кнопку "Cancel", для подтверждения изменений используйте кнопку "Ok".

Рис. 3 Окно выбора переменных для просмотра отладчика TD

Для сложных программ характерен взаимный вызов функций и процедур. Для просмотра последовательности вызова можно использовать окно стека вызова "Call Stack". Это окно показано ниже на рисунке. В списке вызова отражаются вызываемые функции, и процедуры обработки сообщений объектов программы. Ссылка дается квалифицированная, поэтому функция однозначно идентифицируется. Данное окно может активизироваться из линейки отладки, клавишами (Alt+6) или с помощью меню: Tools?>Call Stack.

Рис. 4 Окно стека вызова процедур отладчика TD

Следующее отладочное окно предназначено для просмотра сообщений управляющих программой. Можно включить режим просмотра только пользовательских сообщений SAL (переключатель -"SAM mesages only") или просматривать все сообщения, включая и сообщения WINDOWS (WM_). Последний режим важен, если Вы в программе используете их обработку. Отметим попутно, что можно обрабатывать практически все сообщения WINDOWS и создавать собственные. В окне сообщений отображается: символическое название сообщения (например, SAM_FetchRow), дескриптор оконного объекта, к которому оно адресовано и стандартные параметры (wParam и lParam). Если просмотр сообщений в данный момент не нужен, то его можно отключить ( переключатель - "Stop Watching"). Можно и закрыть все окно, используя панель отладки, клавиши (Alt+7) или с помощью меню: Tools?>Messages. Все управляющие элементы работают в режиме триггера.

Рис. 5 Окно трассировки сообщений отладчика TD

Последнее окно отладчика предназначено для просмотра любых переменных и выражений. Окно "Expressions" представлено ниже. В верхнем списке может быть введено выражение (в нашем случае имя простого поля dfDBName), а в нижнем поле после нажатия кнопки "Eval", формируется текущее значение выражения с указанием типа выражения. В отличии от окна переменных, для получения адекватного значения выражения нужно нажимать кнопку. Вызов данного окна выполняется из панели отладки, клавишами (Alt+8) и меню: Tools?> Expressions.

Рис. 6 Окно просмотра выражений отладчика TD

На следующем рисунке показано, как изменяется вид программы при установке точек останова (Breakpoint). Строка, на которой поставлена точка останова, перекрашивается в красный цвет. Установка и снятие точки останова выполняется клавишей F9 или посредством меню: Debug->BreakPoint->Toggle.

Рис. 7 Точки останова (breakpoint) при отладке в TD

Примечание : 1.При комментировании фрагментов текста точки останова автоматически не удаляются, поэтому их можно сохранять для дальнейшего применения.

2. Нужно иметь вводу, что и при копировании через буфер обмена точки останова тоже копируются.

Диагностика SQL ошибок в Team Developer при работе с БД

Если с отладкой программ мы разобрались выше, то с отладкой SQL запросов дела обстоит не так хорошо. Конечно, можно воспользоваться SQLTalk или встроенного DB Explorer для отладки запросов, но это трудно сделать в том случае, когда запросы генерируются в программе. При этом регистрируются ошибка и программа в большинстве случаев завершается. Для обработки этих ситуаций мы уже рассматривали возможности (обработка сообщений SAM_SqlError и оператор When SqlError). При такой обработке можно дать пользователю и разработчику дополнительную информацию, которая может быть получена от TD с помощью специальных функций.

Ниже на рисунке приведен фрагмент программы, демонстрирующей применение таких функций (для локальной обработки ошибок). Функция SqlExtractArgs позволяет получить нужную информацию: стандартные параметры сообщения об ошибках (wParam и lParam), значение курсора, для которого зафиксирована ошибка (hSqlErr), номер ошибки (nErr) и позицию обнаружения ошибки при компиляции запроса (nPos). Курсор может быть использован для отката транзакции (ROLLBACK), номер ошибки и позиция для формирования текста диагностического сообщения. Номер ошибки (nErr) может быть получен также на основе курсора hSql2 с помощью функции SqlError. Другие две функции (SqlGetError и SqlGetErrorText) помогут получить текст сообщения об ошибке. В фрагменте текста для иллюстрации разных возможностей получения информации об ошибке приводим несколько функций, выполняющих одинаковые операции.

Рис. 8 Фрагмент текста обработки параметров локальных ошибок

Примечание : 1. Информация об ошибках получается из файла error.sql, который расположен в корневом каталоге TD. К сожалению, данный файл не русифицирован. Поэтому диагностика получается на английском языке. Однако, если для клиентских приложений в данном файле заменить английские тексты на русские, то система будет автоматически поставлять тексты описания ошибок на русском языке.

2. Можно и в программе предусмотреть русифицированную информацию (файл, массив и так далее) для индикации ошибок для наиболее часто встречающихся ошибок.

3. Если не предусмотрена обработка ошибок и их перехват, то TD формирует собственное окно с информацией об ошибке. В этом случае это будет окно с английскими текстами, что не всегда устраивает разработчиков и пользователей.

При глобальной обработке ошибок мы получим практически такой же текст, который представлен на нижнем рисунке. Данный фрагмент текста завершается вызовом простого специального пользовательского модального окна (dlgError), для выдачи диагностической информации.

Рис. 9 Фрагмент текста обработки параметров глобальных ошибок

Внешний вид данного окна представлен на рисунке, расположенном ниже.

Рис. 10 Пользовательское окно сообщения об SQL ошибках

Окно использует информацию, полученную с помощью функций: SqlExtractArgs и SqlGetErrorText. Информация в диалоговое окно передается с помощью глобальных переменных. Описание объектов диагностического окна дано ниже. Смысл этих переменных понятен из текстов надписей и меток.

Рис. 11 Описание объектов окна сообщений об ошибках

При создании окна диагностики информация из глобальных переменных заносится, как показано ниже, в поля окна при его создании.

Рис. 12 Переменные окна диалога ошибок

Глобальные переменные приложения, описание которых дано ниже, формируются при обработке ошибок.

Рис. 13 Описание глобальных переменных для индикации ошибок

При обработке локальных ошибок первоначально выдается диагностическое сообщение с помощью функции SalMessageBox. Его текст дан ниже.

Рис. 14 Индикация локальной ошибки

При обработке глобальных ошибок также выдается диагностическое сообщение с помощью функции SalMessageBox. Текст сообщения приведен ниже.

Рис. 15 Индикация глобальной ошибки

При индикации ошибки с помощью стандартного параметра lParam (передаваемого обработчику сообщения SAM_SqlError) не всегда формируется правильный код ошибки, так как он упакован, поэтому целесообразно пользоваться функциями SqlExtractArgs и SqlError.

Рис. 16 Индикация ошибки через lParam

Кроме этого, для детального описания ошибочной ситуации можно использовать функцию SqlErrorText. Эта функция имеет пять параметров. Помимо кода ошибки (nErr), нужно указать формат поставляемой информации (режим SQLERROR_Reason - описание ошибки и причина ее возникновения или режим SQLERROR_Remedy - возможные действия по ее преодолению), строка возвращаемого текста (strErrText), максимальная длинна возвращаемого текста и реальная длинна возвращаемого текста. SQLERROR_Reason и SQLERROR_Remedy - являются константами языка SAL. Кстати, режимы SQLERROR_Reason и SQLERROR_Remedy можно и комбинировать, например:

Call SqlErrorText( nErr, SQLERROR_Reason / SQLERROR_Remedy,
strErrText, 300, nErrLong )

Формирование выборки в таблицу с обработкой сообщений

Рассмотрим далее возможности обработки сообщений, которые посылаются таблице при выполнении функции SalTblPopulate. Дело в том, что эта функция выполняет весь набор действий при заполнении таблицы: компиляцию запросов, добавление строк и выборку записей. Иногда необходимо вмешаться в этот процесс, допустим для изменения содержимого заполняемых полей или, например, для нумерации строк таблицы в отдельной колонке. Для того, чтобы внедриться в эти циклы могут быть использованы специальные сообщения, посылаемые таблице при обработке каждой строки. Это следующие сообщения:

SAM_FetchDone - сообщение, посылаемое таблице при завершении ее заполнения,
SAM_FetchRow - сообщение, посылаемое таблице перед формированием строки,
SAM_FetchRowDone - сообщение, посылаемое таблице после формированием текущей строки.
Для иллюстрации обработки данных сообщений разработано приложение, в котором созданы процедуры обработки этих сообщений. Окно данного приложения показано на рисунке ниже.

Рис. 17 Окно приложения для изучения режимов выборки в таблицу

В верхней части окна "Подключение" построены уже известные (по предыдущим статьям) процедуры подключения к БД и отключения от БД. В центральной части расположена таблица "Таблица с проверкой записей", для которой предусмотрены процедуры обработки табличных сообщений. Кнопка "Добавить из БД" инициирует выполнение функции SalTblPopulate для занесения информации в БД в разных режимах (TBL_FillAll, TBL_FillAllBackground, TBL_FillNormal). Отметим, что обработка табличных сообщений зависит от режима. Кнопка "Очистить Таблицу" позволяет удалить все строки таблицы. Скрытое поле "Число строк" показывает число заполненных строк в таблице. В поле "Сообщение обработки" выполняет индикацию последнего сообщения, обработанного в таблице. Для иллюстрации замены полей в таблице предусмотрено специальное поле ввода фамилии. Если это поле заполнено, то при заполнении таблицы все фамилии, совпадающие со значением в этом поле, автоматически будут заменяться на новое значение (три звездочки -"***"). Замена выполняется в процессе заполнения таблицы. Кроме этого при формировании таблицы в первой колонке "№" вычисляется и заполняется номер записи (в БД он отсутствует). Описание основных переменных окна тестового приложения приведено ниже. Здесь можно выделить три курсора (hSql…), переменные счетчики (nCount, nMaxRs и т.д.) и переменную признака подключения. Значение других переменных мы поясним позже.

Рис. 18 Описание переменных окна тестового приложения

Для индикации ошибок и управления доступом к записям опишем глобальные переменные. Их назначение было рассмотрено выше.

Рис. 19 Описание глобальных переменных тестового приложения

Рис. 20 Процедура подключения к БД

В процедуре подключения к БД в тестовом приложении, помимо выполнения уже знакомых функций (SqlConnect, SqlSetIsolationLevel) используются функции включения и отключения доступа к кнопкам, для того чтобы избежать неверных действий (SalDisableWindow, SalEnableWindow). Отметим, что для того, чтобы сократить объем статьи в данном фрагменте описаны и дополнительные действия, которые необходимы для второго приложения статьи и о них мы расскажем позднее. После нормального подключения к БД, а мы с вами используем уже созданную ранее БД COMPANY, на экране должно появиться следующее сообщение.

Рис. 21 Окно сообщения о подключении

При отключении от БД, помимо операции отключения мы должны сделать недоступными кнопки выборки и отключения (pbAddToTabl, pbDisconnect) и включить кнопку поключения (pbConnect), как показано на рисунке ниже.

Рис. 22 Процедура отключения от БД

При небольших выборках из БД целесообразно выполнять заполнение записей в таблицу в режиме TBL_FillAll. В этом случае все записи заносятся в таблицу. Затем программа продолжит работать. В процессе заполнения таблицы для каждой строки будут инициализированы сообщения SAM_FetchRow и SAM_FetchRowDone. Если обработчиков этих сообщений в программе не предусмотрено, то заполнение таблицы выполняется на основе запроса в функции. Если предусмотрен обработчик сообщений SAM_FetchRow, то, во-первых, в этом обработчике необходимо получить запись для занесения в таблицу (функция SqlFetchRow), и, во-вторых, с помощью возврата указать на завершение процесса обработки выборки (Return FALSE) или продолжения выборки (Return TRUE).

Рис. 23 Выборка в таблицу в режиме TBL_FillAll

На следующем рисунке показана процедура обработки сообщения SAM_FetchRow. Поле индикатора (dfIndicator) заполняется названием типа обрабатываемого сообщения (SAM_FetchRow). Колонка таблицы для заполнения номера (colNumb) заполняется значением из iParam увеличенным на единицу, так как нумерация строк идет с нуля. Это значение преобразуется в символьное значение и к нему добавляется точка ("."). Далее из выборки (скрытой в процедурe SalTblPopulate) считывается текущая запись. Код возврата (nRet) определяет режим продолжения заполнения таблицы (FETCH_Ok). В этом случае определяется текущее число строк (dfNumb) и задается код возврата из процедуры (TRUE). Если записи закончились, то закрывается курсор (SqlCommit) и задается код возврата из процедуры (FALSE).

Рис. 1 Заполнение таблицы в режиме TBL_FillNormal и TBL_FillAll функцией SqlFetchRow

В случае режима TBL_FillAll курсор может быть закрыт и после выполнения функции SalTblPopulate, так как выборка будет полностью завершена. Этого нельзя делать в режиме TBL_FillNormal, освобождение курсора необходимо сделать при обработку сообщения обработки строки. Отметим, что после формирования строки будет инициировано сообщение SAM_FetchRowDone, тоже для каждой строки.

Рис. 2 Закрытие курсора в режиме TBL_FillAll

Выборка в режиме TBL_FillNormal, выполняется аналогично, только в этом случае закрывать курсор можно только после чтения всех записей, а оно завершиться после просмотра в таблице всех выбранных записей. Если записи не просматриваются пользователем до конца, то закрытие курсора нужно выполнить перед следующей выборкой в таблицу или при необходимости его другого применения. Запрос на выборку в режиме TBL_FillNormal, показан на рисунке ниже.

Примечание: В этом случае лучше иметь отдельный курсор для каждого применения, иначе возможны проблемы доступа: выборка (а она определяется курсором) будет разрушена и любая попытка скроллинга таблицы будет невозможна.

Рис. 3 Выборка в таблицу в режиме TBL_FillNormal

При выборке в режиме фона (TBL_FillAllBackground) курсор можно закрывать, только по завершению всей выборки. Запрос в этом режиме показан ниже.

Рис. 4 Выборка в таблицу в режиме TBL_FillAllBackground

Для этого случая предусмотрено специальное сообщение SAM_FetchDone, которое формируется при завершении процесса фоновой выборки. На рисунке, приведенном ниже, показана процедура обработки этого сообщения, с индикацией типа сообщения и закрытием курсора выборки.

Рис. 5 Обработка сообщения SAM_FetchDone и закрытие курсора

После выполнения выборки мы получим окно представленное ниже на рисунке. Первая колонка заполнена номерами записей. В данном примере для второй записи произведена замена содержимого колонки "Имя". Это имя совпало с фамилией для замены - "Иванов".

Рис. 6 Окно приложения с заменой фамилии

Алгоритм замены заложен в обработку сообщения SAM_FetchRowDone, так как при этой операции поля таблицы уже не будут изменяться и они сформированы. При совпадении фамилии (colName = dfFamReplace) значение в колонке будет заменено на "***".

Рис. 7 Обработка сообщения SAM_FetchRowDone

Для демонстрации различных режимов заполнения таблицы рекомендуем Вам использование отладчика (поставьте в процедурах обработки сообщений таблицы точки останова) и обращайте внимание на индикатор сообщений. Кроме того, при анализе приложения можете использовать окно сообщений отладчика и окно просмотра переменных.

Чтобы не усложнять интерфейс при анализе разных режимов используйте способ комментирования и разкомментирования запросов в процедуре обработки нажатия клавиши ("Добавить из БД" - pbAddToTabl)
После выполнения действий вы получите работающее приложение. Некоторые детали мы сознательно опустили из данного изложения, так как они подробно были рассмотрены ниже. Приложение, которое вы получите (step61.app), можно скачать здесь

Работа с записями на основе таблицы

Далее рассмотрим работу с БД на основе выборки. Возможны два варианта: работа с таблицей и работа непосредственно с выборкой из БД (Result Set). Ниже приведено окно приложения, которые мы построили для изучения этих режимов. В процессе дальнейшего изучения данной статьи Вы самостоятельно, тоже сможете построить такое приложение. Заполнение данного окна предназначено для изучения режима совместной работы таблицы и выборки. Отметим, что задача разбивается на следующие шаги:

  • Формирование выборки и заполнение таблицы,
  • Работа с таблицей, построенная на основе выборки из БД,
  • Синхронизация таблицы и выборки,
  • Навигация по записям.

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

Для переключения режимов предусмотрены специальные радиокнопки ("Таблица" и "Result Set"), расположенные в нижней части окна. Верхняя часть окна у нас такая же, как и в предыдущем приложении. Поэтому оставим ее без комментария. В нижней части окна поля имеют следующее назначение: поле "Номер записи" указывает на текущую запись, поле "Имя" используется для ввода и чтения имени сотрудника, поле "Оклад" - для ввода/вывода оклада, а список "Должность", для индикации и ввода должностей. Защищенное поле "Размер RS" - определяет объем выборки из БД.
Кнопки для работы с записями имеет следующее назначение: кнопка "Добавить" добавляет записи, кнопка "Удалить" используется для их удаления, а кнопка "Изменить" предназначена для модификации записей. Думаю, что навигационные кнопки понятны всем по смыслу: "в начало выборки", "назад на запись", "вперед на запись" и "в конец выборки". Поле "Номер для выбора" и кнопка "Выбрать по номеру" позволяют установить текущим конкретный номер записи из таблицы или выборки. Специальная кнопка "Сформировать RS" (выборку), доступна только в режиме "Result Set".

На следующем рисунке показаны все объекты данного приложения. По смыслу и названию читателю несложно будет их сопоставить с экранными элементами, поэтому не будем тратить время на это описание. Отмечу только, что в таблице для синхронизации доступа у нас появилась специальная скрытая колонка с названием colROWID, она будет нами использоваться для редактирования и удаления записей.

Рис. 9 Описание объектов окна приложения

Рассмотрим теперь цикл формирования записей в таблицу на нижнем уровне. Первоначально выполняется запрос, знакомый нам по другим примерам. Он выполняется с помощью функции выполняющей одновременно компиляцию и формирование выборки - SqlPrepareAndExecute. В принципе эта операция может быть разделена на две: отдельно компиляция (SqlPrepare) и отдельно формирование выборки (SqlExecute). В данной функции указываются два параметра: курсор (hSql2) и текст запроса. В самом тексте запроса в разделе оператора выборки INTO перечислены связующие переменные (bind variables), которые для нашего примера совпадают с колонками таблицы: tblTest.colName, tblTest.colOklad, tblTest.colDolg, tblTest.colROWID. Для выделения связующих переменных перед ними ставиться двоеточие. Отметим в этом запросе наличие выборки ROWID в специальную скрытую колонку.

Примечание: В БД для любой записи SQLBase автоматически хранит специальное уникальное полу имеющее имя ROWID. Это символьное поле (40 символов), которое генерируется по специальным правилам и служит для идентификации записей. При изменении и удалении записей оно изменяет свое значение, поэтому оно может служить для выяснения того, была ли запись изменена или удалена. В нашем примере для операций изменения и удаления записей, мы будем использовать эту колонку.

Правильность выполнения операций можно проверить по коду возврата функции (в нашем примере это опущено). После выполнения запроса на выборку мы определяем ее размер с помощью функции SqlGetResultSetCount. Если выборка ненулевая (nCount > 0), то организуем цикл сканирования по выборке с одновременным занесением строк выборки в таблицу.

Рис. 10 Цикл выборки в таблицу из RS на основе счетчика записей

Цикл в этом случае организован с помощью оператора Loop, на основе счетчика nCount. Счетчик уменьшается на единицу, а при достижении нуля цикл прерывается (break). На каждом шаге цикла сначала добавляется строка в таблицу (функция - SalTblInsertRow) и в нее выбирается текущая строка выборки (SqlFetchRow). В колонку номера (tblTest.colNumb), известным нам способом заносится номер с точкой. Счетчик цикла уменьшается на единицу. Далее сбрасываются флаги заголовочной колонки для добавляемых записей (SalTblSetFlagsAnyRows). В конце процедуры выборка будет закрыта и курсор освобождается (SqlCommit). Данный вариант организации цикла выборки не единственно возможный, но на наш взгляд при заполнении таблицы наиболее рациональный.

После заполнения таблицы мы модем начинать работать с записями. Если щелкнуть мышкой по строке или заголовочной колонке, то автоматически будут заполнены поля окна (имя, оклад и должность) и указан номер текущей записи (dfNumb). Эти действия поддерживаются процедурами, как реакция на сообщения таблицы. Фрагменты текста даны ниже.

Рис. 11 Обработка сообщений при выделении строки в таблице

В нашем примере мы будем использовать пользовательское сообщение, для заполнения списка должностей. Эта константу (FILL_LIST) нужно определить в разделе системных констант, как показано на рисунке ниже.

Рис. 12 Описание пользовательской константы FILL_LIST

Реакция на данное сообщение, определенная в разделе сообщений комбинированного списка (cmbDolg) показана на рисунке ниже. При поступлении сообщения этого типа список будет заполнен запросом в функции SalListPopulate.

Рис. 13.  Заполнение списка при создании и обработке пользовательского сообщения

Теперь рассмотрим процедуры для работы с записями сотрудников. Ниже приведены фрагменты текстов программы для добавления, удаления и изменения записей. Первоначально мы должны определить код должности из связанной таблицы, это делается простым запросом на основе состояния списка должностей. Результат получим в переменной - nCodeDolg. Далее для новой записи мы получаем новый уникальный код на основе запроса в таблице сотрудников (nMaxCode). Затем этот код увеличиваем на единицу. Следующим шагом выполняем запрос добавления записи в БД (INSERT). Так как состояние таблицы должно измениться, то очищаем ее и снова заполняем, но на этот раз с помощью функции SalTblPopulate. Запрос заполнения таблицы аналогичен исходному запросу. При удалении записей достаточно использовать ROWID текущей записи в таблице для выполнения запроса. Удаление выполняется стандартной командой SQL - DELETE. После удаления записи таблица должна быть обновлена аналогичным образом. При редактировании записей, необходимо получить новый код должности и выполнить команду SQL UPDATE, используя соответствующие связующие переменные (поля: dfName , nCodeDol, dfOklad). Код записи редактировать нельзя. После редактирования таблица вновь будет заполнена. В принципе, если объем выборки велик, то можно не заполнять таблицу заново, а использовать специальные функции для ее обновления (SalTblDoInsert, SalTblDoDeletes, SalTblDoUpdate). Но эти функции мы рассмотрим позже в других статьях.

Рис. 14 Процедура добавления новой записи сотрудника

Текст процедуры удаления записей представлен ниже.

Рис. 15 Процедура удаления записи из БД

Текст процедуры редактирования записей представлен ниже.

Рис. 16 Процедура редактирования записи в БД

Ранее мы отмечали, что возможны различные варианты циклов для формирования выборки в таблицу. Пример такого цикла, возможно менее экономичного, представлен на рисунке ниже. Особенностью данного цикла является то, что заранее не определяется объем выборки, а завершение цикла происходит на основе кода возврата полученного при сканировании выборки (nErr = FETCH_EOF). Из-за этого приходиться удалять лишнюю строку, сформированную в цикле. Все другие операции с таблицей идентичны.

 


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=2265