Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Работа с файлами и каталогами
Очень часто нужно сохранить какие-либо данные. Для этого существует три способа: сохранение в файл, сохранение в базу данных и сохранение в реестр Windows. Первый способ используется при сохранении информации небольшого объема. Если объем велик, то лучше (и удобнее) воспользоваться базой данных. В реестр Windows обычно сохраняют какие-либо настройки приложения.
Открытие и закрытие файла
Прежде чем работать с файлом, необходимо создать объект файла с помощью инструкции Open
. Инструкция имеет следующий формат:
Open <Имя файла> For <Режим> [Access <Доступ>] [<Блокировка>]
As [#]<Дескриптор> [Len=<Длина>]
В параметре <Имя файла>
указывается путь к файлу. Путь может быть абсолютным или относительным. При указании относительного пути путь определяется с учетом местоположения текущего рабочего каталога, возвращаемого функцией CurDir()
, а также текущего диска (сменить текущий диск позволяет процедура ChDrive()
). Чтобы получить путь к папке, в которой находится файл с рабочей книгой, в Excel можно воспользоваться свойством Path
объекта ThisWorkbook
. Пример создания файла:
Open ThisWorkbook.Path & "\test.txt" For Output As #1
Параметр <Режим>
может принимать следующие значения:
Input
— чтение в последовательном режиме. Если файл не существует, то генерируется ошибка;Output
— запись в последовательном режиме. Если файл не существует, то он будет создан. Если файл существует, то он будет перезаписан;Append
— запись в последовательном режиме. Если файл не существует, то он будет создан. Запись осуществляется в конец файла. Содержимое файла не удаляется;Random
— чтение и запись в произвольном режиме. Если файл не существует, то он будет создан. Содержимое файла не удаляется;Binary
— чтение и запись в бинарном режиме. Если файл не существует, то он будет создан. Содержимое файла не удаляется.
Параметр <Доступ>
задает тип операции с открываемым файлом. Допустимые значения:
Read
— только чтение;Write
— только запись;Read Write
— чтение и запись.
Необязательный параметр <Блокировка>
может принимать следующие значения:
Shared
— другой процесс может читать из файла и писать в файл;Lock Read
— другой процесс не сможет читать из файла;Lock Write
— другой процесс не сможет писать в файл;Lock Read Write
— другой процесс не сможет читать из файла и писать в файл.
Параметр <Дескриптор>
позволяет указать уникальный целочисленный номер файла в диапазоне от 1
до 511
. Перед номером может быть добавлен символ #
. Сгенерировать свободный уникальный номер позволяет функция FreeFile([<Значение>])
. Если в параметре <Значение>
задано значение 0
, или параметр не указан, то генерируется число в диапазоне от 1
до 255
, а если значение 1
— то генерируется число в диапазоне от 256
до 511
. Пример использования функции FreeFile()
:
Dim fd As Integer
fd = FreeFile()
Open ThisWorkbook.Path & "\test.txt" For Output As #fd
В необязательном параметре <Длина>
указывается целое число до 32 767
. При использовании произвольного режима значение задает длину записи, а при использовании последовательного режима — размер буфера. Значение игнорируется в бинарном режиме.
Для закрытия файла используется инструкция Close
. Формат инструкции:
Close [ [#]<Дескриптор1>[, ..., [#]<ДескрипторN>] ]
Инструкция закрывает файлы, дескрипторы которых перечислены через запятую. Если дескрипторы не указаны, то закрываются все открытые файлы. При завершении программы все открытые файлы автоматически закрываются.
Файлы могут быть открыты в трех режимах: последовательном, произвольном и бинарном. Рассмотрим эти режимы подробно.
Чтение и запись в последовательном режиме
Последовательный режим применяется при указании значений Input
, Output
и Append
после ключевого слова For
в инструкции Open
. Запись в файл производится с помощью инструкции Write
. Формат инструкции:
Write #<Дескриптор>, [<Значения>]
В параметре <Дескриптор>
указывается номер файла, который использовался при открытии файла. В параметре <Значения>
задаются записываемые значения через запятую, точку с запятой или через пробел (эквивалентно указанию точки с запятой). Если точка с запятой указывается в конце инструкции Write
, то следующее выводимое значение будет вставляться на одной строке с предыдущим выводом через запятую, а не на новой строке. Если параметр <Значения>
не указан, то вставляется пустая строка. Значения записываются в файл в следующих форматах:
- строки внутри двойных кавычек. Обратите внимание на то, что записываемая строка не должна содержать двойных кавычек, иначе при считывании строка будет разбита на несколько подстрок;
- вещественные числа с разделителем в виде точки;
- дата и время в универсальном формате;
- логические значения
True
иFalse
в виде#TRUE#
и#FALSE#
соответственно; - значение
Null
в виде#NULL#
.
Пример записи в файл:
Open ThisWorkbook.Path & "\test.txt" For Output As #1
Write #1, "Пример" ' "Пример"
Write #1, "При""мер" ' "При""мер"
Write #1, 10 ' 10
Write #1, 55.6 ' 55.6
Write #1, True ' #TRUE#
Write #1, False ' #FALSE#
Write #1, Null ' #NULL#
Write #1, #8/20/2012# ' #2012-08-20#
Write #1, True, 51 ' #TRUE#,51
Write #1, True; 51 ' #TRUE#,51
Write #1, ' Пустая строка
Close #1
Чтение из файла производится с помощью инструкции Input
. Формат инструкции:
Input #<Дескриптор>, <Список переменных через запятую>
В параметре <Дескриптор>
указывается номер файла, который использовался при открытии файла. Во втором параметре задается список переменных, в которых сохранятся считываемые значения. Например, считать данные, записанные в предыдущем примере, можно следующим образом:
Dim v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13
Open ThisWorkbook.Path & "\test.txt" For Input As #1
Input #1, v1 ' "Пример"
Input #1, v2, v3 ' "При" "мер"
Input #1, v4 ' 10
Input #1, v5 ' 55,6
Input #1, v6 ' True
Input #1, v7 ' False
Input #1, v8 ' Null
Input #1, v9 ' 20.08.2012
Input #1, v10, v11 ' True 51
Input #1, v12, v13 ' True 51
Close #1
Обратите внимание на четвертую инструкцию. Ранее мы записывали строку, в состав которой входит двойная кавычка. При считывании одна строка разбивается на две подстроки. В результате переменная v2
будет иметь значение "При"
, а переменная v3
— значение "мер"
.
Для записи в файл можно воспользоваться также инструкцией Print
. Формат инструкции:
Print #<Дескриптор>, [<Значения>]
В параметре <Дескриптор>
указывается номер файла, который использовался при открытии файла. В параметре <Значения>
задаются записываемые значения через запятую, точку с запятой или через пробел (эквивалентно указанию точки с запятой). Если указывается запятая, то следующее значение выводится в начале следующей зоны (по умолчанию начало зоны расположено в каждом 14-ом столбце), а если точка с запятой — то следующее значение выводится сразу после предыдущего:
Print #1, "1", "2", "3" ' 1 2 3
Print #1, "1"; "2"; "3" ' 123
Если точка с запятой указывается в конце инструкции Print
, то следующее выводимое значение будет вставляться на одной строке с предыдущим выводом, а не на новой строке. Если параметр <Значения>
не указан, то вставляется пустая строка. Значения записываются в файл в следующих форматах:
- строки без двойных кавычек;
- вещественные числа с разделителем в виде запятой;
- дата и время в коротком формате;
- логические значения
True
иFalse
в виде строкTrue
иFalse
соответственно; - значение
Null
в виде строкиNull
.
Пример записи в файл:
Open ThisWorkbook.Path & "\test.txt" For Output As #1
Print #1, "Пример" ' Пример
Print #1, "При""мер" ' При"мер
Print #1, 10 ' 10
Print #1, 55.6 ' 55,6
Print #1, True ' True
Print #1, False ' False
Print #1, Null ' Null
Print #1, #8/20/2012# ' 20.08.2012
Print #1, True, 51 ' True 51
Print #1, True; 51 ' True 51
Print #1, ' Пустая строка
Close #1
Второй параметр может содержать следующие функции:
Spc(<Количество>)
— позволяет вставить указанное количество пробелов. Пример:
Print #1, "1"; Spc(5); "2" ' 1 2
Print #1, "1"; Spc(10); "2" ' 1 2
Tab[(<Количество>)]
— если функция указывается без параметра, то происходит переход в начало следующей зоны (эквивалентно вставке запятой между значениями):
Print #1, "1", "2" ' 1 2
Print #1, "1"; Tab; "2" ' 1 2
Параметр <Количество>
задает номер столбца, с которого начинается вывод:
Print #1, """"; Tab(10); "1"; """" ' " 1"
Прочитать файл, записанный с помощью инструкции Print
, позволяет инструкция Line Input
. Чтение производится построчно при каждом вызове инструкции. Формат инструкции:
Line Input #<Дескриптор>, <Переменная>
Прочитаем две строки из записанного ранее файла:
Dim s As String
Open ThisWorkbook.Path & "\test.txt" For Input As #1
Line Input #1, s
Debug.Print s ' Пример
Line Input #1, s
Debug.Print s ' При"мер
Close #1
Чтобы прочитать все строки из файла следует воспользоваться функцией EOF(<Дескриптор>)
. Функция возвращает значение True
, если был достигнут конец файла, и False
— в противном случае. Вывести все строки из файла позволяет следующий код:
Dim s As String
Open ThisWorkbook.Path & "\test.txt" For Input As #1
Do While Not EOF(1)
Line Input #1, s
Debug.Print s
Loop
Close #1
Инструкция Width
позволяет указать предпочитаемую ширину строки. Формат инструкции:
Width #<Дескриптор>, <Ширина>
Параметр <Ширина>
может содержать значения в диапазоне от 0
до 255
. Если указано значение 0
, то ширина не ограничена. Если длина строки больше указанного значения, то значение игнорируется и строка выводится полностью. Пример указания ширины, равной трем символам:
Dim i As Integer
Open ThisWorkbook.Path & "\test2.txt" For Output As #1
Width #1, 3
For i = 1 To 9
Print #1, CStr(i);
Next
Print #1, "Очень длинная строка"
Close #1
' Результат:
' 123
' 456
' 789
' Очень длинная строка
Для чтения файла можно также воспользоваться функцией Input(<Количество символов>, [#]<Дескриптор>)
, которая читает из файла указанное количество символов и возвращает их. Пример:
Open ThisWorkbook.Path & "\test2.txt" For Output As #1
Print #1, "строка"
Close #1
Open ThisWorkbook.Path & "\test2.txt" For Input As #1
Debug.Print Input(1, #1) ' с
Debug.Print Input(5, #1) ' трока
Close #1
Чтение и запись в произвольном режиме
Произвольный режим применяется при указании значения Random
после ключевого слова For
в инструкции Open
. Длина записи в произвольном режиме является фиксированной и задается с помощью параметра <Длина>
(целое число до 32 767
) в инструкции Open
. При чтении и записи длина должна быть указана одинаковой. Запись в файл производится с помощью инструкции Put
. Формат инструкции:
Put [#]<Дескриптор>, [<Позиция>], <Значение>
В параметре <Дескриптор>
указывается номер файла, который использовался при открытии файла. В параметре <Позиция>
задается номер позиции (нумерация начинается с 1
) в которую производится запись. Если параметр не указан, то запись производится в следующую позицию после текущей позиции. Параметр <Значение>
задает записываемое значение. Если длина значения больше длины, указанной в параметре <Длина>
, то генерируется ошибка. Если производится запись строки произвольной длины, то значение в параметре <Длина>
должно быть на 2 байта больше фактической длины строки. Пример записи в файл:
Open ThisWorkbook.Path & "\test3.txt" For Random As #1 Len = 10
Put #1, , 123456
Put #1, , 12.5
Put #1, , "строка"
Close #1
Чтение файла производится с помощью инструкции Get
. Формат инструкции:
Get [#]<Дескриптор>, [<Позиция>], <Переменная>
В параметре <Дескриптор>
указывается номер файла, который использовался при открытии файла. В параметре <Позиция>
задается номер позиции (нумерация начинается с 1
) из которой производится чтение. Если параметр не указан, то читаются данные из следующей позиции после текущей позиции. Пример:
Dim v1 As Long, v2 As Double, v3 As String
Open ThisWorkbook.Path & "\test3.txt" For Random As #1 Len = 10
Get #1, , v1
Get #1, , v2
Get #1, , v3
Close #1
Debug.Print v1, v2, v3 ' 123456 12,5 строка
Чтение и запись в бинарном режиме
Бинарный режим применяется при указании значения Binary
после ключевого слова For
в инструкции Open
. Длина записи в бинарном режиме является фиксированной и равна одному байту. Если указано значение в параметре <Длина>
, то это значение игнорируется.
Чтение и запись в бинарном режиме осуществляется точно также, как и при использовании произвольного режима. Прочитать данные из файла позволяет инструкция Get
, а записать данные инструкция Put
. В параметре <Позиция>
в этих инструкциях указывается порядковый номер байта.
Пример записи строки в файл:
Open ThisWorkbook.Path & "\test4.txt" For Binary As #1
Put #1, , "строка"
Close #1
Пример чтения строки из файла:
Dim s As String
Open ThisWorkbook.Path & "\test4.txt" For Binary As #1
s = Space(LOF(1))
Get #1, , s
Close #1
Debug.Print s ' строка
В этом примере мы воспользовались функцией LOF(<Дескриптор>)
, которая позволяет получить длину файла в байтах. Чтобы считать данные из бинарного файла в строковую переменную необходимо в переменной создать строку такого же размера. В данном случае мы с помощью функции Space()
создаем строку из такого же количества символов, что и размер файла. Обратите внимание на то, что использовать функцию EOF()
в бинарном режиме нельзя, так как она всегда возвращает значение False
.
Для чтения бинарного файла можно также воспользоваться следующими функциями:
Input(<Количество символов>, [#]<Дескриптор>)
— читает из файла указанное количество символов и возвращает их;InputB(<Количество байтов>, [#]<Дескриптор>)
— читает из файла указанное количество байтов и возвращает их.
Запишем строку в бинарный файл, а затем считаем ее с помощью функции Input()
:
Open ThisWorkbook.Path & "\test5.txt" For Binary As #1
Put #1, , "строка"
Close #1
Open ThisWorkbook.Path & "\test5.txt" For Binary As #1
Debug.Print Input(1, #1) ' с
Debug.Print Input(5, #1) ' трока
Close #1
Перемещение указателя внутри файла
Каждый открытый файл поддерживает указатель на текущую позицию в файле. Для перемещения и манипулирования позицией указателя внутри файла используются следующие функции и процедуры:
Loc(<Дескриптор>)
— в произвольном режиме возвращает номер текущей позиции, а в бинарном режиме — номер текущего байта. Первый байт имеет позицию0
;Seek(<Дескриптор>)
— в произвольном режиме возвращает номер текущей позиции, а в бинарном режиме — номер текущего байта. Первый байт имеет позицию1
;Seek [#]<Дескриптор>, <Позиция>
— устанавливает указатель в позицию<Позиция>
. Первый байт имеет позицию1
. Если указано значение меньше1
, то генерируется ошибка. Если значение превышает количество байтов в файле, то файл увеличивается до указанной позиции;LOF(<Дескриптор>)
— возвращает длину файла в байтах.
Запишем строку в файл в бинарном режиме, а затем переместим указатель в начало файла и считаем содержимое файла посимвольно в строку (листинг 12.1).
Листинг 12.1. Перемещение указателя внутри файла
Dim s As String, pos As Long
Open ThisWorkbook.Path & "\test4.txt" For Binary As #1
Put #1, , "строка"
Debug.Print Loc(1), Seek(1) ' 6 7
Seek #1, 1 ' Перемещаем в начало файла
Debug.Print Loc(1), Seek(1) ' 0 1
Do While pos < LOF(1) ' Считываем по одному байту
s = s & Input(1, #1)
pos = Loc(1)
Loop
Close #1
Debug.Print s ' строка
Чтение и запись файлов в кодировке UTF-16
Все строки, которые мы записывали ранее, сохранялись в файле в кодировке, принятой в системе по умолчанию. В моем случае в кодировке Windows-1251. Если необходимо записать данные в кодировке UTF-16 или прочитать данные, то можно воспользоваться функцией StrConv()
(см. разд. 6.8) для преобразования кодировки. В качестве примера запишем данные в фай, а затем прочитаем и выведем их (листинг 12.3).
Листинг 12.2. Чтение и запись файлов в кодировке UTF-16
Dim s As String
s = "строка"
s = Chr(255) & Chr(254) & StrConv(s, vbUnicode, 1049)
Open ThisWorkbook.Path & "\enc.txt" For Binary As #1
Put #1, , s
Close #1
Open ThisWorkbook.Path & "\enc.txt" For Binary As #1
s = Space(LOF(1) - 2)
Seek #1, 3
Get #1, , s
Close #1
s = StrConv(s, vbFromUnicode, 1049)
Debug.Print s ' строка
Обратите внимание на инструкцию
s = Chr(255) & Chr(254) & StrConv(s, vbUnicode, 1049)
Комбинация символов с кодами 255
и 254
является меткой порядка байтов (сокращенно BOM (Byte Order Mark)). Эта метка является обязательной для кодировки UTF-16. При чтении данных мы пропускаем их и начинаем чтение с позиции 3
.
Чтение и запись файлов в кодировке UTF-8
Работа с файлами в кодировке UTF-8 выполняется сложнее. В этом случае необходимо воспользоваться функциями MultiByteToWideChar()
и WideCharToMultiByte()
, входящими в состав Win32 API. Чтобы это стало возможным, нужно в самом начале модуля вставить следующий код:
Private Declare Function MultiByteToWideChar Lib "kernel32.dll" _
(ByVal CodePage As Long, ByVal dwFlags As Long, _
ByVal lpMultiByteStr As String, ByVal cchMultiByte As Long, _
ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" _
(ByVal CodePage As Long, ByVal dwFlags As Long, _
ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, _
ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, _
ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) _
As Long
Далее создадим две функции: ToUtf8()
(для преобразования строки в кодировку UTF-8) и FromUtf8()
(для преобразования кодировки UTF-8 в Unicode):
Public Function ToUtf8(ByVal s As String) As String
Dim n As Long, res As String
res = String$(Len(s) * 2, vbNullChar)
n = WideCharToMultiByte(65001, &H0, StrPtr(s), Len(s), _
StrPtr(res), Len(s) * 2, 0&, 0&)
ToUtf8 = Left$(StrConv(res, vbUnicode), n)
End Function
Public Function FromUtf8(ByVal s As String) As String
Dim n As Long, res As String
res = String$(Len(s), vbNullChar)
n = MultiByteToWideChar(65001, &H0, s, Len(s), StrPtr(res), _
Len(res))
FromUtf8 = Left$(res, n)
End Function
Теперь мы можем пользоваться этими функциями для чтения и записи файлов в кодировке UTF-8:
Dim s As String
s = "строка"
s = ToUtf8(s)
Open ThisWorkbook.Path & "\utf8.txt" For Binary As #1
Put #1, , s
Close #1
Open ThisWorkbook.Path & "\utf8.txt" For Binary As #1
s = Space(LOF(1))
Get #1, , s
Close #1
s = FromUtf8(s)
Debug.Print s ' строка
Помощь сайту
Yandex-деньги: 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов