Вернуться на [главную страницу]. Вернуться на [предыдущую страницу].


Базы данных и сеточные формы.


      Что такое база данных?

      База данных - в обыденном, житейском смысле - подборка какой-либо информации. Однако любой работающий с компьютерами знает, что точнее сказать так: это - группа взаимосвязанных, тщательно структурированных данных.

Структура базы данных 'Горностаи'
Рис.1 Структура базы данных "Горностаи"

      Один из примеров простейшей базы данных - наше "досье" на горностаев. Описание всех характеристик (атрибутов) отдельного объекта располагалось по строкам, а значения однотипных параметров разных объектов можно было проследить по колонкам. Таким образом, каждая строка - запись (record) с описанием индивидуального объекта, в данном случае - той или иной особи. В терминологии баз данных набор записей с одинаковой структурой называется таблицей, а группа взаимосвязанных таблиц образует базу данных. Наша база данных состоит из одной-единственной таблицы. Её структура показана на рисунке 1.

      Потребности в обработке информации стали настолько велики, что в конце концов были разработаны специальные приложения - системы управления базами данных (database management systems, или DBMS). Они значительно упрощают создание и поддержку баз данных. К числу самых известных DBMS-программ относятся Microsoft Access, Microsoft FoxPro, Borland Paradox, Borland dBase и Claris FileMaker. Практически все организации (а крупные - тем более!) с помощью DBMS-программ ведут учёт платежей, клиентов, сотрудников и т.д.

      В данном примере мы поработаем с базой данных из комплекта поставки Visual Basic - BIBLIO.MDB. Эта база данных, подготовленная в Microsoft Access, содержит библиографические сведения по двум тематикам: базам данных и языку программирования Visual Basic. Ее структура показана на рисунке 2.

База данных BIBLIO.MDB
Рис.2 База данных BIBLIO.MDB



Связи по ссылкам
Рис.3 В таблице Titles в полях Au_ID и PublID вместо данных содержаться ссылки на таблицы Authors и Publishers (по номерам-идентификаторам авторов и издательств)

      Она состоит из трех таблиц. Таблица Authors (Авторы) - список авторов с номерами-идентификаторами (ID numbers). Таблица Publishers (Издательства) - группа записей со следующей информацией: издательство, код-идентификатор (ID code), компания-владелец, адрес и телефон. Таблицы Authors и Publishers содержат исходные данные (source data). Таблица Titles (Названия книг), хоть и не отличается по структуре от первых двух таблиц, принципиально иная. В ней хранится список опубликованных книг - сервисных данных (service data) - со ссылками на таблицы Authors и Publishers (по номерам идентификаторам). Есть там и некоторые исходные данные, но ссылок на данные из других таблиц гораздо больше; связь организуется через общие поля, как показано на рисунке 3.

      Ссылка из одной таблицы на другую через какое-нибудь общее поле (common field) называется отношением (relation), а база данных, построенная на таком принципе, - реляционной (relational database). Таблицы могут целиком состоять из одних реляционных полей, ссылающихся как на собственно данные, так и на другие реляционные поля.

      Обращение к таблице (входящей в состав базы данных) за какой-либо информацией называется запросом (query). Перед тем как направить запрос базе данных (через DBMS-сервер или из своего приложения), необходимо сначала определить, из какой группы данных следует извлечь информацию, - это сузит рамки поиска.

      В результате запроса к базе данных Вы всегда получаете что-то вроде таблицы. Это - виртуальная таблица (virtual table), или логическое представление (logical view) запрошенных данных. Определяя набор данных, Вы на самом деле указываете отношения в таблицах базы данных - по сути, формируете новую (виртуальную) таблицу из числа имеющихся. Таким образом, после запроса информация преобразуется в такое логическое представление, которое не существует в базе данных, но построено на реальных данных. Отношения - вот что позволяет конструировать различные логические представления данных. На рисунке 4 показано одно из возможных логических представлений базы данных BIBLIO.MDB.



