Delphi 3 и создание приложений баз данных

         

Понятие столбцов TDBGrid


Компонент TDBGrid используется для показа содержимого записей НД в табличном формате, когда строки соответствуют записям НД, а столбцы -полям записи (рис. 10 1.):

Свойство DataSource компонента TDBGrid содержит имя компонента TDataSource, который ссылается на соответствующий НД (компоненты TTable или TQuery). Изменяя значение свойства DataSource во время выполнения, можно использовать один компонент TDBGrid для показа содержимого различных наборов данных. При продуманном сценарии диалога с пользователем и интерфейса приложения это может существенно минимизировать объем и конструктивную сложность создаваемых приложений.

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

Если редактор столбцов не использовался, берутся поля (компоненты TField), объявленные при помощи редактора полей НД. При этом вид столбцов определяется соответствующими характеристиками компонентов TField, a порядок следования столбцов - порядком их определении

В случае когда для НД компоненты TField не создавались порядок следования полей и их характеристики соответствуют тем что были заданы при определении структуры записи данной ТБД в момент создания таблицы Заметим что умалчиваемыи порядок следования столбцов в TDBGrid можно изменить лишь при помощи редактора полем или редактора столбцов

Пример

В ТБД teachers db находятся сведения о сотрудниках кафедры С данной таблицей в приложении ассоциирован набор данных Table1 Для определения полей в этом НД редактор полей не использовался следовательно по умолчанию для НД Table1 используются все поля объявленные в структуре записи таблицы БД teachers db Пусть порядок следования столбцов в компоненте TDBGrid связанным с НД Table1 взят по умолчанию и совпадает с порядком следования полей в записи таблицы teachers db (рис 10 2 )

Для того чтобы изменить местоположение столбца Doljnost с 3-го на 2-е необходимо

1 Вызвать редактора полей для набора данных Table1

2 Явно добавить все поля в редакторе полеи

3 В инспекторе объектов выбрать поле Doljnost и изменить значение свойства Index с 2 на 1 или перетащить поле мышью на нужное место в окне редактора полей

Чтобы изменить заголовки столбцов в TDBGrid, следует в инспекторе объектов нужным образом изменить значения свойств Display'Label для каждого поля(рис 10 3)



TDBGrid и динамические свойства столбцов


В том случае когда столбцы таблицы (т е поля записи) определены с использованием редактора полей как компоненты типа TField столбцы показываются в сетке TDBGrid в том состоянии которое определяется их текущими свойствами Если то или иное свойство столбца можно менять в процессе выполнения приложения эти изменения немедленно отобразятся в TDBGrid Например в ходе выполнения можно менять ширину столбца (свойство компонента TField Display Width) его видимость (Visible) возможность редактирования значения столбца (ReadOnlv) порядковый номер (Index) заголовок столбца (Display Label)

Пример

Воспользуемся формой из предыдущего примера и добавим в нее компонент CheckBoxl Установим свойство Visible компонента Table lUchStepen (поте Ученая степень"), равным свойству CheckBoxl Checked Тогда отметка CheckBoxl приведет к визуализации столбца 'Ученая степень в таблице TDBGrid (рис 10 4 а), а снятие отметки- к его исчезновению' (рис 1046)

procedure TFormX.CheckBox1Click(Sender: TObject);

begin

Table1UchStepen.Visible := CheckBox1.Checked;



end;

Здесь мы имеем дело с настраиваемым компонентом TDBGnd Многие свойства TDBGnd могут быть переустановлены во время выполнения приложения Это может придать самому приложению значительную гибкостьассический пример - возможность выбора пользователем порядка сортировки записей НД и порядка их расположения в TDBGnd

Пример.

Пусть таблица teachers db ассоциирована с НД Table 1, записи которого показываются в компоненте DBGndl Пусть у таблицы teachers db имеются индексы по полям 'TabNum' (уникальный, установлен в таблице по умолчанию) 'Doljnosf, 'ПО', 'UchStepen,FIO' Разместив в форме компонент TRadioGroup, сделаем выбранной по умолчанию радиокнопку с индексом 0 (соответствующую индексу по полю 'TabNum') и опишем обработчик события выбора одной из радиокнопок

procedure TForm!.RadioGrouplClick(Sender: TObject);

begin

WITH Table1 do begin

CASE RadioGroupl.ItemIndex OF

0 : begin

IndexFieldNames := 'TabNum';

Table1TabNum.Index := 0;

Table1Doljnost.Index := 2;

Table1FIO.Index := 1;

Table1UchStepen.Index := 3;

end;

1 : begin

IndexFieldNames := 'Doljnosf;

Table1Doljnost.Index := 0;

TabielFIO.Index := 1;

Table1UchStepen.Index := 2,Table1TabNum Index := 3;

end;

2 : begin

IndexFieldNames := 'FIO';

Table1FIO.Index := 0;

Table1UchStepen.Index := 1;

Table1Doljnost.Index := 2;

Table1TabNum.Index := 3;

end;

3 : begin

IndexFieldNames := 'UchStepen';

Table1UchStepen.Index := 0;

Table1FIO.Index := 1;

Table1Doljnost.Index := 2;

Table1TabNum.Index := 3;

end;

END; {case}

END; {with}

end;

Тогда при выборе любой из радиокнопок произойдет переключение текущего индекса и порядка следования столбцов в TDBGnd (рис 105, 106)

Заметим, что можно было бы написать обработчик и так:

procedure TForm!.RadioGrouplClick(Sender: TObject) ;

begin

WITH Table1 do begin

CASE RadioGroupl.Itemlndex OF

0 : begin

IndexFieldNames := 'TabNum';

Table1TabNum.Index := 0;

end;

1 : begin

IndexFieldNames := 'Doljnost;

Table1Doljnost.Index := 0;

end;

2 : begin

IndexFieldNames := 'FIO';

Table1FIO.Index := 0;

end;

3 : begin

IndexFieldNames := 'UchStepen';

Table1UchStepen.Index := 0;

end;

END; {case}

END; {with}

end;

Однако в этом случае индексное поле будет первым (левым), а остальные поля будут расположены произвольным образом.



Постоянные и динамические столбцы


Когда свойства столбцов компонента TDBGrid определяются с помощью свойств компонентов TField, созданных в редакторе полей связанного с TDBGrid НД, всякое изменение свойства в TField ведет к изменению соответствующего свойства столбца. Например, изменение свойства Display Label у компонента Table1FIO для рассмотренного выше примера приведет к соответствующему изменению заголовка столбца в TDBGrid.

Связка "Компонент TField - Столбец DBGrid" хороша до тех пор, пока не возникнет необходимость а) не привязывать столбец к определенному полю ТБД; б)установить характеристики столбца в TDBGrid таким образом, чтобы они не изменялись при изменении свойств TField, даже если столбец и отображает некоторое поле из связанного с TDBGrid НД.

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

Заметим, что столбцы TDBGrid, основанные на использовании компонентов TField, называются динамическими столбцами.



Работа с редактором столбцов


Вызвать редактор столбцов можно, проделав следующие действия:

1. Выбрать в форме компонент TDBGrid при помощи мыши;

2. Нажать правую кнопку мыши;

3. В появившемся всплывающем меню выбрать элемент Columns Editor.

В появившемся диалоговом окне Т DBGrid Columns Editor устанавливаются свойства постоянных столбцов. Вначале список столбцов пуст. Для того чтобы добавить столбец, нужно нажать кнопку Add. Тогда будет создан столбец, не связанный ни с каким полем набора данных (рис. 10.7.а)

а) б)

Рис 10.7 а) столбец не связан с конкретным полем набора данных, б) столбец связан с полем Doljnost

Чтобы поставить такому столбцу в соответствие какое-либо поле НД, следует в инспекторе объектов раскрыть список в свойстве Field Name и выбрать нужное поле В этом случае столбец будет назван так же, как поле (рис. 10.7.6).

Когда нужно показывать в TDBGrid столбцы, соответствующие всем или большинству полей набора данных, лучше нажать кнопку AddAllFieldes. Тогда в список полей TDBGrid будут включены столбцы, соответствующие всем полям НД. После этого при помощи кнопки Delete следует удалить определения столбцов, которые не должны показываться в TDBGrid. Используя кнопки Move Up и Move Down, можно изменить порядок следования текущего столбца (рис. 10.8.а, б).

Свойства столбца устанавливаются в инспекторе объектов. Они определяют особенности отображения столбца в TDBGrid.

а) б)

Рис. 10.8. а) до изменения и б) после изменения порядки следования столбцов

Aligment Определяет выравнивание значений в столбце. По умолчанию TField. Aligment.
BultonStyle Определяет тип кнопки, появляющейся в столбце в режиме редактирования: cbsAuto (по умолчанию) - автоматическая установка (показывает кнопку раскрытия выпадающего списка возможных значений, если столбец может принимать лишь одно из значений, определенных связью с иным НД, или списком свойства PickList); cbsEllipse - показывает кнопку (...) в столбце справа; обработчик нажатия кнопки соответствует обработчику события OnEditButtonCUck; cbsNone - никакой кнопки в столбце нет.
Color Определяет цвет фона столбца. По умолчанию TDBGrid.Color.
DropDownRows Если столбцу назначен выпадающий список возможных значений (посредством связи с другим НД или в свойстве PickList}, определяет число строк в нем. По умолчанию равно 7.
FieldName Определяет поле ТБД, ассоциированное с данным постоянным столбцом. Может быть пустым (см. "Пустые постоянные столбцы").
Readonly Определяет возможность редактирования столбца из TDBGrid [True) или невозможность этого {False, по умолчанию).
Width Определяет ширину столбца в пикселах. По умолчанию значение извлекается из TField. DisplayWidth, где, заметим, ширина дается в символах.
Font Определяет тип, размер и цвет шрифта для вывода значений в столбце. По умолчанию TDBGrid.Font
PickList В случае, если для занесения значений в столбец используется раскрывающийся список возможных значений (кроме случая связи с иным НД), определяет этот список

Свойство Title определяет заголовок постоянного столбца:

Подсвойство Назначение
Aligment Определяет выравнивание заголовка. По умолчанию -влево.
Caption Определяет текст заголовка. По умолчанию TField. DisplayLabel или имя поля ТБД.
Color Определяет цвет фона заголовка. По умолчанию TDBGrid.FixedColor.
Font Определяет тип, размер и цвет шрифта. По умолчанию TDBGrid.TitleFont.

Пример. Используя НД таблицы teachers.db из предыдущих примеров, создадим постоянные столбцы в TDBGrid, с которым связан с НД, и установим различные свойства отображения этих столбцов (рис. 10.9)

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



Изменение свойств постоянных столбцов во время выполнения. TDBGridColumns как набор столбцов


Обратиться к конкретному постоянному столбцу компонента TDBGrid через его свойства можно как к TDBGndl .Columns.Itemsp] или как к TDBGrid l .Columns[i], где i принадлежит диапазону [0.. DBGridl.Columns.Count-1].

Свойство property Columns: TDBGridColumns; является набором столбцов TDBGrid. Методы TDBGrid. Columns мы рассмотрим ниже. В данный момент нас интересует возможность обращения к столбцам. Эту возможность обеспечивает массив property Items[Index: Integer]: TColumn; который доступен только во время выполнения программы.

Каждый i-ый столбец массива Items, в свою очередь, имеет свои собственные свойства и методы. Кратко перечислим их:

property Alignment: TAlignment; -

определяет выравнивание;

property ButtonStyle: TColumnButtonStyle; -

определяет тип кнопки, назначенной столбцу (см. выше п.10.3.2); TColumnButtonStyle = (cbsAuto, cbsEllipsis, cbsNone);

property Color: TColor;

- определяет цвет фона;

property DropDownRows: Integer; -

определяет число строк в выпадающем списке возможных значений столбца;

property Field: TField;

- ссылается на компонент TField, связанный со столбцом;

property FieldName: String; -

определяет имя поля, связанного со столбцом;

property Font: TFont; -

определяет шрифт для отображения содержимого столбца, его размер и цвет;

property PickList: TStrings; -

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

property ReadOnly: Boolean;

- разрешает (False) или запрещает (True) редактирование значений в столбце;

property Title: TColumnTitle; -

определяет свойства и методы для работы с заголовком столбца:

property Alignment: TAlignment; -

определяет выравнивание;

property Caption : String; -

содержит текст заголовка столбца;

property Color: TColor; -

определяет цвет фона заголовка столбца;

property Font: TFont; -

определяет шрифт заголовка столбца, его размер и цвет;

function DefaultFont: TFont; -

восстанавливает умалчиваемый шрифт;

function DefaultCaption: String; -

восстанавливает умалчиваемый текст заголовка;

function DefaultColor: TColor; -

восстанавливает умалчиваемый цвет заголовка;

procedure RestoreDefaults; -

восстанавливает все умалчиваемые свойства заголовка столбца;

property Width: Integer; -

определяет ширину столбца в пикселах;

function DefaultWidth: Integer; -

восстанавливает умалчиваемую ширину столбца;

function DefaultReadOnly: Boolean; -

восстанавливает умалчиваемое значение ReadOnly столбца;

function DefaultColor: TColor; -

восстанавливает умалчиваемый цвет столбца;

function DefaultFont: TFont;

- восстанавливает умалчиваемый шрифт столбца;

procedure RestoreDefaults; -

восстанавливает все умалчиваемые свойства столбца.

Пример.

Введем в приложение, рассмотренное выше, возможность динамического изменения свойств постоянных столбцов TDBGrid. Для этого разместим в форме компоненты обеспечивающие диалоги выбора шрифта и цвета - FontDialog! и ColorDialog соответственно, а также экранные кнопки, нажатие которых инициирует изменения свойств постоянных столбцов (рис. 10.10).

Рис 10.10. Форма с кнопками, нажатие которых реализует изменение шрифта, фона у столбца и т заголовка столбца

Опишем следующие обработчики событий нажатия экранных кнопок:

// Обработчик нажатия кнопки "Шрифт столбцов" Вызывает диалог выбора шрифта и устанавливает выбранный шрифт для всех столбцов

procedure TForm1.AssigningColumnsFontButtonClick(Sender: TObject) ;

var i : Integer;

begin

// в диалоге выбора шрифта текущим будет шрифт 0-го столбца

