Здесь у нас 7 компонентов Label, 2 ComboBox, 1 MaskEdit для ввода
номера телефона и 4 Edit для ввода пользовательских данных. Кроме
того, 2 кнопочки с надписями "Добавить телефон" и "Выйти из
программы". В компоненте MaskEdit создайте маску для ввода телефона,
наподобие указанной в рисунке, но с кодом своего города.
Расположите компоненты на форме так, как подсказывает вам
дизайнерский вкус. Верхний ComboBox будет нужен для выбора телефона
из списка, чтобы сразу же высвечивались данные этой записи.
Проверьте свойство TabOrder всех компонентов для ввода, они должны
идти один за другим при нажатии клавиши <Tab>. Свойство TabOrder
показывает индекс компонента на форме. Тот компонент, у которого
TabOrder равен 0, при открытии формы будет иметь фокус ввода, то есть,
будет выделенным. Когда пользователь нажмет клавишу <Tab>, выделение
перейдет к компоненту с TabOrder равным 1, и так далее. С помощью
этого свойства мы можем указывать очередность выделения компонентов,
как правило, она идет сверху - вниз, и слева - направо. Разумеется,
такие компоненты, как Label, фокуса ввода не имеют и у них отсутствует
свойство TabOrder.
Форму переименуйте в fMain, модуль будет называться Main а проект –
tfSprav.
Названия компонентов оставим по умолчанию, их не так много, и мы не
запутаемся. Установите форму в стиль bsDialog, а позицию – по центру
экрана.
Прежде всего, нужно объявить глобальную запись для хранения
необходимых данных, а также глобальный массив элементов типа этой
записи. В этот массив мы будем собирать данные, записывать их в файл и
считывать из файла. Он должен быть глобальным, чтобы мы могли работать
с ним из всех процедур. Поэтому выше раздела implementation пишем
такой код:
type myTFSprav = record TelNum : String[15]; //номер телефона Mobil : Boolean; //мобильник – да? Нет? Imya : String[20]; //имя владельца телефона Otchestvo : String[20]; //его отчество Familiya : String[20]; //его фамилия Adres : String[50]; //его адрес end; //record
var fMain: TfMain; sprav: array of myTFSprav; //объявляем динамический массив нашей записи
Как видите, мы указали немало полей в записи. Однако, не все из них
будут обязательны для заполнения. Есть данные? Запишем. Нет? Поля
можно оставить пустыми. Фактически, необходимыми записями являются
только две – номер телефона и имя его владельца. Номер телефона нам
нужен, потому что это ведь телефонный справочник, и нет смысла в
записи, если мы не указываем там поле с номером телефона. Имя нам тоже
необходимо, ведь зачем нам в файле номер телефона, если мы не знаем,
чей это номер?
Сразу же создадим обработчик событий для кнопки "Выйти из
программы". Там пишем просто:
Close;
Далее обработаем кнопку "Добавить телефон". В самом начале у нас
ведь еще нет записей, поэтому первым делом пользователь введет парочку
– другую телефонных номеров.
{Добавить телефон} procedure TfMain.Button1Click(Sender: TObject); var i : Integer; //для счетчика записей begin {Проверяем обязательные параметры:} //если номера телефона нет, выходим: if MaskEdit1.Text = '8(374)- - - ' then begin //здесь введите свой код города ShowMessage('Впишите номер телефона!'); MaskEdit1.SetFocus; Exit; end; //if
//если имени нет, выходим: if Edit1.Text = '' then begin ShowMessage('Впишите имя владельца телефона!'); Edit1.SetFocus; Exit; end; //if
//действительно ли пользователь хочет сохранить телефон? if Application.MessageBox('Вы уверены, что хотите сохранить этот телефон?', 'Внимание!', MB_YESNOCANCEL+MB_ICONQUESTION)<> IDYES then Exit;
{Пользователь указал номер телефона и имя, и желает сохранить телефон в список.}
//проверяем номер телефона на совпадение с имеющимися номерами, //если там есть записи. Для проверки используем цикл, сверяем каждую запись. //Если такая запись уже есть, сообщаем об этом и выходим из процедуры: if length(sprav) > 0 then for i := Low(sprav) to High(sprav) do if sprav[i].TelNum = MaskEdit1.Text then begin ShowMessage('Такой номер уже есть!'); Exit; end; //if
//добавляем новый элемент к массиву: SetLength(sprav, Length(sprav)+1);
//записываем новый телефон в список: sprav[High(sprav)].TelNum := MaskEdit1.Text; if ComboBox2.ItemIndex = 0 then sprav[High(sprav)].Mobil := True else sprav[High(sprav)].Mobil := False; sprav[High(sprav)].Imya := Edit1.Text; sprav[High(sprav)].Otchestvo := Edit2.Text; sprav[High(sprav)].Familiya := Edit3.Text; sprav[High(sprav)].Adres := Edit4.Text;
//обновим ComboBox с телефонами: ChangeCombo; end;
Процедуры ChangeCombo еще нет, мы предназначили ее для того, чтобы
пользователь мог выбрать нужный телефон из списка, а процедура
обновляет список. Поскольку эта процедура должна быть описана выше
того места, где мы ее используем, то опишем ее самой первой, после
директивы компилятору {$R *.dfm}:
{Процедура обновления ComboBox1} procedure ChangeCombo; var i : Integer; //счетчик для цикла begin //если массив пустой - выходим: if Length(sprav) = 0 then Exit; //если что-то есть, то сначала очистим ComboBox: fMain.ComboBox1.Items.Clear; //затем добавим в него каждый номер телефона из массива: for i := 0 to High(sprav) do fMain.ComboBox1.Items.Add(sprav[i].TelNum); end;
Сохраните проект и скомпилируйте его, впишите пару телефонов и
убедитесь, что они попадают в ComboBox. Программа уже вовсю работает с
динамическим массивом и сохраняет в него данные. Однако пока что
данные хранятся только в памяти, нужно научить программу сохранять их
в файл. Создаем для формы обработчик событий onDestroy, то есть, когда
форма разрушается, наши данные попадут в файл. Файл будет создаваться,
если его не было, или перезаписываться, если он уже был.
{при выходе из программы обновим файл:} procedure TfMain.FormDestroy(Sender: TObject); var f : File of myTFSprav; i : Integer; begin //создаем или перезаписываем файл: try AssignFile(f, 'mySprav.dat'); Rewrite(f); //записываем все данные архива: for i := Low(sprav) to High(sprav) do Write(f, sprav[i]); finally CloseFile(f); end; // try
end;
Как видите, мы объявили файл такого же типа, какой имеет массив. В
прошлой лекции вы уже записывали запись в типизированный файл, однако
теперь нам придется записывать не одну запись, а целый массив таких
записей. Поэтому мы используем функцию:
Write(f, sprav[i]);
причем делаем это в цикле от первого до последнего элемента
массива. Эта функция записывает в файл f запись нужного типа sprav[i].
В примере у нас в этой строке сохраняется только один элемент массива,
все его поля, после чего указатель перемещается к концу. В следующем
проходе цикла сохраняться будет уже следующий элемент массива, и так
далее, увеличивая файл.
Ну и наконец, обратите внимание, что в качестве файла мы указали
только имя и расширение, следовательно, он будет создаваться в той же
папке, откуда запущена программа. Вы можете использовать примеры из
прошлых лекций и изменить имя файла в функции AssignFile(), указав там
и адрес программы.
Сохраните пример и скомпилируйте его. Впишите пару записей и
выйдите из программы. Посмотрите в директорию – там должен появиться
файл – справочник.
Наша программа уже умеет сохранять данные в файл, теперь научим ее
загружать их из файла. Создаем для формы обработчик onCreate, и
вписываем туда код:
{При включении программы загружаем список} procedure TfMain.FormCreate(Sender: TObject); var f : File of myTFSprav; begin try AssignFile(f, 'mySprav.dat'); Reset(f); //считываем все данные в архив: while not Eof(f) do begin //добавляем новый элемент массива SetLength(sprav, Length(sprav)+1); Read(f, sprav[High(sprav)]); end; //while finally CloseFile(f); end; // try //обновим ComboBox с телефонами: ChangeCombo; end;
Обратите внимание, что мы не знаем заранее, сколько там записей,
поэтому использовать цикл for не можем. Зато мы можем использовать
while. Функция Eof(f) вернет истину, когда будет достигнут конец файла
f. И каждый раз, для новой записи, мы добавляем один элемент к
массиву. Мы должны сделать это раньше, чем будем считывать запись,
потому что, если для записи не выделена память, то некуда будет
считывать новую запись и программа выдаст ошибку.
В конце мы опять вызываем процедуру ChangeCombo, чтобы добавить в
ComboBox все телефоны из массива. Сохраните проект, скомпилируйте его
и проверьте работу. В ComboBox должны загружаться все телефоны из
файла.
Однако еще программе не хватает "изюминки" - надо бы, чтобы данные
этой записи отображались на форме, когда пользователь выберет тот или
иной телефон в ComboBox. Выделяем этот компонент и пишем для него
обработчик событий onChange:
{Выбрали другой объект в combobox1} procedure TfMain.ComboBox1Change(Sender: TObject); begin MaskEdit1.Text := sprav[ComboBox1.ItemIndex].TelNum; if sprav[ComboBox1.ItemIndex].Mobil then ComboBox2.ItemIndex := 0 else ComboBox2.ItemIndex := 1; Edit1.Text := sprav[ComboBox1.ItemIndex].Imya; Edit2.Text := sprav[ComboBox1.ItemIndex].Otchestvo; Edit3.Text := sprav[ComboBox1.ItemIndex].Familiya; Edit4.Text := sprav[ComboBox1.ItemIndex].Adres; end;
Все, программа готова! Это конечно, не полноценная база данных, тем
не менее, такой прием программирования будет полезен при сохранении
небольшого количества данных, например, для пользовательских настроек
при многопользовательской программе.