

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
Событие |
Описание |
|
|
TGridDrawState = set of (gdSelected, |
Возникает при необходимости перерисовать |
gdFocused, gdFixed); |
ячейку с табличными координатами (Col, |
TDrawCellEvent = procedure (Sender: |
Row): Rect – прямоугольник прорисовки; |
TObject; Col, Row: LongInt; Rect: TRect; |
State – состояние ячейки (gdSelected – ячейка |
State; TGridDrawState) of object; |
выделена; gdFocused – ячейка имеет фокус |
property OnDrawCell: TDrawCellEvent; |
ввода; gdFixed – ячейка принадлежит |
|
фиксированной зоне таблицы). Для |
|
прорисовки используется табличное свойство |
|
Canvas |
TGetEditEvent = procedure (Sender: |
Возникает при редактировании текста в |
TObject; ACol, ARow: LongInt; var Value: |
ячейке с табличными координатами (ACol, |
String) of object; |
ARow). В параметре Value обработчик |
property OnGetEditMask: TGetEditEvent; |
должен вернуть шаблон для компонента |
|
TEditMask |
property OnGetEditText; TGetEditEvent; |
Возникает при редактировании текста в |
|
ячейке с табличными координатами (ACol, |
|
ARow). В параметре Value обработчик |
|
должен вернуть текст для компонента |
|
TEditMask. |
property OnRowMoved: TMovedEvent; |
Возникает при перемещении строки с |
|
индексом FromIndex в положение, |
|
определяемое индексом ToIndex |
SelectCellEvent = procedure (Sender: |
Возникает при попытке выделить ячейку с |
TObject; Col, Row: LongInt; var CanSelect: |
табличными координатами (Col, Row). В |
Boolean) of object; |
параметре CanSelect обработчик сообщает о |
property OnSelectCell: TSelectCellEvent; |
возможности выделения ячейки |
TSetEditEvent = procedure (Sender: |
Возникает при завершении редактирования |
TObject; ACol, ARow: LongInt; const Value: ячейки (ACol, ARow). В параметре Value |
|
String) of object; |
обработчик получает результат ввода или |
property OnSetEditText: TSetEditEvent; |
редактирования текста |
property OnTopLeftChanged: TNotifyEvent; Возникает после изменения значения TopRow
или LeftCol в результате прокрутки рабочей зоны
Рассмотрим несколько типичных применений компонента TStringGrid.
Ввод значений векторов и матриц
Для ввода таких данных как векторы и матрицы удобно использовать таблицы. Рассмотрим пример программы для обработки данных векторов. Создайте новый проект.
На форму frmVectorsDemo поместите три компонента TStringGrid (sgrFirst, sgrSecond, sgrResult) и два компонента TBitBtn (btnExit, btnCalc). Установите следующие свойства для компонентов sgrFirst, sgrSecond, sgrResult: BorderStyle=bsNone; RowCount=1; FixedCols=0; FixedRows=0; ScrollBars=ssNone. Установите значение свойства
Options.goEditing=True. Установите значение свойства Kind компонента btnExit равным bkClose. Расположите компоненты как показано на рисунке 8.

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
Рисунок 8 – Вид формы после настройки компонентов.
Векторы будем описывать с помощью одномерного массива.
type TVector = array [0..2] of real;
Для записи и чтения значений компонентов вектора из таблицы введем два метода в форму
//загрузка данных из вектора в таблицу
procedure LoadData(Table:TStringGrid; AVector:TVector); //загрузка данных из таблицы в вектор
procedure SaveData(Table:TStringGrid; var AVector:TVector);
Для сложения векторов служит метод
//сложение векторов
procedure Add(AV1, AV2:TVector; var AV3:TVector);
Создайте обработчики событий для кнопок. Код программы не сложен для понимания. Полный листинг программы приведен в листинге 1.
Листинг 1 – Программа для сложения двух векторов
unit UDemoVectors;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, Grids;
type TVector=array[0..2] of real;
type
TfrmVectorsDemo = class(TForm) sgrFirst: TStringGrid; sgrSecond: TStringGrid; sgrResult: TStringGrid; btnExit: TBitBtn;
btnCalc: TBitBtn;
procedure FormCreate(Sender: TObject); procedure btnCalcClick(Sender: TObject);
private
{Private declarations } public
{Public declarations }
//загрузка данных из вектора в таблицу
procedure LoadData(Table:TStringGrid; AVector:TVector); //загрузка данных из таблицы в вектор
procedure SaveData(Table:TStringGrid; var AVector:TVector);

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
//сложение векторов
procedure Add(AV1, AV2:TVector; var AV3:TVector); end;
var frmVectorsDemo: TfrmVectorsDemo;
implementation
{$R *.dfm}
var V1, V2, V3:TVector;
{ TfrmVectorsDemo }
procedure TfrmVectorsDemo.LoadData(Table: TStringGrid; AVector: TVector);
var i:Integer; begin
//устанавливаем число колонок в таблице равным числу //компонентов вектора
Table.ColCount:=High(AVector)+1;
//заполняем таблицу
for i:=0 to High(AVector)+1 do
Table.Cells[i, 0]:=FloatToStrF(AVector[i], ffFixed, 3, 2); end;
procedure TfrmVectorsDemo.SaveData(Table: TStringGrid; var AVector: TVector);
var i:Integer; begin
//заполняем вектор
for i:=0 to Table.ColCount-1 do AVector[i]:=StrToFloat(Table.Cells[i, 0]);
end;
procedure TfrmVectorsDemo.FormCreate(Sender: TObject); begin
//записываем в таблицы начальные значения
LoadData(sgrFirst, V1);
LoadData(sgrSecond, V2);
LoadData(sgrResult, V3); end;
procedure TfrmVectorsDemo.btnCalcClick(Sender: TObject); begin
//считываем введенные значения двух векторов
SaveData(sgrFirst, V1);
SaveData(sgrSecond, V2); //выполняем операцию сложения
Add(V1, V2, V3); //выводим результат
LoadData(sgrResult, V3); end;
procedure TfrmVectorsDemo.Add(AV1, AV2: TVector; var AV3: TVector);
var i:Integer; begin
for i:=0 to High(V1) do AV3[i]:=AV1[i]+AV2[i];

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
end;
end.
Запустите программу, проверьте ее работоспособность.
Вывод данных таблиц
Рассмотрим еще один пример на применение компонента TStringGrid. Следующий пример посвящен выводу табличных данных. Рассмотрим пример вывода таблицы содержащей список группы. Создайте новый проект. Поместите на форму frmGroupList два компонента TPanel (pnTable, pnCommandBar). Установите значение свойства Align компонента pnTable равным alLeft. Поместите на форму компонент TSplitter (VSplitter). Установите значение свойства Align компонента pnCommandBar равным alClient.
Поместите на панель pnTable компонент TStringGrid (sgrTable). Установите значение свойства Align этого компонента равным alClient. Разрешите редактирование таблицы установив флаг Options.goEditing.
Поместите на панель pnCommandBar два компонента TBitBtn (btnExit, btnLoad).
Установите значение свойства Kind компонента btnExit равным bkClose. Настройте вид компонентов как показано на рисунке 9.
Рисунок 9 – Вид формы после настройки всех компонентов
Будем хранить список группы в текстовом файле в формате CVS. Сохранить табличные данные в этот формат можно например из MS Excel или набрать их в любом текстовом редакторе. Формат CVS очень прост, одна строка таблицы представляет собой одну строку текстового файла, данные столбцов внутри строки разделяются с помощью символа «;». Обработчик события для кнопки btnLoad для чтения файла этого формата приведен ниже.
Листинг 2
procedure TfrmGroupList.btnLoadClick(Sender: TObject); var F:TextFile;
buf :String; RowIndex, ColIndex:Integer;
begin

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
//рисуем заголовок таблицы with sgrTable do
begin
ColWidths[0]:=20; //ширина первого столбца равна 20 Cells[0, 0]:='№';
Cells[1, 0]:='Фамилия'; Cells[2, 0]:='Имя'; Cells[3, 0]:='Отчество';
end;
RowIndex:=1;
try
AssignFile(F, 'GroupList.txt'); Reset(F);
while not EOF(F) do begin
//выводим порядковый номер строки sgrTable.Cells[0, RowIndex]:=IntToStr(RowIndex); //считываем очередную строку из файла
readln(F, buf);
//добавляется точка с запятой в конец строки buf:=buf+';';
//извлекаем очередной столбец из строки
ColIndex:=1;
while pos(';', buf)<>0 do begin
sgrTable.Cells[ColIndex, RowIndex]:=Copy(Buf, 1,
pos(';', buf)-1);
Delete(Buf, 1, pos(';', buf)); ColIndex:=ColIndex+1;
end;
//увеличиваем счетчик строк
RowIndex:=RowIndex+1;
//если число строк таблице недостаточно, то увеличиваем его if sgrTable.RowCount<RowIndex then
sgrTable.RowCount:=sgrTable.RowCount+1;
end;
finally CloseFile(F);
end;
end;
Запустите программу и проверьте ее работоспособность. Вид окна работающей программы приведен на рисунке 10.

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
Рисунок 10 – Вид окна «Список группы»
Для улучшения удобочитаемости часто фон в таблице для различных строк делается разного (обычно контрастного) цвета. Ниже приведем пример программы для реализации этой функции.
Компонент TStringGrid содержит событие OnDrawCell (см. таблицу 6) которое возникает каждый раз при прорисовке ячейки. Воспользуется этим событием для нестандартной прорисовки таблицы.
TGridDrawState = set of (gdSelected, gdFocused, gdFixed); TDrawCellEvent = procedure (Sender: TObject; Col, Row: LongInt; Rect: TRect; State; TGridDrawState) of object;
property OnDrawCell: TDrawCellEvent;
Параметр State содержит состояние текущей прорисовываемой ячейки
−gdSelected –ячейка выделена;
−gdFocuced – ячейка имеет фокус ввода;
−gdFixed – ячейка заголовка.
Параметры Col, Row – содержат табличные координаты прорисовываемой ячейки. Параметр Rect содержит прямоугольник для прорисовки текущей ячейки. Обработчик события для создания полосатой таблицы приведен ниже.
Листинг 3
procedure TfrmGroupList.sgrTableDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
with sgrTable.Canvas do begin
//если ячейка заголовка
if gdFixed in State then Brush.Color:=clGray else //если ячейка рабочей области
//рисуем нечетные строки белым, а четные желтым if (ARow mod 2)<>0 then Brush.Color:=clWhite
else Brush.Color:=clYellow; //если ячейка выделена