Одно из возможных логических представлений данных,
выбранных из таблиц базы данных BIBLIO.MDB
Рис.4 Одно из возможных логических представлений данных, выбранных из таблиц базы данных BIBLIO.MDB

      Доступ к данным и их отображение - разные вещи. О том, как в Visual Basic создать приложение, способное решать обе задачи, Вы узнаете из следующего раздела.


      Доступ к данным и их отображение

      В какой-то момент Вам наверняка понадобится создать приложение для работы с информацией, уже содержащейся в базе данных. Можно, конечно, продублировать её в том или ином файле прямого доступа, однако это неэффективно, а порой и просто опасно. Неэффективно потому, что дополнительная копия данных попусту занимает дисковое пространство; а опасно потому, что вполне вероятно рассогласование групп данных в исходной базе и её копии - скажем, Вы обновили информацию в источнике и не сделали того же в его копии.

      Самое разумное - хранить информацию в одном экземпляре в базе данных и запрограммировать приложение так, чтобы оно получило к ней доступ. А делается это инструментом Data (Данные). На рисунке 5 показано, как выглядит инструмент Data в окне шаблонов и что получается после размещения на форме созданного с его помощью объекта.



Инструмент Data (Данные) 
и объект типа 'данные', созданный
с его помощью на форме
Рис.5 Инструмент Data (Данные) и объект типа "данные", созданный с его помощью на форме

      Примечание: Прежде чем применить инструмент Data, разрешите совместный доступ приложений к файлам - если только Вы не работаете в Windows для рабочих групп. Если совместный доступ к файлам в Вашей системе запрещен, выйдите из Windows и из командной строки MS-DOS запустите резидентную программу SHARE.EXE. Затем перезапустите Windows и Visual Basic. И ещё одно: может быть, имеет смысл вставить команду SHARE в файл АUТОЕХЕС.BAT.


      Объект Data

      Этот объект обладает рядом свойств, позволяющих описать характер связи между приложением и базой данных, к которой Вы хотите получить доступ. Если Вас интересует несколько групп данных, создайте и настройте объекты типа "данные" для каждой группы индивидуально. Один объект Data всегда обеспечивает доступ только к одной записи сразу. Такая запись называется текущей (current). Определив нужные свойства, к объекту Data можно подключить другие объекты Visual Basic. Смена текущей записи осуществляется либо щелчком объекта Data, либо программным путем. Этот же объект позволяет отображать на экране содержимое текущей записи. Третья версия Visual Basic поддерживает обмен данными со следующими DBMS-программами:

- Microsoft Access;
- Microsoft FoxPro;
- Borland dBase;
- Borland Paradox.


      Подключение к базе данных

      А теперь попробуем создать приложение, которое сможет обращаться к базе данных BIBLIO.MDB. Мы построим его так: при каждом щелчке объекта Data на экране будет появляться по одной записи с номером-идентификатором автора и названием книги. Для начала в верхней части формы разместим первый элемент управления - объект Data, а затем нарисуем две метки и два текстовых окна. Свойства объектов определите в соответствии с таблицей, приведенной ниже, после чего форма должна выглядеть, как на рисунок 6.

Объект Свойство Значение
Form1 Caption База данных: BIBLIO
Name Biblio
Data1 Caption База данных "Книги"
Name dtaBiblio
Label1 Caption Автор
Label2 Caption Название книги
Text1 Name txtAuthor
Text [нет]
Text2 Name txtTitle
Text [нет]


