В данном
уроке рассматриваются примеры работы с файлами последовательного и прямого доступа.
Конструируя
данное приложение, вы на практике узнаете, как осуществить:
Файл
последовательного доступа
При последовательном
доступе файл рассматривается как последовательность строк произвольной длины,
разделенных специальными знаками. Чтение из файла и запись в файл производится
построчно.
Приведенная
ниже программа является примером создания простейшего текстового редактора,
в который можно загрузить из файла уже существующий текст, отредактировать его
и записать измененный текст в файл. Имя открываемого файла вводится в переменную
имяФайла. Свободный номер для файла получается при помощи функции FreeFile и
записывается в переменную Номер.
Итак, в редакторе
форм создадим диалоговое окно Файл последовательного доступа (рис. У 14.1).
Рис.
У14.1. Диалоговое окно Файл последовательного доступа
Обсудим,
как приведенная ниже программа решает описанную задачу и что в ней происходит.
UserForm_Initialize |
|
||
ToggleButton1_Click |
При установке
переключателя отображается поле, в которое выводится текст из файла,
а также отображается кнопка Сохранить изменения? При снятии переключателя,
поле и кнопка скрываются. |
||
Нажатие кнопки Сохранить изменения? запускает на
выполнение процедуру CommandButton1_Click |
Записывает содержимое
поля в файл. |
||
Открытие и Запись |
Процедуры считывают
содержимое файла в поле и записывают содержимое поля в файл соответственно. |
||
'
' Переменные уровня модуля
'
Option Explicit
Dim ИмяФайла As String
Dim Номер As Integer
'
Private Sub
CommandButtonl_Click()
'
' По нажатию
кнопки содержимое поля записывается в файл
Запись
End Sub
'
Private Sub
ToggleButtonl_Click()
'
' При установке
переключателя отображается поле,
' в которое
выводится текст из файла, и кнопка для
' записи изменений
в поле в файл.
' При снятии
переключателя поле и кнопка скрываются
'
Номер = FreeFile
ИмяФайла = "c:\my_doc\book_ex\help.txt"
'
If ToggleButtonl.Value = True
Then TextBoxl.Visible = True
CommandButtonl.Visible = True
Открытие
End If
If ToggleButtonl.Value = False
Then CommandButtonl.Visible = False
TextBoxl.Visible
= False
End If '
End Sub '
Private Sub
UserForm_Initialize()
' Инициализация
диалогового окна
'
With TextBoxl
.MultiLine =
True
.ScrollBars
= fmScrollBarsBoth
.Visible = False
End With
ToggleButtonl.TripleState = False
With CommandButtonl
.Wordwrap =
True
.Visible = False
End With
UserForm2.Caption = "Файл последовательного доступа"
End Sub
Sub Запись()
' Запись файла
' Открывается
файл последовательного доступа для записи информации
Open ИмяФайла
For Output As Номер
' Содержание поля выводится в файл
'
Print #Номер,
TextBoxl.Text
'
' Закрытие файла
'
Close Номер
'
End Sub
Sub Открытие()
'
' Считывание
из файла в поле
' Открывается файл последовательного доступа для считывания информации
Open ИмяФайла
For Input As Номер
' Содержание файла выводится в поле
'
TextBoxl.Text = Input(LOF(Номер), Номер)
'
' Закрытие файла
'
Close Номер
End Sub
При последовательном
доступе файл рассматривается как последовательность строк фиксированной длины,
причем при открытии указывается длина строки. Благодаря этому становится возможным
переход на любую запись по ее номеру.
Рис.
У14.2. Диалоговое окно для работы с файлом произвольного доступа
Приведенная
ниже программа реализует простейшую базу данных с помощью файла произвольного
доступа. Данный файл предназначен для хранения информации о студентах: фамилии,
имени и группе. Диалоговое окно информация о студентах позволяет перемещаться
от записи к записи, редактировать существующие и создавать новые записи. Переход
от записи к записи производится при помощи счетчика. Отметим, что заголовок
диалогового окна является переменным: при создании нового файла или записи в
заголовок выводится информация о студентах, а при выводе информации о текущем
студенте — его имя и фамилия. При активизации диалогового окна доступными для
пользователя являются только поле со списком и кнопка открытие файла. В поле
со списком отображаются все файлы текущей папки с расширением dat. Пользователь
может выбрать файл из этого списка или ввести в поле имя нового файла. После
ввода имени файла поле со списком и кнопка Открытие файла становятся недоступными
для пользователя, а все остальные элементы управления, наоборот, становятся
доступными. На стандартном листе модуля описан пользовательский тип студенттуре,
который используется в модуле UserForm1 для объявления переменной данного типа.
Эта переменная задает структуру в файле произвольного доступа. Имя открываемого
или вновь создаваемого файла вводится в переменную ИмяФайла. Свободный номер
для файла получается при помощи функции FreeFile и записывается в переменную
Номер.
Итак, в редакторе
форм создадим диалоговое окно для работы с файлом произвольного доступа (рис.
У14.2).
Обсудим,
как приведенная ниже программа решает описанную задачу и что в ней происходит.
UserForm Initialize |
|
||
Нажатие кнопки
Открытие файла запускает на выполнение процедуру CommandButton4_Click |
|
||
SpinButton1 |
|
||
Нажатие кнопки
Новая запись запускает на выполнение процедуру CommandButtonl_Click |
Создает новую
запись в конце файла. |
||
Нажатие кнопки
Записать изменения запускает на выполнение процедуру CommandButton2_Click |
Считывает из
диалогового окна в текущую запись файла информацию при помощи процедуры
ЗаписатьЗапись . |
||
Нажатие кнопки
Закрыть запускает на выполнение процедуру CommandButton3
Click |
Закрывает открытый
файл и диалоговое окно. |
||
Нажатие кнопки
запускает на выполнение процедуру CommandButton5
Click |
Осуществляет
переход на последнюю запись. |
||
Нажатие кнопки
запускает на выполнение процедуру CommandButton6
Click |
Осуществляет
переход на первую запись. |
||
Показать Запись |
Выводит в поля
диалогового окна запись с номером, указанным в переменной текущаяЗапись
. |
||
Записать Запись |
Записывает в
файл из полей диалогового окна запись с номером, указанным в переменной
текущаяЗапись . |
||
На листе
стандартного модуля наберите описание пользовательского типа:
Option Explicit
Public Type
СтудентТуре
Фамилия As String
* 30
Имя As String
* 30
Группа As String * 11
End Type
На листе
модуля userForm1 наберите следующую программу:
Option Explicit
'
' Переменные уровня модуля
'
Dim Студент Аs СтудентТуре
Dim ДлинаФайла As Long
Dim ДлинаЗаписи As Long
Dim ИмяФайла As String
Dim ТекущаяЗапись As Long
Dim ПоследняяЗапись
As Long
Dim Номер As Integer
'
Sub ПоказатьЗапись()
Get #Номер, ТекущаяЗапись, Студент
With Студент
TextBoxl.Text
= Trim(.Фамилия)
TextBox2.Text
= Trim(.Имя)
TextBoxB.Text
= Trim(.Группа)
TextBox4.Text
= ТекущаяЗапись
UserFormi.Caption = TextBoxl.Text & " " & TextBox2.Text
End With
End Sub
'
Sub ЗаписатьЗапись()
With Студент
.Фамилия = TextBoxl.Text
.Имя = TextBox2.Text
.Группа = TextBox3.Text
End With
Put Шомер, ТекущаяЗапись,
Студент End Sub
'
Private Sub CommandButtonl_Click{}
'
' Кнопка Новая
запись '
UserForml.Caption = "Информация о студентах"
'ЗаписатьЗапись
ПоследняяЗапись = ПоследняяЗапись + 1
With Студент
.Фамилия = ""
.Имя = ""
.Группа = ""
End With
I'
TextBoxl.Text => ""
TextBox2.Text = ""
TextBox3.Text
= ""
TextBox4.Text = CStr{ПоследняяЗапись}
'
Put #Номер, ПоследняяЗапись, Студент
'
ТекущаяЗапись = ПоследняяЗапись
'
End Sub
Private Sub CommandButton2_Click ()
'
' Кнопка Записать
изменения '
Записать Запись
End Sub '
Private Sub CommandButton3_Click()
'
' Кнопка Закрыть
'
Close #Номер UserForml.Hide
End Sub
Private Sub
CommandButton4_Click()
' Открытие файла
'
Dim Начало As
Boolean
Управление СЗаписями:=Тгие,
СФайлом:=False
ИмяФайла = Trim(ComboBoxl.Text)
ДлинаЗаписи
= Len(Студент) '
Номер = FreeFile
Open ИмяФайла
For Random As
Номер Len = ДлинаЗаписи '
ТекущаяЗапись
= 1
ПоследняяЗапись
= FileLen(ИмяФайла) / ДлинаЗаписи
Начало = True
If ПоследняяЗапись
= 0 Then
UserForml.Caption
= "Информация о студентах"
ПоследняяЗапись
= 1
Начало = False
End If
'
ПоказатьЗапись
If Начало =
False Then
UserForml.Caption = "Информация о студентах"
End If
TextBoxl.SetFocus
Label4.Caption = "Номер записи из " & ПоследняяЗапись
'
End Sub
'
Private Sub
CommandButton5_Click()
' Переход на последнюю запись
'
ТекущаяЗапись = ПоследняяЗапись
SpinButtonl.Value = ПоследняяЗапись Показать Запись
End Sub
'
Private Sub CommandButton6_Click()
'
' Переход на первую запись
'
SpinButtonl.Value = 1
ТекущаяЗапись
= 1 ПоказатьЗапись
End Sub
'
Private Sub SpinButtonl_Change()
'
SpinButtonl.Min
= 1
SpinButtonl.Max
= ПоследняяЗапись
ТекущаяЗапись
= SpinButtonl.Value
ПоказатьЗапись
'
End Sub
'
Private Sub UserForeinitialize ()
'
Dim ИмяПапки As String
Dim ИмяФайла As String
Dim ДлинаПути As Integer
Dim i As Integer
Управление СЗаписями:=False,
СФайлом:=Тгие
UserForml.Caption
= "Информация о студентах"
With CommandButtonS
.Picture = LoadPicture("vbal7f.bmp")
.PicturePosition
= fmPicturePositionCenter
End With
With CommandButton6
.Picture = LoadPicture("vbal7b.bmp")
.PicturePosition
= fmPicturePositionCenter
End With
Label4.Caption
= "Номер записи"
ComboBoxl.Clear
ИмяПапки = CurDir
ДлинаПути =
Len(ИмяПапки}
With Application.FileSearch
.FileName =
"*.dat"
.SearchSubFolders
= False
If .Execute(SortBy:=msoSortByFileName,
sortorder:=msoSortOrderAscending) > 0 Then
For i = 1 To
.FoundFiles.Count
ИмяФайла = Right(.FoundFiles(i),
Len{.FoundFiles(i))
ДлинаПути - 1) ComboBoxl.Addltem ИмяФайла
Next i
End If
ComboBoxl.Listlndex = 0
End With
End Sub
'
Sub Управление(СЗаписями As Boolean, СФайлом As Boolean)
'
Dim ЭлементУправления
As Object
For Each ЭлементУправления
In Controls
ЭлементУправления.Enabled = СЗаписями Next ЭлементУправления CommandButton4.Enabled = СФайлом
ComboBox1.Enabled = СФайлом
End Sub
В рассмотренном
выше приложении последовательно считывалась каждая запись из файла. Если файл
с данными небольшой, то иногда удобнее создать массив, компоненты которого являются
записями из файла произвольного доступа, а в приложении уже работать не с записями
из файла, а с элементами массива. В приведенной ниже программе записи из файла
Student.dat, созданного в приложении, считываются в массив студенты с последующим
их выводом на рабочий лист.
Sub СчитываниеФайлаВМассив
()
Dim i As Integer
Dim Студенты()
As СтудентТуре
Dim Студент
As СтудентТуре
ДлинаЗаписи
= Len(Студент)
ПоследняяЗапись
= FileLen("Student.dat") / ДлинаЗаписи + 1
ReDim Студенты(1
To ПоследняяЗапись)
Open "Student.dat"
For Random As #1 Len = ДлинаЗаписи
i = 1
Do Until EOF(l)
Get #1, i, Студенты(i)
' Вывод записи
на рабочий лист
Cells (i, 1)
.Value = Студенты(i) .Фамилия
Cells (i, 2).Value
= Студенты(i).Имя
Cells(i, 3).Value
= Студенты(i).Группа
i = i + 1 Loop Close #1
End Sub
При создании
приложений довольно часто принято перед началом его работы создавать заставки
с пояснительным текстом: какие функции выполняет приложение, кто является его
автором.
Рис.
У14.3. Пример заставки приложения
При многократном
использовании приложения появление подобной заставки может начать действовать
на пользователя, как красная тряпка на быка, поэтому, чтобы не злоупотреблять
терпением и временем пользователя в подобных случаях, необходимо предусмотреть
режим отказа от вывода заставки при активизации документа. Естественно, программа
должна хранить где-то информацию о режиме работы: с заставкой или без нее. Эту
и подобную информацию об установках режимов работы приложения обычно хранят
в создаваемых дополнительно ini-файлах.
Рассмотрим
простейший пример создания заставки приложения (рис. У14.3).
На стандартном
листе модуля наберите приведенную ниже процедуру, которая позволит запустить
диалоговое окно заставки. В области описания переменных уровня модуля описывается
пользовательский тип, используемый при записи информации о режиме работы приложения
в файл Файл.INI.
'
' Переменные
уровня приложения '
Туре ФАЙЛ_INI
Информация As
String * 30 Код As Boolean
End Type '
Public Заставка
As ФАЙЛ_INI
'
Sub ПоказатьЗаставку()
'
With UserForml
.Picture = LoadPicture("c:\my_doc\book_ex\bhv.bmp")
.PictureAlignment = fmPictureAlignmentCenter
.PictureSizeMode = fmPictureSizeModeZoom
.Caption = "Пример заставки"
.BorderColor = vbBlue
.BorderStyle = fmBorderStyleSingle
.CheckBoxl.BackColor
= vbWhite .Show
End With
'
End Sub
На листе
модуля UserForm1 наберите следующую процедуру, которая при закрытии заставки
позволит считать из флажка не отображать выбранный пользователем режим работы
для следующего открытия приложения.
Private Sub
UserFormJIerminate()
Open "Файл.INI" For Random As #1
Len = Len(Заставка)
With Заставка
.Информация
= "Отображать заставку:"
If CheckBoxl.Value
= False Then .Код = False
End If
If CheckBoxl.Value
= True Then .Код = True
End If End With
Put #1, 1, Заставка Close #1
End Sub
На листе
модуля ThisWorkbook наберите следующую процедуру, которая при открытии рабочей
книги в зависимости от указанного в файле Файл.INI режима либо будет отображать
заставку, либо нет.
Private Sub
Workbook_Open()
Open "Файл.INI"
For Random As #1
Len = Len(Заставка)
Get #1, 1, Заставка
Close #1
If Заставка.Код = False Then ПоказатьЗаставку
End Sub