- •Объект Debug и его методы
- •Метод Print
- •Метод Assert
- •Доказательство правильности программ
- •Условная компиляция и отладка
- •Директива #const
- •#If … Then … #Else директива
- •Ошибки периода выполнения и их обработка
- •Модель управления ошибками в языке vba.
- •Оператор On Error
- •Оператор Resume
- •Объект Err
- •Метод Clear
- •Метод Raise
- •Класс и обработка ошибок
- •Обработчики ошибок и вложенные вызовы процедур
- •Структура обработчика ошибок
- •Функция CvErr
- •Оптимизация программ
- •Приемы оптимизации кода
- •Объявление переменных
- •Математические операции
- •Строковые операции
- •Проектирование интерфейса. Меню
- •Общие объекты Office 2000
- •Коллекция CommandBars
- •Свойства и методы коллекции CommandBars
- •Свойства и методы объекта CommandBar
- •Коллекция CommandBarControls и ее элементы
- •О роли интерфейса
- •Создание собственных и модификация встроенных меню
- •Немного терминологии
- •Возможности настройки и изменения системы меню
- •Создание собственного головного меню
- •Использование диалогового окна Настройка
- •Создание меню с помощью vba
- •Добавление выпадающих меню
- •Использование диалогового окна Настройка
- •Как добавить встроенное меню
- •Добавление выпадающего меню с помощью vba
- •Добавление подменю
- •Вставка и группировка команд
- •Добавление встроенной команды с помощью окна Настройка
- •Добавление собственной команды с помощью окна Настройка
- •Добавление команд с помощью vba
- •Пример построения документа с собственным меню
- •Группировка команд меню
- •Удаление команд меню
- •Удаление команды с помощью окна Настройка
- •Удаление команды с помощью vba
- •Как восстановить удаленные встроенные компоненты меню
- •Изменение меню во время работы программы
- •Вывод собственной панели меню
- •Динамическое изменение видимости команд меню
- •Управление доступом к командам меню
- •Переименование команды меню
- •Диалоговые окна и элементы управления
- •Общие сведения и применение
- •Встроенные диалоговые окна Коллекция Dialogs и объект Dialog
- •Вывод сообщений. Функция MsgBox
- •Окно ввода данных. Функция InputBox
- •Создание пользовательских диалоговых окон
- •Создание страниц и вкладок в диалоговых окнах
- •Добавление дополнительных элементов управления
- •Пример создания диалогового окна
- •Разработка процедур, обрабатывающих события диалогового окна и его устройств
- •Вызов собственного диалогового окна
- •Установка начальных значений свойств элементов управления
- •Использование Me в качестве имени текущего диалогового окна
- •Модификация управляющих элементов во время работы
- •Управление доступом к элементу
- •Перемещение фокуса на элемент управления
- •Изменение размеров диалогового окна
- •Проверка корректности данных
- •Обмен данными с диалоговым окном
- •Закрытие диалогового окна
- •Объект UserForm (диалоговое окно), коллекция UserForms (диалоговые окна)
- •Коллекция Controls
- •Объекты - элементы управления Перечень основных элементов управления
- •Общие свойства элементов управления Объект-родитель
- •Имя объекта
- •Значение объекта
- •Расположение объекта
- •Параметры внешнего вида объекта
- •Свойства поведения объекта
- •Другие свойства
- •CheckBox - флажок (кнопка выбора)
- •ComboBox - комбинированный список
- •CommandButton - командная кнопка
- •Frame - рамка (группы)
- •Image - изображение
- •Label - метка (надпись, статический текст)
- •ListBox - список
- •MultiPage - набор страниц
- •OptionButton - кнопка-переключатель
- •ScrollBar - полоса прокрутки
- •SpinButton - счетчик
- •TabStrip - полоса вкладок
- •TextBox - поле ввода (окно редактирования)
- •ToggleButton - выключатель
- •Объект DataObject
- •Перемещение объектов. Как реализовать технику DragAndDrop
- •События Событие AddControl (добавился элемент)
- •Событие AfterUpdate (После модификации)
- •Событие BeforeDragOver (Перед завершением перетаскивания)
- •Событие BeforeDropOrPaste (Перед опусканием или вставкой)
- •Событие BeforeUpdate (Перед модификацией)
- •Событие Change (Изменение)
- •Событие Click (Щелчок)
- •Событие DblClick (Двойной щелчок)
- •Событие DropButtonClick (Щелчок кнопки списка)
- •События Enter, Exit (Вход, Выход)
- •Событие Error (Ошибка)
- •События KeyDown, KeyUp (Клавиша нажата, Клавиша отпущена)
- •Событие KeyPress (Клавиша нажата)
- •Событие Layout (Расположение)
- •События MouseDown, MouseUp (Мышь нажата, Мышь отпущена)
- •Событие MouseMove (Мышь движется)
- •Событие RemoveControl (Удаление элемента)
- •Событие Scroll (Прокрутка)
- •События SpinDown (Уменьшить счетчик), SpinUp (Увеличить счетчик)
- •Событие Zoom (Расширение)
- •Методы Метод Add (Добавить)
- •Метод AddItem (Добавить элемент)
- •Метод Clear (Очистить)
- •Метод Copy (Копировать)
- •Метод Cut (Вырезать)
- •Метод DropDown (Вывести список)
- •Метод Move (Сдвинуть)
- •Метод Paste (Вставить)
- •Реализация операций Cut, Copy, Paste в диалоговых окнах
- •Метод RedoAction (Повторить действие)
- •Метод Remove (Удалить)
- •Метод RemoveItem (Удалить элемент)
- •Метод Repaint (Перерисовать)
- •Метод Scroll (Прокрутить)
- •Метод SetDefaultTabOrder (Установить стандартный порядок обхода)
- •Метод SetFocus (Установить фокус)
- •Метод UndoAction (Отменить действие)
- •Реализация операций Undo и Redo в диалоговых окнах
- •Метод zOrder (z-упорядочить)
- •Основные виды файлов в Office 2000
- •Открытие и создание файлов
- •Закрытие файлов
- •Запись в файлы последовательного доступа
- •Чтение файлов последовательного доступа
- •Ввод-вывод для файлов произвольного доступа и бинарных файлов
- •Работа с данными переменной длины
- •Один пример работы с Binary файлом
Работа с данными переменной длины
До сих пор мы усиленно подчеркивали, что при работе с файлом произвольного доступа размер записи фиксирован и это предполагает хранение в таких файлов данных, размер которых фиксирован в момент их объявления. На самом деле, это не так и в таких файлах можно хранить и строки переменной длины и данные типа Variant. В этих случаях просто следует быть более осторожным, поскольку из-за сложности правил хранения таких данных повышается возможность ошибки. Вот некоторые правила, согласно которым оператор Put размещает данные в файле, а оператор Get их читает:
-
Данные всегда помещаются в файл, начиная с границ записей, установленных параметром Len при открытии файла. Если при этом длина данных, записываемых в файл, меньше размера записи, заданного параметром Len, оператор Put заполнит остающееся до длины записи место "случайными" данными из буфера файла, а новые данные поместит, начиная со следующей границы. При попытке записать данные, длина которых больше Len, появится сообщение об ошибке. Таким образом, параметр Len задает максимальный размер записи, внутри которого может храниться значение переменного размера.
-
При записи строк переменной длины, переменных типа Variant, динамических массивов VBA помещает туда же дополнительную информацию для их расшифровки.
-
При записи строки переменной длины Put помещает непосредственно перед ней 2 байта с ее длиной.
-
Два дополнительных байта также помещаются в файл при записи переменной типа Variant. Их содержимое идентифицирует тип значения (как в функции VarType). Например, если оно равно 3, это соответствует типу Long, и запись такой переменной займет 6 байтов (2 - для типа и 4 - для самого числа). Значение VarType = 8 соответствует строковому типу (String). В этом случае Put запишет 2 байта с VarType, затем 2 байта с длиной строки и затем саму строку.
-
В случае динамического массива Put записывает перед его элементами описатель с длиной 2 + 8* (число измерений массива).
-
Массивы фиксированного размера записываются без описателей. Без всякой дополнительной информации записываются и значения остальных типов переменных с фиксированными размерами.
-
Для бинарных файлов параметр Len при записи роли не играет. Put записывает значения переменных подряд без пропусков и не помещает длины динамических строк и дескрипторы массивов.
-
Для переменных с нефиксированными размерами Get выполняет преобразования, обратные тем, что при записи выполнял оператор Put. Например, при чтении в строку переменной длины Get определяет по 2-байтовому описателю длину строки, а затем читает ее содержимое в переменную. Аналогичная расшифровка происходит и при чтении в переменные типа Variant и в динамические массивы.
-
Для бинарных файлов Get читает данные подряд. В переменные фиксированного размера считывается соответствующее их размеру число байтов. При чтении в строку переменной длины в нее считывается число символов, равное длине ее текущего значения.
Приведем пример работы с файлом произвольного доступа, записи которого содержат данные не фиксированного размера:
Public Sub Test2()
'Эта процедура работает с файлом, записи которого
'содержат строки переменной длины, не превосхоящей максимума,
'а также данные типа Variant
Dim Fam As String
Dim Other As Variant
'Открытие файла произвольного доступа для чтения и записи
Open Path & "Strings.var" For Random Access Read Write As #5 Len = 20
Fam = "Степанов"
Put 5, 1, Fam
Get 5, 1, Fam
Debug.Print Fam, LOF(5)
Fam = "Архангельский"
Put 5, 2, Fam
Get 5, 2, Fam
Debug.Print Fam, LOF(5)
Fam = "Куц"
Put 5, 1, Fam
Get 5, 1, Fam
Debug.Print Fam, LOF(5)
'Запись типа Variant
Other = "Петров"
Put 5, 3, Other
Get 5, 3, Other
Debug.Print Other, LOF(5)
Other = 125.25
Put 5, 4, Other
Get 5, 4, Other
Debug.Print Other, LOF(5)
Other = 125
Put 5, 5, Other
Get 5, 5, Other
Debug.Print Other, LOF(5)
Close #5
End Sub
Пример 14.6. (html, txt)
Вот результаты ее работы:
Степанов 10
Архангельский 35
Куц 35
Петров 50
125,25 70
125 84
Приведем комментарии:
-
Операторы Put и Get позволяют записать и корректно прочитать данные переменного размера, не превосходящего максимальный размер, заданный при открытии файла.
-
При записи первой строки переменной длины размер файла стал равным 10 байтам, из которых 8 байтов занимает сама строка, а два байта, предшествующий ей описатель. Описатель позволяет оператору Get корректно прочитать эту строку.
-
Запись второй строки начинается с 21-го байта, границы первой записи, общий размер файла становится равным 35 с учетом размера второй строки и ее описателя.
-
Третья запись не изменяет размера файла, поскольку происходит изменение значения первой записи, так что файл по-прежнему содержит только две записи.
-
Далее начинается запись данных типа Variant. Теперь при записи строки используются два описателя, занимающие 4 байта.
-
Две последние записи содержат числовые данные Double (8 байтов) и Integer (2 байта) с их описателями.
Заканчивая тему работы с файлами произвольного доступа, хотим еще раз обратить внимание на некоторые опасные моменты, возникающие в процессе работы с ними и не контролируемые VBA:
-
Явно задавайте при открытии файла, как при чтении, так и при записи параметр Len ѕ максимальный размер записи. Если этого не сделать, то программа будет работать, но, к сожалению, результаты могут быть не предсказуемыми.
-
Будьте особенно внимательными при работе с данными переменной длины, помните, что к данным автоматически присоединяются описатели.
-
Размер файла определяется записью с максимальным номером. Чтобы избежать большого числа "дырок" в файле стройте разумные функции ключа так, чтобы ключи записей занимали достаточно плотный начальный интервал от 1 до N.