Форма приложения 'База данных: BIBLIO'
Рис.6 Форма приложения "База данных: BIBLIO" [pic06.zip (0.8KB)]

      Пока что Вы всего лишь подготовили форму для приложения. Чтобы подключиться к базе данных, нужно настроить ещё несколько свойств объекта Data, перечисленных ниже. Их значения можно устанавливать как при проектировании, так и в период выполнения программы. Если приложение всегда подключается только к одной базе данных, определяйте свойства на этапе проектирования (в этом случае, кстати, Visual Basic сможет отслеживать более широкий круг ошибок, связанных с обращением к базам данных).

      Итак, выберите в окне Properties объект Data (dtaBiblio) и определите следующие его свойства:

      Connect (Подключение) Это свойство определяет формат данных. В нашем случае его следует приравнять пустой строке, что послужит сигналом Visual Basic: база данных имеет формат Microsoft Access. Другие допустимые значения этого свойства - "foxpro 2.5", "paradox" и "dbase IV". Подробнее о поддерживаемых форматах данных смотрите документацию на Visual Basic.

      DatabaseName (Имя базы данных) Это свойство определяет файл базы данных. Щёлкнув кнопку с многоточием в окне Properties, в появившемся диалоговом окне выберите файл BIBLIO.MDB. Он находится в том же каталоге, что и исполняемый файл VB.EXE.

      RecordSource (Источник записи) Это свойство сообщает Visual Basic, откуда извлечь данные. Оно либо содержит имя таблицы, либо идентифицирует конкретное логическое представление данных. Присвойте ему строку Titles, чтобы получить данные из таблицы Titles.

      Подключение к объекту Data элементов управления отображением

      Теперь приложение "способно" считывать информацию из базы данных. Ещё один штрих, и оно сможет выводить её на экран. Для этого поля таблицы (к которой обеспечивает доступ объект Data) нужно напрямую связать с одним из элементов управления: флажком (check box), изображением (image), меткой (label), окном рисунка (picture box) или текстовым окном (text box). Окна изображений и рисунков можно использовать для показа картинок, хранящихся в базе данных; флажок позволит отображать Булевы величины, а метки и текстовые окна - числовую или текстовую информацию. Какой бы элемент управления Вы ни выбрали, он подключается к объекту Data через свойство DataSource (Источник данных), а свойство DataField (Поле данных) определяет имя поля в таблице, с которой связывается конкретный элемент управления.

      Щёлкните текстовое окно txtAuthor и занесите: в свойство DataSource - dtaBiblio, в свойство DataField - Au_ID. Затем, щёлкнув текстовое окно txtTitle, введите в свойства DataSource и DataField соответственно dtaBiblio и Title. Запустите приложение. Как только Вы щёлкнете объект Data, в текстовых полях формы появятся записи из базы данных. Ни строчки кода, а приложение готово!

      Это приложение позволит даже редактировать данные и записывать их в исходную базу данных.

      Примечание: Очень важно не модифицировать случайно те данные, которые Вас не "касаются". Создавая приложение для доступа к коллективной базе данных, тем более следует принять меры к тому, чтобы обновлять информацию мог только тот, кто имеет на это право. А значит, нужно использовать свойства Exclusive, Options и Readonly (о них Вы прочтёте в документации на Visual Basic).


      Определение множества записей

      Группа записей, к которой Вы хотите получить доступ, называется множеством записей (recordset) и определяется состоянием свойства RecordSource объекта Data. В нашем примере таковым множеством является таблица Titles. Но обычно в приложении требуется либо доступ лишь к некоторому подмножеству записей в базе данных, либо такое представление данных, которое выходит за рамки одной-единственной таблицы.

      Пользы от только что разработанного нами приложения могло бы быть куда больше, если бы оно показывало не номер-идентификатор автора, а его фамилию и имя. Эта проблема решается на основе реляционного подхода. Выйдите из приложеняя и в окне Properties присвойте свойству RecordSource объекта Data следующую строку:

      select Author,Title from Authors,Titles where Authors.Au_ID=Titles.Au_ID

      Это - оператор языка SQL, который создает новое представление базы данных (и определяет новое множество записей), комбинируя таблицы Authors и Titles через отношение Au_ID и выбирая две колонки: Author и Title. Вы должны заменить текущее значение свойства DataField текстового окна txtAuthor значением Author, так как в только что созданном представлении нет поля Au_ID. (О языке SQL можно узнать из документации на DBMS-программы. А еще лучше: просмотрите базу данных BIBLIO.MDB, и Вы узнаете, какие книги опубликованы на эту тему.)

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


      Программное управление доступом к данным

      Записи можно выбирать не только на стадии проектирования приложения, но и в период его выполнения. В сущности, значение свойства Visible объекта Data можно приравнять False и в дальнейшем все манипуляции с данными проводить под управлением самой программы. Вот какие методы сопоставлены с объектом Data:

      Refresh Открывает или закрывает базу данных. Если база данных уже открыта, позволяет повторно открыть её.

      MoveFirst Текущей становится первая запись во множестве записей.

      MoveNext Текущей становится следующая запись во множестве записей.

      MovePrevious Текущей становится предыдущая запись во множестве записей.

      MoveLast Текущей становится последняя запись во множестве записей.

      AddNew Ко множеству записей добавляется новая запись. Метод применим только для таблиц и динамических множеств (dynasets). (Что такое динамическое множество, Вы узнаете из справочной системы Visual Basic.)

      Update Отредактированное поле записывается обратно в базу данных. (Метод применим только для таблиц и динамических множеств.)

      Delete Текущая запись удаляется. Этот метод также применим только к тем множествам записей, что являются таблицей или динамическим множеством. Вызвав этот метод, немедленно примените один из методов Move и сделайте текущей другую запись.

      При перемещении по записям программа должна проверять свойства ВОF (аббревиатура Beginning Of File - начало файла) и ЕОF (End Of File - конец файла) объекта Data. Свойство ВОF равно True, если указатель текущей позиции в файле расположен до каких бы то ни было данных. Такая ситуация обычно возникает после удаления первой записи. Свойство EOF равно True, если указатель текущей позиции находится за существующими данными. Если любое из этих свойств "истинно", значит у текущей записи недопустимый номер. А если "истинны" оба свойства, множество вообще не содержит данных.


      Поиск записей

      Записи не обязательно просматривать последовательно, одну за другой - можно ввести критерий поиска и выводить на экран только записи, удовлетворяющие условию. Для этого предназначены методы FindFirst, FindNext, FindPrevious и FindLast, которые работают примерно так же, как и методы Move, описанные выше. Разница лишь в том, что методы Find действуют во множестве, уже отобранном через объект Data, и требуют параметр - строку с критерием поиска в виде Булева выражения.

      Например, для просмотра всех книг, названия которых начинаются с буквы "Т", напишите что-нибудь в таком духе:

