Vba excel sub private sub отличия

Обновлено: 07.07.2024

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

Список этих функций можно посмотреть в редакторе VBA:

  • Откройте рабочую книгу Excel и запустите редактор VBA (нажмите для этого Alt+F11), и затем нажмите F2.
  • В выпадающем списке в верхней левой части экрана выберите библиотеку VBA.
  • Появится список встроенных классов и функций VBA. Кликните мышью по имени функции, чтобы внизу окна отобразилось её краткое описание. Нажатие F1 откроет страницу онлайн-справки по этой функции.

Кроме того, полный список встроенных функций VBA с примерами можно найти на сайте Visual Basic Developer Centre.

Пользовательские процедуры «Function» и «Sub» в VBA

В Excel Visual Basic набор команд, выполняющий определённую задачу, помещается в процедуру Function (Функция) или Sub (Подпрограмма). Главное отличие между процедурами Function и Sub состоит в том, что процедура Function возвращает результат, процедура Sub – нет.

Поэтому, если требуется выполнить действия и получить какой-то результат (например, просуммировать несколько чисел), то обычно используется процедура Function, а для того, чтобы просто выполнить какие-то действия (например, изменить форматирование группы ячеек), нужно выбрать процедуру Sub.

Аргументы

При помощи аргументов процедурам VBA могут быть переданы различные данные. Список аргументов указывается при объявлении процедуры. К примеру, процедура Sub в VBA добавляет заданное целое число (Integer) в каждую ячейку в выделенном диапазоне. Передать процедуре это число можно при помощи аргумента, вот так:

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

Необязательные аргументы

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

Возвращаясь к предыдущему примеру, чтобы сделать целочисленный аргумент функции необязательным, его нужно объявить вот так:

В таком случае целочисленный аргумент i по умолчанию будет равен 0.

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

Передача аргументов по значению и по ссылке

Аргументы в VBA могут быть переданы процедуре двумя способами:

  • ByVal – передача аргумента по значению. Это значит, что процедуре передаётся только значение (то есть, копия аргумента), и, следовательно, любые изменения, сделанные с аргументом внутри процедуры, будут потеряны при выходе из неё.
  • ByRef – передача аргумента по ссылке. То есть процедуре передаётся фактический адрес размещения аргумента в памяти. Любые изменения, сделанные с аргументом внутри процедуры, будут сохранены при выходе из процедуры.

При помощи ключевых слов ByVal или ByRef в объявлении процедуры можно задать, каким именно способом аргумент передаётся процедуре. Ниже это показано на примерах:

Помните, что аргументы в VBA по умолчанию передаются по ссылке. Иначе говоря, если не использованы ключевые слова ByVal или ByRef, то аргумент будет передан по ссылке.

Перед тем как продолжить изучение процедур Function и Sub более подробно, будет полезным ещё раз взглянуть на особенности и отличия этих двух типов процедур. Далее приведены краткие обсуждения процедур VBA Function и Sub и показаны простые примеры.

VBA процедура «Function»

Редактор VBA распознаёт процедуру Function, когда встречает группу команд, заключённую между вот такими открывающим и закрывающим операторами:

Как упоминалось ранее, процедура Function в VBA (в отличие от Sub), возвращает значение. Для возвращаемых значений действуют следующие правила:

  • Тип данных возвращаемого значения должен быть объявлен в заголовке процедуры Function.
  • Переменная, которая содержит возвращаемое значение, должна быть названа так же, как и процедура Function. Эту переменную не нужно объявлять отдельно, так как она всегда существует как неотъемлемая часть процедуры Function.

Это отлично проиллюстрировано в следующем примере.

Пример VBA процедуры «Function»: Выполняем математическую операцию с 3 числами

Ниже приведён пример кода VBA процедуры Function, которая получает три аргумента типа Double (числа с плавающей точкой двойной точности). В результате процедура возвращает ещё одно число типа Double, равное сумме первых двух аргументов минус третий аргумент:

Эта очень простая VBA процедура Function иллюстрирует, как данные передаются процедуре через аргументы. Можно увидеть, что тип данных, возвращаемых процедурой, определён как Double (об этом говорят слова As Double после списка аргументов). Также данный пример показывает, как результат процедуры Function сохраняется в переменной с именем, совпадающим с именем процедуры.

