Тверской государственный университет
Опубликован: 13.09.2006 | Доступ: свободный | Студентов: 3491 / 369 | Оценка: 4.65 / 4.29 | Длительность: 30:37:00
Специальности: Программист, Менеджер
Лекция 9:

Операции и встроенные функции

Разбор строки, допускающей разные разделители ее элементов. Функция WildSplit

Завершим обзор рассмотрения собственных инструментальных средств описанием функции WildSplit. Когда мы описывали стандартную функцию разбора строки на элементы, мы отмечали, что она, к сожалению, не применима в тех достаточно часто встречающихся ситуациях, когда элементы разделяются разными разделителями. Наша функция в какой то мере пытается восполнить существующий пробел. Она разделяет строку на элементы, которые могут в строке разделяться разными символами, представляющими разделители элементов, возможно, окруженные пробелами.

Алгоритм реализации прост. Он использует ранее написанную функцию замены CharSetReplace, заменяя все разделители одним. После этого становится возможным применить стандартную функцию разбора. На заключительном этапе у элементов убираются пробелы слева и справа. Следует отметить и недостаток этой функции, - преобразование необратимо и последующее применение Join не позволяет восстановить исходную строку в первозданном виде. Приведем текст этой функции:

Public Function WildSplit(expr As String, Optional ByVal delimiter As String = " ", _
	Optional ByVal limit As Long = -1, Optional ByVal compare As 
	VbCompareMethod = vbBinaryCompare) As Variant
	
	'Также, как и стандартная функция Split, эта функция расщепляет 
строку - источник expr
	'на элементы, используя разделители, заданные аргументом delimiter
	'Отличие состоит в том, что при выделении элементов предполагается, 
что разделителем
	'может быть любой из символов множества delimeter, возможно, окруженный 
пробелами
	
	Dim Source As String, ResAr() As String
	Dim find As String, Rep As String
	Dim i As Long
	
	Source = expr
	find = VBA.Mid$(delimiter, 2)
	Rep = VBA.Left$(delimiter, 1)
	'Заменяем в строке все разделители на один из них
	Source = CharSetReplace(Source, find, Rep)
	
	'Теперь используем стандартную функцию Split
	ResAr = Split(Source, Rep, limit, compare)
	
	'Удаляем пробелы
	For i = LBound(ResAr) To UBound(ResAr)
		ResAr(i) = VBA.Trim$(ResAr(i))
	Next i
	WildSplit = ResAr
End Function
8.6.

Приведем также тестовую процедуру, в которой выполняется разбор строки функцией WildSplit:

Public Sub testWildSplit()
	Dim Txt As String, Res As String
	Dim Items() As String
	
	Txt = "a * b - (c+d)/v"
	Items = WildSplit(Txt, "+-*/")
	Res = Join(Items)
	Debug.Print Res
End Sub

Вот результаты ее работы:

a b (c d) v

На этом мы закончим наш затянувшийся разговор о работе со строковыми данными.

Работа с датами и временем

Для того, чтобы обеспечить программисту возможность корректно работать с датами и временем, VBA предоставляет специальный тип данных Date, хранящий дату и время. Над данными этого типа можно выполнять некоторые операции, но, конечно же, при работе с ними чаще всего используются специальные встроенные функции. Попытаемся коротко рассмотреть основные возможности работы с датами. Прежде всего, заметим, что возможный диапазон дат охватывает даты от 1.1.100 года до 1-го января 9999 года. Если говорить о внутреннем представлении дат, занимающих 4 байта памяти, то целая часть хранит число дней от некоторой начальной даты, дробная часть хранит время от полуночи. Начальной датой является 30-е декабря 1899 года. Благодаря такому внутреннему представлению сложение и вычитание целого числа воспринимается как прибавление или вычитание дней.

Присваивание значений

При присваивании значений переменным типа дата следует заключать дату в специальные ограничители " # " или задавать ее как строковую константу. При задании даты в ограничителях, например #9, May, 99 # она автоматически преобразуется к стандартному формату #5/9/99# (месяц/день/год). Вот пример некоторых действий над датами:

Public Sub WorkWithDates()
	
	'Работа с датами
	Dim dat1 As Date, dat2 As Date, dat3 As Date
	
	'Присваивание дат
	dat1 = 12
	dat2 = 9 / 5 / 99
	dat3 = #9/5/1999#
	Debug.Print dat1, dat2, dat3
	dat1 = "15/7/99"
	dat2 = #5/9/1999#
	dat3 = dat3 + 100
	Debug.Print dat1, dat2, dat3
	If dat3 > dat2 Then
		Debug.Print dat3 - dat2
	Else
		Debug.Print dat2 - dat3
	End If

End Sub

Приведем результаты выполнения этой программы:

11.01.1900	0:26:11		05.09.99 
15.07.99		09.05.99		14.12.99 
 219

Прокомментируем результаты, поскольку некоторые из них могут вызывать недоумение. Остановимся на первых двух присваиваниях. Чтобы понять их, нужно вспомнить внутренне представление дат. В первом случае к начальной дате прибавляется 12 дней, отсюда и получается 11 января 1900 года. Во втором случае, поскольку выражение в правой части не заключено в ограничители, оно вычисляется как обычное арифметическое выражение, полученное дробное число воспринимается как время от начала суток, - оно и печатается. Обратите внимание, на третье присваивание, первое число воспринимается как номер месяца, для российских программистов здесь кроется источник возможных ошибок, поэтому лучше задавать даты, используя названия месяцев, которые автоматически будут преобразованы в соответствующий формат.

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

Встроенные функции для работы с датами

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