FontDialog1.Font := DBGrid1.Columns.Items [0].Font;

IF FontDialog1.Execute THEN

FOR i := 0 TO DBGrid1.Columns.Count - 1 do

DBGrid1.Columns.Items[i].Font := FontDialog1.Font;

end;

// Обработчик нажатия кнопки "Шрифт заголовков" Вызывает диалог выбора шрифта и устанавливает выбранный шрифт для заголовков всех столбцов

procedure TForml.AssignFontToColumnsCaptionsButtonClick(Sender: TObject) ;

var i : Integer;

begin

// в диалоге выбора шрифта текущим будет шрифт заголовка 0-го столбца

FontDialog1.Font := DBGrid1.Columns.Items[0].Title.Font;

IF FontDialog1.Execute THEN

FOR 1 := 0 TO DBGrid1.Columns.Count - 1 do

DBGrid1.Columns.Items[i].Title.Font := FontDialog1.Font;

end;

// Обработчик нажатия кнопки "Шрифт столбца" Вызывает диалог выбора шрифта и устанавливает выбранный шрифт для текущего столбца, индекс которого определяется как DBGrid1.Selectedlndex

procedure TForm1.AssignFontToSelectedColumnButtonClick(Sender: TObject) ;

begin

// в диалоге выбора шрифта текущим будет шрифт текущего столбца

FontDialog1.Font := DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Font;

IF FontDialog1.Execute THEN

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Font :=FontDialog1.Font;

end;

// Обработчик нажатия кнопки "Фон столбца" Вызывает диалог выбора цвета и устанавливает выбранный цвет для фона текущего столбца, индекс которого определяется как DBGrid1.Selectedlndex

procedure TForm1.AssignColorToSelectedColumnButtonClick(Sender: TObject) ;

begin

// в диалоге выбора шрифта текущим будет шрифт текущего столбца

ColorDialog1. Color := DBGrid1. Columns. Items [DBGrid1. Selectedlndex] .Color;

IF ColorDialog1.Execute THEN

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Color := ColorDialog1.Color;

end;

// Обработчик нажатия кнопки "Фон заголовка столбца" Вызывает диалог выбора цвета и устанавливает выбранный цвет для фона заголовка текущего столбца, индекс которого определяется как DBGrid1.Selectedlndex

procedure TForm1.AssignColorToSelectedColumnsTitleButtonClick ( Sender: TObject) ;

begin

// в диалоге выбора шрифта текущим будет шрифт заголовка текущего столбца

ColorDialog1.Color :=

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Title.Color,

IF ColorDialog1.Execute THEN

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Title.Color := ColorDialog1.Color;

end;

Пример динамического изменения характеристик столбцов показан на рис 10.11.



Другие свойства набора столбцов TDBGridColumns


Кроме рассмотренных выше, свойство TDBGrid. Columns обладает иными полезными свойствами и методами:

property State: TDBGridColumnsState;

где TDBGridColumnsState = (csDefault, csCustomized);

Это свойство дает возможность определить во время выполнения, имеются ли в данном TDBGrid постоянные столбцы Возможные значения:

csDefault -

столбцы TDBGrid формируются на основе свойств полей ТБД;

csCustomized -

в TDBGrid присутствуют постоянные столбцы.

function Add: TColumn:

Этот метод создает и возвращает новый постоянный столбец (объект типа TColumn). Используется для создания нового столбца во время выполнения, поскольку для аналогичных целей во время разработки приложения используется редактор столбцов. Свойства вновь созданного столбца должны устанавливаться, как это указано в предыдущем параграфе.

procedure RebuildColumns;

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

procedure RestoreDefaults;

Возвращает всем постоянным столбцам их свойства, принятые по умолчанию.

От описанного выше метода RebuildColumns метод RestoreDefaults отличается тем, что если в TDBGrid есть постоянные столбцы, не ассоциированные ни с каким полем, эти столбцы не уничтожаются.



Пустые" постоянные столбцы


Постоянный столбец в TDBGrid не обязательно должен быть ассоциирован с каким-либо полем набора данных. В этом случае свойство столбца FiledName остается незаполненным. Такие столбцы называются пустыми. В них можно выводить какую-либо информацию, основываясь на информации из действительно существующих полей набора данных. Например, из поля набора данных, содержащего фамилию, имя и отчество, можно вывести информацию в 3 "пустых" столбца, содержащих соответственно фамилию, имя и отчество в отдельности.

Другим предназначением пустого столбца является вывод информации по требованию. Например, графические поля, если их выводить для каждой записи в отдельном столбце TDBGrid или даже для текущей записи с помощью отдельного компонента TDBImage, требуют существенных временных затрат для вывода. Поэтому поступают так: устанавливают свойство пустого столбца ButtonSty/e в значение cbsEllips и кодируют обработчик события OnEditButtonClick, которое наступает, когда нажата кнопка (...) в конкретной строке пустого столбца. Заметим, что кнопка становится видна только в режиме редактирования столбца. В обработчике события OnEditButtonClick предусматривают вызов формы, показывающей содержимое графического поля текущей записи, или активизацию компонента TDBImage, расположенного на той же форме, что и TDBGrid. Аналогичным образом можно поступать с мемо-полями набора данных.

Используя механизм кнопки (...), можно также выводить форму, показывающую записи дочерних НД. Также можно вызывать формы для расшифровки того или иного значения. Например, при показе рассчитанного значения "на руки" для приложения расчета заработной платы с помощью кнопки можно вызвать форму, в которой расшифровывается, какая сумма начислена данному работнику, какова сумма премий, как производились вычеты, налогообложение и пр.

Для рассмотренного выше примера приложения введем пустой столбец "Столбец без поля", назначим ему кнопку и напишем обработчик, констатирующий, что данный сотрудник работает в конкретной должности (рис. 10.12).

procedure TForm!.DBGrid1EditButtonClick(Sender: TObject);

begin

WITH Table1 do

ShowMessage(FieldByName('FIO').Value + ' - ' + FieldByName('Doljnosf).Value) ;

end;



Формирование списка возможных значений столбца


Если значения постоянного столбца должны выбираться из некоторого фиксированного множества и Вы хотите получать список значений при редактировании столбца непосредственно в TDBGrid, этот список должен содержаться в свойстве PickList данного постоянного столбца.

При этом возможны 2 варианта - список возможных значений столбца является фиксированным и переменным.

Вариант 1. Список возможных значений столбца является фиксированным, т.е. не изменяется во времени. Тогда достаточно на этапе конструирования программы заполнить список свойства PickList (этот список имеет тип TStrings) постоянного столбца. В свойство ButtonSty/e необходимо установить значение cbsAuto. Тогда Delphi, обнаружив, что список PickList заполнен, автоматически будет помещать в столбце при редактировании его ячейки кнопку типа ComboBox (стрелка вниз).

Например, пусть для рассматриваемого примера сотрудники кафедры могут обладать учеными степенями доктора физико-математических наук (д.ф.-м.н.), доктора технических наук (д.т.н.), кандидата физико-математических наук (к.ф.-м.н.) и кандидата технических наук (к.т.н.). Предположим, что на работу не принимаются обладатели иных ученых степеней (например, доктора и кандидаты химических или социологических наук). Таким образом, список возможных значений столбца "Уч. степень" состоит из 4 значений (рис. 10.13).

При работе приложения, если мы корректируем ячейку столбца "Уч. степени", на экране появляется кнопка типа "Стрелка вниз" (рис.10.14).

Нажатие данной кнопки приведет к появлению выпадающего списка с фиксированными значениями (рис. 10.15).

При этом выбор значения в списке приведет к копированию его в текущую ячейку столбца, и, если данный столбец связан с полем ТБД, к последующему запоминанию в качестве значения поля ТБД в текущей записи.

Заметим, что наличие выпадающего списка не препятствует пользователю занести в столбец и иную информацию (рис. 10.16).

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

таком случае источником значений служит другая, справочная ТБД В процессе работы справочная ТБД может меняться, записи в ней могут корректироваться, добавляться или удаляться Все внесенные изменения должны отображаться в списке PickList для рассматриваемого столбца TDBGnd

Пусть для рассматриваемого примера список возможных должностей находится в ТБД "UCHSTEP DB" (в поле UchStepen) Тогда проблема решается, если при всякой активизации формы, на которой расположен TDBGnd с постоянным столбцом, произвести следующие действия

1 Очистить список PickList для постоянного столбца "Уч степени",

2 Поместить все значения из поля UchStepen таблицы БД "UCHSTEP DB" в список PickList для постоянного столбца "Уч степени"

procedure TForm1.FormActivate(Sender: TObject);

begin

DBGrid1.Columns.Items[3].PickList.Clear;

WITH Table2 do begin

First;

WHILE not EOF do begin

DBGrid1.Columns.Items[3].PickList.Add (FieldByName('UchStepen').Value) ;

Next;

END; {while}

END; {with}

end;

Результат работы показан на рис 1017

ЗАМЕЧАНИЕ 1. Поле UchStepen в ТБД "UCHSTEP DB" должно быть уникальным, иначе в списке PickList появятся дублирующие друг друга значения Если поле, по которому строится PickList, неуникально, нужно программно предусмотреть дополнительный анализ дублирования в списке PickList

ЗАМЕЧАНИЕ

2. Аналогичного или сходного результата можно добиться путем использования поля, возвращающего значение (lookup-поля) Более подробно см раздел "Использование компонента TField"

ЗАМЕЧАНИЕ

3. Если таблица-справочник содержит больше 10-15 записей, в список PickList ее заносить нерационально, поскольку пользователю весьма трудно будет искать нужное значение К другим недостаткам описываемого подхода можно отнести то, что список PickList не позволяет редактировать таблицу-источник (представим, что в процессе работы с кадровым составом кафедры нам понадобилось внести в справочник ученых степеней степень "кандидата философских наук")

Два этих обстоятельства делают работу с выпадающим списком не очень удобной Поэтому, на взгляд автора, более рационально не формировать список PickList вручную или программно, а установить в свойство ButtonStyle постоянного поля значение cbsElhps и написать в обработчике нажатия кнопки (. .) OmtButtonChck вызов модальной формы, содержащей НД справочника После этого следует определить код занесения выбранного в справочнике значения в текущую ячейку постоянного столбца. Пример Для рассмотренной выше формы

1 Добавим в приложение форму Form2 (рис. 10.18), содержащую компонент TDBGnd, в котором показываются значения из ТБД "UCHSTEP DB" с возможностью их корректировки, а также 2 экранные кнопки - "Выбрать" (со свойством Moda/Result = mrOk) и "Отменить" (со свойством ModalResult = mrCancel);

2 Установим у постоянного столбца "Уч степень" в свойство ButtonStyle значение cbsElhps,

3. Напишем такой обработчик нажатия кнопки:

procedure TForm1.DBGridlEditButtonClick(Sender: TObject);

begin

// модальный вызов справочной ТБД "Ученые степени"

Form2.ShowModal;

// Если выбрана клавиша с модальным результатом mrOk // (т.е. клавиша "Выбрать" в Form2)

IF Form2.ModalResult = mrOK THEN

begin

// если НД сотрудников кафедры не находится в режиме dsEdit или dslnsert, переводим НД в режим dsEdit,

// поскольку иначе мы не сможем изменить значения поля UchStepen

IF Tablel.State = dsBrowse THEN TableI.Edit;

// производим присваивание значения поля

Formi.Tablel.FieldByName('UchStepen').Value := Form2.Tablel.FieldByName('UchStepen').Value;

end;

end;

Результат работы показан на рис. 10.19.

Заметим, что при выходе из обработчика мы не выполняем метод Tablel. Post, т.е. оставляем НД сотрудников кафедры в одном из режимов корректировки с тем, чтобы пользователь затем смог сам либо отменить внесение изменений в TDBGrid (клавишей Esc) или подтвердить внесение изменений (перейдя на другую запись в TDBGrid).

В вызываемой форме (Form2) можно добавлять, изменять и удалять записи, прежде чем осуществить выбор.

Заметим также, что в Form2 нужно предусмотреть ситуацию, когда нажата кнопка "Выбрать" или "Отменить", а НД, связанный с ТБД "UCHSTEP.DB", остался в одном из режимов редактирования. Например, в этом случае можно не производить выбора по нажатию кнопки "Выбрать" в обработчике события OnEditButtonClick формы Formi и принудительно переводить НД Form2.Table2 в режим dsBrowse с потерей последних неподтвержденных изменений (выполняя метод Cancel):

procedure TFormI.DBGridlEditButtonClick(Sender: TObject);

begin

Form2.ShowModal;

IF Form2.Tablel.State о dsBrowse THEN

begin

Form2.Tablel.Cancel ;

ShowMessage('Изменения в справочнике не запомнены');

Exit;

end;

IF Form2.ModalResult = mrOK THEN

begin

IF Tablel.State = dsBrowse THEN TableI.Edit;

Form1.Tablel.FieldByName('UchStepen').Value :=Form2.Tablel.FieldByName('UchStepen').Value;

end;

end;



Управление видом и поведением TDBGrid


Свойство Options управляет видом и поведением TDBGrid во время выполнения. Это свойство состоит из группы логических опций, поэтому в инспекторе объектов оно помечено знаком (+). Чтобы получить доступ ко всем опциям, следует щелкнуть мышью на знаке (+). Тогда он преобразуется в знак (-) и будет раскрыт следующий список:

dgEditing True

(по умолчанию) разрешает редактирование, вставку и удаление записей непосредственно из TDBGrid. False запрещает указанные действия.
DgA IwaysShowEditor True выбор поля означает его перевод в состояние редактирования. False (по умолчанию).- поле при его выборе не переводится автоматически в режим редактирования.
dgTitles True (по умолчанию), показывает заголовки столбцов в TDBGrid.

False:

заголовки столбцов не показываются.
Dglndicator True

(по умолчанию)- показывается индикатор текущей записи как самый левый серый столбец. Указатель в режиме dsBrowse - стрелка влево, в режиме dsEdit - символ I-Beam, в режиме dslnsert -звездочка.False: указатель текущей записи не показывается.
DgColumnsResize True (по умолчанию).- возможно изменение ширины столбцов путем сдвига границы столбца в области заголовка. False: изменение ширины столбцов не допускается.
DgColLines True (по умолчанию); показываются вертикальные линии-разделители между столбцами. Falsе: вертикальные разделители столбцов не показываются.
DgRowLines True (по умолчанию).- показываются горизонтальные линии-разделители строк.

False:

разделители строк не показываются.
dgTabs True (по умолчанию): клавиша TAB используется для передвижения между столбцами текущей записи. False: клавиша TAB используется для выхода из TDBGrid.
DgRowSelect True; инверсная полоса, показывающая текущую строку TDBGrid, отмечает всю строку.False (по умолчанию).' инверсная полоса отмечает только ячейку текущего столбца.
DgAIwaysShowSelection True." Инверсная полоса для отметки текущей строки показывается в TDBGrid независимо от того, обладает он фокусом управления, или нет. False (по умолчанию); инверсная полоса видна только в то время, когда TDBGrid обладает фокусом упр-ния.
DgConfirmDelete True (по умолчанию).' при удалении записи из TDBGrid (комбинация клавиш Ctrl+Del) запрашивается подтверждение удаления.

False:

подтверждение удаления не запрашивается, запись удаляется немедленно.

Установка той или иной опции производится путем операции включения ее в множество Options или исключения из него:

// Включение-выключение показа заголовка столбцов TDBGrid

IF CheckBoxl.Checked THEN DBGrid1.Options := DBGridI.Options + [dgTitles]

ELSE DBGrid1.Options := DBGrid1.Options - [dgTitles];

// Включение-выключение показа вертикальных и горизонтальных разделительных линий DBGrid

IF CheckBox2.Checked THEN

DBGrid1.Options := DBGrid1.Options + [dgColLines, dgRowLines]

ELSE DBGrid1.Options := DBGrid1.Options - [dgColLines, dgRowLines];



Добавление записей


НД переводится в режим добавления dslnsert, если:

• пользователь нажал на клавиатуре клавишу Insert; в этом случае в TDBGrid вставляется пустая запись между текущей записью и предшествующей ей;

• пользователь нажал на клавиатуре кнопку "стрелка вниз", находясь на последней записи НД; в этом случае в конец НД добавляется новая запись.

После этого пользователь тем или иным способом должен заполнить поля новой записи. Запоминание добавленной записи в ТБД (с автоматической выдачей метода Post) производится при переходе курсора НД на другую запись в компоненте TDBGrid. Отмена добавления новой записи (с автоматической выдачей метода Саncel) производится, если пользователь нажмет на клавиатуре клавишу Esc.



Корректировка


НД переводится в режим добавления dsEdit, если пользователь, находясь в ячейке TDBGrid, осуществил ввод любого символа.

Если ввод символа не осуществлен, то НД остается в режиме dsBrowse. При использовании в постоянном столбце TDBGrid списка возможных значений

НД остается в режиме dsBrowse и после показа в корректируемой ячейке кнопки (...) или кнопки раскрытия комбинированного списка, и в момент перемещения по списку, заданному свойством PickList или содержащемуся в иной форме. НД переходит в режим dsEdit только после ввода значения, выбранного из списка, в ячейку TDBGrid.



Возникновение исключений при добавлении и корректировке записей в TDBGrid


Возникновение исключений при добавлении или корректировки записей в компоненте TDBGrid чаще всего связано с нарушением уникальности первичного индекса или незаполнения значением поля, для которого установлено требование обязательного ввода значения. В этом случае возбуждается исключение класса EDBEngineError с сообщением 'Key Violation ' или подобным. Возникновение такого исключения не приводит к фатальным последствиям для приложения, но при этом происходит отказ от запоминания записи в ТБД. Запись остается в том режиме, в котором она была на момент попытки автоматической выдачи метода Post - в режимах dslnsert или dsEnter. Пользователю остается либо исправить значение в ключевом поле (или ввести значение в поле, помеченное как обязательное к заполнению, и т.д.), либо отказаться от запоминания записи.



Редактирование наборов данных непосредственно из TDBGrid


Записи НД, отображаемые в компоненте TDBGrid, можно добавлять, изменять или удалять, если одновременно выполняются следующие условия:

• свойство CanModify набора данных установлено в True;

• свойство Readonly компонента TDBGrid установлено в False.

Изменение записей внутри TDBGrid удобно в том случае, если НД состоит из небольшого числа полей или, если число полей в нем велико, требуется вводить или корректировать лишь некоторые из них. Преимущества такого подхода состоят и в том, что в этом случае нет необходимости вставки в приложение новой формы для изменения или добавления записи. Удобству работа с записями непосредственно из TDBGrid служит и наличие таких механизмов, как формирование выпадающего списка возможных значений в столбце -фиксированного или вновь формируемого из иного НД, а также наличие кнопки (...), по нажатию которой в обработчике события OnEditButtonClick можно, вообще говоря, делать что угодно, в том числе и вызывать форму для ввода или корректировки дополнительных полей.



Определение текущего столбца во время выполнения программы и проверка правильности индекса


Компонент TDBGrid обладает рядом методов и свойств, которые позволяют:

а) обращаться к полю TField, ассоциированному с текущим столбцом TDBGrid;

б) проверять правильность обращения к тому или иному столбцу TDBGrid.