Вызов VBA процедуры «Function»

Если рассмотренная выше простая процедура Function вставлена в модуль в редакторе Visual Basic, то она может быть вызвана из других процедур VBA или использована на рабочем листе в книге Excel.

Вызов VBA процедуры «Function» из другой процедуры

Процедуру Function можно вызвать из другой VBA процедуры при помощи простого присваивания этой процедуры переменной. В следующем примере показано обращение к процедуре SumMinus, которая была определена выше.

Вызов VBA процедуры «Function» из рабочего листа

VBA процедуру Function можно вызвать из рабочего листа Excel таким же образом, как любую другую встроенную функцию Excel. Следовательно, созданную в предыдущем примере процедуру Function – SumMinus можно вызвать, введя в ячейку рабочего листа вот такое выражение:

VBA процедура «Sub»

Редактор VBA понимает, что перед ним процедура Sub, когда встречает группу команд, заключённую между вот такими открывающим и закрывающим операторами:

VBA процедура «Sub»: Пример 1. Выравнивание по центру и изменение размера шрифта в выделенном диапазоне ячеек

Рассмотрим пример простой VBA процедуры Sub, задача которой – изменить форматирование выделенного диапазона ячеек. В ячейках устанавливается выравнивание по центру (и по вертикали, и по горизонтали) и размер шрифта изменяется на заданный пользователем:

Данная процедура Sub выполняет действия, но не возвращает результат.

В этом примере также использован необязательный (Optional) аргумент iFontSize. Если аргумент iFontSize не передан процедуре Sub, то его значение по умолчанию принимается равным 10. Однако же, если аргумент iFontSize передается процедуре Sub, то в выделенном диапазоне ячеек будет установлен размер шрифта, заданный пользователем.

VBA процедура «Sub»: Пример 2. Выравнивание по центру и применение полужирного начертания к шрифту в выделенном диапазоне ячеек

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

Вызов процедуры «Sub» в Excel VBA

Вызов VBA процедуры «Sub» из другой процедуры

Чтобы вызвать VBA процедуру Sub из другой VBA процедуры, нужно записать ключевое слово Call, имя процедуры Sub и далее в скобках аргументы процедуры. Это показано в примере ниже:

Если процедура Format_Centered_And_Sized имеет более одного аргумента, то они должны быть разделены запятыми. Вот так:

Вызов VBA процедуры «Sub» из рабочего листа

Процедура Sub не может быть введена непосредственно в ячейку листа Excel, как это может быть сделано с процедурой Function, потому что процедура Sub не возвращает значение. Однако, процедуры Sub, не имеющие аргументов и объявленные как Public (как будет показано далее), будут доступны для пользователей рабочего листа. Таким образом, если рассмотренные выше простые процедуры Sub вставлены в модуль в редакторе Visual Basic, то процедура Format_Centered_And_Bold будет доступна для использования на рабочем листе книги Excel, а процедура Format_Centered_And_Sized – не будет доступна, так как она имеет аргументы.

Вот простой способ запустить (или выполнить) процедуру Sub, доступную из рабочего листа:

  • Нажмите Alt+F8 (нажмите клавишу Alt и, удерживая её нажатой, нажмите клавишу F8).
  • В появившемся списке макросов выберите тот, который хотите запустить.
  • Нажмите Выполнить (Run)

Чтобы выполнять процедуру Sub быстро и легко, можно назначить для неё комбинацию клавиш. Для этого:

  • Нажмите Alt+F8.
  • В появившемся списке макросов выберите тот, которому хотите назначить сочетание клавиш.
  • Нажмите Параметры (Options) и в появившемся диалоговом окне введите сочетание клавиш.
  • Нажмите ОК и закройте диалоговое окно Макрос (Macro).

Внимание: Назначая сочетание клавиш для макроса, убедитесь, что оно не используется, как стандартное в Excel (например, Ctrl+C). Если выбрать уже существующее сочетание клавиш, то оно будет переназначено макросу, и в результате пользователь может запустить выполнение макроса случайно.

Область действия процедуры VBA

