Вы находитесь на странице: 1из 12

Лабораторная работа №24

Работа с сеткой DBGrid

Тема: Работа с сеткой DBGrid


Цель: Изучение свойств и методов компонента DBGrid.
Оборудование: IBM – совместимые компьютеры.
Место проведения: Компьютерный класс.
Техника безопасности: См. инструкцию.

Теоретическая часть
Профессиональные программы отличаются большим набором
дополнительных возможностей для пользователя. В этой работе рассмотрим
дополнительные возможности сетки DBGrid.
Строки сетки DBGrid соответствуют записям подключенного набора
данных, а столбцы - полям. Свойство DataSource содержит ссылку на
выбранный набор данных. Изменяя эту ссылку во время работы программы,
можно изменять выводимые в сетке данные, отображая то одну, то другую
таблицу (или запрос) в одной сетке DBGrid.
Столбцы DBGrid
Столбцы содержат значения полей подключенного к сетке набора
данных. Этими значениями можно манипулировать, показывая или скрывая
поля НД, меняя их местами или добавляя новые столбцы. Нам уже
приходилось это делать в редакторе полей набора данных, однако, это не
всегда оправдано - один набор данных может использоваться в различных
местах приложения, в различных формах и на различных сетках.
Изменение свойств полей набора данных в этом случае коснется и всех
сеток DBGrid, которые подключены к нему, а это требуется далеко не всегда.
Более разумным вариантом будет добавление всех полей в редактор
полей набора данных, а изменение их свойств можно сделать в каждой
сетке по-своему.
Если не пользоваться редактором столбцов самой сетки, DBGrid будет
выводить значения по умолчанию - будут выведены все поля набора данных,
а заголовки столбцов будут соответствовать именам полей. Но стоит только
добавить в редактор столбцов хоть один столбец, и сетка DBGrid будет
отображать только его. Таким образом, мы можем показывать только те
столбцы, которые действительно необходимы.

Выполнение работы:

Создайте новое приложение. Свойству Name формы, как всегда,


присвойте значение fMain, свойству Caption - "Изучение свойств DBGrid".
Проект сохраните в отдельную папку, модулю дайте имя Main, а проекту в
целом - MyDBGrid. В эту же папку скопируйте базу данных ok.mdb из
прошлой лекции. На форме нам понадобятся сетка DBGrid с вкладки Data
Controls, с вкладки ADO компоненты ADOConnectionи ADOTable, с
вкладки Data Access - компонент DataSource. Также для красоты и удобства
можно добавить компонент DBNavigator.
Из прошлых работ вы знаете, как подключить к базе
данных компонент ADOConnection, а затем подключить к нему
таблицу ADOTable. В свойстве TableName таблицы выберите
таблицу LichData, и откройте ее. Компонент DataSource подключите к нашей
таблице, а сетку DBGridи навигатор DBNavigator - к DataSource. В результате
у вас должна получиться простая форма с сеткой и навигатором по ней, в
которой отображаются все поля таблицы LichData:

Рис. 1. Форма проекта

Допустим, в нашем проекте нам нужны не все поля таблицы, а только


некоторые из них. Значит, придется поработать с редактором столбцов
сетки DBGrid. Вызвать редактор можно тремя способами: дважды
щелкнуть по сетке; щелкнуть правой кнопкой по сетке и в контекстном меню
выбрать команду Columns Editor и, наконец, щелкнув дважды по свойству
сетки Columns в Инспекторе Объектов:
Рис. 2 . Редактор столбцов сетки DBGrid

Работа с этим редактором очень похожа на редактор полей набора данных,


но есть и отличия. В верхней части окна вы видите четыре кнопки, слева -
направо:
1. Add New (Добавить новый столбец).
2. Delete Selected (Удалить выделенный столбец).
3. Add All Fields (Добавить все столбцы из набора данных).
4. Restore Defaults (Восстановить значения по умолчанию для
выделенного столбца).
Если столбцов в редакторе нет, то сетка отображает все поля НД.
Добавим один столбец. Для этого нажмем первую кнопку. Сразу же все поля
НД исчезли, а сетка отображает пустой столбец. Выделим его в редакторе
столбцов, а в Инспекторе объектов в свойстве FieldName выберем поле
"Фамилия". Сразу же столбец отобразит это поле. Заголовок столбца будет
соответствовать названию поля. В нашей БД имена полей мы задавали
русскими буквами, однако это бывает не всегда, особенно если вы работаете
с таблицами Paradox или клиент-серверными БД. В этом случае названия
полей будут выводиться латиницей, а это не удобно для пользователя.
Изменить параметры заголовка столбца можно в раскрывающемся
свойстве Title, которое имеет ряд собственных свойств:
Alignment - свойство устанавливает выравнивание заголовка и может
быть taCenter (по центру), taLeftJustify (по левому краю) и taRightJustify
(по правому краю). По умолчанию, заголовок выровнен по левому краю.
Caption - свойство содержит текст, который отображается в заголовке
столбца. Если поле НД имеет имя латинскими буквами, именно здесь можно
отобразить его кириллицей.
Color - цвет заголовка, по умолчанию это свойство равно clBtnFace,
что обеспечивает стандартный серый цвет. Если вы желаете украсить
программу, можете выбрать другой цвет.
Font - шрифт заголовка. Если дважды щелкнуть по этому свойству,
откроется диалоговое окно, в котором можно изменить шрифт, начертание,
размер и цвет шрифта. То же самое можно сделать, если раскрыть это
свойство и непосредственно изменять нужные свойства.
Надо заметить, что свойства Font, Alignment и Color внутри свойства
Title меняют шрифт, выравнивание и цвет фона только заголовка столбца, а
не его содержимого. Но у столбца имеются эти же свойства, они меняют
шрифт, выравнивание и цвет фона выводимых в столбце данных.
Свойство Visible разрешает или запрещает отображение столбца, а
свойство Width позволяет изменить его ширину. О других свойствах
поговорим чуть позже.
Добавьте в сетку другие поля НД: "Имя", "Отчество", "Пол" и
"Военнообязанный".
Обратите внимание, что перетаскивая мышью столбцы в редакторе
столбцов, вы можете менять их порядок в сетке. Пользователь же имеет
возможность менять их порядок, перетаскивая мышью заголовки столбцов.
У сетки DBGrid имеется свойство Columns, которое содержит столбцы.
Щелчок по этому свойству как раз и откроет редактор столбцов сетки.
Столбцы хранятся в свойстве Items в виде массива и имеют индексы от 0
до DBGrid1.Columns.Items.Count-1. Заметим, что свойство Items используется
по умолчанию, и его можно не указывать:

DBGrid1.Columns[0] = DBGrid1.Columns.Items[0]

Шрифт и цвет можно менять не только в Инспекторе объектов, но и


программно. Добавим на форму две кнопки, на которых напишем "Шрифт"
и "Цвет". А также два диалога: FontDialog и ColorDialog. Создадим
процедуру нажатия на первую кнопку и впишем в нее следующее:

{Меняем шрифт}
procedure TfMain.Button1Click(Sender: TObject);
begin
//считаем в диалог шрифта установленный шрифт
FontDialog1.Font :=
DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Font;
//установим выбранный шрифт:
if FontDialog1.Execute then
DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Font :=
FontDialog1.Font;
end;

Здесь вначале мы свойству Font диалога FontDialog присвоили тот


же шрифт, который был в текущем столбце сетки. Затем вызвали выбор
диалога, и если пользователь выбрал другой шрифт (название, начертание,
размер, цвет шрифта), то изменяем шрифт всего столбца на выбранный
пользователем. Аналогичным образом меняем и цвет столбца. Создайте
процедуру обработки второй кнопки, и впишите код:
{Меняем цвет}
procedure TfMain.Button2Click(Sender: TObject);
begin
//считаем в диалог цвета установленный цвет:
ColorDialog1.Color :=
DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Color;
//установим выбранный цвет:
if ColorDialog1.Execute then
DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Color :=
ColorDialog1.Color;
end;

Сохраните проект, скомпилируйте его и проверьте работу кнопок.


И шрифт, и цвет текущего столбца будут меняться:

Рис. 3 . Изменение шрифта и цвета текущего столбца

Следует заметить, что таким образом можно менять параметры не


только содержимого текущего столбца, но и его заголовка, если, например,
вместо
DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Color
использовать
DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Title.Color
А если применить цикл, то можно изменить параметры всех столбцов:
for i:= 0 to DBGrid1.Columns.Count-1 do
DBGrid1.Columns.Items[i].Color :=

Пустые столбцы
Если добавить в редактор столбцов сетки DBGrid новый столбец, но в
свойстве FieldName не выбирать поле БД, а оставить его пустым, мы получим
пустой столбец. Пустые столбцы в сетке могут быть использованы в
следующих случаях. Во-первых, в них можно выводить обработанные
данные из других столбцов. К примеру, пользователю неудобно
просматривать три столбца "Фамилия", "Имя" и "Отчество". Ему было бы
удобней просмотреть один сборный столбец в формате "Фамилия И.О.". Во-
вторых, пустое поле может выводить информацию по требованию.
Рассмотрим эти случаи.
Создайте новый столбец, но не назначайте ему поле из НД. Выделите
этот столбец, и в его свойстве Title.Caption впишите "Фамилия И.О.", а в
свойстве Width укажите ширину в 150 пикселей. Эти сборные данные не
будут видны в момент проектирования таблицы, они выйдут только во время
работы программы.
Столбцы "Фамилия", "Имя" и "Отчество" нам уже не нужны, скройте
их, установив их свойство Visible в False. А новый столбец перетащите
мышью наверх, его индекс будет равен 0.
Нам придется написать код, который нужно вписать в событие
OnDrawColumnCell сетки. Это событие наступает при прорисовке каждой
ячейки столбца. Также имеется событие OnDrawDataCell, которое выполняет
схожие функции, но оно оставлено для поддержки старых версий, и
использовать его не желательно. Итак, выделяем сетку, генерируем
событие OnDrawColumnCell и вписываем код:

{Прорисовка таблицы}
procedure TfMain.DBGrid1DrawColumnCell(Sender: TObject; const Rect:
TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
s: String;
begin
//если это пустой столбец
if Column.Index = 0 then begin
if ADOTable1['Фамилия'] <> Null then
s:= ADOTable1['Фамилия'] + ' ';
if ADOTable1['Имя'] <> Null then
s:= s + Copy(ADOTable1['Имя'], 1, 1) + '.';
if ADOTable1['Отчество'] <> Null then
s:= s + Copy(ADOTable1['Отчество'], 1, 1)+ '.';
DBGrid1.Canvas.TextOut(Rect.Left, Rect.Top, s);
end; //if
end;

Здесь мы вначале проверяем - наш ли это столбец (равен


ли индекс нулю)? Если наш, то в переменную s начинаем собирать нужный
текст. При этом имеем в виду, что пользователь мог и не заполнить
некоторые поля. Чтобы у нас не произошло ошибки, вначале убеждаемся,
что поле не равно Null (то есть, текст есть). Если текст есть, добавляем его в
переменную s. Причем если это имя или отчество, с помощью
функции Copy() получаем только первую букву и добавляем к ней точку.
Когда s сформирована, добавляем этот текст в наш столбец с помощью
метода TextOut() свойства Canvas сетки. В метод передаются три
параметра: координаты левой позиции, верхней позиции и сам текст.
Эти координаты мы берем из параметра события OnDrawColumnCell - Rect,
который имеет такие свойства, как Left и Top, показывающие,
соответственно, левую и верхнюю позиции текущей ячейки.
В результате программа будет иметь вид:

Рис. 4. Заполнение пустого столбца

Теперь о том, как использовать пустой столбец для вывода


информации по требованию пользователя. Допустим, в сетке DBGrid нам
нужна кнопка, нажатие на которую привело бы к выводу сообщения об
образовании сотрудника.
Создайте новый пустой столбец. Перетаскивать его не нужно, пусть
будет последним. Свойство Width (ширина) установите в 20 пикселей.
Название столбца ( Title.Caption ) вписывать не нужно, пусть будет пустым.
В свойстве ButtonStyle выберите значение cbsEllipsis. Это приведет к тому,
что при попытке редактировать этот столбец образуется кнопка с тремя
точками:

Рис. 5 . Кнопка в пустом столбце

Нужный код пишется в событии OnEditButtonClick() сетки DBGrid,


которое происходит всякий раз, когда пользователь нажимает на кнопку
"…". Сгенерируйте это событие и впишите только одну строку:

ShowMessage(ADOTable1['Образование']);
Теперь, когда пользователь нажмет на эту кнопку, ему будет выведено
сообщение с текстом об образовании текущего сотрудника.
Список выбора в столбце
Для организации списков выбора служит компонент ComboBox.
Однако сетка DBGrid позволяет устроить такой же список в одном из своих
столбцов без использования каких-либо других компонентов. В нашем
примере есть поле "Пол". Это текстовое поле из трех символов. Во время
конструирования базы данных ok.mdb с помощью программы MS Access мы
указывали, что это поле может хранить значения либо "муж", либо "жен". То
же самое можно было сделать с помощью сетки. Откройте редактор столбцов
сетки и выделите столбец "Пол". Обратите внимание на свойство PickList в
Инспекторе объектов. Это свойство имеет тип TStrings, то есть представляет
собой набор строк, так же как и свойство Itemsу компонента ComboBox.
Щелкните дважды по PickList, чтобы открыть редактор, и впишите туда
муж
жен
именно так, каждое значение на своей строке. Сохраните проект,
скомпилируйте его и попробуйте редактировать этот столбец. При попытке
редактирования в ячейке покажется похожий на ComboBox список, в котором
можно будет выбрать одно из указанных значений:

Рис. 6. Список выбора в сетке

Следует иметь в виду, что наличие такого списка не препятствует


пользователю ввести какое-то иное значение. Этот список нужен не для
контроля, а только для облегчения пользователю ввода данных. Если же вы
не желаете, чтобы пользователь имел возможность вводить другие
данные, контроль следует организовать иным способом.
Еще нужно заметить, что в практике программирования список чаще
формируется во время работы программы, а строки списка берутся, как
правило, из другой связанной таблицы

Выделение отдельных строк


Очень часто в практике приходится выделять какие-то строки, изменяя
их фон или цвет шрифта. Например, в бухгалтерии обычно выделяют строки,
в которых значение меньше нуля. Допустим, ваша программа показывает
клиентов, а какой-то столбец содержит их баланс на счету вашей компании.
Если этот баланс меньше 0, значит, клиент имеет задолженность перед вашей
фирмой. Бухгалтеру будет очень удобно, если дебиторы (должники) будут
выделяться в общем списке красным цветом.
Способ прорисовки данных в сетке DBGrid зависит от значения ее
свойства DefaultDrawing. По умолчанию свойство равно True, то есть данные
прорисовываются автоматически. Если свойство содержит False, то
прорисовку придется кодировать самостоятельно в свойствах
OnDrawColumnCell или OnDrawDataCell, о которых уже упоминалось.
Если написать алгоритм прорисовки, но свойство DefaultDrawing
содержит True, то вначале сетка заполнится данными автоматически, а затем
будет выполнен наш алгоритм.
Разберем этот метод подробней. В справке Delphi, можно увидеть:
property OnDrawColumnCell: TDrawColumnCellEvent;
То есть, этот метод имеет тип TDrawColumnCellEvent. Описание типа
такое:
type TDrawColumnCellEvent = procedure (Sender:TObject; const
Rect:TRect;
DataCol:Integer; Column:TColumn; State:TGridDrawState) of object;
Разберемся с параметрами.
Rect - координаты прорисовки.
DataCol - порядковый номер текущего столбца (начиная с 0).
Column - данные текущего столбца.
State - состояние ячейки. Может быть:
 gdSelected - ячейка выделена
 gdFocused - фокус ввода в ячейке
 gdFixed - ячейка - заголовок столбца.
Допустим, в нашем примере требуется, чтобы строки с
военнообязанными сотрудниками выделялись красным цветом:

Рис. 7 . Выделение строк

Заметим сразу, что наличие пустых столбцов создает дополнительные,


но решаемые проблемы. Код события OnDrawColumnCell придется
переделать, он будет таким:
{Прорисовка таблицы}
procedure TfMain.DBGrid1DrawColumnCell(Sender: TObject; const Rect:
TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
s: String;
begin

with DBGrid1.Canvas do begin


//поле "Военнообязанный" содержит истину?
if (ADOTable1['Военнообязанный'])= True and
not (gdSelected in State) then begin
//выводим все ячейки строки красным по белому:
Font.Color:= clRed;
FillRect(Rect);
end; //if

//если это пустой сборный столбец


if Column.Index = 0 then begin
if ADOTable1['Фамилия'] <> Null then
s:= ADOTable1['Фамилия'] + ' ';
if ADOTable1['Имя'] <> Null then
s:= s + Copy(ADOTable1['Имя'], 1, 1) + '.';
if ADOTable1['Отчество'] <> Null then
s:= s + Copy(ADOTable1['Отчество'], 1, 1)+ '.';
DBGrid1.Canvas.TextOut(Rect.Left, Rect.Top, s);
end //if
//если это пустой столбец с кнопкой "..."
else if Column.Index = 6 then begin
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
Exit;
end //if
//все остальные столбцы
else
TextOut(Rect.Left+2, Rect.Top+2, Column.Field.Text);
end; //with
end;

Разберемся с кодом. Вначале с помощью with мы указываем, что будем


работать непосредственно со свойством DBGrid1.Canvas, которое отвечает за
стиль прорисовки ячейки. Далее мы смотрим, содержится ли True в поле
"Военнообязанный" текущей записи. Если да, то указываем, что цвет шрифта
должен быть красным, а затем функцией FillRect(Rect) стираем
стандартный вывод.
Далее определяем, прорисовывается ли в данный момент пустой
сборный столбец с "Фамилия И.О.". Если это он, то мы формируем
переменную s с нужными данными и выводим их, как в прошлый раз.
Если же это пустой столбец с кнопкой "…", то мы делаем
стандартный вывод и выходим из процедуры. Если мы этого не сделаем, то
получим ошибку программы.
Все остальные столбцы выводим строкой

TextOut(Rect.Left+2, Rect.Top+2, Column.Field.Text);

Обратите внимание, что мы добавили по два пикселя к крайней левой и


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

Рис. 8. Некорректная прорисовка

Количество добавляемых пикселей зависит от формата данных и


размера шрифта. Обычно это определяется путем проб. Например, ячейка
может содержать цифры, которые обычно прижимаются к правому краю, и
тут двумя пикселями не обойтись.
Сделать проверку на тип данных можно, например, так:
//если текст, сдвинем только на 2 пикселя
if Column.Field.DataType = ftString then
TextOut(Rect.Left, Rect.Top+2, Column.Field.Text)
//если цифры, сдвинем их вправо на 28 пикселей
else TextOut(Rect.Left+28, Rect.Top+2, Column.Field.Text);
Выделение строки красным текстом может оказаться недостаточным
для заказчика. Что, если он потребует, чтобы эти строки выделялись красной
строкой с белым шрифтом? Тогда вместо
Font.Color:= clRed;
FillRect(Rect);
вам придется написать
//выводим все ячейки строки белым текстом по красному фону:
Brush.Color:= clRed;
Font.Color:= clWhite;
FillRect(Rect);
Как видите, подсвойство
DBGrid1.Canvas.Brush.Color
отвечает за цвет заливки ячейки, а
DBGrid1.Canvas.Font.Color
за цвет выводимого в ней шрифта. Список доступных цветов вы можете
открыть в любом свойстве Color любого компонента. Теперь вы сможете
создать сетку со сложными элементами прорисовки.

Студент должен знать: Основные положения теории баз данных,


хранилищ данных, баз знаний, создание базы данных, операторы языка SQL
Студент должен уметь: Создавать объекты баз данных в современных
системах управления базами данных, разработать проект с выполнением
запросов с помощью операторов языка SQL.

Оценить