Практическое занятие № 18

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

Цель работы: получить практические навыки для работы с сеткой DBGrid

 

Ход работы

 

В среде Delphi создайте программу для работы с данными таблицы из БД "personal", в которой в двух таблицах хранится информация о должностях и сотрудниках предприятия (связаны по полю id_dolg).

 

При этом форма должна иметь вид:

 

 

 

В сетке отображаются все поля кроме поля "foto". Все поля должны иметь название по-русски и приемлемую ширину колонок.

 

Указания: для главной форме задайте свойства: Caption="Работа с сеткой DBGrid", Position="DesktopCenter", BorderStyle="bsSingle". На форму нанесите компонент ADOConnection (ADO). В свойстве ConnectionString укажите параметры подключения к БД Access. В свойстве LoginPrompt укажите false, чтобы программа не запрашивала логин и пароль при соединении с БД.

Нанесить на форму компонент ADOTable (ADO). В свойстве Connection укажите соединение с БД ADOConnection1, в свойстве TableName укажите таблицу Sotr.

 

Для того, чтобы программа корректно подключала таблицу в событии формы OnCreate введите код:

 

procedure TForm1.FormCreate(Sender: TObject);

begin

    ADOTable1.Active:=true;

end;

 

Для того, чтобы программа корректно отключала таблицу в свойстве формы OnDestroy введите код:

 

procedure TForm1.FormDestroy(Sender: TObject);

begin

    ADOConnection1.Connected:=false;

end;

 

Двойным щелчком на компоненте ADOTable1, в контекстном меню окна выберите команду "Add All Field". В результате в окне появится список полей таблицы. По очереди выделяйте каждое поле и в свойстве DisplayLabel укажите название поля в сетке, а в поле DisplayWidth укажите ширину поля в символах.

 

Вместо поля "id_dolg" создайте список с перечнем должностей из таблицы Dolg.

 

Указания: для формирования перечня значений для списка будем использовать запрос.

Нанесите на форму компонент ADOQuery (ADO) и задайте свойства: Connection = ADOConnection1, SQL =текст запроса вида:

 

select id_dolg, dolg from dolg

union

select null, null from dolg

 

В событии OnCreate формы добавьте код активации запроса:

 

ADOQuery1.Active:=true;

 

Двойным щелчком на компоненте ADOTable1 откройте список полей таблицы. В контекстном меню выберите команду New Field и для нового поля задайте следующие параметры:

 

Name = dolg (имя нового поля в таблице);

Type = String (тип нового поля в таблице);

Field type = Lookup (поле будет выпадающим списком);

Dataset = ADOQuery1 (источник данных для заполнения выпадающего списка);

Key Fields = id_dolg (поле, по которому таблица Sotr связана с должностями)

Lookup Keys = id_dolg (поле, по которому таблица Dolg связана с сотрудниками)

Result Field = dolg (поле из таблицы Dolg, которое будет отображаться в поле на форме).

 

Для переименования поля задайте для него свойство Display Label = Должность.

 

 

Спроектируйте сетку для отображения данных таблицы.

 

Указание: Нанесите на форму компонент DataSource (DataAccess). Задайте для него свойство DataSet =ADOTable1.

Нанесите на форму компонент DBGrid (DataControls). В свойстве DataSource укажите имя компонента DataSource1. Щелкните два раза на компоненте DBGrid. В окне вызовите контекстное меню и выберите команду "Add All Fields". В результате в окне отобразится список полей таблицы. Для полей "id_dolg" и "foto" задайте свойство Visible=false.

Нанесите на форму компонент DBNavigator (DataControls). Задайте свойство DataSource=DataSource1.

Для выравнивания компонентов на форме для компонента DBNavigator задайте свойство Align = alBottom, для компонента DBGrid свойство Align = alClient.

 

В ячейке колонки "Дата рождения" отображается кнопка с троеточием, с помощью которой открывается вспомогательная форма с календарем:

 

 

 

Указания: для отображения кнопки с троеточием двойным щелчком на сетке откройте список колонок, выделите колонку Datar и задайте свойства: ReadOnly=true; ButtonStyle=cbsEllipsis.

Для редактирования поля "Datar" создадим новую форму. Чтобы форма не создавалась автоматически при запуске программы выполните команду "Project – Options" и перенесите форму  в список "Available Forms". Для новой формы задайте свойства: BorderStyle=bsNone,   Position = poOwnerFormCenter.

Нанесите на форму компонент MonthCalendar (Win32)  и две кнопки. Для календаря задайте свойство Align = alTop.

При открытии этой формы в календаре должна отображаться дата из поля "Datar" сетки. Для этого в событии OnCreate формы введите код:

 

procedure TForm2.FormCreate(Sender: TObject);

begin

//если поле "Datar" не пустое

if form1.ADOTable1.FieldByName('datar').AsString<>'' then

//в календаре отображаем значение этого поля   

MonthCalendar1.Date:=form1.ADOTable1.FieldByName('datar').Value

//если поле "Datar" пустое

else

//в календаре отображаєм текущую дату

MonthCalendar1.Date:=date;

end;

 

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

 

procedure TForm2.Button1Click(Sender: TObject);

begin

    //в поле сетки отображаем выбранную дату

    form1.ADOTable1.FieldByName('datar').Value:=MonthCalendar1.Date;

    //переходим в поле "datar"

    form1.ADOTable1.FieldByName('datar').FocusControl;

    //закрываем форму

    Close;

end;

 

Кнопка "Отменить" закрывает форму не внося изменений в поле сетки. Для кнопки напишем код:

 

procedure TForm2.Button2Click(Sender: TObject);

begin

    //переходим на поле "datar"

    form1.ADOTable1.FieldByName('datar').FocusControl;

    //закрываем форму

    Close;

end;

 

При закрытии формы с календарем форма должна удаляться из памяти. В событии формы OnClose введите код:

 

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);

begin

    Action:=caFree;

 end;

 

При щелчке на кнопке с тремя точками должна открываться созданная вами форма с календарем. Для этого в событие OnEditButtonClick сетки введите код:

 

procedure TForm1.DBGrid1EditButtonClick(Sender: TObject);

begin

    //если пользователь щелкнул в ячейке поля "datar"

    if DBGrid1.Columns[DBGrid1.SelectedIndex].FieldName='datar' then

    begin

    //переводим таблицу в режим редактирования

    ADOTable1.Edit;

    //создаем и открываем форму Form2

    form2:=TForm2.Create(self);

    form2.ShowModal;

    end;

end;

 

В сетке создайте специальную колонку для отображения состояния поля "foto". Если поле заполнено (имеется фото в базе), то в колонке отображается одна иконка, иначе - другая.

 

Указания: для добавления пустой колонки щелкните на сетке два раза. В контекстном меню окна выберите команду "Add". Для созданной колонки задайте свойства: FieldName=pict, Title - Caption = 1 пробел, Width = 25.

Для хранения иконок нанесите на форму компонент ImageList (Win32). Двойным щелчком откройте этот компонент и с помощью кнопки "Add" добавьте в него нужные рисунки.

Для отображения иконок в ячейках созданной колонки в событии OnDrawColumnCell опишите переменную:

 

 var p:TBitmap;

 

и добавьте код:

 

//если заголовок колонки равен пробелу (наша новая ячейка)

if Column.Title.Caption = ' ' then

begin

//создаем в памяти переменную для считывания иконки

p:=TBitmap.Create;

//если поле "foto" не пустое

if not ADOTable1.FieldByName('foto').IsNull then

    //считываем первую иконку (нумерация с 0)

    ImageList1.GetBitmap(0,p)

//иначе, если поле "foto" не пустое

else

    //считываем вторую иконку

    ImageList1.GetBitmap(1,p);

//отображаем считанную иконку в ячейке колонки

DBGrid1.Canvas.Draw(Rect.Left,Rect.Top,p);

end;

 

В сетке выполните условной форматирование строк по правилу: строки с окладом до 1500 обозначаются одним цветом, а более 1500 - другим.

 

Указания: в событии DrawColumnCell сетки НАД КОДОМ ОТОБРАЖЕНИЯ ИКОНОК введите код:

 

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;DataCol: Integer; Column: TColumn; State:TGridDrawState);

begin

    //если поле "oklad" менее 1500

    if ADOTable1.FieldByName('oklad').Value<1500 then

        //для сетки задаем один цвет фона

        DBGrid1.Canvas.Brush.Color:=$00FFAFC8

    else

        //иначе задаем другой цвет фона

        DBGrid1.Canvas.Brush.Color:=$00A5FFB6;

    //заливаем строку указанным цветом фона

    DBGrid1.Canvas.FillRect(Rect);

 

    //после заливки весь текст становится невидимым (залитым фоном)

    //нужно заново вывести весь текст в колонках

    //при этом колонка с рисунком не имеет текста и ее нужно пропустить

 

    //если заголовок текущей колонки не равен пробелу (не колонка с рисунком)

    if Column.Title.Caption <> 'Фото' then

        //выводим в ней текст  

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

end;

 

При щелчке на иконке нужно отображать окно для просмотра и редактирования поля "foto".

 

 

Указания: добавьте новую форму. Чтобы форма не создавалась автоматически при запуске программы выполните команду Project - Options и перенесите форму в список Available Forms. Для новой формы задайте свойства: Caption=Фото, Position = poOwnerFormCenter. С помощью команды File - Use Unit подключите модуль главной формы Unit1.

Нанесите на форму компонент DBImage(DataControls) и две кнопки.

Для DBImage задайте свойства: DataSource=Form1.Datasource, DataField=foto, Align=alTop, Stretch=true.

 Кнопка "Изменить"  открывает диалог выбора файла и записывает указанный файл в поле "foto". Для этого нанесите на форму компонент OpenPictureDalog (Dialogs). В свойстве Filter оставьте только формат *.bmp. Для кнопки напишите код:

 

procedure TForm3.Button1Click(Sender: TObject);

begin

if OpenPictureDialog1.Execute then        

//загружаем в поле "foto" выбранный файл    

TBlobField(form1.ADOTable1.FieldByName('foto')).LoadFromFile(OpenPictureDialog1.FileName);

end;

 

Для работы функции  TBlobFeld подключите модуль DB.

 

Кнопка "Очистить" очищает содержимое поля. Для кнопки напишите код:

 

procedure TForm3.Button2Click(Sender: TObject);

begin

    TBlobField(form1.ADOTable1.FieldByName('foto')).Clear;

end;

 

При закрытии формы нужно форму удалить из памяти. Для этого в событии OnClose формы введите код:

 

procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);

begin

    Action:=caFree;

end; 

 

Созданная форма должна появляться после щелчка пользователем в ячейке с картинкой. Для этого в событии OnCellClick сетки добавьте код: 

 

//если щелкнули в ячейке с картинкой (заголовок колонки равен пробелу)

if Column.Title.Caption = ' ' then

begin

//переводим таблицу в режим редактирования

ADOTable1.Edit;

//создаем и открываем форму Form3

form3:=TForm3.Create(Self);

form3.ShowModal;

end;

 

В программе реализовать сохранение и восстановление таких параметров сетки как: порядок, ширина и заголовок колонок.

 

Указания: для работы с реестром подключите модуль Registry.

 

Для сохранения параметров колонок сетки в событии OnClose формы введите код:

 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

//вначале опишите переменную для работы с реестром и счетчик цикла

var reg:TRegistry; i:integer;

begin

//создаем объект для работы с реестром 

reg:=TRegistry.Create;

//задаем текущий раздел реестра   

reg.RootKey:=HKEY_LOCAL_MACHINE;

//в цикле проходим по всем колонкам сетки 

for i:=0 to DBGrid1.Columns.Count-1 do

begin

//создаем или открываем в реестре раздел для i-й колонки

reg.Openkey('\Software\MyProgram\DBGrid\Col'+inttostr(i),true);

//записываем в реестр параметры сетки   

reg.WriteString('Field',DBGrid1.Columns.Items[i].FieldName);

reg.WriteInteger('Width',DBGrid1.Columns[i].Width);

reg.WriteString('Caption',DBGrid1.Columns[i].Title.Caption);

//закрываем раздел для i-й колонки

reg.CloseKey;

end;

//удаляем из памяти объект для работы с реестром

reg.Free;  

end;

 

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

 

//вначале опишите переменную для работы с реестром и счетчик цикла

var reg:TRegistry; i:integer;

 

//в код события добавьте команды

 

//создаем объект для работы с реестром

reg:=TRegistry.create;

//задаем текущий раздел реестра

reg.RootKey:=HKEY_LOCAL_MACHINE;

//если в реестре существует указанная ветка

if reg.KeyExists('\Software\MyProgram\DBGrid') then

    begin

    //в цикле проходим по всем колонкам сетки

    for i:=0 to DBGrid1.Columns.Count-1 do

    begin

        //открываем в реестре раздел для i-й колонки

        reg.OpenKey('\Software\MyProgram\DBGrid\Col'+inttostr(i),true);

        //применяем к колонке сетки считываемые параметры

        DBGrid1.Columns[i].FieldName:=reg.ReadString('field');

        DBGrid1.Columns[i].Width:=reg.ReadInteger('Width');

        DBGrid1.Columns[i].Title.Caption:=reg.ReadString('caption');

//закрываем раздел для i-й колонки

reg.CloseKey;

    end;

end;

//удаляем из памяти объект для работы с реестром

reg.Free;

end;

 

Запустите программу измените порядок и ширину колонок в сетке. Перезапустите программу и убедитесь, что параметры восстанавливаются корректно.