В части 2 данного самоучителя обсуждалась тема области действия переменных и констант и роль ключевых слов Public и Private. Эти ключевые слова так же можно использовать применительно к VBA процедурам:

Помните о том, что если перед объявлением VBA процедуры Function или Sub ключевое слово не вставлено, то по умолчанию для процедуры устанавливается свойство Public (то есть она будет доступна везде в данном проекте VBA). В этом состоит отличие от объявления переменных, которые по умолчанию бывают Private.

Ранний выход из VBA процедур «Function» и «Sub»

Обратите внимание, что перед тем, как завершить выполнение процедуры Function – VAT_Amount, в код вставлена встроенная VBA функция MsgBox, которая показывает пользователю всплывающее окно с предупреждением.

На данный момент, все процедуры, мы создавали, имеют тип Public , что означает, что они доступны из любого модуля.

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

Запуск процедуры с середины другой процедуры

Чтобы выполнить процедуру с середины другой процедуры, просто введите ее название.

Здесь есть очень простой пример:

Аргументы

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


К процедуре "warning" был добавлен аргумент, в данном случае это переменная "var_text" с типом "String" (строка):

Эта процедура требует аргумент, поэтому мы должны поставить значение после "warning", чтобы выполнить ее:

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

Необязательные аргументы

По умолчанию, если процедура имеет аргументы, то они должны быть обязательно проставлены, и если они не проставлены, тогда процедура не выполнится.

Необязательный аргумент может быть добавлен после обязательного, с помощью ключевого слова Optional . Например:

Теперь эта процедура может быть выполнена с или без опционального аргумента, как здесь:

Аргументы должны быть введены в правильном порядке.

Чтобы протестировать, присутствует ли опциональный аргумент в процедуре, мы используем функцию IsMissing . Эта функция совместима только с некоторыми типами функций (типа Variant) и это является решающим, так как тип необязательно аргументов не был указан в объявлении (необъявленный тип = Variant).

Здесь есть пример, который использует два фрагмента кода, которые рассматривались выше:

См. рисунок ниже (пример 1):


ByRef - ByVal

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

Чтобы стало понятнее, ниже есть пример того, что произойдет, если макрос будет запущен на выполнение:

Второй метод заключается в использовании ByVal .

В отличие от ByRef , который передает ссылки (ярлык), ByVal передает значение, которое означает, что значение передано как аргумент не было изменено.

Ниже вы можете увидеть как предыдущий код и ByVal работают:

Что вам нужно запомнить: используйте ByVal когда переменная не должна быть изменена .

Функции

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

Вот простой пример:

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

Например, чтобы получить квадрат значения, которое введенное в ячейку A1:

Синтаксис оператора Sub состоит из следующих частей:

Part Описание
Public Необязательное. Показывает, что процедура Sub доступна всем другим процедурам во всех модулях. При использовании в модуле, содержащем оператор Option Private, процедура становится недоступной вне проекта.
Private Необязательное. Показывает, что процедура Sub доступна только другим процедурам из модуля, в котором она объявлена.
Friend Необязательное. Используется только в модуле класса. Показывает, что процедура Sub видима по всему проекту, кроме контроллера экземпляра объекта.
Static Необязательное. Показывает, что локальные переменные процедуры Sub сохраняются в промежутках между вызовами. Атрибут Static не влияет на переменные, объявленные вне процедуры Sub, даже если они используются в процедуре.
name Обязательный. Имя процедуры Sub массива; должен соответствовать стандартным правилам именования переменных.
arglist Необязательное. Список переменных, представляющих аргументы, передаваемые в процедуру Sub при ее вызове. В качестве разделителя переменных используется запятая.
Операторы Необязательное. Любая группа операторов, выполняющихся внутри процедуры Sub.

Аргумент arglist имеет следующий синтаксис и элементы:

[ Необязательный ] [ ByVal | ByRef ] [ ParamArray ] varname [( ) ] [ Как тип ] [ = defaultvalue ]


