Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник Емельянов.doc
Скачиваний:
12
Добавлен:
03.11.2018
Размер:
3.25 Mб
Скачать

Оператор with

Оператор With часто называется оператором присоединения. Для того чтобы не записывать каждый раз имя селектора, при обращении к поля*1 записи используется этот оператор, например,

With Data do begin

78

Таблица 12

Табельный

ФИО

Окл., Т.е.

Час

Дни

Дни граф.

3

П

И

1

Иванов ИИ.

6000

176

22

24

2

Петров П. П.

40

184

23

24

В данном случае заданы два варианта расчета зарплаты: по окладу (Окл. = 6000) и по часовой тарифной ставке (Т.е. = 40). В первом случае зарплата расчитывается следующим образом: 3 =

Во втором случае необходимо использовать такие соотношения: 3 = Т.с.Час;Час<8-Дни.

Указанные ограничения в формулах означают, что, если сотрудник отра­ботал больше, чем по графику, то это сверхурочные, которые оплачиваются отдельно (в примере сверхурочные не учитываются). Используемая во вто­ром случае цифра 8 означает, что задан восьмичасовой рабочий день.

Предусмотрена премия не более 150 % от зарплаты, которая выплачива­ется, если предприятие имеет прибыль. Форма с вариантом решения приво­дится на рис. 30.

Рис-30

решается в 2 этапа: вначале - ввод информации (можно изменить исходные данные), затем - расчет.

Как и в предыдущих случаях, в данном примере использовались новые лоненты. Для указания, есть ли премия в данном месяце, необходим пе-

79

реключатель. При решении примера 10 использовался переключатель см зависимой фиксацией TCheckBox. Этот стандартный элемент Windows зволяет выбрать или отменить определенную опцию. С помощью групД таких переключателей можно выбирать или отключать несколько опций on. новременно. Состояние переключателя (вкл/выкл) содержится в свойств Checked. Для обработки переключений используется событие OnClick Кнопку можно перевести в третье состояние ("включенное серое") с иощ щью свойства AllowGrayed. Это свойство используется, если переключатеЯ содержит еще ряд вложенных переключателей. Третье состояние перекли чателя указывает, что вложенные опции не все включены или не все выкли чены. Узнать, включено ли свойство AllowGrayed, можно с помощью свойства State.

Для полноты представления проблемы рассмотрим еще один вид пере-ключателей - переключатель с зависимой фиксацией - TradioButton. Эта вид переключателей в примере 9 уже использовался, но в составе группа Если выбрано несколько таких переключателей, то они автоматически объе диняются в группу и позволяют из множества опций выбрать одну, в отЛ чие от CheckBox. TradioButton также имеет свойство Checked и событие OkClick, свойство AllowGrayed отсутствует.

Для представления табличных данных использовалась графическая таб­лица TDrawGrid, которая, в отличие от TStringGrid, может отображать не только текстовую информацию, но и графическую. TDrawGrid имеет значительно больше возможностей, чем TStringGrid. Например, размеры строк и столбцов можно изменять индивидуально. Можно изменять и цвет ячеек (индивидуально). Внешний вид графической сетки настраивается с помощью следующих свойств: ColCount, RowCount - число столбцов и строк; DefaultCoIWidth, DefauttRowHeight - высота и ширина по умолчанию; Height, Width - ширина и высота таблицы; FixedColls, FixedRows - фикси­рованное число столбцов и строк. Индивидуальные размеры строк и столб­цов содержатся в свойствах ColWidth и RowHeight. Эти свойства являются массивами. Отметим несколько опций свойства Options: GoRowSizing -разрешить или запретить изменение размеров строк, GoColSizing - разре­шить или запретить изменение размеров столбцов, GoEditing - разрешить или не разрешить редактирование, GoAIwaysShowEditor - если эта опция отключена, то редактор загружается клавишей F2 или щелчком мыши, если эта опция включена, то редактор загружается автоматически. В отличие от TStringGrid, TDrawGrid не имеет свойства Cells (ячейки), поэтому ввод дан­ных и их запись после редактирования нужно организовывать самостоятель­но. Для отображения данных необходимо воспользоваться событие*1 OnDrawCell - перерисовка ячеек. При перерисовке ячеек область рисований (в пикселах) задается в виде свойства Rect (прямоугольник). Свойство Rec* преобразует номера колонки и строки в прямоугольник, заданный в пиксе*

Перерисовка ячейки зависит от свойства State (состояние), которое может иметь следующие значения: gdSelected - ячейка выбрана; gdFocused -*а ячейке находится фокус; gdFixed - зафиксированная ячейка (заголовок). Лпя рисования в DrawGrid имеется свойство TCanvas. Для задания прямо-гольника существует метод CellRect, который в соответствии с аргумента­ми- номером столбца и номером строки - задает координаты области рисо­вания в пикселах. Событие OnSelectCell позволяет индивидуально запретить или разрешить передачу фокуса какой-либо ячейке внутри таблицы. Для организации ввода данных используется событие OnGetEditText. Для фик­сирования изменений после ввода (после редактирования) используется со­бытие OnSetEditText.

