Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
_Delphi_1курс лекции / Тема 06 Таблицы строк.doc
Скачиваний:
63
Добавлен:
23.03.2015
Размер:
180.74 Кб
Скачать

Листинг 2. Процедура обработки события OnKeyPress

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);

begin

case Key of

#8,'0'..'9' : ; // цифры и <Back Space>

#13: // <Enter>

if StringGrid1.Col < StringGrid1.ColCount – 1 then

StringGrid1.Col := StringGrid1.Col + 1

else

if StringGrid1.Row < StringGrid1.RowCount – 1 then

begin

StringGrid1.Row:= StringGrid1.Row+1 ;

StringGrid1.Col := StringGrid1.FixedCols;

end;

else Key:=Chr(0);

end;

end;

Этот обработчик позволяет вводить целые положительные числа в компонент StringGrid и при нажатии клавиши <Enter> осуществляет перход в следующую ячейку. Обратите внимание, что обработчик может быть использован для двумерного массива. В этом случае если пользователь нажал клавишу <Enter>, находясь в последней ячейке строки, осуществляется переход в первую ячейку рабочей области на следующей строке. Если же вы планируете работать с одномерным массивом, то ветку else оператора if следует опустить.

Задание. Ввод массива из компонента StringGrid оформите в виде отдельной процедуры. Внесите

необходимые изменения в обработчик нажатия кнопки.

Если нужно ввести массив дробных чисел (a: array [1. .5] of real), то процедура обработки события OnKeyPress несколько усложнится, т. к. помимо цифр допустимыми символами являются символ-разделитель (запятая или точка — зависит от настройки Windows) и минус. С целью обеспечения некоторой дружественности программы по отношению к пользователю можно применить трюк: подменить вводимый пользователем неверный разделитель верным. Определить, какой символ-разделитель допустим в текущей настройке Windows, можно, обратившись к глобальной переменной Decimaiseparator.

В листинге 3 приведен текст модуля приложения ввода и обработки массива дробных чисел. Процедура обработки события OnKeyPress обеспечивает ввод в ячейку таблицы только допустимых при записи дробного числа символов.

Листинг 3. Ввод и обработка массива дробных чисел

unit getar_1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, Grids, StdCtrls;

const n=5;

type

TIntArr = array[1..n] of integer;

TForm1 = class(TForm)

Label1: TLabel;

StringGrid1: TStringGrid;

Button1: TButton;

Label2: TLabel;

procedure Button1Click(Sender: TObject);

procedure StringGrid1KeyPress(Sender: TObject; var Key: Char);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

A : TIntArr;

implementation

{$R *.dfm}

// Процедура обработки массива

procedure CalcArr(A: array of real; var s, sr : real);

var

i : integer;

begin

s:=0;

for i:=low(A) to high(A) do

s := s + A[i];

sr := s / length(A);

end;

procedure TForm1.Button1Click(Sender: TObject);

var

summ: real; // сумма элементов

sr: real; // среднее арифметическое

i: integer; // индекс

begin

// ввод массива

// считаем, что если ячейка пустая, то соответствующий

// ей элемент массива равен нулю

for i:= 1 to StringGrid1.ColCount do

begin

if StringGrid1.Cells[i-1,0] = ''

then

StringGrid1.Cells[i-1,0]:='0';

A[i] := StrToFloat(StringGrid1.Cells[i-1,0])

end;

CalcArr(A,summ,sr);

// вывод результата

Label2.Caption :=

'Сумма элементов: ' + FloatToStr(summ) + #13+

'Среднее арифметическое: ' + FloatToStr(sr);

end;

// Функция обеспечивает ввод в ячейку только допустимых символов

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);

begin

case Key of

#8,'0'..'9' : ; // цифры и <Back Space>

#13: // клавиша <Enter>

if StringGrid1.Col < StringGrid1.ColCount – 1 then

StringGrid1.Col := StringGrid1.Col + 1

else

if StringGrid1.Row < StringGrid1.RowCount – 1 then

begin

StringGrid1.Row:= StringGrid1.Row+1 ;

StringGrid1.Col := StringGrid1.FixedCols;

end;

'.',',': // разделитель целой и дробной частей числа

begin

Key := DecimalSeparator; // заменим разделитель на допустимый

if Pos(DecimalSeparator , StringGrid1.Cells[StringGrid1.Col,0]) <> 0

then Key := Chr(0); // запрет ввода второго разделителя

end;

'-': // минус можно ввести только первым символом,

// т.е. когда ячейка пустая

if Length(StringGrid1.Cells[StringGrid1.Col,0]) <> 0

then Key := Chr(0);

else // остальные символы запрещены

key := Chr(0);

end;

end;

end.

В приведенных примерах размерность массива была известна заранее. Часто размерность массива на этапе проектирования неизвестна и/или может меняться в процессе работы. В этих случаях целесообразно использовать не статические, а динамические массивы.

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

Рис.2

Установим у SpinEdit значения свойств MinValue=1 и MaxValue=100. Для кнопки зададим Name=btnSetDim. В разделе implementation опишем тип TRealVector для работы с динамическим массивом вещественных чисел и глобальную переменную VectCount для хранения количества элементов в массиве. В обработчике создания формы зададим начальное значение для переменной VectCount =5.

В листинге 4 приведен фрагмент модуля обработки массива вещественных чисел с заданием его размерности. Обработчик OnKeyPress для StringGrid в этом примере такой же как в предыдущем, и в листинге не приводится. Жирным шрифтом выделены фрагменты кода в которых листинги 3 и 4 отличаются.

Листинг 4. Ввод и обработка массива изменяемой размерности

type

TRealVector=array of real;

var

Form1: TForm1;

VectCount : integer;

A : TRealVector;

implementation

{$R *.dfm}

// Процедура обработки массива

procedure CalcArr(A:TRealVector ; var s, sr : real);

var

i : integer;

begin

s:=0;

for i:=low(A) to high(A) do

s := s + A[i];

sr := s / length(A);

end;

procedure TForm1.Button1Click(Sender: TObject);

var

summ: real; // сумма элементов

sr: real; // среднее арифметическое

i: integer; // индекс

begin

// ввод массива

// считаем, что если ячейка пустая, то соответствующий

// ей элемент массива равен нулю

SetLength(a,VectCount);

for i:= 0 to StringGrid1.ColCount -1 do

begin

if StringGrid1.Cells[i,0]=''

then

StringGrid1.Cells[i,0]:='0';

A[i] := StrToFloat(StringGrid1.Cells[i,0])

end;

CalcArr(A,summ,sr);

// вывод результата

Label2.Caption :=

'Сумма элементов: ' + FloatToStr(summ) + #13+

'Среднее арифметическое: ' + FloatToStr(sr);

end;

procedure TForm1.btnSetDimClick(Sender: TObject);

var

i: integer;

begin

StringGrid1.ColCount:=SpinEdit1.Value;

VectCount:= SpinEdit1.Value;

if StringGrid1.ColCount>5 then StringGrid1.Height:=48 // для полосы прокрутки

else StringGrid1.Height:=24;

for i:=0 to StringGrid1.ColCount do StringGrid1.Cells[i,0]:='';

Label2.Caption := '';

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

VectCount:=5;

end;

end.

Задание. Ввод массива из компонента StringGrid оформите в виде отдельной процедуры. Внесите

необходимые изменения в обработчик нажатия кнопки.