Part Описание
Необязательное Необязательное. Ключевое слово, которое указывает, что аргумент не является обязательным. При использовании все последующие аргументы в arglist также должны быть необязательными и объявляться с помощью ключевого слова Необязательный. Optional не может использоваться для каких-либо аргументов, если используется ParamArray.
ByVal Необязательное. Указывает, что аргумент передается значением.
ByRef Необязательное. Указывает, что аргумент передается по ссылке. ByRef является значением по умолчанию в Visual Basic.
ParamArray Необязательное. Используется только в качестве последнего аргумента в arglist, чтобы указать, что последним аргументом является необязательный массив элементов Variant. Ключевое слово ParamArray позволяет предоставлять произвольное число аргументов. Ключевое слово ParamArray не может использоваться с аргументами ByVal, ByRef или Optional.
varname Обязательный. Имя переменной, представляющее аргумент; соответствует стандарту соглашений об именовании переменных.
type Необязательное. Тип данных аргумента, переданного процедуре; может быть Byte, Boolean, Integer, Long, Currency, Single, Double, Decimal (не поддерживается в настоящее время), Date, String (только переменная длина), Object, Variant, или определенный тип объекта . Если параметр не является Optional, может быть указан определяемый пользователем тип.
defaultvalue Необязательное. Любая константа или константное выражение. Действительно только для параметров Optional. Если типом является Object, явным значением по умолчанию может быть только Nothing.

Примечания

Если явно не указано с помощью процедур Public, Private или Friend, процедуры Sub являются общедоступными по умолчанию.

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

Ключевое слово Friend может использоваться только в модулях классов. Однако доступ к процедурам Friend может осуществляться в любом модуле проекта. Процедура Friend не отображается в библиотеке типов своего родительского класса; процедура Friend не может быть привязана позднее.

Процедуры Sub могут быть рекурсивными, то есть вызывать сами себя для выполнения определенной задачи. Однако рекурсия может привести к переполнению стека. Как правило, ключевое слово Static не используется с рекурсивными процедурами Sub.

Весь исполняемый код должен находиться в процедурах. Процедуру Sub нельзя объявлять внутри другой процедуры Sub, Function или Property.

Ключевые слова Exit Sub вызывают мгновенный выход из процедуры Sub. Выполнение программы продолжается с оператора, следующего за вызовом процедуры Sub. В процедуре Sub можно использовать сколько угодно операторов Exit Sub.

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

Вы вызываем процедуру Sub, используя имя процедуры, а затем список аргументов. Сведения о том, как вызывать процедуры Sub, см. в заявлении Call.

Переменные, используемые в процедурах Sub, делятся на две категории: объявленные и не объявленные в явном виде внутри процедуры. Переменные, объявленные в явном виде внутри процедуры (с использованием инструкции Dim или ее аналогов) всегда являются локальными для процедуры. Переменные, которые используются, но не были явно объявлены в процедуре, также являются локальными, если они не были объявлены на более высоком уровне вне процедуры.

В процедуре могут использоваться переменные, не объявленные внутри нее в явном виде, однако если на уровне модуля объявлены переменные с такими же именами, может возникнуть конфликт имен. Если процедура ссылается на необъявленную переменную, имя которой совпадает с именем другой процедуры, предполагается, что она ссылается на имя из уровня модуля. Во избежание таких конфликтов рекомендуется объявлять переменные в явном виде. Также можно использовать оператор Option Explicit для принудительного объявления переменных в явном виде.

Операторы GoSub, GoTo или Return нельзя использовать для входа в процедуру Sub и выхода из нее.

Пример

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

См. также

Поддержка и обратная связь

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.

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

vba процедуры

Давайте сначала кратко рассмотрим типы VBA процедур:

Подпрограммы – блоки кода заключенные в конструкцию Sub …. End Sub. Сама по себе подпрограмма не возвращает никакого значения, а просто выполняет прописанные в ней команды.

Функции – также блок кода, но прописанный в конструкцию Function … End Function. После выполнения функции возвращается определенное значение, доступ к которому можно получить через имя VBA функции.

Помимо этого, стоит упомянуть про обработку событий (нажатие кнопки клавиатуры или перемещение мыши) и доступ к объектам, но это отдельная тема.

VBA процедуры типа Sub – подпрограммы

После того как вы добавили в проект новый модуль, для объявления процедуры VBA нужно ее заключить в специальную конструкцию:

Sub ИмяПодпрограмм([аргументы])
Операторы
[Exit Sub]
операторы
End Sub

После ключевого слова Sub следует имя подпрограммы, в круглых скобках можно указывать или не указывать аргументы. Аргументы – это переменные (параметры), значение которых может обрабатываться, аргументы разделяются запятыми. Конструкция Exit Sub также не является обязательной, она говорит том, что нужно произвести выход из подпрограммы и продолжить выполнение кода, следующего после выражения End Sub.

Вызов VBA процедуры осуществляется с помощью ключевого слова call, например, Call MySub.

Давайте напишем простой пример: добавьте в проект новую форму и новый модуль. На поверхность формы добавьте два текстовых поля (TextBox), одну метку (Label) и одну кнопку (CommandButton). Создайте связь между формой и модулем, прописав в редакторе кода для модуля:

Я назвал форму SubForm, а модуль – SubModule, за имя отвечает свойство Name.

vba вызов процедуры

Теперь в редакторе кода для формы пропишите:

Тут все предельно просто, вначале мы объявили процедуру Hipotenuze, которой будут передаваться два аргумента, далее происходит проверка на нулевые значения. Вызов происходит при нажатии на кнопку, находящуюся на форме, параметрами будут значения, хранящиеся в текстовых полях TextBox1 и TextBox2. Результат отображается в метке Label1.

Вызов процедуры VBA может осуществляться и без использования ключевого слова Call, в таком случае, параметры не надо заключать в круглые скобки. Так же, при определении аргументов можно явно указать тип данных, например:

Sub MySub (a As Integer, b As String) … End Sub

Static – данное ключевое слово, прописанное перед ключевым словом Sub позволяет сохранять в памяти значения всех переменных после выполнения процедуры. Его мы рассматривали в с статье – переменные VBA.

ParamArray – данное ключевое слово позволяет передавать процедуре переменное количество параметров, оно может использоваться только для последнего элемента в списке аргументов.

Ключевое слово ParamArray

ParamArray нельзя использовать вместе со словами ByRef, ByVal или Optional, например:

Как видим, мы фактически с помощью ParamArray показываем, что передаем массив, для его обработки мы использовали оператор For …. Each. Тут мы передали при вызове VBA процедуры пять параметров, при этом, первый будет храниться в аргументе a, а остальные в аргументе b, который обрабатывается как массив.

Optional – позволяет указать, что аргумент не является обязательным и одновременно задать значение по умолчанию.

VBA Sub и Function

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

Передача параметров по ссылке и по значению – по умолчанию, при вызове процедуры все параметры ей передаются по ссылке. Передача по ссылке – в простом варианте, это передача адреса по которому хранится значение. При передаче параметра по ссылке, передается не адрес, а копия значения.

Передача VBA параметров по ссылке и по значению

Что бы все стало понятно, рассмотрим следующий пример:

MySub1 – тут происходит объявление переменной MyVar и присвоение ей значения 100, далее в теле происходит вызов VBA процедуры MySumm1, ей в качестве параметры мы передаем значение переменной MyVar – 100. Сама процедура MySumm принимает значение по ссылке, на что указывает ключевое слово ByRef, к принятому значению прибавляется число 100. Стоит обратить внимание, что ByRef можно было и не писать. После VBA вызова процедуры MySumm1 происходит запись значения переменной MyVar в свойство Caption объекта Label1, в итоге, отобразится число 200.

MySub2 – аналог предыдущей процедуры, но тут происходит вызов MySumm2, в которой происходит передача параметров по значению, о чем говорит ключевое слово ByVal, в итоге, значение переменной MyVar не изменится.

VBA процедуры типа Function – функции

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

Function ИмяФункции ([аргументы]) [As ТипДанных]
Операторы
[Exit Function]
Операторы
[ИмяФункции=Выражение]
End Function

Видим, что тут при объявлении функции можно указать ее тип, данный тип будет содержать возвращаемое значение. Что бы функция возвращала значение, в конце нужно его присвоить переменной с именем функции, например:

Спасибо за внимание. Автор блога Владимир Баталий

Читайте также: