Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Уокенбах Формулы в Excel

.pdf
Скачиваний:
212
Добавлен:
26.03.2016
Размер:
35.82 Mб
Скачать

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

Возвращение формулы ячейки

Следующая функция CELLFORMULA возвращает формулу, содержащуюся в ячейке, в виде строки. Если в ячейке нет формулы, функция возвращает пустую строку.

Function CELLFORMULA(cell) As String

1Возвращает формулу ячейки или

1пустую строку, если формулы в ячейке нет

Dim UpperLeft As Range

Set UpperLeft = cell.Range("Al") If UpperLeft.HasFormula Then

CELLFORMULA = UpperLeft.Formula

Else

CELLFORMULA = ""

End If

End Function

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

Скрыта ли ячейка?

Следующая функция CELLISHIDDEN принимает аргумент в виде одной ячейки и возвращает значение TRUE, если ячейка скрыта. Ячейка считается скрытой, если скрыта ее строка или столбец.

Использование функцийэтой главы

Если в этой главе вам встретится функция, полезная длярешения конкретных задач, то используйте ее в своем рабочем листе. Все процедуры этой главы приведены на Web-узле. Откройте соответствующую рабочую книгу (см. Приложение Д с описанием файлов), активизируйте редактор Visual Basic и вставьте листинг функции в модуль VBA вашей рабочей книги. Принеобходимости воспользуйтесь несколькими функциями илисоздайте надстройку (см. главу23).

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

Function CELLISHIDDEN(cell) As Boolean

1Возвращает TRUE если ячейка скрыта Dim UpperLeft As Range

Set UpperLeft = cell.Range("Al") CELLISHIDDEN = UpperLeft.EntireRow.Hidden Or

UpperLeft.EntireColuinn. Hidden

End Function

Возвращение имени рабочего листа

Приведенная ниже функция SHEETNAME принимает один аргумент (диапазон) и возвращает имя рабочего листа с этим диапазоном. В функции используется свойство Parent объекта Range. Свойство Parent возвращает объект, в котором содержится объект Range.

Function SHEETNAME(rng) As

String

1

Возвращает имя рабочей

книги для rng

540

Часть VI. Разработка пользовательскихфункц

SHEETNAME = rng.Parent.Name End Function

А вот еще один вариант этой же функции. В ней не используется аргумент; действие этой функции основано на том, что она может определить ячейку, из которой она вызвана с помощью свойства Application . Caller .

Function SHEETNAME2() As String

1 Возвращает имя книги для ячейки,

1содержащей функцию

SHEETNAME2 = Application.Caller.Parent.Name

End Function

Понятие родительских объектов

Объекты в Excel выстроены в иерархическом порядке. На верхнем уровне иерархии расположен объект A p p l i c a t i o n (сама Excel). В Excel есть и другие объекты; эти объекты, в свою очередь, состоят из других объектов и т.д. Ниже показано, на каком месте в этой иерархии находится объект Range.

Объект Application (Excel) Объект workbook

Объект Worksheet Объект Range

В объектно-ориентированном программировании родительским для объекта Range является объект Worksheet, в котором находится объект Range. Родительским для объекта Worksheet является Workbook. И, наконец, родителем объекта Workbook является объект Application . Разобравшись в такой структуре, используйте свойство Parent, чтобы создавать различные полезные функции.

В этой функции свойство A p p l i c a t i o n . C a l l e r возвращает объект Range, который соответствует ячейке с функцией. Предположим, что в ячейке А1 содержится такая формула:

=SHEETNAME()

Когда выполняется функция SHEETNAME, свойство A p p l i c a t i o n . C a l l e r возвращает объект Range, соответствующий ячейке, содержащей функцию. Свойство Parent возвращает объект Worksheet, а свойство Name возвращает имя рабочего листа.

Возвращение имени рабочей книги

Приведенная ниже функция WORKBOOKNAME возвращает имя рабочей книги. Обратите внимание, что в этой функции свойство Parent используется дважды. Первый раз свойство Parent возвращает объект Worksheet, а во второй раз— объект Workbook; свойство Name возвращает имя рабочей книги.

Function WORKBOOKNAME() As String

1

Возвращает имя книги для ячейки,

1

содержащей функцию

 

WORKBOOKNAME = Application.Caller.Parent.Parent.Name

End

Function

Глава 25. Примеры пользовательских функций VBA

541

Возвращение имени приложения

Следующая функция,в принципе,редко используемая, переносит рассуждения о родительских объектах на следующий логический уровень, обращаясь к свойству Parent три раза. Этафункция возвращает имя объекта Application, которое всегда является строкой Microsoft Excel.

Function APPNAMEO As String

1 Возвращает имя книги для ячейки,

1содержащей функцию

APPNAME = Application.Caller.Parent.Parent.Parent.Name

End Function

Возвращение версии Excel

Следующая функция возвращает номер версии Excel. Например, если используется Excel 2002, то она возвратит текстовую строку 10.0.

Function EXCELVERSIONO As String

'Возвращает номер версии Excel EXCELVERSION = Application.Version

End Function

Обратите внимание, что функция EXCELVERSION возвращает строку, а не значение. Приведенная ниже функция возвращает значение TRUE, если используемым приложением является Excel версии 97 или выше (Excel 97 соответствует версии 8). В этой функции используется функцияVal для преобразования текстовой строки в значение.

Function EXCEL97ORLATERO As Boolean EXCEL97ORLATER = Val(Application.Version) >= 8

End Function

Возвращение информации

оформатировании ячейки

Вэтом разделе приведено несколько пользовательских функций, которые возвращают информацию о форматировании, примененном в ячейке. Такие функции используются при сортировке данных по форматированию (например, по ячейкам с полужирным начертанием).

В функциях этого раздела используется следующее выражение:

Application.Volatile True

Это выражение заставляет функцию проводить перерасчет формул в рабочей книге. Но, как обнаружится позднее, этифункции не всегда возвращают правильные значения. Это происходит из-за того, чтоExcel, скажем, невыполняет перерасчет ячеек при изменении форматирования ячеек. Чтобы все жевыполнить общий перерасчет (и обновить все пользовательские функции), нажмите <Ctr+Alt+F9>.

Следующая функция возвращает значение TRUE, если к ячейке-аргументу применено полужирное начертание.

Function ISBOLD(cell) As Boolean

1Возвращает TRUE, если шрифт ячейки имеет полужирное начертание ISBOLD = cell.RangeC'Al") .Font.Bold

End Function

S42

Часть VI.Разработка пользовательских функц

А эта функция возвращает значение TRUE, если к аргументу одной ячейки применено курсивное начертание.

Function ISITALIC(cell) As Boolean

1 Возвращает TRUE, если шрифт ячейки имеет курсивное начертание ISITALIC = cell.RangeC'Al") .Font. Italic

End Function

В обеих приведенных выше функциях есть небольшое упущение: если кячейке применено смешанное форматирование, то функции возвращают ошибку. Например, если полужирным начертанием форматированы только некоторые символы. Следующая функция возвратит значение TRUE только в том случае, если все символы в ячейке имеют полужирное начертание. Вней используется VBA-функция IsNull, определяющая, возвращает ли свойство Bold объекта Font значение Null. Если да, то в ячейке содержится смешанное форматирование.

Function ALLBOLD(cell) As Boolean

1

Возвращает TRUE,

если весь текст в ячейке

1

имеет полужирное

начертание

 

Dim UpperLeft

As Range

 

Set UpperLeft

= cell.RangeC'Al")

 

ALLBOLD = False

 

 

If UpperLeft.Font.Bold Then ALLBOLD = True

End

Function

 

 

Следующая функция FILLCOLOR возвращает целочисленное значение, которое соответствует индексу цвета заливки ячейки. Если в ячейке нет заливки, функция возвращает значение -4142.

Function FILLCOLOR(cell) As

Integer

1

Возвращает целое число,

соответствующее

1

цвету заливки ячейки

 

 

FILLCOLOR = cell . Range("Al") . Interior . ColorIndex

End

Function

 

Приведенная ниже функция возвращает ввиде строки формат цифр в ячейке.

Function NUMBERFORMAT(cell) AsString 1 Возвращает строку, представляющую ' числовой формат ячейки

Application.Volatile True

NUMBERFORMAT = cell.Range("Al").NUMBERFORMAT End Function

Если вячейке используется формат цифр, заданный по умолчанию, то функция возвратит

строку General.

Определение типаданных вячейке

В Excel предложено несколько встроенных функций определения типа данных, содержащихся в ячейке. Эти функции называются ЕТЕКСТ, ЕЛОГИЧ иЕОШИБКА. Кроме этих функций вVBA есть такие функции, как ЕПУСТО, ЕДАТА иЕЧИСЛО.

Следующая функция принимает аргумент диапазона и возвращает строку (Blank, Text, Logical, Error, Date, Timeили Value), которая описывает тип данных левой верхней ячейкидиапазона.

Function CELLTYPE(cell)

'Возвращает тип левой верхней

1ячейки диапазона

Dim UpperLeft As Range Application.Volatile

Глава 25. Примеры пользовательских функций VBA

543

Set UpperLeft = cell.Range("Al")

Select Case True

Case UpperLeft.NumberFormat = "@"

CELLTYPE = "Text"

Case IsEmpty(UpperLeft)

CELLTYPE = "Blank"

Case WorksheetFunction.IsText(UpperLeft)

CELLTYPE = "Text"

Case WorksheetFunction.IsLogical(UpperLeft)

CELLTYPE = "Logical"

Case WorksheetFunction.IsErr(UpperLeft)

CELLTYPE = "Error"

Case IsDate(UpperLeft)

CELLTYPE = "Date"

Case InStr(l, UpperLeft.Text, ":") <> 0

CELLTYPE = "Time"

Case IsNumeric(UpperLeft)

CELLTYPE = "Value"

End Select

End Function

На рис. 25.1 показана функция CELLTYPE в действии. В столбце В содержатся формулы, обработанные функцией CELLTYPE с аргументами из столбца А. Например, в ячейке В1 содержится такая формула:

=CELLTYPE(A1)

I

*

1

4F

A simple value

 

 

Щ

Value

 

 

 

Т1

8,6

Value

Formula that returns a value

 

 

3jBudget Sheet

Text

Simple text

 

 

 

 

' 4

-

ЛОЖЬ

Logical

Logical formula

 

 

 

