| Пособие-самоучитель on-line "Visual Basic с нуля" |
Глава 7. Работа с текстовыми файлами. Цикл Do...Loop.
Скачать исходник программы "Demo" | Дата создания 20.11.2004 {Автор 4us}

Ну, учимся работать с текстовыми файлами. Это нам нужно, чтобы прочитать существующий файл, изменить его, или создать свой. Крому того, в текстовом файле удобно хранить служебные данные собственной программы, например установки пользователя, результаты обработки данных и т.п.
Текстовой файл, собственно по названию, содержит в себе текстовые символы, ну и символы типа возврат каретки или перевод строки. Традиционно они имеют расширение .txt для текста, .dat для данных, .bat для исполняемых (командных) файлов, ну Windows еще использует .ini, .log, .inf. Читать и записывать их надо последовательно, символ за символом, начиная с первого.

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

Для открытия файла используется оператор Open. Синтаксис его такой:

Open путь For режим As #номер файла
Примечание: для открытия файлов прямого доступа, или двоичных файлов оператор Open содержит еще кое-какие аргументы, но сейчас мы их не используем и опускаем.

Все указанные аргументы должны обязательно присутствовать:
путь - это полный путь к открываемому файлу - (строковое выражение) пишется в кавычках, может состоять из нескольких строк, соединенных знаком конкатенации &. (Например "c:\MyText\referat.txt" или "c:\Mytext\" & "referat.txt")
режим - способ открытия файла и представляет собой ключевые слова. В этой главе му будем использовать Input для считывания данных из файла, Output - для записи данных в файл, и Append - для добавления данных в файл. В режиме Input можно еще раз открыть уже открытый файл под другим номером, не закрывая его, в режимах Output и Append надо сначала закрыть файл, а потом открыть его снова.
#номер файла - это всего лишь номер, по которому VB индентефицирает открытый файл. Он может быть любой от #1 до #255. Однако, лучше всего использовать функцию FreeFile (см. в примере), которая сразу возвратит свободный номер в переменную, и тебе нет нужды искать по своему коду, открыт ли у тебя файл под номером, например #3.

Кстати сказать, после того, как передача или прием данных в (из) файл(а) будут закончены, его надо закрыть, делается это оператором Close. Если этот оператор написать без всяких аргументов, он закроет все открытые файлы. Если же нам надо закрыть файл, скажем номер 2, то пишем Close #2. Попробуем работать с файлами на примерах:

СЧИТЫВАНИЕ из текстового файла.

Создадим новый .exe проект в какой-нибудь папке и в ту же папку положим небольшой текстовой файл (у меня например "Справка.txt"). На форме разместим кнопку Command1 и текстовое поле Text1. В свойствах Text1 свойство Multiline поставим в True (чтобы текст переносился по строкам), а свойство ScrollBars в 2 - Вертикаль (чтобы можно было прокручивать текст, если он не уместился) смотри рис.15.
Рисунок 15.
Откроем окно кода и в (Genarel) объявим переменные F для хранения номера свободного файла, MyText и AllMyText - для хранения считываемого текста:

`Dim` `F As Long
Dim MyText As String
Dim AllMyText As String`

Создадим прцедуру Command1_Click() (щелкнув мышью по Command1 в выпадающем списке в окне кодов в верхнем левом поле, там где (General)). В теле образовавщейся процедуры. Можно также щелкнуть два раза по кнопке Command1 в режиме Объект и перейти в режим Код - там появится нужная нам процедура.

`Private Sub` `Command1_Click()`

Напишем для определения номера свободного файла

`F = FreeFile`

и откроем файл для чтения

`Open` `App.Path & "\Справка.txt" For Input As #F`

Обратите внимание, что для указания пути файла мы опять используем функцию App.Path. Если бы мы написали просто "c:\VB\example\Справка.txt", то при переносе нашей паки с программой на другой диск или компьютер этот путь оказался бы ложным. А функция App.Path всегда возвращает путь, где лежит наша программа. Только перед именем файла не забывайте ставить обратный слеж (\), иначе запись работать не будет.
Для считывания строки текста существует оператор Line Input. Попробуем считать с его помощью содержимое файла в переменную MyText :

`Line Input``#F, MyText`

Передадим значение MyText переменной в Text1, чтобы увидеть, что мы там считали:

`Text1.Text = MyText`

затем закроем файл

`Close``#F
End Sub`

и запустим нашу программу. Когда мы нажмем кнопку Command1, то в Text1 появиться содержимое файла "Справка.txt". Проблема только в том, что, если,( как и случилось в нашем файле "Справка.txt"), при создании текста применялось нажатие кнопки ENTER (перевод строки), то оператор Line Input считает текст до этого знака и все, потому, что строка кончилась. Чтобы этого избежать, мы применим цикл и будем считывать строки до конца файла. Для этого придется разобраться с новым для нас циклом по условию Do... Loop.

Цикл по условию Do...Loop

Это очень простая вещь. Цикл работает до тех пор, пока не выполнится какое-нибудь условие. Например мы будем увеличивать переменную X до тех пор, пока оне не станет равной, например, 100. Для этого применяется аргумент Until:

Do Until x>=100
x=x+1
Loop

при этом когда цикл закончится x будет равно 100. Можно записать его по другому, при этом смысл работы цикла не изменится:

Do
x = x + 1
Loop Until x >=100

Можно цикл записать наоборот, и он будеn выполняться до тех пор, пока соблюдается какое-то условие. Для этого применяется аргумент While (делать, пока...) :

Do While x < 100
x = x + 1
Loop

или же:

Do
x = x + 1
Loop While x < 100

Во всех четырех случаях результат будет один. Цикл остановится, когда X=100. Только надо обращаться с ними аккуратно. Если ты поставишь условие, которое изначально ложно, цикл не выполнится ни разу, и наоборот если условие будет истинно всегда, возникнет бесконечный цикл и программа по-сути зависнет. Вот этот цикл не будет выполняться:

Do While x =100
x = x + 1
Loop

а этот будет бесконечным

Do Until x < 0
x = x + 1
Loop

Ну а теперь используем наш цикл для считывания строк из файла до тех пор, пока не настанет конец файла. Чтобы узнать, достигнут ли конец файла, можно использовать функцию EOF(номер файла), которая примет значение True, как только конец файла будет достигнут. Теперь переделаем нашу процедуру следующим образом:

`Private Sub` `Command1_Click() '1
Text1.Text = "" '2
F = FreeFile '3
Open App.Path & "\Справка.txt" For Input As #F '4
Do Until EOF(F) '5
Line Input #F, MyText '6
Text1.Text = Text1.Text & MyText & vbCrLf '7
Loop '8
Close #F` `'9
End Sub '10`

По строкам здесь:

1 - объявление нашей процедуры
2 - очистка Text1
3 - присваиваем переменной F свободный номер файла
4 - открываем файл "Справка.txt" для последовательного чтения
5 - цикл по условию: до тех пор пока не конец файла
6 - DO в цикле считываем каждую строчку
7 - Присоединяем очередную строку к Text1 и ставим перевод строки (vbCrLf) чтоб красиво было
8 - LOOP завершаем цикл
9 - закрываем наш файл
10- конец процедуры

Ну вот и готово.

Сейчас мы считаем файл другим способом, с помощью функции Input. Синтаксис ее такой:
Input(число, [#]номерФайла)

Смысл ее такой, что она из файла [#]номерФайла, открытого в режиме Input считывает число знаков. Мы используем ее также, как оператор Line Input, только считывать будем не по одной строчке, а по одному символу, и собирать их будем в переменной AllMyText, значение которой присвоим потом текстбоксу Text1. Поместим на нашу форму еще одну кнопку Command2 (свойство Caption присвоим "Функция Input") и создадим для нее прцедуру, где и используем функцию Input.

`Private Sub` `Command2_Click()
F = FreeFile
Open App.Path & "\Справка.txt" For Input As #F
Do Until EOF(F)
MyText = Input(1, #F)
AllMyText = AllMyText & MyText
Loop
Close #F
Text1.Text = AllMyText
End Sub`

Здесь все почти в точности, как и в предыдущем примере, только суть несколько другая.

Ну и в дополнение попробуем прочитать наш файл с помощью оператора Input #. Это не самая лучшая идея, так как эта инструкция считывает файл, желательно, записанный с оператора Write #. Синтаксис такой:

Input #номерФайла, списокПеременных

а смысл в том, что она из последовательно открытого в режиме Input файла с номером #номерФайла считывает в переменные списокПеременных данные, разделенные запятыми. Этот оператор для считывания обычных текстов не годится, а вот данных, а потом использование их в переменных - сколько угодно. Но мы попробуем считать все-таки этот наш файл и этим оператором.
Опять кладем на форму кнопку Command3 и там ваяем по тому же принципу:

`Private Sub` `Command3_Click()
F = FreeFile
Open App.Path & "\Справка.txt" For Input As #F
Do Until EOF(F)
Input #F, MyText
AllMyText = AllMyText & ", " & MyText
Loop
Close #F
Text1.Text = AllMyText
End Sub`

Это, конечно, некорректное применение оператора, но мы вернемся к нему, когда будем рассматривать запись в файл с помощью оператора Write #. Как ты видишь, запятые не выводятся, приходится их запихивать насильно, не всегда к месту, но ради полноты, я посчитал надо показать и это. Все, теперь запись.

ЗАПИСЬ в текстовой файл.

Как и для считывания, прежде, чем записывать в текстовой файл, нужно получить к нему доступ. Для этого используем оператор Open с ключевым словом Output.
Добавим на форму еще кнопку Command4. Создадим для нее процедуру и напишем там:

`Private Sub` `Command4_Click()
F = FreeFile
Open App.Path & "\Запись.txt" For Output As #F`

Таким образом мы открыли файл с последовательным доступом, который называется "Запись.txt" в нашей текущей директории под свободным номером #F, для записи (For Output). При этом, если такого файла не существует, он будет создан, а если существует и в нем что-то записано, то это что-то будет стерто, а вместо будет помещены наши новые данные, которые мы сейчас будем записывать, например, скажем с помощью оператора Print #. Записать его можно аналогично оператору считывания Line Input:

`Print``#F, Text1.Text`

То есть, мы записываем содержимое нашего текстбокса (если там что-то есть. Считайте в текстбокс Text1 наш файл Справка.txt нажатием одной из кнопок Command1-Command3) в файл "Запись.txt". Затем закрываем файл и конец процедуре:

`Close``#F
End Sub`

Ты теперь можешь открыть этот файл с помощью Виндусового Блокнота или в любом текстовом редакторе и посмотреть его. Или напиши в нашей программе свой код, чтоб считать этот файл в Text1 и сразу его посмотреть.
В принципе, если тебе это надо, оператор Print # может форматировать текст, т.е. менять отступы от края, вставлять пробелы, но только между переменными, а не конечно в середину, скажем, нашего текста. Для этого используется аргументы Spc (количество пробелов) для введения пробелов и Tab(номер столбца) для вывода данных по столбцам. Положим на форму еще текстбокс Text2 и кнопку Command5 и в ее процедуре напишем код для форматированной записи. Потом считаем наши записи в Text2 с помощью оператора Line Input. С этим, я думаю, ты разберешся сам. (Не забудь поставить свойства Text2:свойство Multiline поставим в True, а свойство ScrollBars в 2 - Вертикаль.

`Private Sub` `Command5_Click()
F = FreeFile
Open App.Path & "\Запись.txt" For Output As #F
'печатаем тексты с 15-й позиции
Print #F, Spc(15); "Я вывожу этот текст"
Print #F, Spc(15); "очень красиво"
Print #F, Spc(15); "потому, что я настоящий"
Print #F, Spc(15); "ПРОГРАММИСТ"
'печатаем пустую строку
Print #F,
'печатаем тексты в 30-ем, 40-м и 50-м стобцах соответственно
Print #F, Tab(30); "тридцатый столбец"
Print #F, Tab(40); "сороковой столбец"
Print #F, Tab(50); "пятидесятый столбец"
'если оператор завершать точкой с запятой, то перехода на следующую строку не будет
Print #F, Spc(15); "Печатаю текст";
Print #F, Spc(15); "не очень хорошо"
' и наконец несколько текстов в одном операторе
Print #F, Spc(10); "10 пробелов"; Tab(30); "30-й столбец+ 10 пробелов в начале"; Spc(5); "Пять пробелов"
Close #F`

`'считаем записанный текст в Text2
Text2.Text = ""
MyText = ""
F = FreeFile
Open App.Path & "\Запись.txt" For Input As #F
Do Until EOF(F)
Line Input #F, MyText
Text2.Text = Text2.Text & MyText & vbCrLf
Loop
Close #F
End Sub`

Теперь запишем чего-нибудь в файл с помощью оператора Write #, а потом, уже корректно считаем это оператором Input # о котором мы уже говорили в этой главе. С помощью оператора Write # удобно записывать данные твоей программы. Есть две особенности. Первое - данные разделяются разделителем (запятой), и второе - данные надо считывать в переменные того же типа, что и запись в файле ( то есть число - в число, дату в дату, стоку в строку и т.п., иначе возникнет ошибка) и представляются они в файле в достаточно своеобразном виде - каждый в своем формате. Сейчас разберем это на примере, я так думаю, будет понятнее. Положим еще одну кнопку Command6 на форму и в ней объявим переменные четырех разных типов.

`Private Sub` `Command6_Click()
Dim Chislo As Long ' числовая
Dim Stroka As String ' строковая
Dim Logika As Boolean ' логическая
Dim DDate As Date' дата (не путайте с Data)`

Надо заметить, что число выводится в файл как число, строка - как строка в кавычках, логическая переменная может принимать только два значения Да и Нет в формате #False# или #True#, а дата в виде #2004-07-20# , что соответствует 20 июля 2004 года. Дальше присваиваем переменным какие-нибудь значения в соответствующем формате

`Chislo = 15
Stroka = "пятнадцать"
Logika = True
DDate = #7/20/2004#`

`' записываем данные в файл
' обратите внимание, я нарочно разбил оператор Write # на 2, а считываю одним,
'чтобы показать, что нет разницы, сколько операторов Write# или Input# вы будете использовать`

`F = FreeFile
Open App.Path & "\Запись.txt" For Output As #F
Write #F, Chislo; Stroka
Write #F, Logika; DDate
Close #F`

`'теперь считаем данные с помощью оператора Input#
F = FreeFile
Open App.Path & "\Запись.txt" For Input As #F
Input #F, Chislo, Stroka, Logika, DDate
'и выведем их в Text2
Text2.Text = Chislo & " " & Stroka & " " & Logika & " " & DDate
Close #F
End Sub`

Сейчас, когда ты запустишь программу, ты увидишь, что в Text2 данные вывелись в очень достойном виде, но это потому, что мы используем для считывания оператор Input #. Если же ты откроешь файл " Запись" в блокноте или считаешь файл с помощью оператора Line Input, то увидишь несколько иную картину, вот такую:

15,"пятнадцать"
#TRUE#,#2004-07-20#

Поэтому делать текстовые файлы для чтения их в других приложения бессмысленно. Но использовать операторы Write# - Input# внутри программы для работы с собстенными данными очень удобно.

Добавление данных в текстовой файл.

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

`Private Sub` `Command7_Click()
Text2.Text = ""
MyText = ""
F = FreeFile
'открываем файл для дабавления
Open App.Path & "\Запись.txt" For Append As #F
Print #F, Spc(15); "Я добавляю этот текст снова и снова"
Close #F`

`'считаем записанный текст в Text2
F = FreeFile
Open App.Path & "\Запись.txt" For Input As #F
Do Until EOF(F)
Line Input #F, MyText
Text2.Text = Text2.Text & MyText & vbCrLf
Loop
Close #F
End Sub`

Ну вот и все, что я хотел сообщить тебе сегодня про текстовые файлы. Ну нам с файлами еще работать и работать. . Исходник можешь скачать вверху страницы.

Copyright © 2004 4us