Свойство property SelectedField: TField; позволяет обратиться к полю, ассоциированному с текущим столбцом в TDBGrid. Поскольку свойство имеет тип TField, можно использовать все свойства и методы компонента TField.

Пример.

Пусть произведен двойной щелчок мышью по некоторой ячейке TDBGrid. Если текущее поле - Doljnost, его значение записывается в компонентEdit1 с помощью такого обработчика события OnDblClick:

procedure TForm!.DBGrid1DbiClick(Sender: TObject);

begin

IF DBGrid1.SelectedField.FieldName = 'Doljnost' THEN Editl.Text := DBGrid1.SelectedField.Text ELSE Editl.Text :=";

end;

Свойство property Selectedlndex: Integer; возвращает номер поля, ассоциированного с текущим столбцом в TDBGrid. Нумерация полей идет от 0. Если возвращено значение -1, никакое поле с данным столбцом не ассоциировано.

Пример,

приведенный выше для свойства SelectedField с использованием Selectedlndex, можно переписать так:

procedure TForm1.DBGrid1DbiClick(Sender: TObject);

begin

IF DBGrid1.Fields[DBGrid1.Selectedlndex].FieldName = 'Doljnost' THEN

Editl.Text := DBGrid1.SelectedField.Text ELSE Editl.Text := ";

end;

Метод function ValidFieldIndex(FieldIndex: Integer): Boolean; возвращает True, если значение Fieldlndex является правильным индексом столбца TDBGrid, и False - в противном случае. Индекс признается правильным, если в TDBGrid показывается информация из поля с индексом Fieldlndex и обращение TDBGrid.Fields[FieldIndex] не вызовет ошибки. Заметим, что в НД, ассоциированном с TDBGrid, поле с индексом Fieldlndex может существовать, а в самом компоненте TDBGrid - нет. В этом случае выдается False. Такая ситуация возможна, если для формирования столбцов TDBGrid использовался редактор столбцов.

Пример.

var IndexOfSomeField : Integer;

IF DBGrid1.ValidFieldIndex(IndexOfSomeField) THEN

Labell.Caption := DBGrid1.Fields[IndexOfSomeField].Text ELSE Labell.Caption := 'Неверный индекс поля';



Изменение порядка следования столбцов во время разработки приложения


Порядок следования столбцов в TDBGrid на этапе разработки можно изменить так:

• при наличии постоянных столбцов в TDBGrid - путем изменения порядка их следования редакторе столбцов или путем перетаскивания столбцов в TDBGrid (что приводит к автоматическому изменению порядка следования столбцов и в редакторе столбцов );

при формировании колонок TDBGrid на основании списка компонентов TField - путем изменения порядка следования компонентов TField в редакторе полей или путем перетаскивания столбцов в TDBGrid;

• при формировании столбцов TDBGrid, исходя из физической структуры ТБД (что имеет место, если не применялись редактор полей илиредактор столбцов) - изменение порядка следования невозможно



Изменение порядка следования столбцов во время выполнения приложения


Изменение порядка следования столбцов во время выполнения может производиться путем перетаскивания мышью заголовка столбца на новую позицию. Это возможно только если в свойство DragMode установлено значение dmManual; если свойство имеет значение dmAutomatic, перетаскивание столбцов запрещено После перетаскивания возникает событие OnColumnMoved.

При наличии постоянных столбцов возвращение к состоянию столбцов по умолчанию

DBGndl. Columns . State

csDefault;

приведет, помимо прочего, к восстановлению исходного их порядка следования в TDBGrid.

Если в TDBGrid не используются постоянные столбцы, а источником для формирования столбцов служат компоненты TField, добавленные посредством редактора полей, изменять местоположение столбца можно:

а) путем перетаскивания столбца (что ведет к автоматическому изменению свойства TField Index};

б) программно изменяя значение свойства TFiexd Index

Если для формирования состава столбцов в TDBGrid использована физическая структура ТБД, изменить местоположение столбцов в TDBGrid нельзя.



Управление отображением данных в TDBGrid


Ниже рассмотрены средства для выделения (цветом, шрифтом и т.д.) какого-либо столбца в TDBGrid.

На характеристики представления значений в ячейках TDBGrid также могут оказывать влияние такие свойства компонентов TField, как DisplayFormat и EditFormat, которые позволяют задавать формат поля соответственно при его показе и при редактировании, причем эти свойства актуальны для всех компонентов, визуализирующих значение поля (полей), а не только для столбцов TDBGrid.

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

То, как осуществляется прорисовка данных в TDBGrid - стандартным способом или по особому сценарию - определяется свойством property DefaultDrawing: Boolean;

В случае, если имеет место управление прорисовкой со стороны самого приложения, алгоритм прорисовки должен содержаться в обработчиках событий OnDrawColumnCell или OnDrawDataCell. Заметим, что обработчик события OnDrawDataCell введен для совместимости с ранними версиями Delphi.

При автоматической прорисовке (DefaultDrawing = True) метод Paint использует цвет и шрифт свойства Canvas для прорисовки ячейки. Событие

property OnDrawColumnCell: TDrawColumnCellEvent;

TDrawColumnCellEvent = procedure (Sender: TObject; const Rect:

TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState) of object;

где параметры имеют следующий смысл:

Rect - определяет область ячейки, в которой, собственно, происходит прорисовка,

Тип

TRect = record

CASE Integer of

0: (Left, Top, Right, Bottom: Integer);

1: (TopLeft, BottomRight: TPoint);

END;

END;

определяет прямоугольник, в котором прорисовывается ячейка TDBGrid, координаты прямоугольника указываются или как 4 целых числа, содержащие границы прямоугольника в пиксельном исчислении, или как 2 значения типа TPoint, определяющих левый верхний и правый нижний углы прямоугольника:

TPoint = record

X: Longint;

Y: Longint;

end;

DataCol -

определяет порядковый номер текущего столбца, начиная с 0-го;

• Column. TColumn - определяет текущий столбец.

• State TGridDrawState - определяет состояние ячейки.

Тип TGridDrawState = set of (gdSelected, gdFocused, gdFixed) ;

определяет множество возможных состояний ячейки TDBGrid.

Если ячейка находится в состоянии gdFocused (т.е. является текущей), в обработчике события OnDrawColumnCell происходит прорисовка инверсной полосы.

Для вывода ячеек стандартным образом используется метод

procedure DefaultDrawColumnCell(const Rect: TRect; DataCol: Integer; Column:

TColumn; State: TGridDrawState);

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

Пример.

Пусть необходимо выводить белым шрифтом на красном фоне те строки НД, у которых поле'Doljnost' содержит значение 'профессор'(рис. 10.20).

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

WITH DBGrid!.Canvas do begin

// поле "Должность" содержит значение "профессор"?

IF (Table1Doljnost.AsString = 'профессор') AND not (gdFocused in State) THEN

// - да. Выводить все ячейки строки бельм шрифтом на красном фоне

begin

Brush.Color := cIRed;

Font.Color := clWhite;

FillRect(Rect) ;

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

end

ELSE

// - нет, текущее значение "Должности" - не "профессор". Выводим все ячейки строки стандартным образом

DBGrid1.DsfaultDrahColumnCellfRect, DataOol, Column, State);

END; {with}

end;

В отличие от предыдущего примера, в следующем выделяются не строки, а ячейки:

procedure TForm!.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

WITH DBGrid!.Canvas do begin

// текущий столбец - "Должность"?

IF (Column.Field.FieldName = 'Doljnost') AND not(gdFocused in State) THEN

// Текущая ячейка содержит значение "профессор"?

IF Column.Field.Text = 'профессор' THEN

// - да. Тогда вывести ячейку белым шрифтом на красном фоне

begin

Brush.Color := cIRed;

Font.Color := clWhite;

FillRect(Rect) ;

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

Exit;

end;

// сюда попадаем, только если текущий столбец - не "Должность" или "Должность", но значение ячейки столбца - не "профессор"

DBGrid!.DefaultDrawColumnCell(Rect, DataCol, Column, State);

END; {with}

end;

ЗАМЕЧАНИЕ.

В показанном выше примере значение поля "Должность" имеет строковый тип. Строковые значения в ячейках TDBGrid принято выводить выровненными влево. Поэтому в процедуре

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

используется горизонтальная координата Rect.Left.

В случае, когда показываемое в ячейке значение должно быть выровнено вправо (как часто имеет место для цифровых значений), необходимо заменить координату Rect.Left на правую координату ячейки, уменьшенную на ширину выводимого в ячейке текста. Ширина текста возвращается методом TextWidth компонента TDBGrid. Canvas:

function (const Text: string): Integer;

В этом случае содержимое ячейки выводится следующим образом:

TextOutfRect.Right - 3 - TextWidth(Column.Field.Text), Rect.Top,Column.Field.Text) ;

Заметим, что дополнительный сдвиг на 3 пиксела нужен, чтобы оставить справа от текста небольшой пробел.

Заметим также, что сдвиг на 3 пиксела хорош для шрифта MS Sans Serif размером 12 пунктов, который использовался в данном примере; для других шрифтов и размеров эта величина нуждается в изменении. В общем случае, содержание алгоритма, реализующего выравнивание текста, состоит в определении длины и высоты ячейки TDBGrid, а также в определении длины и высоты выводимого в ячейку текста и в их последующем сопоставлении.



