В VBAиспользуются следующие виды функций:
Математические встроенные функции;
Математические функции, не представленные в VBA;
Функции форматирования данных;
Функции преобразования типов
Математические встроенные функции
Возвращаемое значение |
|||||||||||||||||||||
Абсолютная величина числа |
|||||||||||||||||||||
arctg(x) – арктангенс от значения параметра, заданного в радианах |
|||||||||||||||||||||
sin(x) – возвращает синус угла от значения параметра, заданного в радианах |
|||||||||||||||||||||
cos(x) – косинус указанного в радианах угла |
|||||||||||||||||||||
tg(x) – возвращает тангенс угла от значения параметра, заданного в радианах |
|||||||||||||||||||||
e x – возвращает числоe, возведенное в указанную степень, где е – основание натурального логарифма |
|||||||||||||||||||||
ln(x) – возвращает натуральный логарифм от значения числового выражения |
|||||||||||||||||||||
- возвращает квадратный корень числового выражения |
|||||||||||||||||||||
Случайное число из интервала ) Именованные числовые форматы
Практически весь программный код модулей VBA содержится в процедурах двух типов Sub (подпрограммы) и Function (функции). Основная задача процедуры-функции Function - это вычисление некоторого значения и возвращение его в точку вызова процедуры-функции. Синтаксис процедуры-функции Function: Function Имя_Функции(аргументы As) As Имя_Функции = Возвращаемое_Значение End Function Процедуры-функции Function могут быть использованы в различных выражениях. Пример 1 Например, самая простая процедура-функция Function: Function F1(x As Currency) As Currency Function F1(x) можно использовать в дальнейших вычислениях (программном коде модуля). Процедуру типа Function можно выполнить, только вызвав ее из другой процедуры. Для этого в вызывающей процедуре необходимо присвоить имя данной F1(x) некоторой переменной. Пример 2 Например, Function F1(x) можно использовать в процедуре MySub (), присвоив переменной "у" имя F1(x). Dim y As Single ‘Объявление переменной y y = F1 (9) ‘Определяем F1 (x) для значения x=9 Debug.Print y ‘Вывод значений в окне Immediate Function F1 (x As Single) As Single F1 = x ^ 10 ‘Возвращаемое значение х в степени 10 Здесь Function F1(x)=$x^{10}$ для значения $ x=9$ возвращает в вызывающую процедуру MySub () значение $3,486785E+09$. Если для возвращаемого функцией значения или переменной, которая используется в процедуре VBA, не объявлен тип данных, то по умолчанию будет задан тип данных Variant. В VBA используются как процедуры-функции Function, так и встроенные функции. Встроенные функции состоят из двух частей: имени (идентификатора) и аргументов. Встроенные функции - это готовые формулы VBA, которые выполняют определенные действия над выражениями и возвращают некоторое значение в точку их вызова. Функции возвращают результирующее значение вместо их имени, которое используется в дальнейших вычислениях. Как правило, функции требуют наличия аргументов, которые записываются в скобках через запятую. Но некоторые функции не требует аргументов. Например, функция Now(), которая не требует аргументов, возвращает текущую системную дату и время. Функции можно использовать для создания новых выражений или функций. Как вставить функцию в текст программы? Чтобы использовать функцию в выражениях, необходимо ввести ее имя в оператор VBA. Для вызова встроенной функции, не требующей аргументов, достаточно ввести ее имя (например, Now) в код программы модуля: Sub MyDate () Dim TD ‘Объявление переменной TD TD = Now ‘Определяем текущую системную дату и время Debug.Print TD ‘Вывод значений в окне Immediate Для вызова функции, требующей ввода одного или нескольких аргументов, необходимо ввести в правой части оператора присваивания ее имя с заключенными в скобках параметрами (значениями аргументов). Например, для вызова встроенной Function Log (N) с одной переменной N в процедуре типа Sub переменной Log_N присвоено имя функции Log (50) со значением аргумента равного 50. Sub Натуральныйлогарифм () Dim LogN ‘Объявление переменной LogN Debug.Print LogN ‘Вывод значений в окне Immediate Замечание 1 Здесь встроенная функция Log (N) для значения аргумента равного 50 возвращает значение 3,91202300542815 в точку вызова Log (50) вызывающей процедуры "Sub Натуральный_логарифм ()". Функцию можно вызвать как с помощью отдельного оператора VBA, так и поместив ее имя со списком значений аргументов (параметров) в формулу или выражение в программе на VBA. В VBA для сокращения записи используется механизм вложения функций, который позволяет указывать вызов одной функции в качестве аргумента для другой функции. В этом случае возвращаемое первой функцией значение используется в качестве аргумента для следующей функции. В VBA имеется большой набор встроенных функций и процедур, упрощающих программирование, которые можно разделить на следующие категории:
Математические функцииК математическим функциям относят:
Fix(x) и Int(x) обе функции отбрасывают дробную часть числа и возвращают целое значение. Разница между этими функциями состоит для отрицательных значений аргумента. Int(x) возвращает ближайшее отрицательное целое число, меньшее или равное х, а Fix(x) – ближайшее отрицательное целое число, большее или равное х. Функции проверки типовПриведем функции, определяющие каким типом является переменная:
Функция форматированияФункция форматирования возвращает значение типа Variant (String), содержащее выражение, оформленное согласно синтаксиса функции: Format(Выражение[,Формат [,Первый день недели[,Первая Неделя Года]]]),где:
Если к имени функции добавляется знак $, то функция возвращает значение типа String., то функция возвращает значение типа String. При создании собственного числового формата можно использовать следующие символы :
Функции преобразования форматовК ним относят:
Кроме функций Val и Str имеется ряд функций по преобразованию типов выражений. Функции обработки строкСреди множества функций можно выделить следующие:
Функции времени и датыВозвращают значение типа Variant, содержащее системную дату, текущее время и т. д. Например функция Date возвращает значение, содержащее системную дату. С помощью VBA вы можете создать пользовательскую функцию, которую можно использовать на листах точно так же, как обычные функции. Это полезно, когда существующих функций Excel недостаточно. В таких случаях вы можете создать свою собственную пользовательскую функцию (UDF) для удовлетворения ваших конкретных потребностей. В этом руководстве я расскажу о создании и использовании пользовательских функций в VBA. Что такое функциональная процедура в VBA?Процедура Function — это код VBA, который выполняет вычисления и возвращает значение (или массив значений). Используя процедуру Function, вы можете создать функцию, которую вы можете использовать на рабочем листе (как и любую обычную функцию Excel, такую как SUM или VLOOKUP). Когда вы создали процедуру Function с использованием VBA, вы можете использовать ее тремя способами:
Хотя на рабочем листе уже имеется более 450 встроенных функций Excel, вам может потребоваться настраиваемая функция, если:
Обратите внимание, что пользовательские функции, созданные с использованием VBA, могут быть значительно медленнее, чем встроенные функции. Следовательно, они лучше всего подходят для ситуаций, когда вы не можете получить результат, используя встроенные функции. Функция против Подпрограммы в VBA«Подпрограмма» позволяет вам выполнять набор кода, в то время как «Функция» возвращает значение (или массив значений). Например, если у вас есть список чисел (как положительных, так и отрицательных), и вы хотите идентифицировать отрицательные числа, вот что вы можете сделать с помощью функции и подпрограммы. Подпрограмма может проходить через каждую ячейку в диапазоне и может выделять все ячейки, которые имеют отрицательное значение в ней. В этом случае подпрограмма завершает изменение свойств объекта диапазона (путем изменения цвета ячеек). С пользовательской функцией вы можете использовать ее в отдельном столбце, и она может возвратить TRUE, если значение в ячейке отрицательное, и FALSE, если оно положительное. С помощью функции вы не можете изменять свойства объекта. Это означает, что вы не можете изменить цвет ячейки с помощью самой функции (однако вы можете сделать это, используя условное форматирование с пользовательской функцией). Когда вы создаете пользовательскую функцию (UDF) с использованием VBA, вы можете использовать эту функцию на листе, как и любую другую функцию. Я расскажу об этом подробнее в разделе «Различные способы использования пользовательских функций в Excel». Создание простой пользовательской функции в VBAПозвольте мне создать простую пользовательскую функцию в VBA и показать вам, как она работает. Приведенный ниже код создает функцию, которая извлекает числовые части из буквенно-цифровой строки. Function GetNumeric(CellRef As String) as Long Dim StringLength As Integer StringLength = Len(CellRef) For i = 1 To StringLength If IsNumeric(Mid(CellRef, i, 1)) Then Result = Result & Mid(CellRef, i, 1) Next i GetNumeric = Result End Function Если у вас есть вышеуказанный код в модуле, вы можете использовать эту функцию в рабочей книге. Ниже показано, как эту функцию — GetNumeric — можно использовать в Excel. Теперь, прежде чем я расскажу вам, как эта функция создается в VBA и как она работает, вам нужно знать несколько вещей:
Я считаю, что это хороший пример, когда вы можете использовать VBA для создания простой в использовании функции в Excel. Вы можете сделать то же самое с формулой (как показано в этом руководстве), но это становится сложным и трудным для понимания. С этим UDF вам нужно передать только один аргумент, и вы получите результат. Анатомия пользовательской функции в VBAВ приведенном выше разделе я дал вам код и показал, как функция UDF работает на рабочем листе. Теперь давайте углубимся и посмотрим, как создается эта функция. Вы должны поместить приведенный ниже код в модуль в VB Editor. Я рассматриваю эту тему в разделе Function GetNumeric(CellRef As String) as Long " Эта функция извлекает числовую часть из строки Dim StringLength As Integer StringLength = Len(CellRef) For i = 1 To StringLength If IsNumeric(Mid(CellRef, i, 1)) Then Result = Result & Mid(CellRef, i, 1) Next i GetNumeric = Result End Function Первая строка кода начинается со слова «Функция». Это слово говорит VBA, что наш код является функцией (а не подпрограммой). За словом Function следует имя функции — GetNumeric. Это имя, которое мы будем использовать на листе, чтобы использовать эту функцию.
За именем функции следуют некоторые аргументы в скобках. Это аргументы, которые нужны нашей функции от пользователя. Это как аргументы, которые мы должны предоставить встроенным функциям Excel. Например, в функции COUNTIF есть два аргумента (диапазон и критерии). В скобках необходимо указать аргументы. В нашем примере есть только один аргумент — CellRef. Также полезно указывать, какой аргумент ожидает функция. В этом примере, так как мы будем передавать функции ссылку на ячейку, мы можем указать аргумент как тип «Range». Если вы не укажете тип данных, VBA будет рассматривать его как вариант (что означает, что вы можете использовать любой тип данных). Если у вас есть более одного аргумента, вы можете указать те же в круглых скобках — через запятую. Далее в этом руководстве мы увидим, как использовать несколько аргументов в пользовательской функции. Обратите внимание, что функция указана как тип данных «String». Это сообщит VBA, что результат формулы будет иметь тип данных String. Здесь я могу использовать числовой тип данных (например, Long или Double), но это ограничит диапазон возвращаемых чисел. Если у меня есть строка длиной 20 номеров, которую мне нужно извлечь из общей строки, объявление функции как Long или Double приведет к ошибке (так как число будет вне диапазона). Поэтому я сохранил тип выходных данных функции как String. Вторая строка кода — зеленая, которая начинается с апострофа — это комментарий. При чтении кода VBA игнорирует эту строку. Вы можете использовать это, чтобы добавить описание или подробности о коде. Третья строка кода объявляет переменную StringLength как тип данных Integer. Это переменная, в которой мы храним значение длины строки, которая анализируется по формуле. В четвертой строке переменная Result объявляется как тип данных String. Это переменная, в которой мы будем извлекать числа из буквенно-цифровой строки. Пятая строка назначает длину строки во входном аргументе переменной «StringLength». Обратите внимание, что «CellRef» относится к аргументу, который будет предоставлен пользователем при использовании формулы в рабочей таблице (или при использовании ее в VBA — которую мы увидим позже в этом руководстве). Шестая, седьмая и восьмая строки являются частью цикла For Next. Цикл выполняется столько раз, сколько символов во входном аргументе. Этот номер задается функцией LEN и присваивается переменной «StringLength». Таким образом, цикл проходит от «1 до Stringlength». Внутри цикла оператор IF анализирует каждый символ строки и, если он числовой, добавляет этот числовой символ в переменную Result. Для этого он использует функцию MID в VBA. Вторая последняя строка кода присваивает значение результата функции. Именно эта строка кода гарантирует, что функция вернет значение «Result» обратно в ячейку (откуда она вызывается). Последняя строка кода — End Function. Это обязательная строка кода, которая сообщает VBA, что код функции заканчивается здесь. Приведенный выше код объясняет различные части типичной пользовательской функции, созданной в VBA. В следующих разделах мы углубимся в эти элементы, а также увидим различные способы выполнения функции VBA в Excel. Аргументы в пользовательской функции в VBAВ приведенных выше примерах, где мы создали пользовательскую функцию для получения числовой части из буквенно-цифровой строки (GetNumeric), функция была разработана для получения одного аргумента. В этом разделе я расскажу, как создавать функции, не имеющие аргументов, для функций, которые принимают несколько аргументов (как обязательных, так и необязательных). Создание функции в VBA без каких-либо аргументовВ листе Excel у нас есть несколько функций, которые не принимают аргументов (например, RAND, TODAY, NOW). Эти функции не зависят от входных аргументов. Например, функция TODAY возвращает текущую дату, а функция RAND возвращает случайное число в диапазоне от 0 до 1. Вы можете создать такую же функцию в VBA. Ниже приведен код, который даст вам имя файла. Он не принимает никаких аргументов, так как результат, который нужно вернуть, не зависит ни от одного аргумента. Приведенный выше код определяет результат функции как тип данных String (в качестве результата мы хотим получить имя файла, которое является строкой). Эта функция присваивает функции значение «ThisWorkbook.Name», которое возвращается, когда функция используется на рабочем листе. Если файл был сохранен, он возвращает имя с расширением файла, в противном случае он просто дает имя. Выше есть одна проблема, хотя. Если имя файла изменится, оно не будет автоматически обновлено. Обычно функция обновляется при изменении входных аргументов. Но поскольку в этой функции нет аргументов, функция не пересчитывает (даже если вы измените имя книги, закройте ее, а затем снова откройте). При желании вы можете форсировать пересчет с помощью сочетания клавиш — Control + Alt + F9. Чтобы формула пересчитывалась всякий раз, когда в рабочем листе есть изменения, вам нужна строка кода к ней. Приведенный ниже код заставляет функцию пересчитывать всякий раз, когда происходит изменение в рабочем листе (как и в других аналогичных функциях рабочего листа, таких как функция TODAY или RAND). Function WorkbookName() As String Application.Volatile True WorkbookName = ThisWorkbook.Name End Function Теперь, если вы измените имя книги, эта функция будет обновляться всякий раз, когда будут какие-либо изменения в таблице, или когда вы снова откроете эту книгу. Создание функции в VBA с одним аргументомВ одном из разделов выше мы уже видели, как создать функцию, которая принимает только один аргумент (функция GetNumeric, описанная выше). Давайте создадим еще одну простую функцию, которая принимает только один аргумент. Функция, созданная с помощью приведенного ниже кода, преобразует ссылочный текст в верхний регистр. Теперь у нас уже есть функция для этого в Excel, и эта функция просто показывает вам, как она работает. Если вам нужно сделать это, лучше использовать встроенную функцию UPPER. Function ConvertToUpperCase(CellRef As Range) ConvertToUpperCase = UCase(CellRef) End Function Эта функция использует функцию UCase в VBA для изменения значения переменной CellRef. Затем он присваивает значение функции ConvertToUpperCase. Поскольку эта функция принимает аргумент, нам не нужно использовать здесь часть Application.Volatile. Как только аргумент изменится, функция автоматически обновится. Создание функции в VBA с несколькими аргументамиТочно так же, как функции рабочего листа, вы можете создавать функции в VBA, которые принимают несколько аргументов. Приведенный ниже код создаст функцию, которая будет извлекать текст перед указанным разделителем. Он принимает два аргумента — ссылку на ячейку с текстовой строкой и разделитель. Function GetDataBeforeDelimiter(CellRef As Range, Delim As String) as String Dim Result As String Dim DelimPosition As Integer DelimPosition = InStr(1, CellRef, Delim, vbBinaryCompare) - 1 Result = Left(CellRef, DelimPosition) GetDataBeforeDelimiter = Result End Function Когда вам нужно использовать более одного аргумента в пользовательской функции, вы можете иметь все аргументы в скобках, разделенные запятой. Обратите внимание, что для каждого аргумента вы можете указать тип данных. В приведенном выше примере «CellRef» был объявлен как тип данных диапазона, а «Delim» был объявлен как тип данных String. Если вы не укажете какой-либо тип данных, VBA считает, что это вариант данных. Когда вы используете вышеуказанную функцию на листе, вам нужно указать ссылку на ячейку, в которой в качестве первого аргумента указан текст, а в качестве двойного кавычка — символ (ы) в двойных кавычках. Затем он проверяет положение разделителя с помощью функции INSTR в VBA. Эта позиция затем используется для извлечения всех символов перед разделителем (используя функцию LEFT). Наконец, он присваивает результат функции. Эта формула далека от совершенства. Например, если вы введете разделитель, который не найден в тексте, он выдаст ошибку. Теперь вы можете использовать функцию IFERROR на листе, чтобы избавиться от ошибок, или вы можете использовать приведенный ниже код, который возвращает весь текст, когда он не может найти разделитель. Function GetDataBeforeDelimiter(CellRef As Range, Delim As String) as String Dim Result As String Dim DelimPosition As Integer DelimPosition = InStr(1, CellRef, Delim, vbBinaryCompare) - 1 If DelimPosition < 0 Then DelimPosition = Len(CellRef) Result = Left(CellRef, DelimPosition) GetDataBeforeDelimiter = Result End Function Мы можем дополнительно оптимизировать эту функцию. Если вы введете текст (из которого вы хотите извлечь часть перед разделителем) непосредственно в функции, это приведет к ошибке. Давай.. попробуй! Это происходит, когда мы указали «CellRef» в качестве типа данных диапазона. Или, если вы хотите, чтобы разделитель находился в ячейке и использовал ссылку на ячейку вместо жесткого кодирования в формуле, вы не можете сделать это с помощью приведенного выше кода. Это потому, что Delim был объявлен как строковый тип данных. Если вы хотите, чтобы функция имела гибкость, позволяющую принимать прямой ввод текста или ссылки на ячейки от пользователя, вам необходимо удалить объявление типа данных. Это приведет к созданию аргумента в качестве альтернативного типа данных, который может принимать аргументы любого типа и обрабатывать их. Код ниже сделает это: Function GetDataBeforeDelimiter(CellRef, Delim) As String Dim Result As String Dim DelimPosition As Integer DelimPosition = InStr(1, CellRef, Delim, vbBinaryCompare) - 1 If DelimPosition < 0 Then DelimPosition = Len(CellRef) Result = Left(CellRef, DelimPosition) GetDataBeforeDelimiter = Result End Function Создание функции в VBA с необязательными аргументамиВ Excel есть много функций, некоторые из которых не являются обязательными. Например, легендарная функция VLOOKUP имеет 3 обязательных аргумента и один необязательный аргумент. Необязательный аргумент, как следует из названия, указывать необязательно. Если вы не укажете один из обязательных аргументов, ваша функция выдаст вам ошибку, но если вы не укажете необязательный аргумент, ваша функция будет работать. Но необязательные аргументы не бесполезны. Они позволяют вам выбирать из целого ряда вариантов. Например, в функции VLOOKUP, если вы не указали четвертый аргумент, VLOOKUP выполняет приблизительный поиск, а если вы указываете последний аргумент как FALSE (или 0), то он выполняет точное совпадение. Помните, что необязательные аргументы всегда должны идти после всех обязательных аргументов. Вы не можете иметь дополнительные аргументы в начале. Теперь давайте посмотрим, как создать функцию в VBA с необязательными аргументами. Функция только с необязательным аргументомНасколько я знаю, нет встроенной функции, которая принимает только необязательные аргументы (я могу ошибаться, но я не могу думать ни о какой такой функции). Но мы можем создать один с VBA. Ниже приведен код функции, которая выдаст вам текущую дату в формате dd-mm-yyyy, если вы не вводите никаких аргументов (т.е. оставьте это поле пустым), и в формате «dd mmmm, yyyy», если вы введете что-либо в качестве аргумента (т. е. что угодно, чтобы аргумент не был пустым). Function CurrDate(Optional fmt As Variant) Dim Result If IsMissing(fmt) Then CurrDate = Format(Date, "dd-mm-yyyy") Else CurrDate = Format(Date, "dd mmmm, yyyy") End If End Function Обратите внимание, что вышеупомянутая функция использует IsMissing, чтобы проверить, отсутствует аргумент или нет. Чтобы использовать функцию IsMissing, необязательный аргумент должен иметь вариантный тип данных. Вышеуказанная функция работает независимо от того, что вы вводите в качестве аргумента. В коде мы только проверяем, указан ли необязательный аргумент или нет. Вы можете сделать это более надежным, взяв только определенные значения в качестве аргументов и показывая ошибку в остальных случаях (как показано в приведенном ниже коде). Function CurrDate(Optional fmt As Variant) Dim Result If IsMissing(fmt) Then CurrDate = Format(Date, "dd-mm-yyyy") ElseIf fmt = 1 Then CurrDate = Format(Date, "dd mmmm, yyyy") Else CurrDate = CVErr(xlErrValue) End If End Function Приведенный выше код создает функцию, которая показывает дату в формате «дд-мм-гггг», если аргумент не указан, и в формате «дд мммм, гггг», если аргумент равен 1. Во всех других случаях выдается ошибка. Функция с необходимыми и необязательными аргументамиМы уже видели код, который извлекает числовую часть из строки. Теперь давайте рассмотрим похожий пример, который принимает как обязательные, так и необязательные аргументы. Приведенный ниже код создает функцию, которая извлекает текстовую часть из строки. Если необязательный аргумент равен TRUE, он дает результат в верхнем регистре, а если необязательный аргумент имеет значение FALSE или опущен, он дает результат как есть. Function GetText(CellRef As Range, Optional TextCase = False) As String Dim StringLength As Integer Dim Result As String StringLength = Len(CellRef) For i = 1 To StringLength If Not (IsNumeric(Mid(CellRef, i, 1))) Then Result = Result & Mid(CellRef, i, 1) Next i If TextCase = True Then Result = UCase(Result) GetText = Result End Function Обратите внимание, что в приведенном выше коде мы инициализировали значение «TextCase» как False (смотрите в скобках в первой строке). Сделав это, мы убедились, что необязательный аргумент начинается со значения по умолчанию, то есть FALSE. Если пользователь указывает значение как ИСТИНА, функция возвращает текст в верхнем регистре, а если пользователь указывает необязательный аргумент как ЛОЖЬ или пропускает его, то возвращаемый текст остается как есть. Создание функции в VBA с массивом в качестве аргументаДо сих пор мы видели примеры создания функции с необязательными / обязательными аргументами, где эти аргументы были одним значением. Вы также можете создать функцию, которая может принимать массив в качестве аргумента. В функциях листа Excel есть много функций, которые принимают аргументы массива, такие как SUM, VLOOKUP, SUMIF, COUNTIF и т.д. Ниже приведен код, который создает функцию, которая дает сумму всех четных чисел в указанном диапазоне ячеек. Function AddEven(CellRef as Range) Dim Cell As Range For Each Cell In CellRef If IsNumeric(Cell.Value) Then If Cell.Value Mod 2 = 0 Then Result = Result + Cell.Value End If End If Next Cell AddEven = Result End Function Вы можете использовать эту функцию на листе и указать диапазон ячеек, в которых в качестве аргумента используются числа. Функция будет возвращать одно значение — сумму всех четных чисел (как показано ниже). В приведенной выше функции вместо одного значения мы предоставили массив (A1: A10). Чтобы это работало, вам нужно убедиться, что ваш тип данных аргумента может принимать массив. В приведенном выше коде я указал аргумент CellRef как Range (который может принимать массив в качестве входных данных). Вы также можете использовать вариантный тип данных здесь. В коде есть цикл For Each, который проходит через каждую ячейку и проверяет, является ли это число не. Если это не так, ничего не происходит, и он перемещается в следующую ячейку. Если это число, оно проверяет, является ли оно четным или нет (с помощью функции MOD). В конце все четные числа добавляются, и сумма возвращается обратно в функцию. Создание функции с неопределенным числом аргументовПри создании некоторых функций в VBA вы можете не знать точное количество аргументов, которые пользователь хочет предоставить. Поэтому необходимо создать функцию, которая может принимать столько аргументов, сколько необходимо, и использовать их для возврата результата. Примером такой функции рабочего листа является функция SUM. Вы можете предоставить несколько аргументов (например, это): = SUM (A1, A2: A4, B1: B20) Вышеупомянутая функция добавит значения во все эти аргументы. Также обратите внимание, что это может быть одна ячейка или массив ячеек. Вы можете создать такую функцию в VBA, указав последний аргумент (или единственный аргумент) в качестве необязательного. Кроме того, этому необязательному аргументу должно предшествовать ключевое слово «ParamArray». ParamArray — это модификатор, который позволяет вам принимать столько аргументов, сколько вы хотите. Обратите внимание, что использование слова ParamArray перед аргументом делает аргумент необязательным. Однако вам не нужно использовать здесь слово «Необязательно». Теперь давайте создадим функцию, которая может принимать произвольное количество аргументов и добавит все числа в указанные аргументы: Function AddArguments(ParamArray arglist() As Variant) For Each arg In arglist AddArguments = AddArguments + arg Next arg End Function Вышеприведенная функция может принимать любое количество аргументов и добавлять эти аргументы для получения результата. Обратите внимание, что в качестве аргумента вы можете использовать только одно значение, ссылку на ячейку, логическое значение или выражение. Вы не можете предоставить массив в качестве аргумента. Например, если один из ваших аргументов — D8: D10, эта формула выдаст вам ошибку. Если вы хотите использовать оба аргумента из нескольких ячеек, вам нужно использовать следующий код: Function AddArguments(ParamArray arglist() As Variant) For Each arg In arglist For Each Cell In arg AddArguments = AddArguments + Cell Next Cell Next arg End Function Обратите внимание, что эта формула работает с несколькими ячейками и ссылками на массивы, однако она не может обрабатывать жестко закодированные значения или выражения. Вы можете создать более надежную функцию, проверяя и обрабатывая эти условия, но это не является целью. Цель здесь — показать вам, как работает ParamArray, чтобы вы могли разрешить неопределенное количество аргументов в функции. Если вам нужна функция лучше, чем та, которая была создана в приведенном выше коде, используйте функцию SUM на листе. Создание функции, которая возвращает массивДо сих пор мы видели функции, которые возвращают одно значение. С помощью VBA вы можете создать функцию, которая возвращает вариант, содержащий целый массив значений. Формулы массивов также доступны в виде встроенных функций на листах Excel. Если вы знакомы с формулами массива в Excel, вы знаете, что они вводятся клавишами Control + Shift + Enter (а не только Enter). Вы можете прочитать больше о формулах массива здесь. Если вы не знаете формул массива, не беспокойтесь, продолжайте читать.
Давайте создадим формулу, которая возвращает массив из трех чисел (1,2,3). Код ниже сделает это. Function ThreeNumbers() As Variant Dim NumberValue(1 To 3) NumberValue(1) = 1 NumberValue(2) = 2 NumberValue(3) = 3 ThreeNumbers = NumberValue End Function В приведенном выше коде мы указали функцию ThreeNumbers в качестве варианта. Это позволяет ему содержать массив значений. Переменная NumberValue объявлена как массив из 3 элементов. Он содержит три значения и присваивает его функции «Три числа». Вы можете использовать эту функцию на рабочем листе. Введите эту функцию и нажмите клавиши Control + Shift + Enter (удерживайте клавиши Control и Shift и затем нажмите Enter). Когда вы сделаете это, он вернет 1 в ячейке, но в действительности он содержит все три значения. Чтобы проверить это, используйте следующую формулу: = MAX (ThreeNumbers ()) Используйте вышеуказанную функцию с Control + Shift + Enter. Вы заметите, что теперь результат равен 3, так как это самые большие значения в массиве, возвращаемом функцией Max, которая получает три числа в результате нашей пользовательской функции — ThreeNumbers. Вы можете использовать ту же технику для создания функции, которая возвращает массив названий месяцев, как показано в приведенном ниже коде: Function Months() As Variant Dim MonthName(1 To 12) MonthName(1) = "Январь" MonthName(2) = "Февраль" MonthName(3) = "Март" MonthName(4) = "Апрель" MonthName(5) = "Май" MonthName(6) = "Июнь" MonthName(7) = "Июль" MonthName(8) = "Август" MonthName(9) = "Сентябрь" MonthName(10) = "Октябрь" MonthName(11) = "Ноябрь" MonthName(12) = "Декабрь" Months = MonthName End Function Теперь, когда вы введете функцию = Months () на листе Excel и используете Control + Shift + Enter, она вернет весь массив названий месяцев. Обратите внимание, что вы видите только январь в ячейке, поскольку это первое значение в массиве. Это не означает, что массив возвращает только одно значение. Чтобы показать вам тот факт, что он возвращает все значения, сделайте это — выберите ячейку с формулой, перейдите на панель формул, выберите всю формулу и нажмите F9. Это покажет вам все значения, которые возвращает функция. Вы можете использовать это, используя приведенную ниже формулу INDEX, чтобы получить список всех названий месяцев за один раз. =INDEX(Months(),ROW()) Поэтому тот же код, в котором мы создаем функцию «Месяцы», станет короче, как показано ниже: Function Months() As Variant Months = Array("Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", _ "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь") End Function Вышеупомянутая функция использует функцию Array для назначения значений непосредственно этой функции. Обратите внимание, что все функции, созданные выше, возвращают горизонтальный массив значений. Это означает, что если вы выберете 12 горизонтальных ячеек (скажем, A1: L1) и введете формулу = Months () в ячейку A1, вы получите все названия месяцев. Но что, если вы хотите эти значения в вертикальном диапазоне ячеек. Вы можете сделать это, используя формулу TRANSPOSE на листе. Просто выберите 12 вертикальных ячеек (смежные) и введите приведенную ниже формулу. Понимание объема пользовательской функции в ExcelФункция может иметь две области действия — Public или Private.
Если вы ничего не указали, функция по умолчанию является публичной. Ниже приведена функция, которая является частной функцией: Private Function WorkbookName() As String WorkbookName = ThisWorkbook.Name End Function Вы можете использовать эту функцию в подпрограммах и процедурах в тех же модулях, но не можете использовать ее в других модулях. Эта функция также не будет отображаться на листе. Приведенный ниже код сделает эту функцию публичной. Это также будет отображаться на листе. Function WorkbookName() As String WorkbookName = ThisWorkbook.Name End Function Различные способы использования пользовательской функции в ExcelСоздав пользовательскую функцию в VBA, вы можете использовать ее по-разному. Давайте сначала рассмотрим, как использовать функции на листе. Использование пользовательских функций в рабочих листахМы уже видели примеры использования функции, созданной в VBA, на листе. Все, что вам нужно сделать, это ввести имя функции, и оно отобразится в intellisense. Обратите внимание, что для того, чтобы функция отображалась на рабочем листе, она должна быть функцией Public (как описано в разделе выше). Вы также можете использовать диалоговое окно «Вставить функцию» для вставки пользовательской функции (используя шаги ниже). Это будет работать только для публичных функций.
Вышеуказанные шаги вставят функцию в лист. Он также отображает диалоговое окно «Аргументы функции», которое предоставит вам подробную информацию об аргументах и результате. Вы можете использовать пользовательскую функцию, как и любую другую функцию в Excel. Это также означает, что вы можете использовать его с другими встроенными функциями Excel. Например. приведенная ниже формула даст название рабочей книги в верхнем регистре: =UPPER(WorkbookName()) Использование пользовательских функций в процедурах и функциях VBAКогда вы создали функцию, вы можете использовать ее и в других подпроцедурах. Если функция Public, она может использоваться в любой процедуре в том же или другом модуле. Если это Private, его можно использовать только в том же модуле. Ниже приведена функция, которая возвращает имя рабочей книги. Function WorkbookName() As String WorkbookName = ThisWorkbook.Name End Function Приведенная ниже процедура вызывает функцию, а затем отображает имя в окне сообщения. Sub ShowWorkbookName() MsgBox WorkbookName End Sub Вы также можете вызвать функцию из другой функции. В приведенных ниже кодах первый код возвращает имя рабочей книги, а второй возвращает имя в верхнем регистре, вызывая первую функцию. Function WorkbookName() As String WorkbookName = ThisWorkbook.Name End Function Function WorkbookNameinUpper() WorkbookNameinUpper = UCase(WorkbookName) End Function Вызов пользовательской функции из других книгЕсли у вас есть функция в рабочей книге, вы можете вызвать эту функцию и в других рабочих книгах. Есть несколько способов сделать это:
Создание надстройкиСоздав и установив надстройку, вы получите настраиваемую функцию, доступную во всех книгах. Предположим, вы создали пользовательскую функцию — «GetNumeric» и хотите, чтобы она была во всех книгах. Для этого создайте новую рабочую книгу и поместите код функции в модуль этой новой рабочей книги.
Теперь надстройка была активирована. Теперь вы можете использовать пользовательские функции во всех книгах. Сохранение функции в персональной книге макросовПерсональная книга макросов — это скрытая рабочая книга в вашей системе, которая открывается при каждом запуске приложения Excel. Это место, где вы можете хранить макросы и получать к ним доступ из любой книги. Это отличное место для хранения тех макросов, которые вы хотите часто использовать. По умолчанию в вашем Excel нет личной книги макросов. Вам необходимо создать его, записав макрос и сохранив его в личной книге макросов. Ссылка на функцию из другой книгиХотя первые два метода (создание надстройки и использование личной рабочей книги макроса) будут работать во всех ситуациях, если вы хотите сослаться на функцию из другой рабочей книги, эта рабочая книга должна быть открыта. Предположим, у вас есть рабочая книга с именем «Рабочая тетрадь с формулой», и она имеет функцию с именем «GetNumeric». Чтобы использовать эту функцию в другой рабочей книге (когда рабочая книга с формулой открыта), вы можете использовать следующую формулу: =’Workbook with Formula’!GetNumeric(A1) Приведенная выше формула будет использовать пользовательскую функцию в файле Workbook with Formula и даст вам результат. Обратите внимание: поскольку в имени книги есть пробелы, его необходимо заключить в одинарные кавычки. Использование оператора выхода из VBAЕсли вы хотите выйти из функции во время выполнения кода, вы можете сделать это с помощью оператора «Выход из функции». Приведенный ниже код извлекает первые три числовых символа из буквенно-цифровой текстовой строки. Как только он получает три символа, функция завершается и возвращает результат. Function GetNumericFirstThree(CellRef As Range) As Long Dim StringLength As Integer StringLength = Len(CellRef) For i = 1 To StringLength If J = 3 Then Exit Function If IsNumeric(Mid(CellRef, i, 1)) Then J = J + 1 Result = Result & Mid(CellRef, i, 1) GetNumericFirstThree = Result End If Next i End Function Вышеприведенная функция проверяет количество числовых символов, и когда она получает 3 числовых символа, она выходит из функции в следующем цикле. Отладка пользовательской функцииЕсть несколько методов, которые вы можете использовать при отладке пользовательской функции в VBA: Отладка пользовательской функции с помощью окна сообщенияИспользуйте функцию чтобы показать окно сообщения с определенным значением. Отображаемое значение может быть основано на том, что вы хотите проверить. Например, если вы хотите проверить, выполняется ли код или нет, будет работать любое сообщение, и если вы хотите проверить, работают ли циклы или нет, вы можете отобразить определенное значение или счетчик цикла. Отладка пользовательской функции путем установки точки остановаУстановите точку останова, чтобы иметь возможность проходить шаг за шагом по каждой строке. Чтобы установить точку останова, выберите нужную строку и нажмите F9 или нажмите на серую вертикальную область, которая слева от строк кода. Любой из этих методов вставил бы точку останова (вы увидите красную точку в серой области). Как только вы установили точку останова и выполнили функцию, она идет до линии точки останова и затем останавливается. Теперь вы можете просмотреть код с помощью клавиши F8. Нажмите F8 один раз, чтобы перейти к следующей строке в коде. Отладка пользовательской функции с помощью Debug.Print в кодеВы можете использовать оператор Debug.Print в своем коде, чтобы получить значения указанных переменных / аргументов в непосредственном окне. Например, в приведенном ниже коде я использовал Debug.Print, чтобы получить значение двух переменных — «j» и «Result». Function GetNumericFirstThree(CellRef As Range) As Long Dim StringLength As Integer StringLength = Len(CellRef) For i = 1 To StringLength If J = 3 Then Exit Function If IsNumeric(Mid(CellRef, i, 1)) Then J = J + 1 Result = Result & Mid(CellRef, i, 1) Debug.Print J, Result GetNumericFirstThree = Result End If Next i End Function Когда этот код выполняется, он показывает следующее в immediate window. Встроенные функции Excel против Пользовательской функции VBAЕсть несколько сильных преимуществ использования встроенных функций Excel по сравнению с пользовательскими функциями, созданными в VBA.
Хотя существует множество веских причин для использования встроенных функций Excel, в некоторых случаях лучше использовать пользовательскую функцию.
Где разместить код VBA для пользовательской функцииПри создании пользовательской функции необходимо поместить код в окно кода для книги, в которой вы хотите использовать функцию. Ниже приведены инструкции по размещению кода для функции «GetNumeric» в книге. Функция представляет собой группу повторно используемого кода, который может быть вызван в любом месте в вашей программе. Это устраняет необходимость повторного написания одного и того же кода. Это позволяет программистам разделить большую программу на множество небольших и управляемых функций. Помимо встроенных функций, VBA также позволяет писать пользовательские функции. В этой статье вы узнаете, как писать свои собственные функции в VBA. Определение функцииФункция VBA может иметь необязательный оператор return. Это необходимо, если вы хотите вернуть значение из функции. Например, вы можете передать два числа в функции, а затем вы можете ожидать от функции возврата своего умножения в вашу вызывающую программу. Примечание . Функция может возвращать несколько значений, разделенных запятой, как массив, назначенный самому имени функции. Прежде чем использовать функцию, нам нужно определить эту конкретную функцию. Наиболее распространенным способом определения функции в VBA является использование ключевого слова Function , за которым следует уникальное имя функции, и оно может содержать или не содержать список параметров и оператор с ключевым словом End Function , который указывает конец функции. Ниже приведен базовый синтаксис. СинтаксисДобавьте кнопку и добавьте следующую функцию. Function Functionname(parameter-list) statement 1 statement 2 statement 3 ....... statement n End Function ПримерДобавьте следующую функцию, которая возвращает область. Обратите внимание, что значение / значения могут быть возвращены с именем самой функции. Function find_area(Length As Double, Optional Width As Variant) If IsMissing(Width) Then find_area = Length * Length Else find_area = Length * Width End If End Function Вызов функцииЧтобы вызвать функцию, вызовите функцию, используя имя функции, как показано на следующем снимке экрана. Вывод области, как показано ниже, будет отображаться пользователю. Большинство функций рабочего листа Microsoft Excel можно использовать в коде Visual Basic (список этих функций: List of Worksheet Functions Available to Visual Basic) Вызов функции рабочего листа из Visual BasicВ Visual Basic функции рабочего листа (worksheet) Microsoft Excel доступны через объект WorksheetFunction . Например, здесь используется функция Min для определения наименьшего значения в диапазоне ячеек: Sub UseFunction() Dim myRange As Range Set myRange = Worksheets("Sheet1").Range("A1:C10") answer = Application.WorksheetFunction.Min(myRange) MsgBox answer End Sub Здесь сначала объявляется переменная myRange как объект типа Range , и затем ей назначается диапазон ячеек A1:C10 на листе Sheet1. Переменной answer присваивается результат применения функции Min к myRange . Полученное значение answer отображается в окне сообщения. Диапазон ячеек необходимо объявить как объект Range ! Например, в формуле в ячейке таблицы Excel Sub FindFirst() myVar = Application.WorksheetFunction.Match(9, Worksheets(1).Range("A1:A10"), 0) MsgBox myVar End Sub Функции Visual Basic (без префикса WorksheetFunction ) могут иметь такое же имя, как и функция Excel, но работать иначе. Например, Application.WorksheetFunction.Log и Log возвращают разные значения. Вставка функции рабочего листа в ячейкуЧтобы вставить функцию в ячейку, нужно присвоить ее свойству Formula соответствующего объекта Range . Например: Sub InsertFormula() Worksheets("Sheet1").Range("A1:B3").Formula = "=RAND()" End Sub результат функции RAND (она возвращает случайное число) присваивается свойству Formula диапазона ячеек A1:B3 на листе Sheet1в активной книге Excel. (Using Microsoft Excel Worksheet Functions in Visual Basic Office 2003 )
Похожие статьи
Категории
Видеоматериалы
Популярное
|