Создаем свою первую функцию в Excel

Дополнительные сведения: ByVal (Visual Basic)

Пример

В следующем примере демонстрируется использование ByVal механизма передачи параметров с аргументом ссылочного типа. В примере аргумент — это c1 экземпляр класса Class1 . ByVal запрещает коду в процедурах изменять базовое значение ссылочного аргумента, c1 , но не защищает доступные поля и свойства c1 .

Module Module1 Sub Main() ‘ Declare an instance of the class and assign a value to its field. Dim c1 As New Class1() c1.Field = 5 Console.WriteLine(c1.Field) ‘ Output: 5 ‘ ByVal does not prevent changing the value of a field or property. ChangeFieldValue(c1) Console.WriteLine(c1.Field) ‘ Output: 500 ‘ ByVal does prevent changing the value of c1 itself. ChangeClassReference(c1) Console.WriteLine(c1.Field) ‘ Output: 500 Console.ReadKey() End Sub Public Sub ChangeFieldValue(ByVal cls As Class1) cls.Field = 500 End Sub Public Sub ChangeClassReference(ByVal cls As Class1) cls = New Class1() cls.Field = 1000 End Sub Public Class Class1 Public Field As Integer End ClassEnd Module

Public – Private

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

Sub example()’Идентична к:Public Sub example()

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

Private Sub example()

Visual Basic (VBA) функции и процедуры

Функции и процедуры в VBA немного похожи, поэтому их многие путают, но тем не менее у них есть отличия:

  • функция по своей особенности может возвращать какое-то значение через собственное имя, то есть ее можно применять в качестве операнда в выражениях, а процедура может возвращать результаты только через параметры, поэтому ее нельзя применять в выражениях;
  • функция вызывается путем указания ее имени в каком-либо операторе, а процедура вызывается отдельным оператором.

Visual Basic (VBA) функции и процедуры

Что такое ByVal и для чего он нужен.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.

Правила форума

Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут

закрыты

.

Читайте

требования к создаваемым темам

.

Gigahard Бывалый
Бывалый   Сообщения: 253Зарегистрирован: 24.07.2002 (Ср) 11:15Откуда: Russia

Что такое ByVal и для чего он нужен.

Сообщение Gigahard » 24.10.2004 (Вс) 12:15

Раньше думал, что данный префикс предотвращает изменение значения переменной вне функции. Выяснил я это вот на таком примере:

Код: Выделить всёDim iOne As Integer
Dim iTwo As Integer
‘—————————————–
Private Sub test1(ByVal param As Integer)
param=param + 1
MsgBox “Inside value: ” & param
End Sub
‘—————————————–
Private Sub test2(param As Integer)
param=param + 1
MsgBox “Inside value: ” & param
End Sub

‘—————————————–

Private Sub Form_Load()
iOne=1
iTwo=1
End Sub
‘—————————————–
Private Sub cmdByVal_Click()
test1 iOne
MsgBox “Outside value: ” & iOne
End Sub
‘—————————————–
Private Sub cmdCommon_Click()
test2 iTwo
MsgBox “Outside value: ” & iTwo
End Sub
На этом примере получается, что при использованиии префикса ByVal в функцию передается лишь значение переменной, но не сама переменная. И соответственно значение переменной изменяется только внутри функции. Я прав?

Только вот недавно начал изучать winsock API, так там есть API функция для получения имени локального хоста.

Вот ее синтаксис:

Код: Выделить всёPublic Declare Function gethostname Lib “ws2_32.dll” (ByVal host_name As String, ByVal namelen As Long) As Long

В данном случае функция меняет параметр host_name как бы возвращая результат. После этого я окончательно запутался в назначении ByVal. Как же так? В первом примере этот префикс предотвращает изменение переменной, в случае с gethostname нет.

Пожалуйста объясните ситуацию.

Старый глюк лучше новых двух!

GSerg Шаман
Шаман   Сообщения: 14286Зарегистрирован: 14.12.2002 (Сб) 5:25Откуда: Магадан

Сообщение GSerg » 24.10.2004 (Вс) 12:21

Всё правильно. Просто со ссылочными и со структурными объектами ByVal работает по-разному.

Для структурного объекта – это передача копии объекта.

Для ссылочного – это передача копии указателя на объект. В результате ты не сможешь заставить переданный параметр ссылаться на другой объект, но изменить свойства объекта сможешь.

Особенность маршалинга при работе со String через API в том, что по ByVal передаётся указатель на сами данные, а при ByRef передаётся указатель на указатель… В общем, просто запомни, что строки в API нуно передавать всегда ByVal, и это совсем не означает запрет на изменение, а совсем даже наоборот

:)

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

kazah_ Обычный пользователь
Обычный пользователь   Сообщения: 99Зарегистрирован: 13.01.2003 (Пн) 18:37Откуда: Russia
  • Сайт

Сообщение kazah_ » 25.10.2004 (Пн) 15:47

какие все умные…

Mr DEN – THE WAY YOU KNOW / Мр. ДЕН – Ваш Путь к Познанию!

FaKk2 El rebelde gurú
El rebelde gurú Аватара пользователя
  Сообщения: 2031Зарегистрирован: 09.03.2003 (Вс) 22:10Откуда: Los Angeles

Сообщение FaKk2 » 25.10.2004 (Пн) 16:58

Дык шаманы

8)

Для получения ответа надо продемонстрировать качества, позволяющие стать компетентным — внимательность, вдумчивость, наблюдательность, желание активно участвовать в выработке решения.

Цукерман Начинающий
Начинающий   Сообщения: 4Зарегистрирован: 17.11.2004 (Ср) 22:29

Сообщение Цукерман » 17.11.2004 (Ср) 22:45

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 0

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

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

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

Private Sub warning() MsgBox “Caution !!!”End SubSub macro_test() If Range(“A1”) = “” Then warning ‘

Процедуры VBA

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

Процедура в VBA имеет следующий шаблон построения:
Sub НаименованиеПроцедуры ([параметры процедуры через «запятую»])
    ОператорыПроцедуры

End Sub, где:

  • «НаименованиеПроцедуры» — это уникальное имя процедуры Sub;
  • параметры можно указывать, а можно не указывать;
  • «ОператорыПроцедуры» — в этом блоке расположены все операторы, которые определяют функциональность процедуры.

См. также

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

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

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

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

Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)

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

‘Пример 1: отображаем фамилию:dialog_boxes last_name1 ‘Пример 2: отображаем фамилию и имя:dialog_boxes last_name1, first_name1 ‘Пример 3: отображаем фамилию и возраст:dialog_boxes last_name1, , age1 ‘Пример 4: отображаем фамилию, имя и возраст:dialog_boxes last_name1, first_name1, age1

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

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

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

Sub macro_test() Dim last_name1 As String, first_name1 As String, age1 As Integer last_name1 = Range(“A1”) first_name1 = Range(“B1”) age1 = Range(“C1″) ‘Пример 1: отображаем фамилию: dialog_boxes last_name1 ‘Пример 2: отображаем фамилию и имя: dialog_boxes last_name1, first_name1 ‘Пример 3: отображаем фамилию и возраст: dialog_boxes last_name1, , age1 ‘Пример 4: отображаем фамилию, имя и возраст: dialog_boxes last_name1, first_name1, age1End SubPrivate Sub dialog_boxes(last_name As String, Optional first_name, Optional age) If IsMissing(age) Then ‘Если переменная age отсутствует… If IsMissing(first_name) Then ‘Если переменная first_name отсутствует, тогда ‘будет отображаться только фамилия MsgBox last_name Else ‘В противном случае, будет отображаться фамилия и имя MsgBox last_name & ” ” & first_name End If Else ‘Если переменная age присутствует… If IsMissing(first_name) Then ‘Если переменная first_name отсутствует, тогда ‘будет отображено фамилию и возраст MsgBox last_name & “, ” & age & ” лет” Else ‘В противном случае будет отображено фамилию, имя и возраст MsgBox last_name & ” ” & first_name & “, ” & age & ” лет” End If End If End Sub

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

test2.png

ByRef – ByVal

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

Наприклад:

Sub macro_test() Dim var_number As Integer var_number = 30 calcul_square var_number MsgBox var_numberEnd SubPrivate Sub calcul_square(ByRef var_value As Integer) ‘ByRef не обязательно указывать ‘(является значением по умолчанию) var_value = var_value * var_valueEnd Sub

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

var_number = 30’Начальное значение переменной “var_number” є 30calcul_square var_number’Под-процедура запускается с “var_number” как аргументPrivate Sub calcul_square(ByRef var_value As Integer)’Переменная “var_value” в некоторой степени служит для быстрого доступа к переменной “var_number”,’что означает, что если переменная “var_value” изменена, переменная “var_number” будет также изменена”(и они не должны обязательно иметь одинаковое имя)var_value = var_value * var_value’Значение переменной “var_value” изменено (и поэтому “var_number” также одновременно изменено)End Sub’Конец под-процедурыMsgBox var_number’Переменная “var_number” была изменена, поэтому 900 будет сейчас отображено в диалоговом окнеВторой метод заключается в использовании ByVal .

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

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

var_number = 30’Начальное значение переменной “var_number” есть 30calcul_square var_number’Под-процедура запускается с “var_number” как аргументPrivate Sub calcul_square (ByVal var_value As Integer)’Переменная “var_value” копирует значение переменной “var_number” (2-е переменные не являются связанными)var_value = var_value * var_value’Значение переменной “var_value” измененоEnd Sub’Конец под-процедуры (в этом примере под-процедура не имеет никакого влияния ни на что)MsgBox var_number’Переменная “var_number” не была изменена, и поэтому 30 будет отображено в диалоговом окне

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

Функции

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

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

Function square(var_number) square = var_number ^ 2 ‘Функция “square” возвращает значение “корень квадратный”End FunctionSub macro_test() Dim result As Double result = square(9.876) ‘Переменной result присваивается значение, которое было рассчитано функцией MsgBox result ‘Отображается результат (в данном случае квадрат для 9.876)End Sub

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

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

square.png

Статьи по теме:

VBA-Урок 8.2. Циклы (Loops) VBA-Урок 10. Диалоговые окна (Dialog boxes)

Рейтинг
( 1 оценка, среднее 5 из 5 )
Загрузка ...