Перемещение между ячейками TDBGrid


Для перехода от текущего столбца к другому можно воспользоваться клавишей TAB - для перехода к столбцу справа от текущего;

• комбинацией клавиш SHIFT+TAB - для перехода к столбцу слева от текущего;

мышью - независимо от того, к какому столбцу нужно перейти.

При смене столбца возникают 2 события в такой очередности:

• OnColExit - наступает в момент, когда мы покидаем текущий столбец;

• OnColEnter - наступает в момент, когда новый столбец становится текущим.

В следующем примере на экран выводятся имена полей, ассоциированных с покидаемым и новым столбцами:

procedure TForm1.DBGrid1ColEnter(Sender: TObject);

begin

ShowMessage('Мы вошли в ' + DBGrid1.SelectedField.FieldName );

end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);

begin

ShowMessage ('Мы покинули ' + DBGrid1.SelectedField.FieldName );

end;



Действия с мышью и клавиатурой в момент, когда TDBGrid обладает фокусом управления


Для компонента TDBGrid предусмотрены следующие события:

OnDblChck -

наступает после двойного щелчка мышью.

Пример.

Пусть требуется изменить на желтый цвет фон столбца, на котором произведен двойной щелчок мышью:

procedure TFormI.DBGrid1DblClick(Sender: TObject);

begin

DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Color := clYellow;

end;

• OnKeyDown - наступает, когда пользователь нажимает любую клавишу или комбинацию клавиш на клавиатуре (но еще не отпустил).

• OnKey Up - наступает, когда пользователь отпускает любую клавишу или комбинацию клавиш.

• OnKeyPress - возникает, когда пользователь нажимает отдельную клавишу (цифрового или алфавитного символа) на клавиатуре, а также комбинацию клавиш, что приводит к формированию кода цифрового или алфавитного символа (например, клавишу 'и' или SHIFT + "и, что в результате дает 'U').

Пример

вызова различных форм в зависимости от нажатия той или иной клавиши:

procedure TFormI.DBGrid1KeyPress(Sender: TObject; var Key: Char);

begin

ShowMessage(key);

CASE Key OF

'u' : Form2.ShowModal;

's' :

Form3.ShowModal ;

END;



Работа с компонентом TDBCtrlGrid


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

• большим количеством полей, в этом случае приходится или помещать все поля в TDBGrid, что обычно приводит к необходимости их горизонтальной прокрутки, или помещать в TDBGrid лишь часть полей, а прочие либо выводить в отдельной форме, активизирующейся по нажатию экранной кнопки, или располагать ниже TDBGrid как компоненты TDBText, TDBEdit, TDBRadioGroup и т.д.;

• длинными заголовками столбцов; в этом случае приходится их сокращать, что ведет к потере смысла и удобочитаемости;

• невозможностью отображать в TDBGrid значения полей в виде, предоставляемом компонентом TDBCheckBox, и т.п.

Этот список при желании можно продолжить. Для преодоления подобных трудностей создан компонент типа TDBCtrlGrid, введенный в версию Delphi 3.0. Обладая основной функциональностью обычного компонента TDBGrid, он позволяет отображать информацию из одной записи НД в прямоугольной панели и размещать эту информацию на ней произвольным образом (рис. 10.22.):

Для работы с компонентом TDBCtrlGrid необходимо поместить его в форму, связать с компонентом TDataSource, который, в свою очередь, связать с каким-либо набором данных (TTable или TQuery) и затем разместить необходимые компоненты для работы с полями базы данных (TDBText, TDBEdit, TDBCheckBox) в верхней строке TDBCtrlGrid (рис. 10.23.):

Во время выполнения приложения расположение компонентов в верхней строке TDBCtrlGridvi их состав будет реплицирован на все оставшиеся строки, как это видно из рис. 10.22.

Порядок редактирования, добавления и удаления записей непосредственно из TDBCtrlGrid аналогичен порядку редактирования, добавления и удаления записей из TDBGrid. Для вставки новой записи необходимо нажать на клавиатуре клавишу Insert или попытаться перейти с последней записи в НД вниз на одну строку (рис. 10.24).

Для изменения записи достаточно ввести новое значение в какое-либо поле. Для удаления записи необходимо нажать комбинацию клавиш Ctrl+Delete. При этом на возможности редактирования, добавления и удаления записей в TDBCtrlGrid влияет ряд свойств как других компонентов (Table. Readonly, TField.ReadOnly, TDBEdit.Readonly), размещенных на панелях TDBCtrlGrid, так и самого компонента TDBCtrlGrid (AllowDelete, Allowlnsert).

Произведем выборочный обзор свойств, методов и событий TDBCtrlGrid:

Свойства

Разрешение корректировки

property AllowDelete: Boolean; -

определяет возможность удаления записей из TDBCtrlGrid {True, по умолчанию) или невозможность удаления (False);

property Allowlnsert: Boolean; -

определяет возможность вставки записей в TDBCtrlGrid (True, по умолчанию) или невозможность вставки (False);

Параметры показа:

property PanelHeight: Integer; -

высота в пикселах;

property PanelWidth: Integer; -

ширина в пикселах;

property Orientation: DBCtrlGridOrientation; -

определяет ориентацию TDBCtrlGrid- вертикальную (по умолчанию) или горизонтальную; DBCtrlGridOrientation = (go Vertical, goHorizontal);

property Pane/Border: DBCtrlGridBorder; -

определяет тип края панели -выступающий (по умолчанию) или отсутствующий; DBCtrlGridBorder = (gbNone, gbRaised); Число панелей, текущая панель, число колонок:

property Pane/Count: Integer; -

число панелей, видимых в TDBCtrlGrid.

property Panellndex: Integer;

- показывает, какая панель (в диапазоне 0.-PanelCount - 1) отображает текущую запись.

property RowCount: Integer; -

содержит число панелей в TDBCtrlGrid, начиная с 1. Изменение этого свойства ведет, к увеличению/уменьшению числа панелей в TDBCtrlGrid без изменения их высоты (PanelHeight). Отличие этого свойства от PanelCount состоит в том, что число RowCount можно изменять, например:

WITH DBCtrlGridl do RowCount := StrToInt(Edit1.Text) ;

property ColCount: Integer; -

определяет число колонок в TDBCtrlGrid. По умолчанию равно 1.

Метод procedure DoKey(Key: DBCtrlGridKey);

Выполняет определенное действие над TDBCtrlGrid. Действие определяется параметром А'еу. Некоторые из возможных значений:

gkNull

Действия нет

gkEditMode

Переводит компонент в режим редактирования

gkLeft Moves

Перемещает компонент на 1 колонку влево, при необходимости делает прокрутку окна компонента

gkRight

Перемещает на 1 колонку вправо

gkUp

Перемещает на 1 запись вверх

gkDown

Перемещает на 1 запись вниз

gkScrolIUp

Делает запись в предыдущей строке текущей без изменения ее местоположения

gkScrollDown

Делает запись в следующей строке текущей без изменения ее местоположения

gkPageUp

Перемещает к предыдущей странице TDBCtrlGrid

gkPageDown

Перемещает к следующей странице TDBCtrlGrid

gkHome

Перемещает на первую запись

gkEnd Moves

Перемещает на последнюю запись

Пример. Разместим в форме 4 кнопки для перемещения к первой, последней, следующей и предыдущей записи в TDBCtrlGrid (рис. 10.25).

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

// нажата клавиша "1-я запись"

procedure TForm1. FirstButtonCiick (Sender : T0bj]ect);

begin

DBCtrlGridl.DoKey(gkHome) ;

end;

// нажата клавиша "Последняя запись"

procedure TForm!.LastButtonClick(Sender: TObject) ;

begin

DBCtrlGridl.DoKey(gkEnd) ;

end;

// нажата клавиша "Запись вверх"

procedure TForm!.UpButtonClick(Sender: TObject) ;

begin

DBCtrlGridl.DoKey(gkScrolIUp) ;

end;

// нажата клавиша "Запись вниз"

procedure TForm! . DownButtonClick (Sender : TObjiect);

begin

DBCtrlGridl.DoKey(gkDown) ;

end;

Тогда нажатие соответствующей экранной клавиши приведет к соответствующим перемещениям компонента TDBCtrlGrid.

Можно также поставить в соответствие отдельным клавишам на клавиатуре определенные действия с TDBCtrlGrid. Например, пусть мы хотим, чтобы при нажатии клавиш происходили следующие действия:

u (up) переход на одну запись вверх

d (down) переход на одну запись вниз

f (first) переход на первую запись

I (list) переход на последнюю запись

Тогда в обработчике события OnKeyDown для TDBCtrlGrid следует записать такой код:

procedure TFormI.DBCtrlGridlKeyDown (Sender: TObject; var Key: Word; Shift: TShiftState) ;

var S : TDBCtrlGridKey;

begin

CASE Key OF

68 : S := gkScrollDown; // нажата "d"

70 : S := gkHome; // нажата "f"

76 : S := gkEnd; // нажата "1"

85 : S := gkDown; // нажата "и"

END; {case}

DBCtrlGridl.DoKey(S) ;

end;

События

Для TDBCtrlGrid определены следующие события, аналогичные одноименным событиям TDBGrid: OnClick, OnDblClick, OnDragDrop, OnDragOver, OnEndDrag, OnEnter, OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnStartDrag.

Дополнительно введены события property OnPaintPanel: TPaintPanelEvent;

TPaintPanelEvent = procedure(DBCtrlGrid: TDBCtrlGrid; Index: Integer) of object;

Наступает для каждой панели TDBCtrlGrid перед ее показом. Обработчик этого события может управлять рисованием панели. Параметр TDBCtrlGrid показывает, какой именно компонент TDBCtrlGrid отображается в данный момент; параметр Index' определяет индекс отображаемой панели. /

property OnMouseDown: TMouseEvent;

наступает, когда пользователь нажимает левую кнопку мыши, находясь при этом на TBCtrlGrid.

property OnMouseUp: TMouseEvent;

наступает, когда пользователь отпускает нажатую ранее кнопку мыши, находясь при этом на TBCtrlGrid.

Работа с абзацем


Текущим в тексте форматированного комментария считается абзац, на котором находится курсор.

Свойство property Paragraph: TParaAttributes; определяет характеристики параграфа. Рассмотрим свойства компонента TParaAttributes:

• property Alignment: TAlignment;

определяет выравнивание параграфа. Значения:

taLeftJustify - влево;

laCenier -

по центру;

taRightJustify -

вправо.

• property Firstlndent: Longint;

определяет в пикселах абзацный отступ (первой строки параграфа) относительно левого края.

• property Leftlndent: Longint;

определяет в пикселах отступ всех строк параграфа от левого края.

• property Numbering: TNumberingStyle;

определяет отметку параграфов. Значения:

nsNone -

отметка не производится.

nsBullet -

отметка производится символом '•'.

• property Rightlndent: Longint;

указывает в пикселах отступ от правого края.

Пример.

Определим кнопку, реализующую выравнивание текущего абзаца и напишем обработчик события нажатия этой кнопки:

procedure TFormI.SpeedButton3Click(Sender: TObject) ;

begin

DBRichEdit1.Paragraph.Alignment := taCenter;

end;



Компонент TDBText


Компонент TDBText применяется для показа значения текстового поля текущей записи НД. Изменять значение, показываемое при помощи TDBText, нельзя. Компонент является аналогом компонента TLabel, за исключением того, что значение для отображения берется из текущей записи НД.

Для использования компонента TDBText нужно:

• указать в свойстве property DataSource: TDataSource; имя соответствующего компонента TDataSource, связанного с НД;

• указать в параметре property DataField: String; имя поля. При заполненном свойстве DataSource в инспекторе объектов, когда мы устанавливаем значение свойства DataField, появляется список:

- имен полей, определенных в редакторе полей;

- имен всех полей НД, на который ссылается соответствующий компонент TDataSource, ест редактор полей не применялся.

Пример.

Пусть имеем ТБД "TOV.DB", в состав записи которой входят поля GrNum (номер группы товаров) и Tovar (наименование товара). Требуется в компоненте TDBGrid показывать только наименования товаров, а внизу, под TDBGrid - номер группы для текущей записи в НД.

Расположим в форме компоненты DataSourcel, Table1 (указывающий на ТБД "TOV.DB") и DBGridI, связанные между собой стандартным образом. Расположим также в форме компоненты Label 1 (свойство Caption = 'Номер группы текущей записи - ') и DBTextl (рис. 11.1).

Назначим в инспекторе объектов свойства DBTexlt.DalaSource = DataSourcel и DBTextl. DataField = GrNum. Тогда во время выполнения приложения DBTextl будет показывать содержимое поля GrNum текущей записи.



Компонент TDBEdit


Компонент TDBEdit позволяет редактировать значение строкового поля текущей записи НД. Он повторяет функциональность компонента TEdit (позволяющего корректировать значение переменной), но источником данных и их приемником в этом случае служит поле НД. Поэтому для TDBEdit необходимо указывать свойства

property DataSource: TDataSource; -

имя компонента DataSource, определяющего НД; *

property DataField: string; -

имя редактируемого поля;

property ReadOnly: Boolean; -

если содержит True, значение поля доступно только для чтения, если False - значение поля можно изменять.

Пример.

Пусть необходимо корректировать, изменять, удалять текущую запись в НД, связанном с ТБД "TOV.DB" (товары), в состав записи которой входят поля GrNum (номер группы товаров) и Tovar (наименование товара).

Поместим в форму компоненты Table1 (связанный с ТБД "TOV.DB") и DataSource 1, указывающий на Table I. Пусть группа кнопок реализует перевод НД в режимы dslnsert, dsEdit, а также обращение к методам Delete, Post, Cancel. Поместим в форму компоненты DBEdit1 (указывает на поле GrNum) и DBEdit2 (указывает на поле GrNazv). При добавлении новой записи или при изменении существующей необходимо вводить и корректировать значения полей в компонентах DBEdit1 и DBEdit2 (рис. 11.2).

При вводе значения в TDBEdit приложение автоматически отслеживает, чтобы введенное значение было совместимо по формату с полем набора данных, с которым связан данный компонент TDBEdit. Ввод неверных значений блокируется. Например, если в компонент TDBEdit, связанный с полем типа даты и времени, попытаться поместить строковое значение, будет возбуждено исключение.