(S'u

 

ИСТИНА

Logical

Logical value

 

 

 

' б'Т

ЭДЕЛ/DI

Error

Formula error

 

 

 

"7~.

07 06 2002

Date

Formula that returns a date

 

 

j

"'

4 00 РМ

Time

A time

 

 

 

 

~9

143

Text

Value preceded byapostrophe

 

 

Тб>34

 

Text

Cell formatted asText

 

 

 

"tT'A1 C4

Text

Text with a colon

 

 

 

"12J

 

Blank

Empty cell

 

 

 

 

'13|

 

Text

Cell with a single space

 

 

 

14

 

 

 

 

 

 

 

 

1

 

 

""

HI

..J

 

-Tic

И 4 » w\sheetl/

 

 

 

 

Г

 

Рис. 25.1. Функция CELLTYPE возвращает строку с описанием типа содержимого ячейки

Многофункциональная функция

В этом разделе показаны способы создания одной функции рабочего листа, которая работает как несколько функций. Такая функция VbA, называемая STATFUNCTION,работает с двумя аргументами— диапазоном (rng) и оператором (ор). В зависимости от значения ор функция возвращает значение, вычисленное с использованием одной из функций рабочего листа: СРЗНАЧ, СЧЁТ, МАКС,МЕДИАНА, МИН, МОДА и т.д. Эту функцию можно использовать на рабочем листе:

=STATFUNCTION(B1:B24;A24)

Результат формулы зависит от содержимого ячейки А24, которая содержит строку, например, Average, Count, Max и т.д. Таким образом можно работать и с другими типами функций.

544

Часть VI.Разработка пользовательских функций

Function STATFUNCTION(rng, op) Select Case UCase(op)

Case "SUM"

STATFUNCTION = Application.Sum(rng) Case "AVERAGE"

STATFUNCTION = Application.Average(rng) Case "MEDIAN"

STATFUNCTION = Application.Median(rng) Case "MODE"

STATFUNCTION = Application.Mode(rng) Case "COUNT"

STATFUNCTION = Application.Count(rng) Case "MAX"

STATFUNCTION = Application.Max(rng) Case "MIN"

STATFUNCTION = Application.Min(rng) Case "VAR"

STATFUNCTION = Application.Var(rng)

Case "STDEV"

STATFUNCTION = Application.StDev(rng)

Case Else

STATFUNCTION = CVErr(xlErrNA) End Select

End Function

На рис. 25.2 представлена функция STATFUNCTION, используемая вместе с раскрывающимся списком, созданным с помощью команды Excel Данные1^Проверка. Формула находится в ячейке С14:

=STATFUNCTION(С1:С12;В14)

Следующая функция STATFUNCTION2 имеет более простой вид,но работает так же, как и функция STATFUNCTION. В этой функции для вычисления выражения используется оператор Evaluate.

Function STATFUNCTION2(rng, op) STATFUNCTION2 = Evaluate(op & "(" & _ rng.Address(external:=True) & ")")

End Function

SSSUM

 

 

8

' j

С

 

 

1

 

Observation 1

 

135,52 '

 

 

2

 

Observation 2

 

244,09

 

 

3

 

Observation 3

 

187,33

 

 

4

 

Observation 4

 

209,00

 

 

5

'

Observat on 5

 

200,91

 

 

6

 

Observat on 6

 

189,23

 

 

7 "

 

Observat on 7

 

198.22

 

 

'в'

 

Observat on 8

 

231,78

 

 

9

,

Observat on 9

 

189,14

 

 

10'

 

Observat on 10

 

221,15

 

 

11

 

Observat on 11

 

189.05

 

 

12'

 

Observation 12

 

198.22

 

 

13"

 

 

 

 

 

 

J4J

Mm

U

135,52

<--

STATFUNCTION

15

 

Average

A.

135,52

<--

STATFUNCTION2

16*

 

Median

~

 

 

 

 

Mode

 

 

 

 

17'

 

 

 

 

 

 

Count

 

 

 

 

18

 

 

 

 

 

 

Max

 

 

 

 

19'

 

 

 

 

 

 

20'

 

StDev

" •

 

 

j<j

к < »

 

 

w\sheeH/

 

 

 

' ;

l ' ,joixj

G

H ~Z

j >\&

Рис. 25.2. Результатвыбора операции изсписка отображается в ячейке В14

Глава 25. Примеры пользовательских функций VBA

545

Предположим, что аргумент r n g соответствует С1 :С12, а аргумент ор является строковым значением SUM. Выражение, используемое в качестве аргумента оператора E v a l u a t e , имеет следующий вид:

SUM(C1:C12)

Оператор E v a l u a t e подсчитывает аргументы и возвращает результат. Кроме того, что это довольно короткое выражение, преимущество этой версии функции STATFUNCTION заключается еще и в том, что необязательно перечислять все возможные функции.

Генерированиеслучайныхчисел

В этом разделе представлены две функции, работающие со случайными числами. Одна из них генерирует случайные числа, которые не изменяются. Другая выбирает из диапазона случайную ячейку.

Генерирование неизменяемых случайных чисел

Чтобы быстро создать диапазон ячеек, состоящих из случайных чисел, воспользуйтесь в Excel функцией СЛЧИС. Но, как выяснится позднее, функция СЛЧИС генерирует новое случайное число каждый раз при пересчете рабочего листа. Если нужно создать диапазон случайных чисел, которые не изменяются при каждом пересчете, используйте процедуру STATICRAND:

Function STATICRAND()

1

Возвращает

произвольное число, не

1

изменяющееся

при перерасчете данных

 

STATICRAND

=

Rnd

End Function

 

 

В функции STATICRAND используется функция Rnd VBA, которая, как и функция СЛЧИС, возвращает случайное число от 0 до 1. Но при использовании STATICRAND случайные числа не меняются при пересчете листа.

При нажатии клавиши <F9> новые значения функции STATICRAND не генерируются, это можно сделать с помощью сочетания клавиш <Ctrl+Alt+F9> (клавиатурное сокращение "глобального пересчета" в Excel).

Чтобы сгенерировать серии случайных целых чисел между 1 и 1000, используйте формулу

=ЦЕЛОЕ(STATICRAND()*1000)+1

Выбор случайной ячейки

Следующая функция, которая называется DRAWONE, выбирает случайным образом одну ячейку из введенного диапазона и возвращает ее содержимое.

Funсtion DRAWONE(rng)

1 Выбор одного из чисел диапазона произвольным образом DRAWONE = rng(Int((rng.Count) * Rnd +1))

End Function

Используя эту функцию, обратите внимание, что при пересчете рабочего листа она не пересчитывается. Другими словами, эта функция не является временной (более подробно об управлении процессом пересчета рассказывается во врезке "Управление пересчетом функции" далее в этой главе). Функцию можно сделать изменяемой, добавив следующее выражение:

Application.Volatile True

546

Часть VI. Разработка пользовательских функ

Управлениепересчетом функции

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

Пользовательские функции ведут себя как встроенные функции рабочего листа Excel. Обычно пользовательская функция пересчитывается только тогда, когда она должна быть пересчитана, т.е. когда изменяются аргументы функции. Но пересчет функции можно делать чаще. Добавив следующее выражение в процедуру, в функции выполнится пересчет при изменении любой ячейки.

Application.Volatile True

Оператор v o l a t i l e в объекте A p p l i c a t i o n принимает один аргумент (либо True, либо False). Атрибут v o l a t i l e у функции заставляет ее пересчитываться каждый раз при пересчете любой ячейки рабочего листа.

Например, пользовательскую функцию STATICRAND, представленную в этой главе, можно заменить на ее эмулятор, функцию Excel слчис (), использовав оператор V o l a t i l e :

Function NONSTATICRAND()

1

Возвращает произвольное

число, не

1

изменяющегося

при

перерасчете

Application.Volatile

True

 

NONSTATINCRAND

= Rnd

 

 

End Function

 

 

 

Использование в операторе v o l a t i l e аргумента False заставляет функцию выполнить пересчет только в том случае, если изменяются один или несколько ее аргументов (если в функции нет аргументов, то этот метод неэффективен). По умолчанию все функции дейст-

| вуют так, как будто для них задано выражение A p p l i c a t i o n . V o l a t i l e False.

После этого функция DRAWONE будет отображать новые случайные значения каждый раз при пересчете листа.

Далее в этой главе представлены еще две функции управления случайными числами.

Вычисление комиссионных отпродаж

Менеджерам по продажам часто необходимо просчитать комиссионные, полученные от продаж. Расчеты в примере функции, представленной ниже, основаны на подвижной шкале: чем больше работник продал, тем больше комиссионных он получил (табл. 25.1). Например, менеджер с продажами в диапазоне от $10000 до $19999 получает 10,5% комиссионных.

Таблица 25.1.Ставка комиссионных дляпродажзамесяц

Продажа за месяц

Процентная ставка

Менее $10000

8,0%

$10000-$19999

10,5%

$20000-$39999

12,0%

$40000 иболее

14,0%

Глава 25.Примеры пользовательских функцийVBA

547

Комиссионные можно вычислить для различных объемов продаж, указанных на рабочем листе. Можно использовать сложную формулу со вложенными функциями IF,например:

=IF(A1<O;O;IF(AK1OOOO;A1*O,O8;IF(A1<2OOOO;A1*O,105;IF(Al<40000;А1*0,1

2;А1*0,14))))

Но это не наилучший способ по нескольким причинам. Во-первых, формула получается слишком громоздкой и запутанной, что затрудняет ее понимание. Во-вторых, значения в формуле указываются жестко, что затрудняет внесение изменений в формулу. И если есть больше семи процентных ставок, то запись функциивыйдет за ограничения по вложенным функциямExcel.

Лучший способ описать эти условия — воспользоваться функцией таблицы Lookup для подсчета комиссионных, а именно:

=ПРОСМОТР(Al;Table;2)*А1

Использование функции ПРОСМОТРявляется хорошей альтернативой, но она не выполняется, если структура начисления комиссионных слишком сложная. (См. подраздел "Функция сложной структуры начисления комиссионных"). Еще одной альтернативой является создание пользовательской функции.

Функция простой структуры начисления комиссионных

Следующая функция COMMISSIONпринимает один аргумент (Sales) и вычисляет ставку комиссионных.

Function COMMISSION(Sales) As Single

1Вычисляет комиссионные с продаж Const Tierl As Double = 0.08 Const Tier2 As Double = 0.105 Const Tier3 As Double = 0.12 Const Tier4 As Double = 0.14 Select Case Sales

Case

Is >= 40000

 

COMMISSION2 = Sales * Tier4

Case

Is. >= 20000

 

COMMISSION2 = Sales * Tier3

Case

Is >= 10000

 

COMMISSION2 = Sales * Tier2

Case

Is < 10000

 

COMMISSION2 = Sales * Tierl

End Select

End Function

 

Приведенная ниже формула рабочего листа возвращает значение 3000 (объем продаж 25000 соответствует ставке 12%):

=COMMISSION(2 5000)

В этой функции легко разобраться. В ней используется константа для хранения ставки комиссионных и структура Selec t Case для определения того, какую ставку следует брать.

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

548

Часть VI. Разработка пользовательскихфунк

Функция сложной структуры начисления комиссионных

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

Ниже приведена измененная функция COMMISSION (онаназывается COMMISSION2). Теперь этафункция принимает двааргумента: объем продажи за месяц (Sales) и количество отработанных в компании лет (Years).

Function COMMISSION2(Sales,

Years) As Single

1

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

с продаж на основе

1рабочего стажа

Const Tierl As Double = 0..08 Const Tier2 As Double = 0.105 Const Tier3 As Double = 0.12

Const Tier4 As Double = 0.14 Select Case Sales

Case Is >= 40000

COMMISSION2 = Sales * Tier4 Case Is >= 20000

COMMISSION2 = Sales * Tier3 Case I s >= 10000

COMMISSION2 = Sales * Tier2 Case Is < 10000

COMMISSION2 = Sales * Tierl End Select

COMMISSION2 = COMMISSION2 + ((COMMISSION2 * Years / 100) End Function

На рис. 25.3 представлена функция COMMISSION2. Формула вячейке D2такая:

=COMMISSION2(B2;C2)

 

А

1

B

С

D.

<

 

1 iSalesRep

lAmount Sold

Years Employed

Commission

 

2

Adams, Robert

 

5 010.54

1

 

404,85

 

Э

Baker,Sheila

 

9 833.91

0

786,71

 

4

Clarke, Edward

 

12 500.32

2

1 338,78

 

5

Davis, Don

 

35 988.22

3

4 448,14

 

*6

"Elfin,Bill

 

41 822.99

3

6 030,88

 

7

Franklin, Ben

 

8 090.32

1

653,70

8

Gomez, Chris

 

11098.32

2

1 188,63

9

Harley.Mary

 

48 745.23

5

7 165,55

 

10'

 

 

 

 

 

 

 

11

 

 

 

 

 

 

 

12'

 

 

 

 

 

 

 

1 3 . .

 

.

 

 

1

HP

 

 

 

 

 

 

Рис. 25.3. Пересчет комиссионных на основе объема продаж: иколичестваотработанныхвкомпании лет

Функции управления текстом

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

Глава 25. ПримерыпользовательскихфункцийVBA

549