Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсовая / Источники / excel_2010_professionalnoe_programmirovanie_na_vba_RuLit_Me_412629.pdf
Скачиваний:
4
Добавлен:
27.09.2025
Размер:
22.97 Mб
Скачать

302

Часть III. Visual Basic for Applications

В обоих этих примерах функция Com m ission должна содержаться в активной рабо­ чей книге; в противном случае Excel отобразит сообщение об ошибке, указывающее, что функция не определена.

Используйте аргументы, а не ссылки на ячейки

Все применяемые в пользовательской функции диапазоны должны передаваться в качестве аргументов. Рассмотрим функцию, которая возвращает значение в ячей­ ке А1, умноженное на 2.

F u n c t io n D o u b le C e llO

D o u b le C e ll = R a n g e ( " A l" ) * 2

E n d F u n c t io n

Хотя эта функция работает, в некоторых случаях она выдает неправильный резуль­ тат. Причина в том, что вычислительный механизм Excel не учитывает диапазоны, кото­ рые не передаются в качестве аргументов. Вследствие этого иногда перед возвратом функцией значения не вычисляются все связанные величины. Следует также написать функцию D o u b le C e ll, в качестве аргумента которой передается значение ячейки А1.

F u n c t io n D o u b l e C e l l ( c e l l )

D o u b le C e ll = c e l l * 2

E n d F u n c t io n

Функция с двумя аргументами

Представим, что менеджер, о котором речь шла выше, внедряет новую политику, разработанную для уменьшения текучести кадров: общая сумма комиссионных, подле­ жащих выплате, увеличивается на 1% за каждый год, который служащий проработал в компании.

Изменим пользовательскую функцию Commission (описанную в предыдущем разде­ ле) так, чтобы она принимала два аргумента. Новый аргумент представляет количество лет, отработанных сотрудником в компании. Назовем эту новую функцию Commission2.

F u n c t io n C o m m is s io n 2 ( S a le s , Y e a r s )

 

 

 

 

1

В ы ч и с л я е т к о м и с си о н н ы е с

продаж

на о с н о в е

 

 

'

р а б о ч е г о

ста ж а

в к о м п а н и и

 

 

 

 

 

 

C o n s t T i e r l = 0 .0 8

 

 

 

 

 

 

C o n s t T ie r 2 = 0 .1 0 5

 

 

 

 

 

 

C o n s t T ie r 3 = 0 .1 2

 

 

 

 

 

 

C o n s t T ie r 4 = 0 .1 4

 

 

 

 

 

 

S e le c t C a se S a le s

 

 

 

 

 

 

C a se 0 T o 9 9 9 9 .9 9 : C o m m is s io n 2 = S a le s * T i e r l

 

C a se

1000

To

1 9 9 9 9 .9 9 :

C o m m is s io n 2 =

S a le s

*

T ie r 2

 

C a se

2 0000

T o

3 9 9 9 9 .9 9 : C o m m is s io n 2

= S a le s

*

T ie r 3

 

C a se I s >= 4 0 0 0 0 :C o m m is s io n 2

=S a le s

* T ie r 4

 

 

 

E n d S e le c t

 

 

 

 

 

 

 

 

 

C o m m is s io n 2

=

C o m m is s io n 2

+ (C o m m is s io n 2 * Y e a r s

/ 100)

E n d

F u n c t io n

 

 

 

 

 

 

 

 

Довольно просто, правда? Добавим второй аргумент (Years) в оператор Function и применим дополнительные вычисления, изменяющие формулу комиссионных.

Далее приведен пример написания формулы с использованием этой функции (предполагается, что объем продаж задан в ячейке А1, а количество лет, которые прора­ ботал в компании рассматриваемый служащий, указано в ячейке В1).

= C o m m is s io n 2 (А 1 ,В 1 )

Глава 10. Создание функций

303

Компакт-диск

Все описанные выше процедуры вычисления комиссионных находятся на прилагаемом к книге компакт-диске, в файле c o m is s io n f u n c t i o n s . x ls m .

Функция с аргументом в виде массива

В качестве аргументов функции могут принимать один или несколько массивов, об­ рабатывать этот массив (массивы) и возвращать единственное значение.

Функция, представленная ниже, принимает как аргумент массив и возвращает сумму его элементов.

F u n ctio n S u m A rra y ( L i s t ) A s D o u b le

Dim

Ite m

A s

V a r i a n t

Sum Array

=

0

 

 

For

E a ch

Ite m

I n

L i s t

I f W o r k s h e e t F u n c t io n . Is N u m b e r(Ite m ) T h e n _

 

S u m A rra y

=

S u m A rra y + Ite m

Next

Ite m

 

 

 

 

End F u n c tio n

Функция Excel ЕЧИСЛО (IsNumber) проверяет, является ли каждый элемент числом, прежде чем добавить его к общему целому. Добавление этого простого оператора про­ верки данных устраняет ошибки несоответствия типов при попытке выполнить арифме­ тическую операцию над строкой.

Следующая процедура демонстрирует, как вызвать эту функцию в процедуре. Проце­ дураMakeList создает 100-элементный массив и присваивает каждому элементу мас­ сива случайное число. Функция MsgBox отображает сумму значений массива в резуль­ татевызова функции SumArray.

Sub M a k e L is t

()

 

 

Dim

N u m s(l

To

10 0)

A s D o u b le

Dim

i

a s

I n t e g e r

 

For

i

= 1

 

To

100

 

Num s(i )

=

Rnd *

1000

Next

i

 

 

 

 

 

MsgBox

S u m A rra y (N u m s)

End Sub

 

 

 

 

 

 

Так как функция SumArray не объявляет тип данных своего аргумента (и аргумент имеет тип Variant), она работает и в формулах рабочего листа. Например, следующая формула возвращает сумму значений в диапазоне А1:С10.

=SumArray (А1 :С 10)

Возможно, вы заметили, что при использовании в формуле функция SumArray по­ добна функции Excel СУММ. Единственное отличие заключается в том, что функция Su­ mArray принимает только один аргумент. Не стоит забывать, что этот пример приведен только в целях обучения. Функция SumArray в формуле не имеет абсолютно никаких преимуществ перед функцией Excel СУММ.

Компакт-диск

Ц Э Д Этот пример под названием array argument.xlsm находится на прилагаемом к книге компакт-диске.

304

Часть III. Visual Basic for Applications

Функция с необязательными аргументами

Многие встроенные функции Excel имеют необязательные аргументы. Пример — функция ЛЕВСИМВ, возвращающая символы с левого края строки. Она имеет следующий синтаксис:

Л ЕВСИ М В( текст, к о л _ с и м в о л о в )

Первый аргумент — обязательный, в отличие от второго. Если не указан второй ар­ гумент, Excel предполагает значение 1. Следовательно, две формулы, приведенные ниже, возвращают одинаковые результаты.

=ЛЕВСИМ В(A l ,1 )

=ЛЕВСИМ В(А1)

Пользовательские функции, разработанные в VBA, также могут иметь необязатель­ ные аргументы. Необязательный аргумент вы зададите, если введете перед именем аргу­ мента ключевое слово Optional. В списке аргументов необязательные аргументы оп­ ределяются после всех обязательных.

Далее приведен пример пользовательской функции с необязательным аргументом.

F u n c t io n U s e r ( O p t io n a l U p p e r c a s e A s V a r ia n t )

I f

I s M is s in g ( U p p e r c a s e ) T h e n U p p e r c a s e = F a ls e

U s e r = A p p lic a t io n . U s e r N a m e

I f

U p p e r c a s e T h e n U s e r = U C a s e ( U s e r)

E n d F u n c t io n

Если аргумент равен False или опущен, то имя пользователя возвращается без ка­ ких-либо изменений. Если же аргумент функции True, то имя пользователя возвращает­ ся в символах верхнего регистра (с помощью VBA-функции Ucase). Обратите внимание на первый оператор функции — он содержит VBA-функцию IsMissing, которая опре­ деляет наличие аргумента. Если аргумент отсутствует, оператор присваивает переменной Uppercase значение False (задано по умолчанию).

Приведенные ниже формулы справедливы, а первые две возвращают одинаковые ре­ зультаты.

=U s e r ()

=U s e r ( F a ls e )

=U s e r( T ru e )

Примечание

Если нужно определить, подставляется ли необязательный аргумент в функ­ цию, объявите его с типом данных V a r ia n t . Затем можно использовать встроенную функцию I s M is s in g , как показано в этом примере.

Далее' приведен пример еще одной пользовательской функции с необязательным ар­ гументом. Эта функция случайным образом выбирает одну ячейку из диапазона данных и возвращает содержимое этой ячейки. Если второй аргумент имеет значение True, то выделенное значение изменяется при каждом пересчете рабочего листа. Если второй ар­ гумент имеет значение False (или не задан), функция не пересчитывается, кроме тех случаев, когда изменяется одна из ячеек диапазона введенных данных.

F u n c t io n D ra w O n e (R n g A s V a r i a n t , O p t io n a l

R e c a lc A s V a r i a n t = F a ls e )

1

С лучай ны м о б р а з о м в ы б и р а е т о д н у я ч е й к у

и з д и а п а з о н а ;

'

ф ункция и з м е н я е м а я , е с л и а р г у м е н т R e c a lc и м е е т з н а ч е н и е T ru e

 

A p p l i c a t i o n . V o l a t i l e R e c a lc

 

1

О п р е д е л е н и е с л у ч а й н о й я ч е й к и

 

Глава 10. Создание функций

305

DrawOne = R n g (I n t ( (R n g . C o u n t )

* R nd + 1 ))

End F u n c t io n

 

Обратите внимание, что второй аргумент функции Draw содержит ключевое слово O ptional, а также значение, заданное по умолчанию.

Все приведенные ниже формулы корректны, причем первые две возвращают одина­ ковые результаты.

=DrawOne (A l : A l 0 0) =DrawOne ( A l : A 100 , F a ls e ) =DrawOne (A l :A l 0 0, T r u e )

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

Компакт-диск

Приведенная выше функция доступна на прилагаемом к книге компактдиске и находится в файле d r a w . x ls m .

Функция VBA, возвращающая массив

VBA содержит весьма полезную функцию с названием A rray. Она возвращает значе­ ние с типом данных V a ria n t, которое содержит массив (т.е. несколько значений). Если вы знакомы с формулами массивов в Excel, то сможете легко разобраться в функции Аг - ray в VBA. Формула массива вводится в ячейку после нажатия <Ctrl+Shift+Enter>. Excel добавляет вокруг формулы скобки, чтобы указать, что это формула массива.

©Более подробную информацию о формулах массивов вы найдете в главе 3.

Примечание

Важно понимать, что массив, возвращаемый функцией A r r a y , — это не тот обычный массив, который состоит из элементов с типом данных V a r ia n t .

Другими словами, массив V a r i a n t существенно отличается от массива зна­ чений типа V a r ia n t .Перекрестная ссылка

Функция MonthNames, приведенная ниже,— простой пример применения функции Array в пользовательской функции.

Fu n ctio n M onthN am es ()

MonthNames

= A r r a y ( " Я н в " , "Ф е в ", "М а р ", "А п р " , _

"М ай",

"И ю н", "И ю л", " А в г " , " С е н " , " О к т " , _

"Н о я ",

"Д е к ")

End F u n c tio n

 

Функция MonthNames возвращает горизонтальный массив названий месяцев. Вы можете создать формулу массива для нескольких ячеек, используя функцию M onth­ Names. Прежде чем ее использовать, убедитесь, что в модуле VBA введен код функции. Затем на рабочем листе выделите несколько ячеек в строке (для начала выделите 12 яче­ ек), введите следующую формулу и нажмите <Ctrl+Shift+Enter>.

{=MonthNames () }

Т Р А Н С П

306 Часть III. Visual Basic for Applications

Если необходимо сгенерировать вертикальный массив названий месяцев, выделите вертикальный диапазон, введите следующую формулу и нажмите <Ctrl+Shift+Enter>.

{ = ТРАН СП (M o n th N a m e s ( ) ) }

Данная формула использует функцию Excel для преобразования горизон­ тального массива в вертикальный.

Следующий пример — вариация на тему функции MonthNames.

F u n c t io n

M o n th N a m e s ( O p tio n a l

M ln d e x )

 

 

D im

A llN a m e s A s

V a r i a n t

 

 

 

 

 

 

D im M o n th V a l A s L o n g

 

 

 

 

 

 

A llN a m e s

=

A r r a y ( " Я н в " ,

"Ф е в ",

"M a p ",

" A n p " ,

_

 

"М а й ",

 

"И ю н",

"И ю л",

" А в г " ,

" С е н " ,

" О к т " ,

_

 

" Н о я ",

 

"Д е к ")

 

 

 

 

 

 

 

 

I f I s M is s in g ( M ln d e x ) T h e n

 

 

 

 

 

 

M onthN am es

=

A llN a m e s

 

 

 

 

 

 

E ls e

 

 

 

 

 

 

 

 

 

 

 

 

 

S e le c t C a se M in d e x

 

 

 

 

 

 

 

 

C a se

I s

>= 1

 

 

 

 

 

 

 

 

 

1

О п р е д е л и ть

з н а ч е н и е

м е с я ц а

(н а п р и м е р , 13=1)

 

 

M o n th V a l

=

( ( M ln d e x

-

1)

Mod 12)

 

 

 

M onthN am es

=

A llN a m e s ( M o n th V a l)

 

 

 

C a se I s <= 0 1 В е р ти к а л ь н ы й м а с с и в

 

 

 

M onthN am es

=

A p p l i c a t i o n . T r a n s p o s e ( A llN a m e s )

 

E n d

S e le c t

 

 

 

 

 

 

 

 

 

E n d

I f

 

 

 

 

 

 

 

 

 

 

 

 

E n d F u n c t io n

 

 

 

 

 

 

 

 

 

 

 

Обратите внимание, что для проверки незаданного аргумента используется функция VBA IsM issin g . В данной ситуации невозможно задать значение по умолчанию для незаданного аргумента в списке аргументов функции, так как значение по умолчанию определяется в функции. Функцию IsM issin g можно использовать, только если необя­ зательный аргумент имеет тип V a ria n t.

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

Если аргумент не задан, функция возвращает горизонтальный массив названий месяцев.

Если аргумент меньше или равен 0, функция возвращает вертикальный массив

названий месяцев. Для преобразования массива используется функция Excel

Т Р А Н С П (Transpose).

Если аргумент больше или равен 1, функция возвращает название месяца, соот­ ветствующее значению аргумента.

Примечание

В этой процедуре используется оператор Mod для определения значения месяца. Этот оператор возвращает остаток от деления первого операнда на второй. Учтите, что нумерация индексов в массиве A llN a m e s начинается с нуля, а их диапазон простирается от 0 до 11. Поэтому из аргумента функции вычитается единица. Таким образом, аргумент 13 возвращает 0 (январь), ар­ гумент 24 — 11 (декабрь).

Эту функцию можно использовать разными способами, как показано на рис. 10.6.

308 Часть III. Visual Basic for Applications

R e m o v e V o w e ls = R e m o v e V o w e ls & M id ( T x t , i , 1)

E n d I f

N e x t i

E n d F u n c t io n

При использовании в составе формулы рабочего листа эта функция удаляет гласные буквы из аргумента, находящегося в одной ячейке. Если в качестве аргумента использу­ ется числовое значение, возвращается строка. В этом случае предпочтительнее возвра­ щать сообщение об ошибке (#Н/Д).

Возможно, потребуется создать строку, которая выглядит как значение ошибки в формуле Excel.

R e m o v e V o w e ls = "# Н /Д "

Несмотря на то что строка выглядит как значение ошибки, она не обрабатывается как ошибка другими формулами, которые могут на нее ссылаться. Чтобы получить в резуль­ тате выполнения функции настоящее значение ошибки, используйте функцию Cover, которая преобразует номер ошибки в настоящую ошибку.

К счастью, в VBA содержатся встроенные константы для обозначения ошибок, кото­ рые должна возвращать пользовательская функция. Эти значения — ошибки выполнения формул Excel, а не ошибки выполнения кода VBA. Ниже перечислены встроенные кон­ станты ошибок:

xlErrDivO (для ошибки #ДЕЛ/0 !);

xlErrNA (для ошибки #Н/Д);

xlErrName (для ошибки #ИМЯ?);

xlErrNull (для ошибки #ПУСТО !);

xlErrNum (для ошибки #ЧИСЛО !);

xlErrRef (для ошибки #ССЫЛ !);

xlErrValue (для ошибки #ЗНАЧ !).

Чтобы получить ошибку #Н/Д в пользовательской функции, примените следующий оператор:

R e m o v e V o w e ls = C V E r r ( x lE r r N A )

Ниже приведена преобразованная функция RemoveVowels. Конструкция If-Then применяется для выполнения альтернативного действия в случае, когда аргумент не является текстовым. Эта функция вызывает функцию Excel ЕТЕКСТ (IsText), кото­ рая определяет, содержит ли аргумент текст. Если ячейка содержит текст, то функция возвращает нормальный результат. Если же ячейка содержит не текст (или пуста), то функция возвращает ошибку #Н/Д: Если ячейка не содержит текст (или пуста), возвра­ щается ошибка #Н/Д.

F u n c t io n R e m o v e V o w e ls (T x t) A s V a r i a n t

 

 

'

У д а л я е т в с е гл а с н ы е б у к в ы и з т е к с т о в о г о а р г у м е н т а ;

'

в о з в р а щ а е т ош ибку # ЗНАЧ!, е с л и

а р г у м е н т

— не

с т р о к а

 

D im

i A s

L o n g

 

 

 

 

R e m o v e V o w e ls = ""

 

 

 

 

I f

A p p lic a t io n . W o r k s h e e t F u n c t io n . I s T e x t ( T x t )

T h e n

 

 

F o r i = 1 To L e n ( T x t )

 

 

 

 

 

I f

N o t U C a se (M id ( T x t , i ,

1 )) L ik e

" [АЕЮиАЕИОУЫЭЮ Я] " th e n

 

 

 

R e m o v e V o w e ls = R e m o v e V o w e ls & M id ( T x t , i , 1)

 

 

En d

I f