Dim Criteria As String
'
Criteria="Title>='T' And Title<'U'"
dtaBiblio.Recordset.FindFirst Criteria
'
Do While Not dtaBiblio.Recordset.NoMatch
  Debug.Print dtaBiblio.Recordset.Fields("Title").Value
  dtaBiblio.Recordset.FindNext Criteria
Loop

      Приведенный выше фрагмент программы демонстрирует также, как пользоваться свойством NoMatch по завершении операции Find и как получить доступ к определенному полю во множестве записей. Если поиск оказался безрезультатен (свойство NoMatch сохраняет значение True), номер текущей записи не меняется.


      Приложение "Картотека"

      Давайте сведем воедино всё, о чём мы говорили в этой главе, и дополним приложение-пример блоком поиска информации по имени автора. При этом мы воспользуемся тем преимуществом, что записи в базе данных отсортированы в алфавитном порядке по именам авторов.

      Растяните форму приложения и в нижний левый угол вставьте небольшую командную кнопку (см. рисунок 7). Свойству кнопки Caption присвойте латинскую букву A, а свойству Name - cmdLetter.



Дополненная форма приложения 'База данных: BIBLIO'
Рис.7 Дополненная форма приложения "База данных: BIBLIO" [pic07.zip (0.8KB)]

      Чтобы приложение походило на картотек создайте ряд кнопок с названиями от A до Z. Но не вычерчивать же их по отдельности! Ну уж нет, пусть этим займется Visual Basic - мы превратим командную кнопку в массив объектов, присвоив для этого нулевое значение её свойству Index. Затем в процедуру Form_Load введём такой код:

Sub Form_Load( )
  Dim I As Integer
  '
  For I=1 To 25
    ' создаем новый объект с индексом I
    Load cmdLetter(I) 
    ' располагаем его рядом с предыдущим объектом
    cmdLetter(I).Left=cmdLetter(I-1).Left+cmdLetter(I-1).Width
    ' создаем название кнопки (А, В, С, D, ...)
    cmdLetter(I).Caption=Chr$(Asc("A>)+I)
    cmdLetter(I).Visible=True
  Next I
End Sub

      Когда при запуске выполняется эта процедура, в окне формы создается ещё 25 командных кнопок, расположенных одна за другой и помеченных буквами латинского алфавита от B до Z. Теперь осталось сделать так, чтобы при "нажатии" кнопок активизировался метод Find. В качестве критерия поиска используем значение свойства кнопки Caption - при щелчке N-ой кнопки критерий примет вид Author>='N'. Поэтому в процедуру обработки события Click для массива командных кнопок надо ввести такой код:

Sub cmdLetter_Click(Index As Integer)
  Dim Criteria As String
  '
  Criteria="Author>='"+cmdLetter(Index).Caption+"'"
  dtaBiblio.Recordset.FindFirst Criteria
End Sub

      Теперь - после щелчка кнопки с буквенной меткой - указатель позиции устанавливается на запись, удовлетворяющую текущему критерию поиска. Поскольку имена авторов хранятся в таблице по алфавиту, записи можно "перелистывать" ещё и кнопками-стрелками объекта "данные" Next (Вперед) или Previous (Назад). После запуска окно приложения должно выглядеть, как на рисунке 8.



'Картотечная' версия
приложения 'База данных: BIBLIO'
Рис.8 "Картотечная" версия приложения "База данных: BIBLIO" [pic08.zip (1.1KB)]


      Динамический доступ к базе данных

      В предыдущих примерах множество записей определялось на этапе проектирования. Соответственно мы имели возможность подключать к объекту Data различные элементы управления и тем самым автоматически выводить на экран содержимое полей этого множества. Но ведь может понадобиться приложение, способное открывать неизвестную базу данных, выбранную пользователем. Тогда поля в базе данных придется определять динамически, т.е. в период выполнения программы. В этом разделе и пойдет речь о том, как написать приложение, которое способно открывать любую базу данных, создавать на экране список содержащихся в ней таблиц и - когда пользователь сделает свой выбор - формировать сеточную форму с данными из конкретной таблицы.

      В Visual Basic для описания интересующей Вас базы данных, кроме свойства Rеcordset объекта Data, предусмотрен ещё целый ряд объектов. Доступ к этим объектам осуществляется через соответствующие свойства объекта Data. Например, свойство Database обеспечивает доступ к объекту "дескриптор базы данных". В свою очередь, у этого объекта тоже несколько свойств. Вспомните: объекты, с которыми мы работали до сих пор, обладали свойствами простых типов; например, у объекта "командная кнопка" свойство Caption оперирует со строками, а Height - с целыми числами. Однако в Visual Basic существуют такие объекты, свойства которых возвращают нечто посложнее простых строк и целых чисел - например, наборы (collections) (о них в следующем разделе). Чтобы получить доступ к свойству объекта, являющемуся свойством другого объекта, к исходному выражению достаточно добавить ещё одну разделительную точку и имя нужного свойства. Таким образом, выражение X.Y.Z - это ссылка на свойство Z объекта, адресуемого через свойство Y объекта X.


      Наборы

      Набор - нечто среднее между списком и массивом. Как и массив, это чисто программная конструкция; в то же время, подобно списку, он является объектом со своими свойствами. Любой набор обладает свойством Count, по значению которого определяют, сколько еще объектов содержится в нем. К последним объектам обращаются по числовому индексу (от 0 до Count-1) или по их именам. В частности, в примере, приведенном выше, Вы получали доступ к набору Fields объекта Recordset с помощью оператора:

Debug.Print dtaBiblio.Recordset.Fields("Title").Value

      В этом операторе имя "Title" использовалось для обращения к нужному полю (объекту набора Fields).


      Примеры обращения к объектам наборов

      Вот несколько примеров выражений, помогающих анализировать структуру базы данных, к которой Вы подключились через объект Data. (Предполагается, что этот объект имеет имя dtaBiblio - как в предыдущих примерах.)

Выражение Смысл
dtaBiblio объект Data
dtaBiblio.Database объект "дескриптор базы данных"
dtaBiblio.Database.Name имя базы данных
dtaBiblio.Database.TableDefs.Count количество таблиц в базе данных
dtaBiblio.Database.TableDefs(0).Name имя первой таблицы в базе данных
dtaBiblio.Database.TableDefs(0).Fields.Count количество полей в первой таблице
dtaBiblio.Database.TableDefs(0).Flelds(0).Name имя первого поля в базе данных
dtaBiblio.Recordset текущее множество записей, к которому получен доступ через объект Data
dtaBiblio.Recordset.Fields.Count количество полей во множестве данных
dtaBiblio.Recordset.Fields(0).Name имя первого поля во множестве данных
dtaBiblio.Recordset.Fields(0).Value значение первого поля во множестве данных

      Теперь, зная, как определить структуру неизвестной базы данных, Вы сможете разработать программу для динамического отображения информации. Но чем создавать текстовые окна для каждого поля по отдельности, гораздо лучше воспользоваться инструментом Grid (Сетка).


      Объект "сеточная форма"

      Сеточная форма - это двумерный массив экранных полей, или ячеек (cells), который специально предназначен для отображения информации так, как это принято в базах данных или электронных таблицах. На рисунке 9 показано, как выглядит инструмент Grid (он появляется в окне шаблонов только в том случае, если в окне проекта присутствует файл GRID.VBX).



Инструмент Grid (Сетка)
Рис.9 Инструмент Grid (Сетка)

      На рисунке 10 показаны два образца сеточной формы. Та, что слева, содержит в верхней строке и левой колонке серые ячейки и имеет вертикальную и горизонтальную линейки прокрутки. А у той, что справа, нет линеек прокрутки и колонки с серыми ячейками. Внешний вид сеточной формы определяется состоянием ее свойств:

      Rows (Строки) Общее количество строк в сеточной форме. Если строк задано больше, чем может уместиться в отведенном ей окне, появляется вертикальная линейка прокрутки.

      Cols (Колонки) Общее количество колонок в сеточной форме. Если колонок задано больше, чем может уместиться в отведенном ей окне, появляется горизонтальная линейка прокрутки.

      FixedRows (Фиксированные строки) Количество строк (отсчёт сверху) с фиксированной позицией. Такие строки нельзя прокручивать и они затеняются серым фоном. Обычно они применяются для вывода "шапки" таблицы.

      FixedCols (Фиксированные колонки) Количество колонок (отсчёт от левого края) с фиксированной позицией. Обычно используются в тех же целях, что и фиксированные строки; их тоже нельзя прокручивать и они выделяются серым фоном.

      ColWidth (Ширина колонки) Ширина указанной колонки в twips (1/20 пункта).

      RowHeight (Высота строки) Высота заданной строки (также измеряется в twips).



Два образца сеточной формы
Рис.10 Два образца сеточной формы (внешний вид зависит от значений ее свойств)


      Приложение Data Browser

      Собрав воедино все, что Вы узнали о сеточных формах, можно создать приложение, которое открывает любую базу данных, формирует список таблиц и показывает содержимое выбранной таблицы в сеточной форме. Начнем с создания нового проекта. Если в окне Project нет файла GRID.VBX, выберите из меню File команду Add File (Добавить файл) и загрузите его в свой проект. GRID.VBX должен находиться в подкаталоге SYSTEM основного каталога Windows. Поскольку Вам все равно придется просматривать каталоги в поисках файла нужной базы данных, добавьте в окно Project (по аналогии с GRID.VBX) и файл CMDIALOG.VBX.

      Разместите на форме командную кнопку комбинированный список и по одному объекту: Data, Common Dialog и Grid (см. рисунок 11). Свойства объектов установите в соответствии с приведенной ниже таблицей.



Исходная разметка формы
Рис.11 Исходная разметка формы [pic11.zip (0.7KB)]

Объект Свойство Значение
Form1 Caption Data Browser
Name Grid1
ComDlg1 Name dlog
Data1 Name dtaTable
Visible False
Command1 Caption Открыть базу данных
Name cmdOpen
Combo1 Name cboTables
Text [нет]
Grid1 FixedCols 0
Name grdData

      Объект Data сделан невидимым, потому что весь доступ к базе данных будет происходить на программном уровне. Свойство FixedCols объекта Grid приравнено нулю, так как в строках не будет меток - только "шапка" таблицы в верхней фиксированной строке сеточной формы.

      Первую строку кода введите в раздел общих объявлений формы. Затем наберите текст процедуры Click для командной кнопки. (Константа OFN_FILEMUSTEXIST взята из файла CONSTANT.TXT)

Const OFN_FILEMUSTEXIST=&H1000&

Sub cmdOpen_Click( )
  ' очистим окно списка
  cboTables.Clear
  ' ищем базы данных MS Access
  dlog.DefaultExt="MDB"
  dlog.FileName=""
  dlog.Filter="Базы данных MS Access (*.MDB)|*.MDB|Bсe файлы (*.*)|*.*"
  dlog.Flags=OFN_FILEMUSTEXIST
  ' вызываем диалоговое окно Открыть (Open)
  dlog.Action=1 
  If dlog.FileName="" Then
    Exit Sub
  End If
  OpenDataFile dlog.FileName
End Sub

      После щелчка командной кнопки программа выводит на экран диалоговое окно Открыть или Open (в зависимости от того, в какой версии Windows Вы работаете: русской или оригинальной). В этом окне выберите файл базы данных. Программа предназначена для просмотра файлов в формате Microsoft Access, имеющих расширение MDB. Если файл выбран, программа вызывает процедуру OpenDataFile, передавая ей имя этого файла. Вот какой код следует поместить в процедуру OpenDataFile:

Sub OpenDataFile (ByVal DataFile As String)
  Dim I As Integer
  ' Выбираем формат MS Access
  dtaTable.Connect=""
  dtaTable.DataBaseName=DataFile
  ' это ускоряет доступ
  dtaTable.ReadOnly=True
  ' это тоже ускоряет доступ
  dtaTable.Exclusive=True
  ' загружаем базу данных
  dtaTable.Refresh
  '
  For I=0 To dtaTable.Database.TableDefs.Count-1
    ' заносим имя каждой таблицы в комбинированный список
    cboTables.AddItem dtaTable.DataBase.TableDefs(I).Name
  Next I
  ' пока ничего не выбрано
  cboTables.Text="[нет]"
End Sub

      Процедура OpenDataFile инициализирует объект Data, а затем запрашивает объект Database об именах всех таблиц в базе данных. Эти имена вставляются в окно комбинированного списка. Код, управляющий списком, прост; он всего лишь вызывает процедуру, заполняющую сеточную форму. Составьте для комбинированного списка такую процедуру обработки события Click:

Sub cboTables_Click( )
  FiIIGrid cboTables.Text
End Sub

      Теперь остается написать процедуру FillGrid, позволяющую заполнять сеточную форму, - она получает имя выбранной таблицы как параметр, обращается к базе данных за именами полей в таблице, размещает их в фиксированной строке сеточной формы и "проходит" по таблице, считывая значения из каждой записи и вставляя их в соответствующие ячейки сеточной формы.

Sub FiIIGrid (ByVal TableName As String)
  Dim I As Integer
  Dim CellWidth As Integer
  ' инициализируем множество записей
  dtaTable.RecordSource = TableName
  ' выясняем "шапку" таблицы
  grdData.Cols = dtaTable.Database(TableName).Fields.Count
  grdData.Row = 0
  For I = 0 To dtaTable.Database(TableName).Fields.Count - 1
    grdData.Col = I
    grdData.Text = dtaTable.Database(TableName).Fields(I).Name
    grdData.ColWidth(I) = TextWidth(grdData.Text) + 100
  Next I
  '
  dtaTable.Refresh
  '
  ' определяем количество записей
  ' и устанавливаем размер сеточной формы
  dtaTable.Recordset.MoveLast
  grdData.Rows = dtaTable.Recordset.RecordCount + 1
  '
  ' заполняем сеточную форму, начиная с первой записи
  dtaTable.Recordset.MoveFirst
  grdData.Row = 0
  '
  Do While Not dtaTable.Recordset.EOF
    grdData.Row = grdData.Row + 1
    '
    For I = 0 To dtaTable.Database(TableName).Fields.Count - 1
      grdData.Col = I
      '
      ' записывать пробел, если текущее поле данных пусто
      If IsNull(dtaTable.Recordset(I).Value) Then
        grdData.Text = ""
      Else
        grdData.Text = dtaTable.Recordset(I).Value
      End If
      '
      ' делаем так, чтобы все данные были видны
      CellWidth = TextWidth(grdData.Text) + 100
      If CellWidth > grdData.ColWidth(I) Then
        grdData.ColWidth(I) = CellWidth
      End If
    Next I
    '
    dtaTable.Recordset.MoveNext
  Loop
End Sub

      Примечание: В этом приложении предполагается, что в памяти умещаются все записи из заданной таблицы. Некоторые базы данных имеют таблицы с сотнями тысяч записей. Чтобы это приложение сделать по-настоящему универсальным, в памяти нужно держать не более 100 записей, а остальные считывать (подзагружать) по мере прокрутки строк в сеточной форме. Работая с массивными базами данных, Вам придется поступать именно таким образом.

      О процедуре FillGrid нужно сказать ещё несколько слов. Чтобы определить количество строк, которое должно быть в сеточной форме, процедура переходит к концу таблицы (с помощью метода MoveLast) и проверяет значение свойства RecordCount для последней записи. Затем масштабирует соответствующим образом сеточную форму и начинает загрузку данных с первой строки таблицы. В процессе загрузки процедура проверяет: не встречаются ли пустые поля (для этого она пользуется функцией IsNull). При обнаружении пустого поля в ячейку вставляется пробел. Заполнив сеточную форму, процедура настраивает ширину каждой колонки (ColWidth) так, чтобы были видны все данные, содержащиеся в них. С этой целью процедура вызывает метод формы TextWidth. Обратите внимание: обращение к методу TextWidth предполагает, что для формы и для сетки используются одинаковые шрифты; в противном случае метод даст неверный результат.

      Итак, программа закончена и теперь её можно запустить. На рисунке 12 показано, как выглядит окно приложения, если открыть базу данных BIBLIO.MDB и выбрать таблицу Publishers.



Окно приложения DataBrowser
Рис.12 Окно приложения DataBrowser [pic12.zip (1.8KB)]





Хостинг от uCoz