Определение текущей даты или времени.
  • Date - возвращает текущую дату.
  • Time - возвращает текущее время по часам компьютера.
  • Now - возвращает значение типа Variant (Date), содержащее текущую дату и время по системному календарю и часам компьютера.
Вычисления над датами

Функция DateAdd предназначена для добавления или вычитания указанного временного интервала из значения даты. Заметьте, с ее помощью можно задавать временной интервал не только в днях, но и в месяцах, годах и так далее.

DateAdd(interval, number, date)

Аргумент interval - строка, указывающая тип добавляемого временного интервала, number - число временных интервалов, на которое следует изменить дату, date - дата, к которой добавляется указанный временной интервал. Допустимые значения аргумента interval: приведены в следующей таблице.

Таблица 8.4. Возможные временные интервалы
Значение Описание
yyyy Год.
Q Квартал.
m Месяц.
Y День года.
D День месяца.
w День недели.
ww Неделя.
H Часы.
N Минуты.
S Секунды.

Для примера, приведем два вызова этой функции в окне отладки:

? DateAdd("m", 1, "31-янв-95")
28.02.95 
? DateAdd("m", -1, "31-янв-95") 
31.12.94

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

DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
  • Аргумент interval задает тип временного интервала при вычислении разности между датами date1 и date2, - его возможные значения те же, что и для функции DateAdd,
  • date1 и date2 - две даты, разность между которыми следует вычислить.
  • firstdayofweek - константа, указывающая первый день недели (по умолчанию считается, что неделя начинается с воскресенья).
  • firstweekofyear - константа, указывающая первую неделю года (по умолчанию первой неделей считается неделя, содержащая 1 января).

Приведем примеры вызова этой функции в окне отладки:

? DateDiff("m", "18.10.55", "31-янв-95")
 471 
? DateDiff("Y", "18.11.97", "01.01.97")
-321

Функция DatePart предназначена для определения указанного компонента даты. Например, с помощью этой функции можно определить день недели или текущий час. Синтаксис:

DatePart(interval, date[,firstdayofweek[, firstweekofyear]])
  • Аргумент interval задает тип возвращаемого временного интервала,
  • date - дата, подлежащая обработке.
  • Необязательные аргументы Firstdayofweek и Firstweekofyear имеют тот же смысл, что и для функции DateDiff.

Примеры вызова:

? DatePart("ww", "02.09.89")
 35 
? DatePart("w", "02.09.89")
 7

Функция DateSerial позволяет вычислить значение даты типа Variant (Date) по ее компонентам, - году, месяцу и дню. Ее синтаксис:

DateSerial(year, month, day)

Значение каждого аргумента должно лежать в соответствующем диапазоне: 100 -- 9999 для года, 1 - 31 для дней и 1 - 12 для месяцев. Можно также использовать для аргументов числовые выражения для описания относительной даты.

Примеры:

? DateSerial(1997 - 25, 10 - 2, 18 - 1)	
17.08.72 
? DateSerial(Year(Now) - 3,Month(Now) - 2, Day(Now) - 1)
08.03.96

Функция DateValue переводит аргумент-строку в дату. В отличие от функции преобразования CDate, функция DateValue правильно обрабатывает допустимые даты, содержащие полные или краткие названия месяцев.

Ее синтаксис:

DateValue(date)

Аргумент date может задавать как дату, так и время. Возможные разные форматы задания даты, в том числе и с названиями месяцев:

Примеры:

? DateValue ("25.04.1997")
25.04.97 
? DateValue ("04.25.1997") 
25.04.97 
? DateValue ("25 апреля 1997")
25.04.97 
? DateValue ("25 - апр.-97") 
25.04.97 
? DateValue ("Апрель, 25, 97")
25.04.97 
? DateValue ("25/04/1997") 
25.04.97 
? DateValue ("25.04") 
25.04.99

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

Функции Day(date), Month(date), и Year(date) являются, в некотором смысле, обратными к двум предыдущим. Они по аргументу-дате определяют номер дня, месяца и года. Функция Weekday(date, [firstdayofweek]) возвращает значение типа Variant (Integer), содержащее целое число, представляющее день недели. Второй аргумент задает первый день недели (по умолчанию - воскресенье ). Значение 2 соответствует понедельнику.

Функции Hour(время), Minute(время) и Second(время) по аргументу, являющемуся числовым или строковым выражением, представляющим время, возвращает содержащее целое число, которое представляет, соответственно, часы, минуты и секунды в значении времени.

Функция TimeSerial(hour, minute, second) вычисляет результат Variant (Date), содержащее значение времени, соответствующее указанным часу, минуте и секунде.

Функция TimeValue(время) возвращает значение типа Variant (Date), содержащее время. Аргумент время обычно задается строковым выражением, представляющим время от 0:00:00 (12:00:00 A.M.) до 23:59:59 (11:59:59 P.M.) включительно. Задавать его нужно корректно, чтобы не возникало ошибок, как в последних двух примерах:

? Year(Now)
 1999 
? Month(now)
 5 
? Day(Now)
 9 
? Hour(Now)
 11 
? Minute (Now)
 57 
? Second(Now)
 28 
? TimeSerial(Hour(Now), Minute(now), Second(Now))
11:59:00 
? TimeValue("12:30 PM")
12:30:00 
? TimeValue("12.30")
0:00:00 
? TimeValue("12,5") 
0:00:00
полина есенкова
полина есенкова
Дмитрий Вологжин
Дмитрий Вологжин
Добрый день, прошел тесты с 1 по 9, 10 не сдал, стал читать лекцию и всё пройденные тесты с 1 по 9 сбросились, когда захотел пересдать 10 тест.