Свойство property Text: string; хранит текущее содержимое поля НД в текстовом виде.

Событие property OnChange: TNotifyEvent; наступает при изменении значения поля.

События property OnEnter: TNotifyEvent; property OnExit: TNotifyEvent; наступают при получении и утрате фокуса управления компонентом TDBEdit.



Компонент TDBCheckBox


Компонент TDBCheckBox позволяет "отметить" и "снять отметку" с логического поля в составе текущей записи НД.

Он обладает функциональностью компонента TCheckBox, но источником данных и их приемником в этом случае служит поле НД.

Свойства property DataSource: TdataSource; property DataField: string;. property ReadOnly: Boolean; имеют такое же назначение, как и аналогичные свойства компонента TDBEdit.

Пример.

Расширим пример, приведенный выше для компонента TDBEdit. Пусть в ТБД "TOV.DB" имеется поле Uzenka (тип Boolean). Значение True в этом поле означает, что товары данной группы подлежат уценке, значение False - не подлежат.

Добавим в форму компонент DBCheckBox1 (свойство DataSource = DataSource1, свойство DataField = Uzenka). Тогда в процессе работы можно устанавливать в данное поле значения True или False, делая или не делая отметки DBCheckBox1 (рис. 11.3).

ЗАМЕЧАНИЕ.

При показе содержимого НД Table1 в TDBGrid в столбце Uzenka для тех записей, у которых поле Uzenka содержит True, выводится символ '+', а для тех записей, у которых поле Uzenka содержит False - ничего не выводится. Такая функциональность реализуется в следующем обработчике события OnGetText для поля Uzenka (компонент Table1 Uzenka).

procedure TForm1.Table1UzenkaGetText(Sender: TField;

var Text: string;

DisplayText: Boolean);

begin

IF DisplayText and Table1Uzenka.Value THEN Text := '+' ;

end;

Напомним, что событие OnGetText наступает перед показом содержимого поля каждой записи в визуальных компонентах.

Свойство

property Checked : Boolean;

позволяет определить, отмечено поле, на которое ссылается TDBCheckBox (значение True) или не отмечено (False).

Свойство

property State: TCheckBoxState;

возвращает состояние поля. Возможные значения:

cbUnchecked-

поле не отмечено;

cbChecked -

поле отмечено;

cbGrayed -

промежуточное состояние, когда поле не отмечено, но в нем показывается серый символ отметки. Он означает, что поле не содержит ни True, ни False, а содержит пустое значение. Именно это состояние присуще компоненту DBCheckBoxl при добавлении записей в приводившемся выше примере. Добиться того, чтобы во вновь добавляемых записях поле Uzenka по умолчанию содержало значение False можно в обработчике события OnNew Record компонента Table1 (событие наступает всякий раз при добавлении новой записи):

procedure TForm1.Table1NewRecord(DataSet: TDataSet) ;

begin

Table1Uzenka.AsBoolean := False;

end;

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

Свойство

property ValueChecked: string;

устанавливает значения поля, при которых TDBCheckBox переходит в состояние cbChecked. При наличии нескольких значений они разделяются точкой с запятой:

DBCheckBox1.ValueChecked := 'True;Yes;On;Дa;Д';

Свойство

property ValueUnchecked: string;

устанавливает значения поля, при которых TDBCheckBox переходит в состояние cbUnchecked. При наличии нескольких значений они разделяются точкой с запятой:

DBCheckBoxl.ValueUnchecked := 'False;No;Off; Нет;Н';

События

property OnEnter: TNotifyEvent;

property OnExit: TNotifyEvent;

наступают при получении и утрате фокуса управления компонентом.

Событие

property OnClick: TNotifyEvent;

наступает, если на компоненте TDBCheckBox щелкнуть мышью. Поскольку именно таким образом происходит снятие отметки или отметка компонента, данное событие может использоваться для оценки изменения значения свойства Checked.



Компонент TDBRadioGroup


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

Свойства

property DataSource : TDataSource;

property DataField: string;

property ReadOnly: Boolean;

аналогичны по назначению одноименным полям компонента TDBEdit.

Напомним, что число и названия вариантов возможных значений поля, содержащихся в TDBRadioGroup, определяются в его свойстве Items: TStrings.

Пример.

Расширим пример, приведенный выше для компонента TDBCheckBox. Пусть в ТБД "TOV.DB" имеется поле Hranenie типа String, которое может принимать только 2 значения ("до 5 дней", "свыше 5 дней"). Для выбора одного из этих значений добавим в форму компонент DBRadioGroup1, связав его с DataSource 1 и указав в свойстве DataField на поле Hranenie (рис. 11.4):

Заметим, что индекс текущего выбора можно определить, используя свойство TDBRadioGroup.ItemIndex : Integer, которое возвращает номер выбранного значения в порядке, в котором они определены в TDBRadioGroup.Items; при этом отсчет ведется с 0. Например, для приведенного выше примера (товар "Колбаса краковская") DBRadioGroupl. ItemIndex = 0.

Свойство property Value: string; возвращает значение поля, связанного с компонентом TDBRadioGroup, в текстовом виде.

Свойство property Columns: Integer указывает, сколько назначено столбцов для вывода переключателей (в примере на рис. 11.4. Columns = 2

Событие property OnChange: TnotifyEvent наступает при изменении значения поля, связанного с компонентом TDBRadioGroup.

События property OnEnter: TNotifyEvent; property OnExit: TNotifyEvent; наступают при получении и утрате фокуса управления компонентом.



Компонент TDBListBox


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

Свойства property DataSource : TDataSource; property DataField: string; property ReadOnly: Boolean; аналогичны по назначению одноименным свойствам компонента TDBEdit.

Свойство property Items: TStrings; содержит список возможных значений поля.

Пример.

Пусть в ТБД "TOV.DB" имеется поле Hranenie типа String, которое может принимать только 2 значения ("до 5 дней", "свыше 5 дней"). Для выбора одного из этих значений добавим в форму компонент DBListBox1, связав его с DataSource1 и указав в свойстве DataField на поле Hranenie (рис. 11.5).

События property OnEnter: TNotifyEvent; property OnExit: TNotifyEvent; наступают при получении и утрате фокуса управления компонентом TDBEdit.

События property OnClick: TNotifyEvent; property OnDblClick: TNotifyEvent; наступают при одиночном и двойном щелчке мышью на компоненте TDBListBox



Компонент TDBComboBox


Этот компонент аналогичен компоненту TDBListBox, за исключением того, что в режиме dsBrowse текущее значение поля показывается аналогично TDBEdit, а в режимах добавления (dslnsert) и редактирования (dsEdit) при занесении значения в поле появляется "выпадающий список" (рис. 11.6.). Длина списка в строках определяется свойством property DropDownCount: Integer;



Компонент TDBLookupComboBox


Компонент TDBLookupComboBox применяется для выбора значений в поле одного набора данных (назовем его НД-1) из списка значений, источником которого выступают значения какого-либо поля из другого набора данных (НД-2). Наборы данных НД-1 и НД-2 связываются по полю связи. Это поле присутствует и в НД-1, и в НД-2 и имеет идентичный тип. Таким образом, НД-1 и НД-2 состоят в связи, как правило, "многие (НД-1) к одному (НД-2)". При этом реляционная связь может быть не оформлена при помощи первичного (НД-1) и внешнего (НД-2) индексов. Поэтому вхождения поля связи ни в текущий, ни в какой-либо иной индекс не требуется.

Разберем ключевые свойства и методы компонента TDBLookupListBox.

property DataSource: TDataSource; -

указывает на компонент TDataSource, связанный с набором данных-1.

property DataField: string; -

устанавливает поле НД-1, в которое будет помещаться значение из НД-2.

property ListSource: TDataSource; -

указывает на компонент TDataSource НД-2.

property ListField: String; -

устанавливает поле, значения которого будут показываться в списке выбора. Если значение не заполнено, берется значение свойства Key Field.

Можно указать несколько полей. Тогда все они будут показываться в списке выбора. Имена полей разделяются точкой с запятой.

property RowCount: Integer; -

указывает, сколько строк показывается в выпадающем списке. При изменении размеров списка, например путем занесения нового значения в свойство Height, RowCount изменятся автоматически.

property KeyField: string; -

устанавливает поле связи между наборами данных 1 и 2.

property KeyValue: Variant; -

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

Пример.

Пусть в ТБД "Сотрудники" (поле Doljnost) нужно вводить значения из списка, определяемого полем Doljnost ТБД "Должности, оклады". Для иллюстрации будем в списке показывать также значения поля Oklad ТБД "Должности, оклады".

С ТБД "Сотрудники" связан НД TeachersTable (TTable), с ТБД "Должности, оклады" - НД OkladyTable (TTable). С ними соответственно связаны компоненты TDataSource DS_Teachers и DS_Oklady.

Для ввода в поле Doljnost (НД TeachersTable) разместим в форме компонент DBLookupComboBox1 и установим такие значения его свойств:

DataSource DS_Teachers

DataField

Doljnost

ListSource

DS_Oklady

ListField

OklaD;Doljnost

KeyField

Doljnost

Тогда при занесении значения в поле Doljnost НД TeachersTable получим комбинированный список значений оклада и должности из НД OkladyTable (рис. 11.7).

В компоненте определены свойства property DropDownAlign : TAlign; property DropDownRows: Integer; property DropDownWidth: Integer; определяющие соответственно выравнивание, число строк в списке и его ширину, а также методы procedure DropDown; - раскрывает ("распахивает") список выбора;

procedure CloseUp; -

сворачивает распахнутый список выбора.

Компонент TDBLookupListBox


Повторяет функциональность компонента TDBLookupComboBox, за исключением того, что выбор производится не из постоянно присутствующего на экране, а "раскрывающегося" (или "выпадающего") списка. Отсутствуют следующие свойства и методы компонента TDBLookupComboBox: DropDownAlign, DropDownRows, DropDown Width, DropDown и CloseUp.



Компонент TDBMemo


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

При корректировке текста комментария в компоненте TDBMemo набор данных, к которому принадлежит поле комментария, автоматически переводится в состояние dsEdit.

Пример.

Пусть в ТБД "TOV.DB" имеется поле комментария Komment. Расположим в форме компонент DBMemo1 и укажем в его свойстве DataSource имя компонента TDataSource, связанного с НД, к которому принадлежит поле

комментария После этого в свойстве DataField из выпадающего списка выберем имя поля Komment. Если нужно представлять текст комментария только для просмотра, установим в свойство ReadOnly компонента DBMemo1 значение True, а если текст может изменяться - значение False (рис. 11.8).

Свойство AutoDisplay : Boolean; в состоянии True указывает на необходимость того, чтобы любые изменения в поле НД автоматически отображались и в TDBMemo. В состоянии False подобные действия не производятся и обновление информации в TDBMemo необходимо производить программно.

Свойство Alignment; TAlignment; определяет выравнивание текста в TDBMemo - влево (taLeftJustify), вправо (taRightJustify), по центру (taCenter).

Свойство WordWrap : Boolean; в состоянии Тгие разрешает показывать с новой строки те слова, которые не умещаются в области показа (при этом свойство ScrollBars не должно определять линию горизонтальной прокрутки). В состоянии False этого не происходит(рис.11.9.а и б).

Свойство ScrollBars : TScrollStyle; определяет полосы прокрутки в окне TDBMemo. отсутствие полос прокрутки (ssNone), горизонтальную (ssHorizonlal), вертикальную (ssVertical) и обе (ssBoth).

Свойство Lines: TStrings; содержит строки поля комментария. Для работы с Lines допустимо (и рекомендуется) использовать свойства и методы класса TStrings. Приведем наиболее важные из них:

• Count: Integer;

Возвращает общее число строк в Lines.

• Memol.Lines|i| : String;

Позволяет обратиться к i-й строке. При этом i принадлежит к интервалу 0..Lines.Count -1.

Пример.

Требуется строчные буквы всех строк в DBMemol заменить на заглавные. Для преобразования используем стандартную функцию AnsiUpperCase:

procedure TForm1 .ButtonlClick (Sender: T0bj]ect) ;

var i : Integer;

begin

TableI.Edit; //набор данных - в режим редактирования

WITH DBMemol do begin

FOR i := 0 TO Lines.Count - 1 do

Lines [i] := AnsiUpperCase(Lines[i]);

END; {with}Table1.Post;

end;

Нужно отметить, что того же эффекта можно добиться, обращаясь к содержимому поля комментария как к длинному текстовому полю с использованием его свойства property Text: String; Например:

procedure TForm1.Button2Click(Sender: TObject);

begin

Table1.Edit; //набор данных - в режим редактирования

DBMemol.Text := AnsiUpperCase(DBMemol.Text);

Table1.Post;

end;

Заметим, что изменение значения свойства Text или значения одного или нескольких строк Lines не переводит НД в режим редактирования и изменения внесенные в текст комментария в TDBMemo, в поле НД, с которым этот компонент связан, не переносятся Поэтому перед внесением изменений в значения свойств Lines или Te\f следует переводить набор данных в режим dsEdif, а затем запоминать изменения методом Post

Аналогичным по последствиям будет обращение к тексту комментария через свойство Value компонента TField, назначенного полю комментария

Table1.Edit; //набор данных - в режим редактирования

Table1.Komment.Value := AnsiUpperCase(Table1Komment.Value);

Table1.Post;

В некоторых случаях бывает полезным формировать содержимое комментария во временном компоненте TMemo и затем присваивать свойство Lines компоненту TDBMemo

Table1.Edit; //набор данных - в режим редактирования

DBMemol.Lines.Assign(TmpMemo1.Lines) ;

Table1.Post;

Такой же подход нужно применять и тогда, когда содержимое поля комментария изменяется построчно

Table1.Edit; //набор данных - в режим редактирования

DBMemol.Lines [i].Add('какое-то значение') ;

Table1.Post;

Часто производимый перевод НД из состояния dsBrowse в dsEdif и обратно способен существенно замедлить работу приложения Наоборот, работая со

свойством Lines компонента TMemo, мы всегда работаем только с оперативной памятью Впоследствии накопленные изменения запоминаются в поле комментария за один раз

function Index0f(const S: string): Integer;

Возвращает индекс (начиная с 0) строки, совпадающей с S (если таковая есть), и -1, если такой строки нет

procedure Clear;

Очищает Lines Значение свойства Count становится равным 0

function Add(const S: string): Integer;

Добавляет строку в конец Lines и возвращает номер добавленной строки

procedure Insert (Index: Integer; const S: string);

Вставляет строку S после строки с индексом Index

procedure Delete (Index: Integer);

Удаляет строку с индексом Indev

Метод procedure LoadFromFile(const FileName: string); загружает в TDBMemo содержимое файла, имя которого определяется параметром FileName

Метод procedure SaveToFile(const FileName: string); записывает содержимое TDBMemo в файл FileName

Часто необходимо обеспечить поиск в тексте комментария вхождений какого-либо поискового контекста В этом случае с содержимым поля комментария работают не построчно (через свойство Lines), а как с единым целым (текстовой переменной) через свойство Text Для поиска используется символьная функция Роs, которая возвращает значение, отличное от 0, если поиск был удачен Свойства SelStart и SelLength используются для последующего выделения найденного вхождения Приведем пример простейшего контекстного поиска в поле комментария (реализован в обработчике события Find компонента FmdDialog)

procedure TForm1.FindDialog1Find(Sender: TObject);

var

ToFind: string; // строка, вхождение которой ищем

FindIn: string; // строка (Мемо), где ищем

Found: integer; // результат поиска

Index: integer; // начальная позиция (№ символа) найденного вхождения

FoundLen: integer; //длина найденного текста

begin

ToFind := FindDialog1.FindText; {Поисковая строка - из FmdDialog}

FoundLen := Length(FindDialog1.FindText); {Длина искомого фрагмента текста}

FindIn := MemoSee.DBMemol.Text; {Текст, где будем искать}

Found := Pos(ToFind, Findin) ;

IF Found > 0 then

begin {Отметим найденный фрагмент)

DBMemol.SelStart:= Found -1;

DBMemol.SelLength := FoundLen;

end

ElSE

MessageDIg('Такого вхождения нет!', mtlnformation, [mbOK], 0) ;

end;



Назначение компонента


Компонент TDBRichEdit позволяет просматривать и корректировать информацию в поле форматированного комментария (рис. 11.10).

Форматированный комментарий располагается в поле комментария. Текст в нем может содержать фрагменты, набранные различным шрифтом, размером,

стилем, цветом и т.д. В отличие от компонента TDBMemo, который позволяет работать только с однородным (неформатированным) текстом, компонент TDBRichEdit умеет интерпретировать специальные символы разметки текста в формате RTF (Rich Text Format).

Свойства

property AutoDisplay: Boolean;

property DataField: string;

property DataSource: TDataSource;

ro property Field: TField;

property Lines: TStrings;

procedure LoadMemo; property ReadOnly: Boolean;

аналогичны по назначению одноименным свойствам компонента TDBMemo.

Длина текста форматированного комментария в символах возвращается методом function GetTextLen: Integer;

Метод procedure Clear; полностью удаляет текст из компонента.

Метод procedure Print(const Caption: string); выводит текст комментария на печать. Параметр Caption определяет заголовок в очереди печати.

Свойство property HideScrollBars; определяет, следует автоматически убирать (True) или нет (False) полосы скроллинга из окна TDBRichEdit, если в их присутствии нет необходимости.

Свойство property HideSelection: Boolean; определяет, следует (True) или не следует (False) скрывать выделение текста в окне TDBRichEdit, если фокус управления перешел к другому компоненту.

При изменении размера шрифта наступает событие property OnResizeRequest: TRichEditResizeEvent; TRichEditResizeEvent = procedure (Sender: TObject; Rect: TRect) of object ; Параметр Rect содержит сведения о новых границах изменяемого текста (в экранных координатах).

При изменениии текста наступает событие property OnChange: TNotifyEvent; TNotifyEvent = procedure(Sender: TObject) of object;



Сохранение комментария в файле и считывание комментария из файла


Форматированный комментарий может быть записан в файл и считан из него. Для этой цели применяются методы свойства Lines, procedure SaveToFUe(const FileName: string); procedure LoadFromFile(const FileName: string);

Свойство property PlainText: Boolean; указывает (True), что нужно игнорировать разметку текста (шрифт, цвет и т.д.) при записи из файла в компонент или из компонента в файл. В этом случае текст представляется в виде обычного текстового файла. Значение False (по умолчанию) указывает на необходимость принимать во внимание разметку текста. Например,

RichEdit1.PlainText := True;

RichEdit1.Lines.LoadFromFile(Path);

RichEdit2.PlainText := False;



Работа с выделенным текстом


Фрагмент текста форматированного комментария выделяется так же, как и в популярном текстовом процессоре WinWord; для выделения необходимо установить указатель мыши на начало выделяемого фрагмента, нажать левую кнопку мыши и, не отпуская кнопки, установить указатель мыши на конец фрагмента, после чего кнопку отпустить. Есть и другой способ (при помощи клавиатуры): следует переместить курсор на начало выделяемого фрагмента, нажать кнопку с изображением стрелки влево (вправо) и одновременно - кнопку Shift; движение курсора следует остановить на конце выделяемого фрагмента.

Следующие свойства позволяют определить параметры выделенного фрагмента в тексте комментария:

property SelLength: Integer;

возвращает число выделенных символов. property SelStart: Integer; возвращает номер первого выделенного символа в тексте. property SelText: string; возвращает выделенный текст.

Программное изменение одного из указанных свойств изменяет границы выделенного фрагмента.

Весь текст комментария может быть выделен вручную - нажатием на клавиатуре комбинации Ctrl+A, и программно - путем выполнения метода procedure SelectAll;

Свойство property SelAttributes: TTextAttributes; позволяет установить характеристики выделенного текста. Свойства компонента TTextAttributes: . -

• property Color: TColor;

определяет цвет выделенного текста;

• property Height: Integer;

определяет высоту в пикселах выделенного текста;

• property Pitch: TFontPitch;

определяет, имеют ли литеры выделенного текста одинаковую ширину.

Значения:

fpDefault-

определяется используемым шрифтом;

fpFixed -

одинаковая ширина;

fp Variable -

переменная ширина.

• property Protected: Boolean;

определяет (True), что текст защищен от изменения пользователем. В случае, если пользователь пытается изменить защищенный текст, вызывается обработчик события OnProtectChange.

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

• property Size: Integer;

определяет высоту в пикселах выделенного текста.

* property Style: TFontStyles;

определяет стиль выделенного шрифта. Множество Style может состоять из одного или нескольких значений:

fsBold - жирный;

fsltalic -

наклонный;

fs Underline -

подчеркнутый;

fsStrikeout -

зачеркнутый.

Пример.

Установить шрифт, цвет, размер и стиль выделенного текста аналогичными параметрам шрифта, выбранного посредством компонента TFontDialog:

IF FontDialog1.Execute THEN begin

WITH DBRichEditl.SelAttributes do begin

Color := FontDialogl.Font.Color;

Size := FontDialogl.Font.Size;

Name := FontDialogl.Font.Name;

Style := FontDialogl.Font.Style;

END;//with

END;//if

Пример.

Сделать выделенный фрагмент текста защищенным:

DBRichEditI.SelAttributes.Protected := True;

Событие

property OnProtectChange: TRichEditProtectChange;

TRichEditProtectChange = procedure(Sender: TObject; StartPos, EndPos: Integer; var AllowChange: Boolean) of object;

наступает, если пользователь пытается изменить защищенный текст. Параметры StartPos и EndPos содержат границы защищенного текста. Установка в True изменяемого параметра AllowChange разрешает изменять защищенный текст.

Пример.

В случае, если пользователь пытается изменить символ, ранее помеченный как защищенный, запрашивается подтверждение; если пользователь подтверждает изменение защищенного символа, тот изменяется; если не подтверждает, изменение символа отвергается.

procedure TForm1.DBRichEdit1ProtectChange(Sender: TObject;

StartPos,

EndPos: Integer; var AllowChange: Boolean);

begin

IF MessageDIg('Изменяемый текст являются защищенным. ' + 'Желаете все-таки его изменить?',mtConfirmation,

[mbYes,mbNo],0) = mrYes THEN AllowChange := True;

end;

Выделенный фрагмент текста может быть удален методом procedure ClearSelection;

Метод procedure CopyToClipboard; копирует выделенный текст в буфер обмена Windows.

Метод procedure CutToClipboard; вырезает выделенный текст и вставляет его в буфер обмена Windows.

Метод procedure PasteFromCUpboard; вставляет содержимое буфера обмена Windows в текст комментария, начиная с текущей позиции курсора.

Пример.

Определим кнопки "Копировать в буфер обмена", "Вырезать в буфер обмена", "Вставить из буфера обмена" и напишем обработчики события нажатия этих кнопок:

// кнопка "Копировать в буфер обмена"

procedure TForm1.SpeedButton6Click(Sender: TObject);

begin

DBRichEditI.CopyToClipboard;

end;

// кнопка "Вырезать в буфер обмена"

procedure TFormI.SpeedButton7Click(Sender: TObject);

begin

DBRichEditI.CutToClipboard;

end;

// кнопка "Вставить из буфера обмена"

procedure TForm1.SpeedButtonSClick(Sender: TObject);

begin

DBRichEdit1. PasteFromCUpboard;

end;



Поиск фрагмента текста


Метод function FindText(const SearchStr: string; StartPos, Length: Integer; Options: TSearchTypes): Integer; ищет в тексте комментария строку SearchStr. Поиск производится во фрагменте текста начиная с позиции StartPos и заканчивая StartPos + Length -1. Первый символ текста комментария имеет номер 0.

Если поиск успешен, возвращается номер символа, начиная с которого SearchStr входит в текст комментария. В противном случае возвращается -1.

Параметр Options представляет собой множество, в который могут входить такие элементы:

stWholeWord-

поиск ведется целыми;

stMatchCase -

игнорируется разница в высоте букв.

Пример.

Произвести поиск во всем тексте DBRichEdit1. Поисковая строка находится в Edit1.Text. Если фрагмент найден, выделить его.

procedure TForm1.FindButtonClick(Sender: TObject) ;

begin

WITH DBRichEditl do begin

SelStart := FindText(Editl.Text,0,GetTextLen,[]) ;

SelLength := Length(Edit1.Text) ;

END;//with

end;



Назначение компонента TSession


Для каждого приложения в Delphi автоматически создается компонент типа TSession с именем Session. Он управляет всеми соединениями с базами данных. Его методы и свойства носят глобальный характер для всего приложения.

Обычно в приложении имеется один поток (Thread) работы с БД. В некоторых случаях можно создать два и более потока. При этом, если в каждом из этих потоков реализовать запросы к БД, они будут выполняться независимо друг от друга. В случае нескольких потоков, компонент типа TSession создается для каждого из них.



Работа с установками BDE


Метод procedure GetAliasNames(List: TStrings); очищает список List и затем заносит в него список псевдонимов БД , определенных в BDE.

Пример:

Session.GetAliasNames(ListBoxl.Items) ;

Метод procedure GetAliasParams(const AliasName: string; List: TStrings); очищает список List и затем помещает в него параметры псевдонима AliasName.

Пример:

var TekAllias : String;

Session.GetAliasParams(TekAllias, ListBox2.Items);

Примеры возвращаемых результатов:

SERVER NAME=C:\Program

Files\Borland\IntrBase\EXAMPLES\EMPLOYEE.GDB

USER NAME=SYSDBA

OPEN MODE=READ/WRITE

SCHEMA CACHE SIZE=8

LANGDRIVER=

SQLQRYMODE=

SQLPASSTHRU MODE=SHARED AUTOCOMMIT

SCHEMA CACHE TIME=-1

PATH=d:\book\data

DEFAULT DRIVER=PARADOX

ENABLE BCD=FALSE



Чтение имен таблиц базы данных


procedure GetTableNames(const DatabaseName, Pattern: string; Extensions, SystemTables: Boolean; List: TStrings); очищает список List и добавляет в него имена всех таблиц, определяемых параметром DatabaseName. Если необходимо добавить имена только некоторых таблиц, шаблон их имени указывается параметром Pattern. Значение параметра SystemTables, равное True, включит в состав таблиц, чьи имена занесены в List, имена системных таблиц (для удаленных баз данных). Установка в True параметра Extensions приведет к включению в имена таблиц расширений имени файла.

Пример:

var TekAllias : String;

Session.GetTableNames(TekAllias, '*.*', False, False, ListBox5.Items);

Метод procedure GetDriverNames(List: TStrings); очищает список List и затем заносит в него информацию об установленных на текущий момент драйверах BDE. Заметим, что драйверов 'PARADOX' и 'DBASE' не существует, поскольку эти СУБД управляются драйвером 'STANDARD'.

Пример:

Session.GetDriverNames(ListBox3.Items);

Метод procedure GetDriverParams(const DriverName: string; List: TStrings); очищает список List и затем заносит в него параметы по умолчанию для драйвера, названного в параметре DriverName. В случае использования Paradox или dBASE (DriverName = 'STANDARD') , имеет место только один параметр, 'РАТН='. Драйверы SQL-СУБД могут иметь переменное число параметров.

Пример:

var TekDriver : String;

Session.GetDriverParams(TekDriver,ListBox4.Items);

Пример результата для драйвера 'INTRBASE':

SERVER NAME=IB_SERVER:/PATH/DATABASE.GDB

USER NAME=MYNAME

OPEN MODE=READ/WRITE

SCHEMA CACHE SIZE=8

LANGDRIVER=

SQLQRYMODE=

SQLPASSTHRU MODE=SHARED AUTOCOMMIT

SCHEMA CACHE TIME=-1

MAX ROWS=-1

BATCH COUNT=200

ENABLE SCHEMA CACHE=FALSE

SCHEMA CACHE DIR=

ENABLE BCD=FALSE

Пример результата для драйвера 'STANDARD:'

РАТН=

DEFAULT DRIVER=PARADOX



Список объявленных БД


Метод procedure GetAliasNames(List: TStrings); возвращает список псевдонимов БД, объявленных для BDE на данном компьютере.

Количество активных в данном приложении БД возвращает свойство property DatabaseCount: Integer; При этом отсчет активных БД ведется начиная с 0.