На форме (см. рис. 30) выбраны такие значения для некоторых свойств DrawGrid: ColCount = 9, RowCount - 3, Options: goColSizing = true, goEditing = true, goAlwaysShowEditor = True, DefaultDrawing = False. Последнее свой­ство может отключать событие OnDrawCell, включая прорисовку по умол­чанию.

В данном примере необходимо реализовать несколько обработчиков со­бытий:

  • OnClick-запуск рисования ячеек;

  • OnDrawCell - перерисовка ячеек;

  • OnGetEditText - вызов редактора ввода данных в ячейки;

  • OnSetEditText - запись информации после ввода;

  • OnKeyPress - ограничение (фильтр) ввода;

  • OnSelectCell - ограничение доступа к некоторым ячейкам.

  • При выполнении приложения наступает момент, когда форма рисуется на экране. Ответствен за этот процесс обработчик OnCreate, который вызы­вается автоматически. Можно дополнять код этого обработчика. В данном случае предусмотрим дополнительный код изменения ширины столбцов для DrawGrid.

  • С помощью Button 1 предусмотрим обработчик, задающий начало рас­чета (OnClick).

  • Для Edit1 необходим OnKeyPress.

  • Для Edit1 необходим OnExit, чтобы контролировать ввод числа (не бо­лее 150) по условию задачи.

  • Для CheckBoxl организуем обработчик при потере фокуса этим эле­ ментом (OnExit) и передаче фокуса или Edit1 или DrawGridl (обход Edit1).

Для записи результатов ввода и итоговых результатов предусмотрим Двумерный массив Field, который должен объявляться глобально. Размеры Массива [0...2], [0...8] - 3 строки и 9 столбцов. Для выполнения всех расчетов воспользуемся типом данных запись. Ниже приводится программа.

unit primlO; interface

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, Buttons, StdCtrls, ExtCtrls;1 type TMainForm = class(TForm)

Panel1: TPanel;

Button1: TButton;

BitBtnl: TBitBtn;

DrawGridl: TDrawGrid;

CheckBoxl: TCheckBox;

Edit1: TEdit;

Label1: TLabel;

procedure DrawGridlDrawCell(Sender: TObject; ACol,

ARow: Integer; Rect: TRect; State: TGridDrawState); procedure DrawGridlGetEditText(Sender: TObject;

ACol, ARow: Integer; var Value: String); procedure DrawGridlClick(Sender: TObject); procedure FormCreate(Sender: TObject);

procedure DrawGridlSetEditText(Sender: TObj ect;

ACol, ARow: Integer;const Value: String); procedure DrawGridlSelectCell(Sender: TObject; ACol, ARow: Integer;var CanSelect: Boolean); procedure DrawGridlKeyPress (Sender: TObject;

var Key: Char);

procedure CheckBoxlExit(Sender: TObject); procedure Edit1KeyPress(Sender: TObject;

var Key: Char)

procedure Button1Click(Sender: TObject); end;

0..8] of string =(('Ta6N' , 'Дней','Дн.г.','Зарпл', ','Иванов И.И.','6000', ','0'),('2','Петров П.П.,

0 ' , ' 0 ', ' 0 ') ) ;

var MainForm: TMainForm; const Field: array [0..2, 'Ф.И.О.','Окл,Т','Час,

Премия','Итого') , ('1 476','22','24', '0', '0’, ‘О' , 484' , '23', '24', implementation

{$R *.DFM)

procedure TMainForm.DrawGridlDrawCell(Sender: TObject;

ACol, ARow: Integer;Rect: TRect; State: TGridDrawState); var i,j:byte; begin

With DrawGridl do

for j:=0 to RowCount-1 do begin if j=0 then Canvas.Brush.Color:=clBtnFace

else Canvas.Brush.Color:=clWindow; for i:=0 to ColCount-1 do begin Rect:=CellRect(i,j); with Canvas,Rect do TextRect(Rect,Left+(Right-

82

Left-TextWidth(Field[j,i])) div 2,Top+(Bottom-Top-TextHeight(Field[j,i])) div 2,Field[j,i]); end;

end;

end;

procedure TMainForm.DrawGridlGetEditText(Sender:TObj ect; ACol, ARow: Integer;var Value: String);

begin

Value:=Field[ARow,ACol] ;

end;

procedure TMainForm.DrawGridlClick(Sender: TObject);

begin

with DrawGridl do begin

DrawGridlDrawCell(Sender,0,0,CellRect(0,0), [gdFixed]); DrawGridlDrawCell(Sender, 0,1,CellRect(0,1),

[gdSelected,gdFocused]) ; DrawGridlDrawCell(Sender,0,2,CellRect(0,2),

[gdSelected,gdFocused] ) ; end;

end;

procedure TMainForm.FormCreate(Sender: TObject);

var i:byte; begin

with DrawGridl do

for i:=0 to ColCount-1 do case i of

0,2: ColWidths[i]:=40; 1: ColWidths[i]:=90; 3..5:ColWidths[i]:=36; else ColWidths[i]:=57; end; end;

procedure TMainForm.DrawGridlSetEditText(Sender: TObject; ACol, ARow: Integer;const Value: String);

begin

if (ARow = 1) and (ACol <> 3) or (ARow = 2) and (ACol <> 4)

then Field[ARow,ACol]:=Value; if (ARow = 1) and (ACol = 4) then

if Length(Value) > 0 then Field[ARow,3]:=

IntToStr(StrToInt(Value)*8); •if (ARow = 2) and (ACol = 3) then

if Length(Value) > 0 then Field[ARow,4]:=

IntToStr(round(StrToInt(Value)/8));

end;

procedure TMainForm.DrawGridlSelectCell(Sender: TObject;

ACol, ARow: Integer;var CanSelect: Boolean); begin

CanSelect:=true;

83

with DrawGridl do

if (ARow - 1) or (ARow = 2) then

if ACol in [0,5..8] then CanSelect:=false; end; procedure TMainForm.DrawGridlKeyPress(Sender: TObject;

var Key: Char); begin

with DrawGrid1 do

if Row > 0 then begin

if (Col - 2) and (not (key in ['0'..’9’, '.',#8]))

then key:=#0; if ((Col = 3) or (Col = 4))and(not

(key in [' 0 ' . . '9',#8])) then key:=#0; end; end;

procedure TMainForm.CheckBoxlExit(Sender: TObject); begin

if CheckBoxl.Checked then Edit1.SetFocus

else DrawGridl.SetFocus; end; procedure TMainForm.Edit1KeyPress(Sender: TObject;

var Key: Char); begin

if not (key in ['0'..'91,'.',#8]) thenkey:=#0; end;

procedure TMainForm.Edit1Exit(Sender: TObject); begin

if Length(Edit1.Text)=O then Edit1.Text:=T0.0'; if (StrToFloat(Edit1.Text)=0.0> or (StrToFloat{Edit1.Text)>150.0) then if Application.MessageBox('Введите % премии', 'Число <= 150',MB_OK)=IDOK then Edit1.SetFocus; end;

procedure TMainForm.Button1Click(Sender: TObject); type rec=record

tbn: word; fio: string[20]; okl: Currency; ch,dn,dng: word; zp,pr,it: Currency;

end; var z:array [1..2] of rec;

i:byte; begin

for i:=l to 2 do begin with z [i] do begin

tbn:=StrToInt(Field[i,0]); fio:=Field[i,l];

84

okl:=StrToFloat(Field[i,2]); ch:= StrToInt(Field[i,3]); dn:= StrToInt(Field[i,4]); dng:=StrToInt(Field[i,5]); if i = 1 then

if dng <> 0 then zp:=okl*dn/dng else zp:=0

else if ch>dng*8 then zp:=okl*dng*8

else zp:=okl*ch;

Field[i,6]:=FormatFloat('0.00',zp); if CheckBoxl.Checked then

pr:=StrToFloat(Edit1.Text)*zp/100 else pr:=0.0;

Field[i,7]:=FormatFloat('0.00',pr) ;

It:=zp-t-pr;

Field[i,8]:=FormatFloat('0.00',it); with DrawGridl do DrawGridlDrawCell(Sender,0,i,

CellRect(0,i), [gdSelected,gdFocused]); end; end;

BitBtnl.SetFocus; end; end.

Обработчик событий onSetEditText содержит три оператора. Первый оператор не позволяет изменить количество часов для табельного номера 1 (оно связано с количеством отработанных дней) или количество дней для второго сотрудника (оно связано с количеством отработанных часов). Вто­рой оператор изменяет количество часов, если количество дней изменено пользователем. Третий оператор служит тем же целям, что и второй, - изме­няет количество дней для табельного номера 2. Обработчик OnSelectCell запрещает при вводе выбор ячеек, находящихся в столбцах 0, 5, 6, 7, 8.

СОВМЕСТИМОСТЬ И ПРЕОБРАЗОВАНИЕ ТИПОВ ДАННЫХ

Когда в тех или иных операциях или операторах присутствуют данные Различных типов, то возникают вопросы о соответствии типов друг другу. Стандартно выделяют три группы вопросов:

•идентичность типов;

•совместимость типов;

•совместимость по присваиванию.

85