2 Курс Информатика VBA(ЗО) / Книги / В.Д.Хорев - Самоучитель программирования на VBA в Microsoft Office
.pdfОператоры и встроенные функции языка VBA 295
Оператор Put
Запись в файлы произвольного доступа производится при помощи оператора Put. При этом необходимо указать номер файла, номер записи, в которую производится запись (этот параметр необязателен, он просто неявно использует функцию Loc) и имя переменной, в которой содержатся подлежащие записи данные.
Open "C:\WORK\Sotrud.dat" For Random Access Read Write As MyFileNum _
Len=Len(MySotrudnik)
Put MyFileNum, 10, MySotrudnik
В результате содержимое переменной MySotrudnik будет записано в 10-ю запись файла
C:\WORK\Sotrud.dat.
Оператор Get
Противоположное действие, то есть чтение из файла произвольного доступа, осуществляется оператором Get. Здесь тоже необходимо указать номер файла, номер записи, в которую производится запись (этот параметр, так же, как и в случае Put, необязателен) и имя переменной, в которую следует прочитать данные из файла:
Get MyFileNum, 10, MySotrudnik
Функция EOF
После выполнения операторов Put или Get указатель текущей записи перемещается вперед, на следующую запись. Если использовать Put или Get без указания номера записи, то текущей записью, то есть записью, с которой должна производиться операция записи или чтения, будет каждый раз становиться следующая запись. И так будет продолжаться до тех пор, пока функция EOF с параметром — номером данного файла, не вернет значение True, что будет означать конец файла.
Оператор Lock
Если программа работает в многопользовательской среде (например, обращается к сетевому файлу), то при операциях с файлами произвольного доступа следует блокировать запись, к которой производится обращение. Это необходимо сделать по той причине, что два пользователя могут одновременно изменить данные в одной и той же записи, и в этом случае состояние файла окажется неопределенным.
Для блокирования записей используют оператор Lock:
Open "C:\WORK\Sotrud.dat" For Random Access Read Write As MyFileNum _ Len=Len(MySotrudnik)
...
Lock MyFileNum, 10 To 11
Put MyFileNum, 10, MySotrudnik1 Put MyFileNum, MySotrudnik2 Unlock MyFileNum, 10 To 11
Оператор Lock блокирует, то есть переводит в режим исключительного (монопольного) доступа записи с 10-й по 11-ю. Блокированные записи становятся недоступными для модификации другим приложением. Затем в 10-ю и в 11-ю записи выводятся данные из двух переменных типа
Sotrudnik.
Оператор Unlock
Оператор Unlock предназначен для разблокирования файла, который был блокирован оператором Lock. В предыдущем примере последняя строка кода снимает блокировку с 10 и 11 записей файла MyFileNum.
296 Приложение. VBA, как язык программирования: данные, синтаксис и функции
Работа с системным реестром Windows
Всю необходимую информацию о приложениях, программной и аппаратной среде, Windows хранит в системном реестре. Реестр имеет иерархическую древообразную структуру. Часть реестра, относящаяся к некоторому приложению, состоит из разделов, каждый из которых представляет собой набор параметров и соответствующих им значений. Кроме того, раздел может содержать подразделы и так далее. Значение каждого параметра можно прочитать, модифицировать или удалить.
ПРИМЕЧАНИЕ
Системный реестр играет исключительно важную роль в функционировании операционной системы Windows. Любые действия с реестром требуют осторожности. Если в реестре возникнуть серьезные нарушения, при загрузке Windows могут возникнуть проблемы. Не следует выполнять никаких действий в отношении системного реестра, если смысл этих действий вам не вполне ясен.
Для VBA-программы доступен раздел \HKEY_CURRENT_USER\SOFTWARE\VB and VBA Program Settings\... Результаты работы приведенных ниже примеров можно увидеть в этом разделе при помощи редактора реестра Windows — программа \WINDOWS\REGEDIT.EXE.
Оператор SaveSetting
Оператор SaveSetting позволяет сделать запись в реестре, при этом должны быть указаны (все параметры обязательны!) имя приложения, имя раздела реестра, имя параметра реестра и собственно значение параметра.
Предположим, надо сохранить в системном реестре сведения об имени последнего пользователя программы и дате последнего сеанса работы. Пусть новый раздел называется “Моя программа”, а подраздел со сведениями о последнем пользователе — “Последний пользователь”. В этом подразделе создадим два параметра: “Имя” и “Дата”. Следующий код, все это реализует:
SaveSetting "Моя программа", "Последний пользователь", _
Имя", "Иванов"
SaveSetting "Моя программа", "Последний пользователь", _
Дата", Now
Запустив редактор системного реестра (для этого нужно выбрать команду Выполнить (Run) в меню кнопки Ïóñê (Start), ввести в поле Открыть (Open) строку REGEDIT и нажать клавишу
[Enter]), нетрудно убедиться, что в разделе \HKEY_CURRENT_USER\SOFTWARE\VB and VBA Program Settings появился подраздел “Моя программа\Последний пользователь” с параметрами “Имя” и “Дата”.
Благодаря этому механизму VBA-программа может сохранять в системном реестре свои конфигурационные данные.
Функция GetSetting
Функция GetSetting возвращает значение параметра по заданному имени приложения, имени раздела реестра, имени параметра реестра. Четвертым (также обязательным!) параметром функции должно быть значение по умолчанию, которое функция вернет в случае ошибки доступа к реестру. Возвращаемые функцией значения относятся к типу Variant.
Чтобы в VBA-коде прочитать значения параметров, сохраненных в предыдущем примере оператором SaveSetting, используем функцию GetSetting:
Dim MyName As String
Dim MyDate As Date
MyName = GetSetting("Моя программа", "Последний пользователь", "Имя", "") MyDate = GetSetting("Моя программа", "Последний пользователь", "Дата", "")
Операторы и встроенные функции языка VBA 297
MsgBox MyName
MsgBox MyDate
Оператор DeleteSetting
Оператор DeleteSetting позволяет удалить весь раздел реестра, если указаны только имя приложения и имя раздела, или позволяет удалить конкретную запись в реестре, если дополнительно указано имя параметра.
Удалить свой раздел программа может посредством оператора DeleteSetting:
DeleteSetting "Моя программа", "Последний пользователь"
Работа со значениями даты и времени
Операции со значениями даты и времени обладают определенной спецификой. В форматах представления даты и времени очень многое зависит от версии Windows, версии Office и локализации того и другого. Понятно, что форматы представления таких значений отличаются в локализованных русских, паневропейских и американских версиях. Кроме того, на представление значений даты и времени влияют пользовательские настройки конкретного компьютера, то есть пара-
метры, заданные при помощи диалогового окна Язык и стандарты (Regional Settings Properties)
панели управления Windows. Для его отображения нужно выполнить команду Настройка | Панель управления (Settings | Control Panel) меню Ïóñê (Start).
Представление значений даты и времени в MS Office и VBA
Значения даты и времени представляются в приложениях Office в форме так называемого кода “дата-время” (называемом также “датой_в_числовом_формате”). Код “дата-время” представляет собой число, целая часть которого кодирует дату (день), а дробная — время. Такое представление позволяет очень просто выполнять любые арифметические операции с любыми временными промежутками.
Представление значений времени
Промежутку времени, равному 24 часам соответствует число 1 (оно же соответствует одному дню в значениях даты).
Полудню (12:00) соответствует значение 1/2, шести часам вечера (18:00) — 3/4 и т.д. Отсюда легко получить дробные числа, соответствующие элементарным промежуткам времени: 1 час = 1/24, 1 минута = 1/1440 и 1 секунда = 1/8640.
Представление значений даты
Значения даты представляют собой целое число, обозначающее количество дней, отсчитанных от так называемой первой даты. В разных системах дат используются разные первые даты, то есть даты, котором соответствует код “дата-время”, равный 1. По умолчанию приложения Office используют “Систему дат 1900”, кроме этого, Office может работать в “Системе дат 1904”, именуемой также “Системой дат 21 века”.
В среде VBA существует небольшое отличие для “Системы дат 1900” — в качестве первой даты VBA использует 31 декабря 1899 года, в то время как компоненты MS Office — 1 января 1900 года. Для дат позднее 29 февраля 1900 года вышеописанное различие не существует.
Функция DateSerial
Преобразовать дату в числовой формат, то есть в код “дата-время”, а точнее, значение типа Date, можно при помощи функции DateSerial. В качестве параметров функции необходимо указать три числа: год, месяц и день месяца. Число месяцев может превышать 12, а число дней может превышать 31 — все необходимые поправки будут внесены автоматически. Например:
Dim MyDate As Date
MyDate = DateSerial(5, 10, 11)
298Приложение. VBA, как язык программирования: данные, синтаксис и функции
Врезультате в переменной MyDate будет содержаться дата “11.10.2005”. Следующая строка
кода
MyDate = DateSerial(1996, 15, 6)
присваивает переменной MyDate дату “06.03.1997”. Следующая строка кода
MyDate = DateSerial(1996, 15, 45)
присваивает переменной MyDate дату “14.04.1997”. Следующая строка кода
MyDate = DateSerial(2035, 2, 3)
присваивает переменной MyDate дату “03.02.2035”.
Преобразование строк в значения даты (функция DateValue)
Значения даты в виде текстовой строки также можно преобразовать в значение типа Date. Такое преобразование выполняет функция DateValue. Эта функция способна распознавать текстовые даты, записанные самыми разными способами:
Dim MyDate As Date
...
MyDate = DateValue("11.08.2005")
MyDate = DateValue("17 Апр 2001") MyDate = DateValue("15 марта 99")
MyDate = DateValue("26/01/2000")
Распознаваемые форматы строкового значения даты зависят от настроек вкладки Äàòà (Date)
диалогового окна Язык и стандарты (Regional Settings Properties) панели управления Windows.
Подходящий вариант можно выбрать при помощи списков Краткий формат даты (Short date) и Полный формат даты (Long date). В приведенном выше примере предполагается, что выбраны форматы “дд.ММ.гг” и “дд ММММ гггг” соответственно.
Функция TimeSerial
Аналогичный набор операций доступен в отношении значений времени. Преобразование времени суток, заданном в виде числа часов, минут и секунд, в значение времени (представленное, как и значения даты, типом Date) выполняется функцией TimeSerial:
Dim MyTime As Date
...
MyTime = TimeSerial(12, 8, 5)
В результате в переменной MyTime будет содержаться значение времени “12:08:05”. Следующая строка кода
MyTime = TimeSerial(14, 80, 6)
присваивает переменной MyTime значение времени “15:20:06”. Следующая строка кода
MyTime = TimeSerial(8, 85, 95)
присваивает переменной MyTime значение времени “9:26:35”. Следующая строка кода
MyTime = TimeSerial(36, 85, 95)
присваивает переменной MyTime значение даты-времени “31.12.1899 13:26:35”.
Операторы и встроенные функции языка VBA 299
Последний пример иллюстрирует универсальность и взаимозаменяемость времени и даты в значениях даты-времени. Если число часов превышает одни сутки, то у кода “дата-время” появляется целая часть числа, обозначающая дату. Число 1, как отмечалось, в “Системе дат 1900” соответствует дате “31.12.1899”.
Преобразование строк в значения времени (функция TimeValue)
Для преобразования текстовых значений времени в код “дата-время” используют функцию TimeValue. Подобно функции DateValue, эта функция способна распознавать значения времени, записанные различными способами, например:
MyTime As Date
MyTime = TimeValue("12:08:05")
В результате в переменной MyTime будет содержаться значение времени “12:08:05”. Следующая строка кода
MyTime = TimeValue("3:20:06pm")
присваивает переменной MyTime значение времени “15:20:06”. Следующая строка кода
MyTime = TimeValue("9:26:35 AM")
присваивает переменной MyTime значение времени “9:26:35”.
Системная дата и системное время
Функция Date
Системная дата, то есть дата “сегодня” по встроенным часам персонального компьютера, доступна для VBA-программ посредством функции Date. Эта функция возвращает значение типа
Date. Например, следующий код вычисляет значение даты, отстоящей на 100 дней от сегодняшней даты:
Dim MyDate As Date
...
MyDate = Date + 100 MsgBox MyDate
Присваиванием значения этой функции можно изменить текущую системную дату. Например, перевести компьютерные часы на 1 день вперед можно при помощи оператора:
Date = Date + 1
Функция Time
Функция Time возвращает текущее значение системного времени. Например, вычислить значение времени, которое будет через 3 часа от текущего момента можно при помощи следующего кода:
Dim MyTime As Date
...
MyTime = Time + (3/24) MsgBox MyTime
Так же, как и функция Date, функция Time позволяет изменить системное время, присваиванием ей нового значения время. Следующий оператор присваивания позволяет перевести системные часы компьютера на 12 часов дня:
300 Приложение. VBA, как язык программирования: данные, синтаксис и функции
Time = ("12:00")
Функция Now
Наконец, значения системного времени и даты одновременно возвращает функция Now. Функция возвращает значения в коде “дата-время”. Например, оператор
MsgBox Now
выведет на экран сообщение, заключающее в себе одновременно значение даты и времени (рис.
П.5)
Рис. П.5. Функция Now возвращает одновременно значения даты и времени
Календарные вычисления
Для вычислений со значениями даты в Visual Basic предусмотрены специальные функции. Вообще, если речь идет о значениях даты или времени, преобразованных в код “дата-время”, то любые вычисления сводятся к простым арифметическим действиям. Например, простое суммирование значений типа Date означает суммирование значений даты и времени. Однако этим не исчерпываются все возможные потребности в календарных расчетах, возникающие перед VBAпрограммистом.
Функция DateAdd
Функция DateAdd позволяет вычислять даты и время, получаемые добавлением к исходному значению даты-времени заданного количества единичных интервалов: лет, месяцев и т. д., вплоть до секунд. Второй и третий параметры этой функции определяют количество добавляемых интервалов и исходное значение. В табл. П.7 приведены обозначения первого параметра, которым задается вид интервала.
ТАБЛИЦА П.7. ЗНАЧЕНИЯ ПЕРВОГО ПАРАМЕТРА ФУНКЦИИ DATEADD
Обозначение |
Интервал |
|
|
yyyy |
Год |
Q |
Квартал |
m |
Месяц |
Y |
День года |
D |
День месяца |
w |
День недели |
ww |
Неделя |
H |
Часы |
N |
Минуты |
S |
Секунды |
Вот как, например, можно вычислить значения даты-времени, отстоящие на различные интер-
валы от даты “01/01/2000”:
Dim MyDate As Date
Операторы и встроенные функции языка VBA 301
MyDate = DateAdd("yyyy", 3, "01.01.2000")
В результате переменная MyDate будет содержать значение даты “01/01/2003”. Следующая строка кода
MyDate = DateAdd("Q", 3, "01.01.2000")
присваивает переменной MyDate значение даты “01/10/2000”. Следующая строка кода
MyDate = DateAdd("m", 3, "01.01.2000")
присваивает переменной MyDate значение даты “01/04/2003”. Следующая строка кода
MyDate = DateAdd("ww", 3, "01.01.2000")
присваивает переменной MyDate значение даты “22/01/2003”. Следующая строка кода
MyDate = DateAdd("H", 3, "01.01.2000")
присваивает переменной MyDate значение даты-времени “01/01/2003 3:00:00”.
Функция DateDiff
Сходным образом устроена и действует функция DateDiff. Эта функция используется для решения обратной задачи — для вычисления числа единичных интервалов между двумя датами. В качестве параметров ей необходимо задать вид интервала (см. табл. П.7) и две даты.
Вот примеры вычислений при помощи функции DateDiff:
Dim MyNum As Long
MyNum = DateDiff("yyyy", "01.01.2000", "31.12.2001")
В результате переменная MyNum будет содержать число 1. Следующая строка кода
MyNum = DateDiff("Q", "01.01.2000", "31.05.2001")
присваивает переменной MyNum число 5. Следующая строка кода
MyNum = DateDiff("m", "01.01.2000", "28.02.2000")
присваивает переменной MyNum число 1.
Для вычисления числа недель функции DateDiff можно указывать еще один параметр — константу Visual Basic, задающую способ определения границ недели: константа vbMonday, например, соответствует неделе, начинающейся с понедельника, а vbSunday — неделе, начинающейся с воскресенья. Например:
MyNum = DateDiff("ww", "01.01.2000", "30.07.2000", vbSunday)
В результате переменная MyNum будет содержать число 31. Следующая строка кода
MyNum = DateDiff("ww", "01.01.2000", "30.07.2000", vbMonday)
присваивает переменной MyNum число 30.
Функция DatePart
Функцию DatePart используют, для того чтобы определить, к какому единичному интервалу (году, кварталу, месяцу и т.д.) относится заданная дата. В качестве параметров необходимо указать вид интервала (см. табл. П.7) и собственно дату, например:
Dim MyNum As Long
302 Приложение. VBA, как язык программирования: данные, синтаксис и функции
MyNum = DatePart("yyyy", "01.01.2001")
В результате переменная MyNum будет содержать число 2001. Следующая строка кода
MyNum = DatePart("Q", "01.01.2001")
присваивает переменной MyNum число 1. Следующая строка кода
MyNum = DatePart("m", "01.01.2001")
присваивает переменной MyNum число 1.
Точно так же, как и в случае с DateDiff, при помощи дополнительного параметра можно указать первый день недели, что может оказать влияние на расчеты, связанные с неделями:
MyNum = DatePart("ww", "21.01.2001", vbSunday)
В результате переменная MyNum будет содержать число 4. Следующая строка кода
MyNum = DatePart("ww", "21.01.2001", vbMonday)
присваивает переменной MyNum число 3.
Функция Year
В Visual Basic предусмотрен ряд традиционных функций, возвращающих номер определенного интервала в дате-параметре. Задавать дату можно произвольным образом — эти функции “понимают” как даты в виде текста, так и значения типа Date.
Функция Year возвращает целое число, соответствующее году в заданной дате, например:
Dim MyYear As Integer
MyYear = Year("26.01.2000")
В результате переменная MyYear будет содержать число 2000.
Функция Month
Функция Month возвращает целое число, соответствующее месяцу в заданной дате, например:
Dim MyMonth As Integer
MyYear = Month ("26.01.2000")
В результате переменная MyMonth будет содержать число 1.
Функция Day
Функция Day возвращает целое число, соответствующее дню месяца в заданной дате, например:
Dim MyDay As Integer
MyYear = Day ("26.01.2000")
В результате переменная MyDay будет содержать число 26.
Функция Weekday
Функция WeekDay возвращает номер дня недели в заданной дате. При этом посредством необязательного второго параметра можно задать первый день недели. Вот как, например, функция WeekDay определяет день 01/01/2001 (понедельник):
Dim MyDyOfWeek As Integer
MyDyOfWeek = WeekDay("01.01.2001")
Операторы и встроенные функции языка VBA 303
В результате переменная MyDyOfWeek будет содержать число 2. Следующая строка кода
MyDyOfWeek = WeekDay("01.01.2001", vbSunday)
присваивает переменной MyDyOfWeek число 2. Следующая строка кода
MyDyOfWeek = WeekDay("01.01.2001", vbMonday)
присваивает переменной MyDyOfWeek число 1.
Как легко убедиться, по умолчанию, в качестве первого дня недели используется воскресенье.
Вычисления со значениями времени
Сходный набор функций предусмотрен для получения значений количества временных интервалов в виде целого числа. Эти функции “понимают” любые допустимые способы задания времени — от значений типа Date, возвращаемых функциями даты-времени (например, Now или Time) до текстовых обозначений времени.
Функция Hour
Функция Hour возвращает значение типа Integer, соответствующее часам в значении времени, переданному функции в качестве параметра. Например:
MsgBox "Сейчас " + Str(Hour(Now)) + "-й час"
Функция Minute
Функция Minute возвращает значение типа Integer, соответствующее минутам в значении времени, переданному функции в качестве параметра. Например:
MsgBox "Сейчас " + Str(Minute(Now)) + "-я минута"
Функция Second
Функция Second возвращает значение типа Integer, соответствующее минутам в значении времени, переданному функции в качестве параметра. Например:
MsgBox "Сейчас " + Str(Second(Now)) + "-я секунда"
Функция Timer
Наконец, функция Timer возвращает значение типа Single, соответствующее количеству секунд, прошедших с последней полуночи. Функция возвращает значение с точностью до сотых долей секунды. Например:
MsgBox "Текущим суткам исполнилось " + Str(Timer) + " секунд"
Работа со строками
В действиях с данными особое место всегда занимает работа со строковыми значениями. За многие годы развития языков программирования выработался “джентльменский набор” функций для выполнения различных операций с символьными строками. Все основные функции этого набора имеются и в Visual Basic.
Сравнение строк (функция StrComp)
Для сравнения строк используют функцию StrComp. Эта функция возвращает целое число со знаком, характеризующее результат сравнения двух строк, переданных ей в качестве параметров. Третьим параметром функции является константа, определяющая режим сравнения. Константа vbTextCompare соответствует текстовому сравнению строк, а константа vbBinaryCompare
304 Приложение. VBA, как язык программирования: данные, синтаксис и функции
— двоичному. В последнем случае принимаются во внимание различия между прописными и строчными буквами.
Если строки совпадают, функция возвращает значение 0.
Если первая строка больше второй, функция возвращает значение 1. Если вторая строка больше первой, функция возвращает значение –1. Например:
Dim MyResult As Integer
MyResult = StrComp("Иванов", "иванов", vbBinaryCompare)
В результате переменная MyResult будет содержать число –1. Следующая строка кода
MyResult = StrComp("Иванов", "иванов", vbTextCompare)
присваивает переменной MyResult число 0. Следующая строка кода
MyResult = StrComp("иванов", "Иванов", vbBinaryCompare)
присваивает переменной MyResult число 1. Следующая строка кода
MyResult = StrComp("иванов", "иванов", vbBinaryCompare)
присваивает переменной MyResult число 0.
Выделение подстроки
Для того чтобы извлечь из строки подстроку, используется специальный набор функций.
Функции Left и LeftB
Функция Left возвращает подстроку, состоящую из заданного числа символов исходной строки, начиная с первого. (Если строка содержит двоичные данные, то следует использовать функцию LeftB). Например:
Dim MyString As String
MyString = Left(“АБВГДЕ”, 3)
В результате переменная MyString будет содержать строку “АБВ”.
Функции Right и RightB
Функция Right возвращает подстроку, состоящую из заданного числа символов исходной строки, оканчивая последним. (Если строка содержит двоичные данные, то следует использовать функцию RightB). Например:
Dim MyString As String
MyString = Right(“АБВГДЕ”, 3)
В результате переменная MyString будет содержать строку “ГДЕ”.
Функции Mid и MidB
Функция Mid возвращает подстроку, состоящую из заданного числа символов исходной строки, начиная с заданной позиции. (Если строка содержит двоичные данные, то следует использовать функцию MidB). Например:
Dim MyString As String
MyString = Mid(“АБВГДЕ”, 2, 3)
В результате переменная MyString будет содержать строку “БВГ”. Следующая строка кода