Уокенбах Формулы в Excel
.pdf•Пропущено одно или несколько аргументов.
•Аргумент неправильного типа (например, текстовый вместо числового).
•Аргумент находится вне приемлемого числового диапазона (например,деление наноль).
Во многих случаях ошибку можно просто проигнорировать. Если не указать корректное значение аргумента, то функция просто выдаст значение ошибки. Устранением ошибки занимается пользователь вручную. Так исправляются ошибки в рабочем листе Excel.
В любых случаях появившиеся ошибки нужно исправлять. Оператор On Error в Excel позволяет выявить иустранить их.
Чтобы просто проигнорировать ошибку, воспользуйтесь следующим выражением: Or Error Resume Next
При использовании этого выражения ошибки определяются в результате проверки свой-
ства |
Number объекта Err. Если свойство равно нулю, ошибка не появляется. Если |
Err |
.Number равно другому значению, то появляется сообщение обошибке. |
Вследующем примере написана функция, возвращающая имя ячейки или диапазона. Если
уячейки или диапазона нетимени, то появляется ошибка, а формула, в которой используется функция, возвращает #ЗНАЧ!.
Function RENGENAME(rng)
RANGENAME = rng . Name. Name
End Function
В приведенном ниже листинге показана улучшенная версия этой же функции. Оператор On Error Resume Next сообщает VBA, что ошибку нужно проигнорировать. Оператор I f Err проверяет наличие ошибок. Если они есть, то функция возвращает пустую строку.
Function RANGENAME(rng)
On Error Resume Next
RANGENAME = rng . Name. Name
If Err.Number <> 0 Then RANGENAME =
End Function
Представленное ниже выражение предлагает VBA проверить существование ошибок, и, если ошибка найдена, продолжить выполнение с другого места; в данном случае, с оператора ErrHandler .
On Error GoTo ErrHandler
В следующей процедуре функции продемонстрировано практическое применение этого выражения. Функция DIVIDETWO принимает два аргумента {numl и пит2) и возвращает результат — numl, деленный на пит2.
Function DIVIDETWO(numl, num2) on Error GoTo ErrHandler DIVIDETWO = numl / num2 Exit Function
ErrHandler:
DIVIDETWO = "ERROR" End Function
В случае возникновения ошибки, выражение On Error GoTo предлагает VBA перейти к операциям, помеченным какErrHandler. В результате функция возвратит строку (ERROR), если при выполнении функции возникнет ошибка. Обратите внимание на оператор Exit Function. Без этого выражения выполнение кода продолжится, и всегда будет отображаться ошибка. Другими словами, функция всегда будет возвращать ERROR.
530 |
Часть VI. Разработка пользовательских функ |
Важно понять, что функция DIVIDETWO нестандартная. Здесь при появлении ошибки (ERROR) в качестве результата возвращается строка, чего нет в Excel. В Excel обычно возвращается действительное значение ошибки.
В главе 25 приведены несколько примеров использования выражения On Error, в том числе пример, показывающий, чтосделать, чтобы функция возвратиладействительное значение ошибки.
Работа с диапазонами
Многие созданные пользовательские функции работают сданными, расположенными вячейке или вдиапазоне ячеек. Не забудьте, что диапазоном называется как одна ячейка, так игруппа ячеек. В этом разделе описываются некоторые основные способы улучшенного выполнения задач. Приведенная в этом разделе информация рассчитана напрактическое применение. Чтобы подробно ознакомиться с ихфункционированием, обратитесь ксправочной системе.
В главе 25 приведено много практических примеров использования диапазонов. Изучение этих примеров поможет разобраться синформациейданного раздела.
Конструкция For Each-Next
Иногда процедуру функции нужно зациклить наопределенном диапазоне ячеек. Например, можно написать функцию, которая в качестве аргумента принимала бы диапа-
зон. В описанном случае код проверяет каждую |
ячейку диапазона и выполняет опреде- |
ленное действие. Конструкция For Each-Next |
очень удобна для операций такого ро- |
да. Вней используется следующий синтаксис: |
|
For Each элемент In группа |
|
[операторы] |
|
[Exit For] |
|
[ опера торы] |
|
Next [элемент] |
|
Нижеприведенная процедура Function принимает аргумент диапазона и возвращает сумму квадратов величин этого диапазона.
Function SUMOFSQUARES(rng asRange) Dim total asDouble
Dim cell asRange total = 0
For Each cell In rng total = total + cell Л 2
Next cell
SUMOFSQUARES = t o t a l End Function
А вотформула Excel, вкоторой используется функция SumOf Squares: =SumOfSquares(Al:C100)
В описанном случае аргументом функции является диапазон, состоящий из 100ячеек.
Глава24. Принципы программирования на VBA |
531 |
В предыдущем |
примере cell и тд— имена переменных. В именах нет ничего |
необычного; их |
можно изменить на любое другое допустимое название. |
Ссылка надиапазон
В коде VB А к диапазону можно обратиться несколькими способами:
•с помощью свойства Range
•с помощью свойства Cell s
•с помощью свойства Offset
Свойство Range
Свойство Range можно использовать для прямого обращения к диапазону, используя адрес или имя ячейки. В приведенном ниже примере значение ячейки А1 присваивается переменной,которая называется I n i t . Таким образом, организуется доступ к свойству Value диапазона.
Init = Range("Al").Value
Кроме Value VBA предлагает и другие свойства диапазона. Например, следующее выражение подсчитывает количество ячеек в диапазоне и присваивает это значение переменной Cnt.
Cnt = Range("Al:C300").Count
Свойство Range также удобно использовать для обращения к одной ячейке многоячеечного диапазона. Например, можно создать функцию, которая принимает в качестве аргумента одну ячейку. Если пользователь задает в качестве аргумента несколько ячеек, то с помощью свойства Range можно получить значение левой верхней ячейки диапазона. В следующем примере используется свойство Range (с аргументом А1) для получения значения левой верхней ячейки диапазона, представленного аргументом c e l l .
Function Square(cell as Range) Dim CellValue as Double
CellValue = cell.Range("Al").Value Square = CellValue Л 2
End Function
Предположим, что пользователь ввел следующую формулу: =Square(C5:C12)
Функция Square обращается к левой верхней ячейке диапазона С5 : С12 (т.е. С5) и возвращает квадрат его значения.
Так работают многие функции Excel. Например, если в качестве первого аргумента функции ЛЕВСИМВ задать многоячеечный диапазон, то Excel примет левую верхнюю ячейку диапазона. Однако Excel — противоречивая программа. Если многоячеечный диапазон указать в качестве аргумента функции SQRT, TO Excel возвратит ошибку.
Свойство Cells
Другим способом обращения к диапазону является свойство Cells . Оно принимает два аргумента (номер строки и столбца) и возвращает одну ячейку. В следующем выражении значение ячейки А1 присваивается переменной F i r s t C e l l :
F i r s t C e l l = Cells(1,1).Value
532 |
Часть VI. Разработка пользовательских функ |
А следующее выражение возвращает левую верхнюю ячейку диапазона С5 :С12: UpperLeft = R a n g e ( " C 5 : C 1 2 H ) . C e l l s ( 1 , 1 )
Если свойство Cells используется безаргумента, то оно возвращает диапазон, содержащий всеячейки рабочего листа. В приведенном ниже примере переменная T o t a l C e l l s содержит общее количество ячеек рабочего листа:
TotalCells = Cells.Count
В следующем выражении используется функция Excel для определения количества непустых ячеек листа:
NonEmpty = WorksheetFunction.COUNTS(Cells)
Свойство Offset
Свойство Offset (как и свойства Range и Cells) также возвращает объект Range. Свойство Offset применяется к диапазону. Оно принимает два аргумента, соответствующие относительному расположению левой верхней ячейки определенного объекта Range. Аргументы могут быть положительными, отрицательными или равными нулю. В следующем примере возвращается значение ячейки, которая на одну ниже ячейки А1 (т.е. А2), и присваивается переменной NextCell:
NextCell = Range("Al").Offset(1, 0).Value
В следующей процедуре функции принимается аргумент одной ячейки и используется цикл For-Next для возращения суммы 10 ячеек, находящихся под выбранной ячейкой:
Function SumBelow(cell as Range) Dim Total As Double
Dim i as Integer Total = 0
For i = 1 To 10
Total = Total + cell.Offset(i, 0) Next i
SubBelow = Total End Function
Часто используемые свойства диапазона
В предыдущих разделах приводились примеры использования свойства Value диапазона. VBA предоставляет возможность работать со многими дополнительными свойствами диапазона. Некоторые наиболее полезные свойства кратко описаны в следующих разделах. Более полная информация по тому или иному свойству находится в справочной системе.
Свойство Formula
Свойство Formula возвращает формулу (как строку), которая находится в ячейке. При обращении к свойству Formula диапазона, содержащего несколько ячеек, возникает ошибка. Если в ячейке нет формулы, то свойство возвратит строку — значение ячейки в таком виде, в каком оно выглядит в строке формул. Следующая функция отображает формулу левой верхней ячейки диапазона:
Function CELLFORMULA(cell)
CELLFORMULA =cell.Range("Al").Formula End Function
Чтобы определить, есть ли в ячейке формула, используйте свойство HasFormula.
Глава 24. Принципы программирования на VBA |
533 |
Свойство Address
Свойство Address возвращает адрес диапазона в виде строки. По умолчанию это свойство возвращает адрес в виде абсолютной ссылки (например, $А$1:$С$12). Следующая функция, используемая не так уж и часто, возвращает адрес диапазона.
Function RANGEADDRESS(rng) RANGEADDRESS = rng.Address
End Function
А следующая формула возвращает строку $А$1: $С$3:
=RANGEADDRESS(А1:СЗ)
Свойство Count
Свойство Count возвращает количество ячеек в диапазоне. Оно используется в следующем примере:
Function CELLCOUNT(rng) CELLCOUNT = rng.Count
End Function
Эта формула возвращает 9:
=CELLCOUNT(A1:C3)
Свойство Parent
Свойство Parent возвращает объект, соответствующий контейнеру текущего объекта. Для объекта Range свойство Parent возвращает объект Worksheet (рабочий лист, содержащийдиапазон).
В приведенной ниже функции используется функция Parent; она возвращает имя рабочего листа диапазона, используемого в качестве аргумента:
Function SHEETNAME(rng) SHEETNAME = rng.Parent.Name
End Function
Следующая формула возвращает строку Sheet 1: =SHEETNAME(Sheetl!A16)
Свойство Name
Свойство Name возвращает объект Name ячейки диапазона. Чтобы получить реальное имя ячейки или диапазона, нужно обратиться к свойству Name объекта Name. Если у ячейки или диапазона нет имени, то свойство Name возвратит ошибку.
В следующей процедуре функции определяется имя ячейки или диапазона, переданных в качестве аргумента. Если у диапазона или ячейки нет имени, функция возвращает пустую строку. Обратите внимание, что в ней используется выражение On Error Resume Next. Таким образом, учитывается ситуация, когда у диапазона нет имени.
Function RANGENAME (rng)
On Error Resume Next RANGENAME = rng.Name.Name
If Err.Number <> 0 Then RANGENAME = "" End Function
534 |
Часть VI. Разработка пользовательских функ |
Свойство Numberformat
Свойство Numberformat возвращает числовой формат ячейки (в виде строки), присвоенный самой ячейке или диапазону. В приведенной ниже функции показан формат номера левой верхней ячейки диапазона:
Function NUMBERFORMAT(cell)
NUMBERFORMAT =cell.Range("Al").NumberFormat End Function
Свойство Font
Свойство Font возвращает объект Font диапазона или ячейки. Чтобы осуществить какоелибо действие с помощью объекта Font, нужно обратиться к его свойствам. Например, у объекта Font есть такие свойства, как Bold, I t a l i c , Name, Color и так далее. Следующая функциявозвращает значение TRUE,если клевой верхней ячейке применено полужирное начертание:
Function ISBOLD(cell)
ISBOLD =cell.Range("Al").Font.Bold End Function
Свойства Columns иRows
Свойства Columns и Rows используются для управления строками и столбцами диапазона. Например, следующая функция с помощью обращения к свойству Count возвращает количество столбцов в диапазоне:
Function COLUMNCOUNT(rng) COLUMNCOUNT = rng.Column.Count
End Function
Свойства Entirerow и Entirecolumn
Свойства Entirerow и Entirecolumn позволяют работать со всей строкой или столбцом, в которой(ом) расположена текущая ячейка. Следующая функция принимает в качестве аргумента одну ячейку и использует свойство EntireColumn, чтобы получить диапазон, содержащий целый столбец с заданной ячейкой. Далее используется функция Excel СЧЁТЗ, чтобы определить количество непустых ячеек в столбце.
Function NONEMPTY(cell)
NONEMPTY = WorksheetFunction.CountA(cell.EntireColumn) End Function
Свойство Hidden
Свойство Hidden используется для управления строками и столбцами. Оно возвращает значение TRUE, если строка или столбец скрыт. Если применить это свойство к диапазону, в который не входит целая строка или столбец, возникает ошибка. Приведенная ниже функция принимает аргумент одной ячейки и возвращает TRUE, если либо строка, либо столбец с указанной ячейкой скрыт:
Function CELLISHIDDEN(cell)
If cell.EntireRow.Hidden Orcell.EntireColumn.Hidden Then
CELLISHIDDEN = True Else
CELLISHIDDEN = False End If
End Function
Глава24. Принципы программирования на VBA |
535 |
Эту функцию можно записать без использования конструкции If-Then-Else. В следующей функции выражение справа от знака равенства возвращает либо TRUE, либо FALSE — и это значение присваивается переменной, возвращаемой функцией.
Function CELLISHIDDEN(cell)
CELLISHIDDEN = cell.EntireRow.Hidden Or cell.EntireColumn.Hidden
End Function
Ключевое словоSet
Важным моментом VBA является возможность создавать новый объект Range и присваивать его переменной, а конкретнее, создавать переменную объекта. Эта задача выполняется с помощью ключевого слова Set. Следующее выражение создает переменную объекта MyRange:
Set MyRange =Range("Al:A10")
После выполненияэтого выражения переменную MyRange можно использовать в коде для обращения кдиапазону. Примеры следующих подразделов помогут разобраться в этой возможности.
Создание объекта Range отличается отсоздания именованного диапазона. Другими словами, имя объекта Range нельзя использовать в формулах.
Функция Intersect
Функция I n t e r s e c t |
возвращает диапазон, образованный пересечением двух диапазо- |
||
нов. Например, возьмем два диапазона, представленных |
на рис.24.2. У этих диапазонов, |
||
D3 : D10 и В5 : F5, есть одна общая ячейка (D5). Другими словами, D5 является пересечением |
|||
D3 :D10 HB5:F5. |
|
|
|
i |
D |
E i |
F jfti^ii^il |
•i |
|
|
|
~5~ |
•1 |
|
|
10 |
|
||
"6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
Ж |
|
I |
2 |
|
Рис.24.2. Использование функции Intersect для управления пересечением двух диапазонов
Следующая процедура функции принимает два диапазона и подсчитывает, сколько у них общих ячеек.
Function CELLSINCOMMON(rngl, rng2) Dim CommonCells As Range
On Error Resume Next
Set CommonCells = Intersect(rngl,rng2) If Err.Number = 0 Then
536 |
ЧастьVI.Разработка пользовательских функций |
CELLINCOMMON = CommonCelIs.Count Else
CELLINCOMMON = 0 End If
End Function
Функция CELLINCOMMON использует функцию I n t e r s e c t для создания объекта диапазона CoiranonCells. Обратите внимание на использование выражения On Error Resume Next. Оно необходимо, поскольку, если у диапазонов нет общих ячеек, функция I n t e r s e c t возвращает ошибку. Если встречается ошибка и используется выражение On Error Resume Next, то ошибка игнорируется. Последнее выражение проверяет свойство Number объекта Err. Если оно равно 0, то ошибка не возникает, и функция возвращает значение свойства Count объекта CommonCells. Если возникает ошибка, то Err .Number принимает значение, отличное от нуля, и функция возвращает 0.
Функция Union
Функция Union объединяет два и более диапазона в один. В следующем выражении функция Union используется для создания объекта диапазона, содержащего первый и третий столбцы рабочего листа:
Set TwoCols = Union(Range("A:A"), Range("C:C")) Функция Union может содержать любое количество аргументов.
Свойство UsedRange
Свойство UsedRange возвращает объект Range, характеризующий используемый диапазон рабочего листа. При нажатии клавиш <Ctrl+End> активизируется правая нижняя ячейка используемого диапазона. Свойство UsedRange может быть полезно при повышении эффективности выполнения функций.
Рассмотрим следующую процедуру функции. Эта функция принимает аргумент диапазона и возвращает количество ячеек с формулами в диапазоне.
Function FORMULACOUNT(rng As Range) Dim cnt As Long
Dim cell As Range cnt = 0
For Each cell In rng
If cell.HasFormula Then cnt = cnt + 1 Next cell
FORMULACOUNT = cnt End Function
В большинстве случаев эта функция прекрасно работает. Но что если пользователь введет следующую формулу:
=FORMULACOUNT("А:С")
С аргументом, содержащим один или более столбцов, эта функция не работает, поскольку она в цикле просматривает каждую ячейку диапазона, даже те ячейки, которые лежат вне области использованного листа. Ниже приведена функция, исправляющая рассмотренный недостаток предыдущей функции:
Function FORMULACOUNT(rng As Range) Dim cnt As Long
Dim cell As Range
Глава 24. Принципы программирования на VBA |
S37 |
cnt = О
set WorkRange = Intersect(rng, rng.Parent.UsedRange) For Each cell In WorkRange
If cell.HasFormula Then cnt = cnt + 1 Next cell
FORMULACOUNT = cnt End Function
Эта функция создает объект Range с именем WorkRange, в котором сохраняется пересечение диапазона, принимаемого в качестве аргумента, и используемого диапазона рабочего листа. Другими словами, WorkRange состоит из подмножества аргументов диапазона, в которое входят ячейки используемого диапазона рабочего листа.
Резюме
Вэтой главе вы познакомились с элементами языка VBA, а именно с переменными, типами данных, константами и массивами. Здесь также рассматривались различные методы регулирования выполнения процедур функций. Было представлено несколько примеров функций, которые продемонстрировали управление массивами и использование встроенных функций VBА.
Вследующей, последней главе приведены примеры пользовательских функций.
538 |
Часть VI. Разработка пользовательских функ |
Глава 25
Примеры пользовательских функций VBA
Вэтой главе...
•Простые функции
•Определение типа данных в ячейке
•Многофункциональная функция
•Генерирование случайных чисел
•Вычисление комиссионных от продаж
•Функцииуправления текстом
•Функции подсчета и суммирования
•Функцииуправления датами
•Возвращение последней непустой ячейки столбца или строки
•Функциидля работы в нескольких листах
•Дополнительные пользовательские функции
•Резюме
Вэтой главе приведены различные примеры полезных (или потенциально полезных) пользовательских функций VBA. Большинство функций можно использовать в таком виде, в каком они приведены. Но некоторые функции нужно немного изменить, чтобы они отвечали конечным задачам. Для повышения производительности и эффективности выполнения таких процедур функций в этой главе описываются все используемые в них переменные.
Простые функции
Относительно простые функции, представленные в этой главе, могут оказаться очень полезными. Многие из них основаны на том факте, что VBA получает доступ к большому количеству полезной информации, которая обычно не используется в формулах. Например, код VBA может обратиться к свойству ячейки HasFormula, чтобы определить, содержится ли в ячейке формула. Странно, но в Excel нет такой встроеннойфункции.
Есть ли вячейке формула?
Приведенная ниже функция CELLHASFORMULA принимает аргумент в виде одной ячейки и возвращает значение TRUE,если в ячейке содержится формула.
Function CELLHASFORMULA(cell) As Boolean
1 |
Возвращает TRUE если в ячейке введена формула |
|
CELLHASFORMULA = cell.Range("Al").HasFormula |
End |
Function |
Глава 25. Примеры пользовательских функций VBA |
539 |