Свойство property Databases[Index: Integer]: TDatabase; обеспечивает доступ к активной БД с индексом Index; при этом каждой БД из списка Databases соответствует компонент типа TDatabase. Таким образом, при работе с каждой активной БД из списка Databases можно пользоваться свойствами, методами и событиями, присущими компоненту TDatabase.

Например,

поместить в ListBox2 список активных БД приложения:

var i : Integer;

ListBox2.Clear;

WITH Session do begin

FOR i := 0 TO DatabaseCount - 1 do

ListBox2.Items.Add(Databases[i].DatabaseName) ;

END;//with



Хранение соединения с неактивной БД


Пусть некоторая БД имела наборы данных, открытые в определенный период времени, но затем эти НД были закрыты. Свойство property KeepConnections: Boolean; определяет, следует ли приложению хранить соединение с неактивными БД. False означает "не хранить"; при значении True соединение с неактивными БД будет ликвидировано либо при окончании работы приложения, либо после выполнения метода procedure DropConnections; К преимуществам постоянного соединения с неактивной БД можно отнести отсутствие необходимости выполнять повторное соединение с БД при открытии набора данных, использующего таблицы этой БД. А соединение, как известно, требует времени.

К недостаткам можно отнести расход ресурсов компьютера на поддержание постоянного соединения.



Работа с активными БД


Метод function OpenDatabase(const DatabaseName: string): TDatabase; пытается отыскать компонент TDatabase, у которого свойство DatabaseName совпадает с параметром DatabaseName метода FindDatabase. В случае успеха возвращается указатель на найденный и открытый компонент TDatabase; если такой компонент не существует, он создается, открывается и указатель на него возвращается в качестве результата работы метода. Метод OpenDatabase следует использовать в паре с методом CloseDatabase в блоке try...finally для обработки исключений, которые могут возникнуть при выполнении данных методов.

Метод procedure CIoseDatabase(Database: TDatabase); закрывает открытую БД, определяемую параметром Database, который содержит ссылку на экземпляр типа TDatabase. Принудительное закрытие БД практикуется достаточно редко, поскольку закрытие всех открытых БД производится при окончании работы приложения.

Метод function FindDatabase(const DatabaseName: string): TDatabase; пытается отыскать БД (компонент TDatabase} в коллекции TSession. Databases (коллекция открытых БД). Имя искомой БД определяется строковым параметром DatabaseName. Если в коллекции открытых БД сессии имеется такая БД, у которой значение DatabaseName совпадает с параметром DatabaseName метода FindDatabase, в качестве результата возвращается указатель на найденный компонент TDatabase. В противном случае возвращается nil.



Работа с паролями для Paradox-таблиц


Базой данных в Paradox, как известно, считается набор ТБД, хранящихся в одном месте. Каждая из таких таблиц физически занимает один файл и может иметь один или несколько паролей. При этом каждый из паролей может обеспечивать свои права доступа к таблице - доступ для чтения и записи, только для чтения и т.д. Более подробно с установкой паролей ТБД можно ознакомиться в среде Database Desktop, в разделе Table Properties \ Password Security. Окно Auxiliary Passwords (дополнительные пароли) позволяет определить для Paradox-ТБД несколько паролей с разными правами доступа (рис. 12.1.а и б).

Можно установить следующие права доступа:

• All - с

данными в ТБД можно делать все, плюс изменять структуру самой ТБД и физически удалять ее из БД;

• Insert & Delete -

можно добавлять, удалять, очищать данные, но нельзя реструктурировать таблицу и удалять ее из БД;

Data Entry - можно добавлять и изменять записи, но нельзя удалять записи, изменять структуру ТБД и удалять ее из БД;

Update -

можно просматривать записи ТБД и изменять в записях значения неиндексных полей. Остальное нельзя;

Read Only -

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

Кроме того, можно установить права доступа и к отдельным полям. Для этого необходимо сделать текущим нужное поле и нажимать кнопку Field Rights до тех пор, пока не будут выбраны нужные права по отношению к данному полю для данного пароля. Права доступа следующие:

All

(по умолчанию) - любое изменение данных в поле, с учетом накладываемых на поле ограничений, если такие определены в DataBase Desktop;

Read Only -

данные можно просматривать, но не изменять;

None -

данные нельзя ни просматривать, ни изменять, Database Desktop прячет значения поля после открытия ТБД.

Таким образом, при попытке открытия ТБД, для которой определены пароли, выдается запрос на ввод паролей в виде следующего окна (рис. 12.2).

Add

позволяет добавить один или несколько паролей в список паролей;

Remove

удаляет текущий пароль; RemoveAll удаляет все введенные пароли и список паролей очищается; Ok закрывает окно, после чего все пароли в списке анализируются на соответствие действительным паролям данной ТБД, и, если хотя бы один из них отвечает требованиям, ТБД может быть открыта; Close отменяет попытку ввести пароль, ТБД не открывается.

Средства TSession для работы с паролями


Три метода TSession позволяют вводить пароли в список, удалить текущий пароль или удалить все пароли: procedure AddPassword(const Password: string); procedure RemoveAllPasswords; procedure ReniovePassword(const Password: string);

Можно не прибегать к помощи стандартного окна ввода паролей, а вводить их, например, из компонента TEdit и затем добавлять в список паролей: Session.AddPassword(Edit1.Text) ; После этого можно применить метод Table1.Open; для попытки открытия ТБД. В том случае, если с использованием AddPassword был введен хотя бы один пароль, дающий права доступа к таблице, ТБД будет открыта В противном случае будет вызвано стандартное окно запроса паролей.

Заметим, что используя методы AddPassword. RemoveAllPaswords. RemovePassword, можно написать собственное окно ввода паролей, если Вас не устраивает стандартное окно. Принудительный вызов стандартного диалога ввода паролей реализуется методом function GetPassword: Boolean;

Он вызывает обработчик события OnPassword (если определен). В противном случае выдает стандартный диалог ввода пароля. Если пользователь нажал кнопку ОК., метод возвращает True; в случае нажатия кнопки Cancel возвращает False.

Метод может использоваться для ввода пароля с отложенным открытием БД. Если введен правильный пароль, открытие БД или ТБД (для персональных СУБД) не приведет к повторному запросу на ввод пароля.



Управление парольной защитой


Ниже описывается работа с паролями Paradox. При работе с иными СУБД обеспечение парольной защиты может отличаться.



Определение служебных каталогов сессии


Свойство property NetFileDir: string; указывает каталог, в котором содержится управляющий сетевой файл BDE PDOXUSRS.NET. Это свойство обеспечивает одновременную работу нескольких пользователей в сети. Значение свойства NetFileDir замещает значение сетевого каталога, определяемого в параметрах Paradox-драйвера в утилите настройки параметров BDE (BDE Administrator).

property PrivateDir: string;

Значение свойства PrivateDir определяет каталог, который используется для хранения временных файлов сессии БД.

Событие активизации сессии


Событие property OnStartup: TNotifyEvent; наступает при активизации сессии в тот момент, когда сессия еще не стала активной. Используя обработчик данного события, во время выполнения причожения можно устанавливать значения свойств NetFileDir и PrivateDir .



Создание графика


Для того чтобы создать график, поместите в форму компонент TDBChart в форме будет создана заготовка (рис 131) Затем щелкните мышью по этой заготовке два раза. Будет произведен переход в редактор графика В среде этого редактора можно установить свойства графика и его серий. Содержимое редактора графика представляет собой табулированный блокнот Для нового графика первой всегда показывается закладка Chart и для страницы Chart - закладка Series (рис 13 2).

Каждая из закладок на странице Chart предназначена для установки параметров того или иного компонента графика

Series -

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

General -

устанавливает общие параметры графика, такие как объемность графика, отступы от краев, возможность увеличения (Zoom) и др.

Axis -

устанавливает свойства осей (рис. 13.4).

В области ShowAxis определяется, для какой оси устанавливаются параметры - левой, правой, верхней или нижней. На странице, определяемой закладкой Scales, устанавливаются свойства масштаба значений по оси. Automatic устанавливает автоматическое масштабирование данных по оси - минимум и максимум вычисляются динамически, исходя из текущих значений серии. При отмене автоматического масштабирования можно установить автоматическое масштабирование минимального {Minimum} или максимального (Maximum} значения (отметка Auto). Для установки значения максимума и (или) минимума вручную следует нажать соответствующую кнопку Change. Шаг масштаба по оси выбирается автоматически, если в Desired Increment установлено значение 0. Установить фиксированное значение шага можно, нажав кнопку Change. Закладка Title позволяет установить текст заголовка по оси, угол расположения заголовка и шрифт, которым заголовок выводится. Закладка Labels задает параметры меток для оси. Закладка Tiks устанавливает параметры самой линии оси.

Titles - определяет заголовок графика, шрифт, выравнивание и др. Legend - задает параметры легенды. Легенда - область графика, где приводится информация о графике. Например, на рис. 13.5 показана легенда, которая расположена под графиком на рис. 13.3, и служит для пояснения графика.

Panel -

определяет параметры панели, на которой располагается график.

Paging -

устанавливает параметры многостраничного графика.

Walls

- задает "стенку" графика. Например, на рис.13.3 "стенка" расположена по левой вертикальной оси.

Добавление серии в график


На графике одновременно может располагаться несколько серий. В большинстве случаев их значения строятся по одинаковому закону и две и более серий одновременно показываются в графике для сравнения.

Чтобы добавить в график серию, следует на странице Chart, (закладка Series) нажать кнопку Add. После этого появится окно выбора типа серии (рис 13.6).

Рис 13.6 Редактор графика - окно выбора типа серии Рис 13.7 Редактор графика - список серий графика

После выбора типа серии в график добавляется компонент, дочерний от базового типа TChartSeries - TLineSeries, TBarSeries, TPieSeries и т.д. Выберем серию типа Line и нажмем Ok. В окне страницы Chart (закладка Series) будет показана серия (рис. 13.7).

Кнопка Add может использоваться для добавления других серий, кнопка Delete - для удаления текущей серии. После нажатия кнопки Title можно определить заголовок серии, кнопки Clone - создать новый экземпляр такой же серии в этом же графике, кнопки Change - изменить тип текущей серии.

Перейдем с закладки Chart на закладку Series. На этой странице представлен блокнот с закладками Format, General, Marks, DataSource. Рассмотрим свойства серии, которые можно установить на страницах, соответствующих этим закладкам.



Выбор источника данных


Несомненно, главные свойства серии можно определить на странице DataSource. На ней определяется источник данных для серии. Выпадающий список ниже закладки позволяет определить тип источника данных для серии:

No Data -

серии не назначается источник данных. Далее мы собираемся сделать это программно. Кроме того, заготовленный шаблон серии может в разное время использоваться для показа данных из разных источников, которые мы также собираемся переключать программно во время выполнения.

Random Values -

набор случайных чисел. Бывает полезен при формировании заготовки серии, источник данных которой мы собираемся установить позднее.

Function

- функция (Сору, Average, Low, High, Divide, Multiply, Subtract, Add) - служит для построения графиков на основании данных в двух или более сериях.

DataSet -

позволяет указать НД, значения полей (столбцов) которого будут использоваться для формирования точек серии. В качестве НД могут выступать компоненты TTable, TQuery, TClientDataSet.

Выберем DataSet и из выпадающего списка выберем компонент Table 1, ранее расположенный на нашей форме. Table1 (тип TTable) - набор данных, связанный с таблицей Kap_pryb.DB, где хранятся данные о зависимости между размером капитала некоторой фирмы (поле Kapital) и приростом дохода для каждого факта увеличения капитала (поле ProcKPred). Укажем, что поле Kapital содержит значения по оси X, а поле ProcKPred - значения по оси Y (рис. 13.8.)

ЗАМЕЧАНИЕ Не все типы серии требуют значений по осям Y или Х Для серий типа Pie, Bar можно указывать значения по одной из осей и значения меток Labels В качестве меток могут использоваться символьные поля и поля типа даты и времени Для примера приведем графики отпуска товара конкретному покупателю (рис 13 9), где в качестве данных по оси Y или Х берется сумма отпуска конкретного товара, а в качестве меток Labels - названия товаров Показаны три графика - серии типа Pie, Vertical Bar (или просто Bar) и Horizontal Bar

Серия типа Bar может содержать точки, сформированные как по осям X, Y, так и по оси Y (Bar) и меткам Labels

После того, как мы указали источник данных и поля для формирования значений по осям Х и Y, нажмем кнопку Close и выйдем изредактора графика На ранее пустой панели будет построен график (рис 13 10)

Если вернуться в редактор графика, на странице Series можно, помимо DataSource, увидеть закладки Format, General, Marks Их назначение-

Format -

определяет свойства палитры, линий графика и т д

Gene/a/ - задает форматы данных

Marks -

устанавливает марки - значения в рамке над точками серии На графике, приведенном на рис 13.10, марки показывают значения узловых точек по оси Y 175, 160, 140 и 120 Марки показываются на графике, если отмечено свойство Visible, свойство Style определяет вид марок (рис 13.11)

Определение функций


На странице Series (закладка Data Source) в качестве источника данных можно определить функцию. Функция обычно используется для показа отношений между другими сериями.

Пусть для графика определены две серии, показывающие общую сумму продаж товаров по месяцам и сумму продаж для конкретного покупателя. Источниками данных этих серий выступают два компонента TQuery. Определим третью серию, которая показывала бы разницу между первыми двумя. Для этого добавим в график новую серию и на странице Series в закладке Data Source выберем Function. В диалоговом окне определения функций выберем тип функции - Subtract (вычитание). В области Source Series \ Available показаны серии, присутствующие в графике. Используя кнопку ”, переместим две упомянутые выше серии (источником которых служат TQuery) в область Selected (рис. 13.12).

Тогда на графике получим три серии, причем белым цветом показана серия, источником которой служит функция разности значений первых двух серий (рис. 13.13).



Добавление серии во время выполнения


Число серий, присутствующих в текущий момент в графике, во время выполнения можно определить при помощи метода компонента TDBChart function SeriesCount: Longint;

Список серий графика содержится в его свойстве property Series[Index:Longint]:TChartSeries; где Index лежит в диапазоне 0.. SeriesCount-1, поскольку отсчет серий идет с нуля.

Метод procedure RefreshData; обновляет данные в серии из наборов данных, которые служат их источником. Например, пусть график показывает отпуск товара конкретному покупателю. Источником данных для серии графика служит Query 1, которому в качестве параметра передается имя покупателя. При всякой смене имени покупателя происходит обновление Query 1, сопровождающееся изменением данных. Эти изменения отражаются в графике так:

Queryl.Open;

DBChartl. RefreshData;

Покажем, как можно добавить серию в график во время выполнения:

var

MySeries : TBarSeries;

MySeries := TBarSeries.Create(Self);

MySeries.ParentChart := DBChartl;

MySeries.SeriesColor := cIGreen;

MySeries.DataSource := Queryl;

MySeries.XLabelsSource := 'MES';

MySeries.YValues.ValueSource:='S';

MySeries.Active := True;

MySeries.Title := Table1POKUP.Value;

В приведенном примере создается серия типа Bar (вертикальная столбчатая диаграмма), в качестве родительского графика ей назначается DBChartl. В качестве источника данных назначается Queryl. Для формирования значений серии используются поля компонента Queryl: S (по оси Y) и MES (в качестве Labels). Затем серия активизируется (после этого она становится видна в графике) и ее заголовку присваивается наименование покупателя.



Свойства компонента TChartSeries


property Active : Boolean; - активизирует (показывает) серию в графике (значение True) и дезактивизирует (скрывает) серию (False). Например: DBChartl.Series[0].Active :=True;

property DataSource : TComponent; -

ссылается на компонент типа НД (TTable, TQuery, TClientDataSet) или на другую серию, откуда берутся данные для показа в серии. Например: DBChartl.Series[0].DataSource := Query2;

property HorizAxis: THorizAxis; -

указывает, какая горизонтальная ось будет использована для серии. Значения: aTopAxis • верхняя горизонтальная ось; aBottomAxis - нижняя горизонтальная ось.

property Marks : TSeriesMarks; -

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

property Arrow : TChartPen; -

задает свойства пера, рисующего марку. Свойства объекта Arrow:

property Color: TColor; -

цвет линий;

property Mode: TPenMode; -

способ рисования линий;

property Style: TPenStyle; -

стиль линий;

property Visible: Boolean; -

видимость линий;

property Width: Integer; -

задает ширину линий;

property ArrowLength : Integer; -

длина в пикселях линии, соединяющей марку с соответствующим изображением элемента серии. По умолчанию 16;

property BackColor: TColor; -

определяет цвет фона марки. По умолчанию $80FFFF (желтый);

property Clip: Boolean; -

если содержит True, марки не могут накладываться на другие элементы графика (на легенду, метки осей и т.д.);

property Font : TFont; -

определяет шрифт, которым выводится информация внутри марки;

property ParentSeries : TChartSeries; -

содержит указатель на серию, к которой принадлежат марки;

property Style : TSeriesMarksStyle; -

определяет содержимое марки. По умолчанию smsLabel. В обработчике события TChartSeries. OnGetMarkText можно переопределить значения, принятые по умолчанию. Например: DBChartl.Series[0].Style := smsLabelValue;

Возможные значения свойства Style:

• smsValue -

значения по осиУ (YValue), за исключением THorizBarSeries (XValue). Например, "9087";

• smsPercent - процентное значение, например "44%"; для форматирования процентного значения также используется свойство TChartSeries. PercentFormat;

• smsLabel -

показывает метку, ассоциированную с точкой графика, например "Сахарный песок" (при построении графика продаж по товарам); в том случае, если метки со значениями не ассоциированы, в марках выводятся сами значения;

• smsLabelPercent -

показывает метку и процентное значение, например "Сахарный песок 44%";

• smsLabelValue -

показывает метку и значение, например "Сахарный песок 9087";

• smsLegend -

показывает один из элементов легенды графика, список возможных значений доступен через свойство TChartLegend. TextStyle;

• smsPercentTotal -

показывает процентное значение и общую сумму, от которой оно взято, например "44% от 20563".

• smsLabelPercent Total -

показывает метку, процентное число и общую сумму, например "Сахарный песок 44% от 20563";

• smsXValue •

показывает значение по оси Х (XValue), например "01.02.1997";

• property Transparent: Boolean; -

значение True определяет, что цвет фона марки не используется (в качестве фона используется "прозрачный цвет"); по умолчанию False;

property Visible : Boolean;

-определяет, видимы ли (True) или нет (False) марки на графике.

property ParentChart : TCustomChart; -

указывает компонент TDBChart, к которому принадлежит серия. Изменение этого свойства позволяет во время выполнения добавлять в график новые серии, показывать серии в других графиках. Например:

var

MySeries : TBarSeries;

MySeries := TBarSeries.Create(Self);

MySeries.ParentChart := DBChartI;

property PercentFormat : String; -

определяет формат показа процентных значений;

property RecalcOptions: TSeriesRecalcOptions; -

указывает перечень событий, приводящих к пересчету значений серии ( учитывается только для серий, свойство DataSource которых указывает на другую серию) по умолчанию [rOnDelete, rOnModify, rOnInsert, rOnClear],

property SeriesColor: TColor; -

определяет цвет, которым выводятся значения серии в графике. Например:

DBChartI.Series[0].SeriesColor := clBlue;

property ShowInLegend: Boolean; -

определяет, показывать ли (True) легенду или нет (False). по умолчанию True;

property Title: String; -

определяет заголовок серии; по умолчанию заголовок отсутствует, но он может быть назначен в редакторе графика (кнопка Title в окне Series). Например: DBChart1.Series[0].Title := Edit1.Text;

property ValueColor[Index:LongInt]:TColor;

- массив, определяет цвет элемента серии с номером Index, например, DBChart1.Series[0].ValueColor[2] := clAqua;

property ValueFormat: String; -

определяет формат показа значений серии; при прорисовке осей используется для форматирования меток, при прорисовке серии используется для форматирования значений, показываемых в марках;

property ValueMarkTextlIndex:Longint]:String; -

массив значений, выводимых в марках серии;

property VertAxis : TVertAxis; -

определяет местоположение вертикальной оси - слева на графике (aLeftAxis) или справа (aRightAxis);

property XLabel[Index:LongInt]: String; -

массив, хранящий метки серии по оси X; Index должен находиться в диапазоне 0. Count -1;

DBChartI.Series[0].XLabel[2] := Edit2.Text; property XLabelsSource: String; - имя поля НД (или иного источника значений для серии), определяемого в свойстве DataSource. Содержимое этого поля служит для отображения значений по оси X. Поле должно быть типа, к которому применяется метод AsString. Если значение свойства опущено, значения по оси Х не выводятся. Например: DBChartI.Series [0].XLabelsSource := 'MES';

property XValue[Index:LongInt] : Double;

- возвращает значение в списке XValues (см. ниже) с индексом Index (значение в диапазоне 0. Count -1).

property XValues:TChartValueList; -

хранит значения серии по оси X. Значения из этого списка НЕЛЬЗЯ удалять, добавлять и т.д. напрямую. Для этого следует воспользоваться соответствующими методами компонента TChartSeries. Могут быть полезны следующие свойства TCliart ValueList:

• property Valuel Index:LongInt |: Double; -

обеспечивает доступ к элементу серии с индексом Index (значение в диапазоне 0. Count -1). Например:

DBChart1.Series[0].YValues.Value[2] := StrToFloat(Edit3.Text) ;

DBChart1.Series[0].Repaint;

• property ValueSource : String; -

указывает источник данных для формирования значений по оси X. В зависимости от того, каков источник данных для серии (свойство DataSource компонента TChartSeries), может содержать:

1) имя поля - числового типа, типа даты, времени, даты и времени; в этом случае свойство серии DataSource должно ссылаться на НД (TTable, TQuery, TClientDataSet), например:

DBChart1.Series[0].DataSource := Query2;

DBChart1.Series[0].XValues.ValueSource := 'Pole1';

при этом необходимо помнить, что данные будут взяты в серию только из открытого НД; если НД закрыт, то получение данных будет отложено до открытия НД;

2) имя существующего TChart ValueList из другой серии; в этом случае свойство DataSource серии должно ссылаться на другую серию, например:

DBChart1.Series[0].DataSource := DBChart2.Series [4] ;

DBChart1.Series[0].XValues.ValueSource := 'X';

Свойства property YValuetIndex:LongInt]: Double; property YValues: TChartValueList; аналогичны свойствам XValue и XValues и используются для вертикальной оси.



Методы компонента TChartSeries


function AddXY(Const AXValue, AYValue: Double; Const AXLabel: String; ACoIor: TColor): Longint;

Добавляет новую точку в серию. Параметры AXValue и AYValue содержат соответственно значения по осям Х и Y. Параметр AXLabel содержит метку для добавляемой точки серии. Параметр ACoIor определяет цвет. Функция возвращает позицию новой точки в серии. Например:

DbChartl.Series[0].AddXY(TmpX,TmpY,TmpLabel,clAqua) ;

function AddY(Const AYValue: Double; Const AXLabel: String; AColor: TColor): Longint;

добавляет в серию новое значение по оси X. Применяется для тех серий, в которых график строится по Х и меткам значений по Х (например, Pie, Bar). Назначение параметров такое же, как у метода AddXY.

procedure Assign Values(Source: TChartSeries); -

копирует все точки из серии Source в текущую серию.

procedure CheckDataSource; -

обновляет точки в серии, независимо от того, какой компонент является источником данных - набор данных или другая серия. Обновление производится по текущим данным источника. Метод рекомендуется вызывать в случае изменений данных в источнике.

procedure Clear; -

удаляет все значения из серии; если вслед за этим не занести новых точек, будет показываться пустой график.

procedure ColorRange(AValueList: TChartValueList ;Const From Value, To Value: Double; AColor: TColor);

Изменяет цвет указанного диапазона точек серии. AValueList - либо XValues, либо YValues. From Value указывает начальное, а То Value конечное значение в списке AValueList. AColor - новый цвет. Например:

WITH DbChartl.Series[0] do begin

ColorRange(XValues,XValues.Value[2], XValues.Value[2],clAqua) ;

END;//with

function Count : Longint; -

возвращает число точек в серии. Например, поместить все значения по Х и Y точек серии в ListBoxl:

ListBoxl. Items . Clear;

WtTH DbChartl.Series [0] do begin for i := 0 TO Count - 1 do

ListBoxl.Items.Add(

FloatToStr(XValues.Value[i]) + ' ' + FloatToStr(YValues.Value[i])) ;

END;//with

procedure Delete(ValueIndex : Longint); -

удаляет из серии точку с номером ValueIndex. График, к которому принадлежит серия, автоматически перерисовывается. Например: DBChartl.Series[0].Delete(4) ;

procedure DoSeriesClick(ValueIndex:LongInt; Button:TMouseButton; Shift:

TShiftState; X, Y: Integer); virtual; -

инициирует наступление события OnClick.

function GetCursorValueIndex : Longint; -

возвращает индекс точки серии в TChart ValueList, ближе всего к которой расположен курсор мыши. Если такую точку определить не удается, возвращается - 1. Например, в следующем фрагменте Label7.Caption будет содержать индекс ближайшей точки к курсору мыши или '???', если такая точка не определена:

procedure TForm1.DBChartlDblClick(Sender: TObject);

var Tmp : Integer;

begin

Tmp := DBChartl.Series[0].GetCursorValueIndex;

IF Tmp >= 0 THEN Label7.Caption := IntToStr(Tmp)

ELSE Label7.Caption := '???';

end;

procedure GetCursorValues( Var x, у: Double

); - возвращает значения по X и Y точки графика (а не только серии), ближе всего к которой расположен курсор мыши. Например, Label lO.Caption и Labell2.Caption в следующем фрагменте содержат соответственно значения координат Х и Y графика, соответствующие точке, на которой находится курсор мыши:

var TmpX, TmpY : Double;

DBChartl.Series[0].GetCursorVaiues(TmpX,TmpY);

LabellO.Caption := Format('%10.2f,[TmpX]);

Labell2.Caption := Format('%10.2f,[TmpY]);

function GetHorizAxis: TChartAxis; -

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

function GetVertAxis:TChartAxis; -

возвращает указатель на вертикальную ось.

function MaxXValue: Double; virtual; -

возвращает максимальное значение по X.

function MinXValue: Double; virtual; -

возвращает минимальное значение по X.

function MaxYValue: Double; virtual; -

возвращает максимальное значение по Y.

function MinYValue: Double; virtual; -

возвращает минимальное значение по Y.

procedure RefreshSeries; -

обновляет значения серии из источника данных, указанного в свойстве DataSource.

procedure Repaint; -

приводит к полной перерисовке всего графика. Рекомендуется вызывать этот метод в случае изменения хотя бы одного из основополагающих свойств серии (например, при изменении значения в DataSource и др.).

function ValuesListCount:LongInt; -

возвращает число списков значений точки, используемых в серии. Обычно это 2 (XValues и YValues), но некоторые серии используют 3 (BubbleSeries - XValues, YValues, Radius; GanttSeries -Y, Start,End).

function VisibleCount: Longint; -

возвращает число точек серии, видимых на графике.

События компонента TChartSeries


property OnBeforeAdd: TSeriesOnBeforeAdd;

TSeriesOnBeforeAdd = Function(Sender: TChartSeries): Boolean of object;

Наступает перед добавлением точки в серию. В обработчике данного события может производиться анализ корректности добавляемых в серию точек. Наступает также при соединении серии с источником данных (TTable или TQuery).

property OnAfterAdd: TSeriesOnAfterAdd;

TSeriesOnAfterAdd = procedure(Sender:TChartSeries; ValueIndex:Longint) of object;

Происходит после добавления точки в серию.

property OnClear Values: TSeriesOnClear;

TSeriesOnClear = procedure(Sender: TChartSeries) of object;

Происходит при очистке серии от точек.

property OnClick: TSeriesClick;

TSeriesClick = procedure(Sender:TChartSeries; ValueIndex: Longint; Button:

TMouseButton; Shift: TShiftState; X, Y: Integer);

Происходит при щелчке мышью на серии.

property OnGetMarkText: TSeriesOnGetMarkText;

TSeriesOnGetMarkText = procedure ( Sender : TChartSeries ; ValueIndex :

Longint; Var MarkText: String)

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