Новости           

Программы

Turbo Pascal

Игры

Документация

"Странности"

FAQ

Ссылки

Благодарности

Гостевая книга

От автора

ПРИМЕР ПРОСТОГО ПОЧТОВОГО СПИСКА

              В качестве примера использования Turbo Access будет заново с
         применением  его возможностей написана программа ведения простого
         почтового списка,  разработанная в главе 2,  которая использовала
         связанные ссылки.  Во-первых, нам необходимо найти размер записи,
         используемой для хранения адресной информации,  а затем вы приме-
         ните  программу  SETCONST для вычисления соответствующих значений
         шести констант, требующихся для процедур Turbo Access.
              Так как  Turbo  Access  использует первые два байта в каждой
         записи в качестве флага индикации удаления,  необходимо  добавить
         поле целой переменной к исходной адресной записи. Кроме того, по-
         ля "предыдущий" и "следующий" больше не используются. Результиру-
         ющая запись выглядит следующим образом:

              type
                address = record
                   status: integer; { используется Turbo Access }
                   name: string[30];
                   street: string[40];
                   city: string[20];
                   state: string[2];
                   zip: string[9];
                end;

         Длина в байтах поля adress,  которая найдена,  используя  SizeOf,
         равна 108.  Вам нужно будет данное число при выполнении программы
         SETCONST.PAS.
              Программа SETCONST.PAS определяет значения констант, необхо-
         димых для Turbo Access.  При запуске программы появляется  экран,
         аналогичный показанному на рис.9-2,  со значениями,  принимаемыми
         по умолчанию. Руководство пользователя по инструментарию баз дан-
         ных говорит,  что для большинства применений вам необходимо изме-
         нить только длину записи и длину ключа,  чтобы  подстроиться  под
         ваши особенности.  Необходимо также изменить число записей, запо-
         минаемых в базе данных, если оно превышает 10000. Размер страницы
         и размер стека страниц изменять не надо. Длина записи adress рав-
         на 108, так что сначала надо ввести это значение. В данном приме-
         ре поле name будет использоваться в качестве ключа,  поэтому зна-
         чение 30 вводится как длина  ключа.  Клавишу  RETURN  нажать  для
         оставшихся полей. Когда информация введена, SETCONT.PAS отобража-
         ет экран, показанный на рис.9 -3.

              При выходе  из  SETCONST.PAS вы можете автоматически создать
         соответствующую декларацию const. Декларация для программы

              ** 1 - рабочий лист задания констант Turbo Access, версия
                                                         1.10А **
              размер записи данных (байт)                  200    200
              длина строки ключа (символов)                 10
              размер базы данных (записей)               10000
              размер страницы (ключей)                      24
              размер стека страниц (страниц)                10
              плотность (процент используемых элементов в средней странице)
                                                         50% 75% 100%

              общее количество  страниц индексного  файла
              память,  используемая для стека страниц (байт)
              размер страницы индексного файла (байт)
              размер индексного  файла (байт)
              размер файла данных (байт)

              порядок
              максимальная высота
              среднее количество просмотров, необходимое для нахождения ключа
              среднее количество просмотров,  удовлетворяемое стеком страниц
              среднее количество просмотров на диске для нахождения ключа

              нажмите ESC для завершения программы

              Рис.9-2. Начальный экран SETCONST.PAS

           ** Turbo Access constant determination worksheet, Version  1.10A
         Data record size (bytes)                        108
         Key string Iength (characters)                   30
         Size of the database (records)                10000
         Page size (keys)                                 24
         Page stack size (pages)                          10

         Density (Percent of Items in use per average Page)50% 75% 100%

         Total Index file pages                            834  556  417
         Memory used for page stack (bytes)               8430 8430 8430
         Index file page size (bytes)                      843  843  843
         Index file size (bytes)
         Data file size (bytes)

         Order                                              12   12   12
         MaxHeight                                           4    4    3
         Average searches needed to find a key            3.71 3.19 2.90
         Average searches satisfied by page stack         1.75 1.50 1.38
         Average disk searches needed to find a key       1.96 1.69 1.52

         ESC to end program
        Рис.9-3. Экран   SETCONST.PAS   с   вычисленными   значениями:
         почтового списка показаны ниже. Комментарии даны автором.

              Const
                {данные  константы  сгенерированы программой SETCONST.PAS,
                 предоставляемой инструментарием баз данных.    }
                MaxDataRecSize = 108;
                MaxKeyLen      = 30;
                PageSize       = 24;
                Order          = 12;
                PageStackSize  = 10;
                MaxHeight      =  4;

         данные константы  сгенерированы программой SETCONST.PAS,  предос-
         тавляемой инструментарием баз данных.

              С данной  информацией  и  включенными  необходимыми  файлами
         Turbo Access первая часть  программы  почтового  списка  выглядит
         следующим образом:
              program db_example;

              Const
                {данные  константы  сгенерированы программой SETCONST.PAS,
                 предоставляемой инструментарием баз данных.         }
                MaxDataRecSize = 108;
                MaxKeyLen      =  30;
                PageSize       =  24;
                Order          =  12;
                PageStackSize  =  10;
                MaxHeight      =   4;

              type
                address = record
                  status: integer; {используется Turbo Access }
                  name: string[30];
                  street: string[40];
                  city: string[20];
                  state: string[2];
                  zip: string[9];
                end;
              {следующие файлы содержат процедуры баз данных}
              {$i access.box} {основные процедуры баз данных}
              {$i addkey.box} {добавить элементы            }
              {$i delkey.box} {удалить элементы             }
              {$i getkey.box} {поиск по дереву              }

              var
                dbfile: DataFile;
                ifile: IndexFile;
                done: boolean;

              В основном тексте программы,  показанном далее, сначала ини-
         циализируется таблица индексов с помощью процедуры InitIndex. Да-
         лее либо открываются, либо создаются соответствующие файлы данных
         и  индексный.  Основной  цикл программы аналогичен тому,  который
         разработан в главе 2,  и позволяет пользователю выбрать различные
         опции. При завершении файлы данных и индексный закрываются.

              begin
                InitIndex;
                OpenFile(dbfile, 'mail.lst', SizeOf(address));
                if not OK then
                begin
                  WriteLn('creating new data file');
                  MakeFile(dbfile, 'mail.lst', SizeOf(address));
                end;
                OpenIndex(ifile, 'mail.ndx', 30, 0);
                if not OK then
                begin
                  WriteLn('creating new index file');
                  MakeIndex(ifile, 'mail.ndx', 30, 0);
                end;
                done:=false;
                repeat
                  case MenuSelect of
                    '1': Enter;
                    '2': Remove;
                    '3': ListAll;
                    '4': Search;
                    '5': Update;
                    '6': done:=true;
                  end;
                until done;
                CloseFile(dbfile);
                CloseIndex(ifile);
              end.
              Отметим, что больше не необходимо явно загружать и сохранять
         почтовый список: процедуры Turbo Access объявляют файлы автомати-
         чески.
              Процедура Enter,  показанная далее, вводит адресную информа-
         цию,  запоминает ее в файле данных и помещает  ключ  в  индексный
         файл.  Отметим, что поле status каждой записи установлено в 0. По
         соглашению Turbo Access использует 0 для обозначения активной за-
         писи,  а не нулевое значение для обозначения уничтоженных элемен-
         тов.
                temp: string[30];
                info: address;
              begin
                done:=FALSE;
                repeat
                  Write('Enter name:');
                  Read(info.name); WriteLn;
                  if Length(info.name)=0 then done:=TRUE
                  else
                  begin
                    Write('Enter street: ');
                    Read(info.street); WriteLn;
                    Write('Enter city: ');
                    Read(info.city); WriteLn;
                    Write('Enter state: ');
                    Read(info.state); WriteLn;
                    Write('Enter zip: ');
                    Read(info.zip); WriteLn;
                    info.status:=0; {сделать активной }
                    FindKey(ifile, recnum, info.name);
                    if not OK then {убедитесь,  что  нет  дублированных
                                      ключей }

                    begin
                      AddRec(dbfile, recnum, info);
                      AddKey(ifile, recnum, info.name);
                    end else WriteLn('Duplicate key ignored');
                  end;
                until done;
              end; {Enter}

              Как вы  видите,  данная  процедура  осуществляет проверку на
         дублирование ключей.  Так как дублированные имена не допускаются,
         процедура,  во-первых, проверяет, соответствует ли новый ключ ка-
         кому-либо уже существующему в файле.  Если это так, то он игнори-
         руется. Порядок вызова AddRec и AddKey критичен, так как перемен-
         ная RecNum должна быть сначала установлена  процедурой  AddRec  и
         затем запомнена процедурой AddKey (Помните, что номер записи фай-
         ла данных связан с ключем в индексном файле  и  используется  для
         последующего нахождения данных).
              Процедура ListAll  рассчитывает  все  содержимое   почтового
         списка:
              procedure ListAll;

              {добавить адрес к списку}
              procedure Enter;
              var
                done: boolean;
                recnum: integer;
              var
                info: address;
                len, recnum: integer;
              begin
                len: = filelen(dofile) -1;
                for recnum:=1 to len do
                begin
                GetRec(dbfile, recnum, info);
                {display if not deleter}
                if info.status = 0 then display(info);
              end;
            end; {ListAll}
              Процедура FileLen  возвращает  число  записей  активных  или
         уничтоженных в файле данных, включая первую запись, которая заре-
         зервирована для использования Turbo Access.  Следовательно, дейс-
         твительное число пользовательских записей на единицу меньше. Кро-
         ме того,  из-за того, что некоторые записи могут быть уничтожены,
         необходимо проверять поле status до отображения информации.
              Поиск определенного адреса включает в себя поиск ключа в ин-
         дексном  файле  с  помощью процедуры FindKey.  Когда ключ найден,
         возвращается соответствующий номер записи в файле данных и он ис-
         пользуется  процедурой  GetRec  для  получения нужной информации.
         Процедура Search, показанная далее реализует данный подход:
              {найти заданный элемент}
              procedure Search;
              var
                name: string[30];
                recnum: integer;
                info: address;
              begin
                Write('Enter name: ');
                ReadLn(name);

                {найти ключ,если он существует}
                FindKey(ifile, recnum, name);
                if OK then { если найден }
                begin
                  GetRec(dbfile, recnum, info);
                  {display if not deleter}
                  if info.status = 0 then Display(info);
                end else WriteLn('not found');
              end; {Search}

              Наконец, модификация существующей записи  предполагает,  что
         вы должны сначала найти запись,  считать ее, модифицировать и за-
         писать обратно в файл данных. Процедура Update иллюстрирует прос-
         той метод обновления, в котором пользователь должен ввести заново
         всю информацию. Более сложные подходы требуют перевода только из-
         меняемых полей.
              { изменение адреса в списке, исключая поле имени }
              procedure Update;
              var
                done: boolean;
                recnum: integer;
                temp: string[30];
                info: address;
              begin
                Write('Введите имя: ');
                Read(info.name); WriteLn;
                FindKey(ifile, recnum, info.name);
                if OK then
                begin
                  Write('Введите улицу: )';
                  Read(info.street); WriteLn;
                  Write('Введите город: ');
                  Read(info.city); WriteLn;
                  Write('Введите штат: ');
                  Read(info.state); WriteLn;
                  Write('Введите индекс: ');
                  Read(info.zip); WriteLn;
                  info.status:=0; {сделать активной}
                  PutRec(dbfile, recnum, info);
                end else WriteLn('ключ не найден');
              end; {Update}

              Целиком программа,  использующая Turbo Access для  работы  с
         файлами, выглядит следующим образом:
              program db_example;

              Const
                {данные  константы  сгенерированы программой SETCONST.PAS,
                 предоставляемой инструментарием баз данных.         }
                MaxDataRecSize = 108;
                MaxKeyLen      = 30;
                PageSize       = 24;
                Order          = 12;
                PageStackSize  = 10;
                MaxHeight      =  4;

              type
                address = record
                  status: integer; {используется Turbo Access }
                  name: string[30];
                  street: string[40];
                  city: string[20];
                  state: string[2];
                  zip: string[9];
                end;
              {следующие файлы содержат процедуры баз данных}
              {$i access.box} {основные процедуры баз данных}
              {$i addkey.box} {добавить элементы            }
              {$i delkey.box} {удалить элементы             }
              {$i getkey.box} {поиск по дереву              }

              var
                dbfile: DataFile;
                ifile: IndexFile;
                done: boolean;

              function MenuSelect:char; {возврат  пользовательского
                                      выбора }

              var
                ch:char;
              begin
                WriteLn('1.       ');
                WriteLn('2. Удалить имя      ');
                WriteLn('3. Отобразить список');
                WriteLn('4. Обновление       ');
                WriteLn('5. Поиск по имени   ');
                WriteLn('6. Выход            ');
                repeat
                  WriteLn;
                  Write('Введите ваш выбор:');
                  Read(ch); ch:=UpCase(ch); WriteLn;
                  until (ch>='1') and (ch<='6');
                  MenuSelect:=ch;
                end; {MenuSelect}

              {добавить адрес к списку}
                procedure Enter;
                var
                  done: boolean;
                  recnum: integer;
                  temp: string[30];
                  info: address;
                begin
                  done:=FALSE;
                  repeat
                    Write('Введите имя: ');
                    Read(info.name); WriteLn;
                    if Length(info.name)=0 then done:=TRUE

                  else
                  begin
                  Write('Введите улицу: ');
                  Read(info.street); WriteLn;
                  Write('Введите город: ');
                  Read(info.city); WriteLn;
                  Write('Введите штат: ');
                  Read(info.state); WriteLn;
                  Write('Введите индекс: ');
                  Read(info.zip); WriteLn;
                  info.status:=0; {сделать активной}
                    FindKey(ifile, recnum, info.name);
                    if not OK then {убедитесь,  что  нет  дублированных
                                      ключей }
                    begin
                      AddRec(dbfile, recnum, info);
                      AddKey(ifile, recnum, info.name);
                    end else WriteLn('Дублированный ключ игнорирован');
                  end;
                until done;
              end; {Enter}

              { изменение адреса в списке, исключая поле имени }
              procedure Update;
              var
                done: boolean;
                recnum: integer;
                temp: string[30];
                info: address;
              begin
                Write('Введите имя: ');
                Read(info.name); WriteLn;
                FindKey(ifile, recnum, info.name);
                if OK then
                begin
                  Write('Введите улицу: ');
                  Read(info.street); WriteLn;
                  Write('Введите город: ');
                  Read(info.city); WriteLn;
                  Write('Введите штат: ');
                  Read(info.state); WriteLn;
                  Write('Введите индекс: ');
                  Read(info.zip); WriteLn;
                  info.status:=0; {сделать активной}
                  PutRec(dbfile, recnum, info);
                end else WriteLn('ключ не найден');
              end; {Update}

              {удалить адрес из списка }
              procedure Remove;
              var
                recnum: integer;
                name: string[30];
                info: address;
              begin
                Write('Введите имя для удаления : ');
                Read(name); WriteLn;
                FindKey(ifile, recnum, name);
                if OK then
                begin
                  DeleteRec(dbfile, recnum);
                  DeleteKey(ifile, recnum, name);
                end else WriteLn('Не найдено');
              end; {Remove}

              procedure Display(info: address);
              begin
                WriteLn(info.name);
                WriteLn(info.street);
                WriteLn(info.city);
                WriteLn(info.state);
                WriteLn(info.zip); WriteLn;
              end; {Display}

              procedure ListAll;
              var
                info: address;
                len, recnum: integer;
              begin
                len := fileLen(dbfile) -1;
                for recnum:=1 to len do
                begin
                  GetRec(dbfile, recnum, info);
                  {отобразить,  если не уничтожен}
                  if info.status = 0 then display(info);
                end;
              end; {ListAll}

              {Найти заданный элемент }
              procedure Search;
              var
                name: string[30];
                recnum: integer;
                info: address;
              begin
                Write('Введите имя: ');
                ReadLn(name);
                {найти ключ,  если существует}
                FindKey(ifile, recnum, name);
                if OK then
                begin
                  GetRec(dbfile, recnum, info);
                  {отобразить,  если не уничтожен}
                  if info.status = 0 then Display(info);
                end else WriteLn('не найден');
              end; {Search}

              begin
                InitIndex;
                OpenFile(dbfile, 'mail.lst', SizeOf(address));
                if not OK then
                begin
                  WriteLn('Cоздание нового файла');
                  MakeFile(dbfile, 'mail.lst', SizeOf(address));
                end;
                OpenIndex(ifile, 'mail.ndx', 30, 0);
                if not OK then
                begin
                  WriteLn('Cоздание нового файла ');
                  MakeIndex(ifile, 'mail.ndx', 30, 0);
                end;
                done:=false;
                repeat
                  case MenuSelect of
                    '1': Enter;
                    '2': Remove;
                    '3': ListAll;
                    '4': Search;
                    '5': Update;
                    '6': done:=true;
                  end;
                until done;
                CloseFile(dbfile);
                CloseIndex(ifile);
              end.

(с)Все права защищены

По всем интересующим вопросампрошу писать на электронный адрес

    Rambler's Top100 PROext: Top 1000
    Rambler's Top100 Яндекс цитирования
Hosted by uCoz