TURBO PASCAL |
Новости
|
Редактирование и добавление записей
Для редактирования и добавления записей создадим окно, показанное на рис. 15.11. Режим редактирования отличается от режима добавления записей двумя обстоятельствами: во-первых, в режиме редактирования поля ввода данных окна должны содержать текст, взятый из редактируемой записи, а в режиме ввода эти поля пусты. Во-вторых, режим редактирования завершается сразу после нажатия на клавишу Enter, в то время как в режиме ввода нажатие на эту клавишу означает добавление к файлу текущей записи и переход к вводу следующей: режим ввода завершается командой cmClose (клавиша Esc). С учетом этого оба режима реализуются в рамках одной процедуры AddItem (Edit), а параметр Edit указывает нужный режим: если Edit = True, реализуется режим редактирования, если False - режим добавления записей. Вот текст этой процедуры: Рис.15.11. Окно ввода/редактирования записей Procedure AddItem(Edit: Boolean); {Добавляет новый или редактирует старый элемент данных} const у = 1; dy= 2; L -= LName+LPhone+LAddr; var Data: DataType; R: TRect; InWin: PDialog; BName,BPhone,BAddr: PInputLine; Control: Word; OldCount: Word; s: String; р: PString; begin Seek(DataFile,FileSize(DataFile));{Добавляем записи в конец файла} repeat {Цикл ввода записей} if Edit then {Готовим заголовок} s := 'Редактирование:' else begin Str(FileSize(DataFile)+1,s); while Length(s) < 3 do s := '0'+s; s :- 'Вводится запись N '+s end; FillChar(Data,SizeOf(Data),' ');{Заполняем поля пробелами} R.Assign(15,5,65,16) ; InWin := New(PDialog, Init(R, s));{Создаем окно} with InWin do begin{Формируем окно:} R.Assign(2,y+1,2+LName,y+2); BName := New(PInputLine, Init(R,LName)); Insert(BName); {Поле имени} R.Assign(2,y,2+LName,y+1); Insert(New(PLabel, Init(R, 'Имя',BName))); R.Assign(2,y+dy+1,2+LPhone,y+dy+2); BPhone := New(PInputLine, Init(R,LPhone)); Insert(BPhone); {Поле телефона} R.Assign (2,y+dy, 2+LPhone,y+dy+1) ; Insert (New(PLabel,. Init(R, 'Телефон',BPhone))); R.Assign(2,y+2*dy+1,2+LAddr,y+2*dy+2); BAddr := New(PInputLine, Init(R,LAddr)); Insert(BAddr); {Поле адреса} R.Assign(2,y+2*dy,2+LAddr,y+2*dy+1); Insert(New(PLabel, Init(R, 'Адрес',BAddr))); {Вставляем две командные кнопки:} R.Assign(2,y+3*dy+1,12,y+3*dy+3); Insert(New(PButton, Init(R, 'Ввести',cmOK,bfDefault))); R.Assign(2+20,y+3*dy+1,12+20,y+3*dy+3); Insert(New(PButton, Init(R, 'Выход',cmCancel,bfNormal))); SelectNext(False) {Активизируем первую кнопку} end; {Конец формирования окна} if Edit then with Data do begin {Готовим начальный текст:} р :=PS.At(Location); {Читаем данные из записи) S:=p; Name := copy(s,1,LName); Phone:= copy(s,succ(LName),LPhone); Addr := copy(s,succ(LName+LPhone),LAddr); InWin.SetData(Data) {Вставляем текст в поля ввода} end; Control := DeskTop.ExecView(InWin); {Выполняем диалог} if Control=cmOk then with Data do begin if Edit then DeleteItem; {Удаляем старую запись} Name := BName.Data; Phone:= BPhone.Data; Addr := BAddr.Data; s[0] := chr(L) ; FillChar(s[1],L,' '); move(Name[1],s[1],Length(Name)) ; move(Phone[1],s[succ(LName)],Length(Phone)); move(Addr[1],s[succ(LName+LPhone)],Length(Addr)); OldCount := PS.Count; {Прежнее количество записей} РS.insert(NewStr(s)); {Добавляемв коллекцию} {Проверяем добавление} if OldCount <> РS.Count then Write(DataFile,Data) {Да - добавляем в файл} end until Edit or (Control=cmCancel); Draw end; {AddItem} Вначале указатель файла смещается в самый конец, подготавливая добавление записей (судя по всему, режим добавления будет использоваться гораздо чаще, чем режим редактирования). Затем формируется заголовок окна и само окно. Операторы if Edit then with Data do begin {Готовим начальный текст:} ....... end; готовят начальное состояние полей ввода в режиме редактирования. Оператор InWin. SetData (Data) помещает подготовленный текст в нужные поля. При обращении к процедуре SetData данные должны быть предварительно подготовлены в строгом соответствии с порядком создания диалоговых полей в окне и типом их данных. Поскольку в нашем случае формат данных в полях ввода окна совпадает с форматом файловых данных, мы можем использовать одну и ту же переменную как для работы с файлом, так и для установки начальных значений диалоговых полей. В самом общем случае пользователь должен объявить новый тип, соответствующий формату помещаемых в окно данных, и использовать выражение этого типа в качестве параметра обращения к процедуре SetData. Например, если бы в нашем окне было предусмотрено только одно поле ввода «Телефон», то установку данных можно было бы осуществить таким оператором: InWin. SetData (DataType . Phone) где DataType.Phone - выражение типа String [LPhone]. Контроль за соответствием типа устанавливаемых данных порядку объявления и типу данных диалоговых полей полностью возлагается на программиста. В операторах if Control=cmOk then with Data do begin ..... end данные, полученные из диалогового окна, помещаются сначала в отсортированную коллекцию, а затем - в файл. С помощью оператора if OldCount <>PS. Count then проверяется изменение количества данных в коллекции (напомню, что в отсортированную коллекцию можно поместить только уникальную запись). Если количество записей в коллекции изменилось, значит новая запись не совпадает ни с одной из уже имеющихся и ее следует поместить в файл. Операторы if Edit then DeleteItem; {Удаляем старую запись} предварительно удаляют старую запись с помощью обращения к процедуре DeleteItem.
|
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |