Основы офисного программирования и язык VBA

         

Запись в файлы последовательного доступа


При записи и чтении данных в последовательный файл происходит автоматическое редактирование данных. В зависимости от того, на кого ориентировано это редактирование, человека или программу компьютера применяются две формы редактирования. Соответственно операторы записи и чтения существуют в двух вариантах:

  1. Для записи "человеко-ориентированных" данных применяется оператор Print#, представляющий данные в формате, подготовленном для отображения на экране дисплея. По существу, мы уже хорошо знакомы с этим оператором, поскольку ни одна наша программа не обходилась без вывода данных в окно отладки, а применяемый для этих целей метод Print объекта Debug по синтаксису и по действию подобен оператору Print#.
  2. Для записи данных, обрабатываемых после их чтения программой, используется оператор Write#. Заметим, в каком - то смысле это более универсальный оператор, чем Print, он, например, не зависит от локализации.

Оператор Print# записывает в файл форматированные данные. Его вызов имеет вид:

Print #номер-файла, [список-вывода]

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

[{Spc(n) | Tab[(n)]}] [выражение] [симв-поз]

  • Spc(n) задает количество вставляемых пробелов.
  • Альтернативный параметр Tab(n) указывает абсолютный номер n столбца, в котором будет начинаться текст, определяемый параметром выражение. Если не указывать аргумент у Tab, то позицией вставки является следующая зона печати. (Можно полагать, что при выводе экран разделен на зоны, и табуляция позволяет переходить от одной зоны к другой).
  • Параметр выражение задает выражение, значение которого после редактирования и преобразования его в текстовую строку будет записано в файл.
    На выражения не накладывается особых ограничений, Это могут быть как строковые, так и числовые выражения, они могут содержать данные разных типов. Даты записываются в файл в кратком формате, значения булевых переменных - как ключевые слова Ложь (False) или Истина (True), пустое значение Empty - как пустое слово, нулевое значение Null выводится как "Null". Данные об ошибке выводятся в виде кода ошибки. Числовые данные выводятся в формате, зависящем от локализации. При выводе можно вызвать для форматирования данных функцию Format.
  • Параметр симв-поз задает положение следующего выражения. Если он равен ";" или пробелу, вставка следующего выражения будет происходить сразу за последним выведенным символом, Tab(n) указывает номер n столбца, начиная с которого будет выводиться выражение. Tab без аргумента или "," - переход в следующую позицию табуляции (зону печати).


Создадим теперь открытый ранее файл read.me, записывая в него выражения, позволяющие продемонстрировать все возможности оператора Print:

Пример 14.2.

(html, txt)

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

Public Sub ReadingWithLine() Dim MyStr As String

Close #1 Open Path & "read.me" For Input As #1 Do While Not EOF(1) Line Input #1, MyStr Debug.Print MyStr Loop End Sub



Текст в окне отладки выглядит в полном соответствии с нашими ожиданиями. Вот он:

Первая строка файла Зона 1 Зона 2 Зона 1 Зона 2 Привет,старик! Привет,старик! 5 пробелов Старик, привет! one two False 14.06.99 Null 3,1416 3,14 03,142 6 Error 2000

Обратите внимание, ошибки, возбуждаемые методом Raise и функцией CVErr, редактируются по-разному, в первом случае записывается только код ошибки, во втором ѕ код сопровождается ключевым словом Error, не переводимым в локализованных версиях.

Заметьте, точно такой же текст можно получить, если в процедуре WritingWithPrint заменить оператор Print на Debug.Print, поскольку этот метод и этот оператор порождают одинаковый результат, разница лишь в том, что один из них помещает результаты в файл, а другой ѕ в окно отладки.



При выводе данных можно управлять шириной выводимых строк. Ширину выводимых строк для открытого файла устанавливает оператор:

Width #номер-файла, ширина

Параметр ширина принимает значения от 0 до 255. Если при печати в файл оператором Print добавление значения очередного выражения в строку приведет к превышению установленной границы, это значение будет печататься с новой строки. При этом значение одного выражения не переносится, даже если его длина превышает установленную границу. Например, если для файла с номером 1 ограничить ширину строки 5 символами:

Width #1,5

а затем напечатать строку:

Str = "раму мылом" Print #1, "мама", "мыла", Str

то в файле окажутся строки:

мама мыла раму мылом

Обращаем внимание и на то, что переход к новой строке может происходить и при встрече с разделителем Tab(n), если n задает позицию меньшую, чем текущая позиция. Пример такой ситуации встречался в нашей процедуре.

Как было показано, оператор Print вводит в файл данные разных типов, редактируя их в момент ввода и преобразуя в текстовый формат. Попутно он занимается и форматированием текста, приводя его к форме, удобной для отображения на дисплее. Во многих ситуациях форматирование, ориентированное на выдачу на экран дисплея, не является необходимым. В этих случаях для создания последовательного файла применяется Write#. Его синтаксис:

Write #номер-файла, [список-вывода ]

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

Также как и оператор Print, оператор Write производит редактирование данных в момент записи. При этом приняты следующие соглашения:

  • В числах в качестве разделителя целой и дробной частей всегда используется точка.
  • В качестве булевых значений используются слова #TRUE# и #FALSE#.
  • При записи дат применяется универсальный формат.
  • Ошибки выводятся в формате #ERROR код-ошибки#.
  • Для пустого значения выражения (Empty) ничего не записывается
  • Значение Null записывается как #Null#.




В отличие от оператора Print, оператор Write# вставляет при записи запятые между соседними выражениями и заключает строковые значения в кавычки. После записи последнего выражения вставляется перевод на новую строку (Chr(13) + Chr(10)).

Следующая процедура создает файл с последовательным доступом "readme.txt" и записывает в него данные с помощью оператора Write#. При записи мы старались повторить содержимое предыдущего файла, чтобы можно было сравнить работу, выполняемую операторами Print и Write. Вот текст этой процедуры:

Пример 14.3.

(html, txt)

Результат выполнения этой процедуры - файл "readme.txt" - в текстовом редакторе выглядит так:

"Первая строка файла" "Зона 1","Зона 2" "Привет,","старик!" "Мама ","мыла ","раму мылом. " #FALSE# #1999-06-14# #NULL# 3.1416,"3,14","03,142" 6 #ERROR 2000#

Сравните эти строки с теми, что выдаются оператором Print.



'Создание файла Write #7, "Первая строка файла" ' запись текстовой строки. Write #7, "Зона 1", "Зона 2" ' запись двух строк. Write #7, "Привет,", "старик!" 'еще две строки MyStr = "раму мылом. " Write #7, "Мама ", "мыла ", MyStr MyBool = False ' булева переменная Write #7, MyBool MyDate = #6/14/1999# ' значение даты Write #7, MyDate ' запись даты MyNull = Null ' нулевое значение Write #7, MyNull MyFloat = 3.1416 'вещественное значение ' использование функции Format: Write #7, MyFloat, Format(MyFloat, "0.00"), Format(MyFloat, "00.000") On Error Resume Next Err.Raise 6 MyErr = Err Write #7, MyErr MyErr = CVErr(2000) Write #7, MyErr

End Sub

Пример 14.3.

Результат выполнения этой процедуры - файл "readme.txt" - в текстовом редакторе выглядит так:

"Первая строка файла" "Зона 1","Зона 2" "Привет,","старик!" "Мама ","мыла ","раму мылом. " #FALSE# #1999-06-14# #NULL# 3.1416,"3,14","03,142" 6 #ERROR 2000#

Сравните эти строки с теми, что выдаются оператором Print.


Содержание раздела