Як повернути результат від функції VBA


277

Як повернути результат від функції?

Наприклад:

Public Function test() As Integer
    return 1
End Function

Це дає помилку компіляції.

Як змусити цю функцію повернути ціле число?


Відповіді:


429

Для необ'єктних типів повернення потрібно призначити значення імені вашої функції, наприклад:

Public Function test() As Integer
    test = 1
End Function

Приклад використання:

Dim i As Integer
i = test()

Якщо функція повертає тип об'єкта, вам потрібно використовувати таке Setключове слово:

Public Function testRange() As Range
    Set testRange = Range("A1")
End Function

Приклад використання:

Dim r As Range
Set r = testRange()

Зауважте, що призначення присвоєного значення імені функції не припиняє виконання вашої функції. Якщо ви хочете вийти з функції, то вам потрібно прямо сказати Exit Function. Наприклад:

Function test(ByVal justReturnOne As Boolean) As Integer
    If justReturnOne Then
        test = 1
        Exit Function
    End If
    'more code...
    test = 2
End Function

Документація: http://msdn.microsoft.com/en-us/library/office/gg264233%28v=office.14%29.aspx


32
Для повноти слід зазначити, що, коли ви повертаєте об'єкт (наприклад, Rangeнаприклад), вам потрібно скористатися так Setсамо, як і при встановленні змінної об'єкта в звичайному методі. Так, якби, наприклад, "тест" був функцією, яка повертала Діапазон, оператор return буде виглядати приблизно так set test = Range("A1").
Джей Карр

Чому це @JayCarr?
PsychoData

4
@PsychoData - Просто тому, що саме так ви встановлюєте змінну об'єкта в цілому, і це робити без цього setможе призвести до проблем. У мене виникли проблеми з цим, але якщо я не використовую set:)
Джей Карр

1
Я думаю, також варто згадати, що поведінка функції відрізняється, коли ви викликаєте її з електронної таблиці, порівняно з викликом її з іншої функції VBA або Sub.
Дуг Дженкінс

2
При виклику в межах VBA функція повертає об'єкт діапазону, але при виклику з робочого аркуша повертає саме значення, тому set test = Range("A1")точно еквівалентне test = Range("A1").Value, де "тест" визначається як Варіант, а не Діапазон.
Дуг Дженкінс

86

Функції VBA трактують саме ім’я функції як своєрідну змінну. Отже, замість використання returnзаяви, ви просто скажете:

test = 1

Зауважте, що це не виходить з функції. Будь-який код після цього твердження також буде виконаний. Таким чином, у вас може бути безліч операторів присвоєння, яким присвоюються різні значення test, і яке б значення не було, коли ви досягнете кінця функції, значення буде поверненим.


Насправді ви відповіли на питання чіткіше, отримавши додаткову інформацію (що потенційно може призвести до іншого запитання від нового для хлопця VBA). Будьте в
курсі

Вибачте, здавалося, що ви просто відповіли на те саме, що і на мою відповідь, яку я мав спочатку, але просто додав той факт, що це не виходить з функції. Це приємне доповнення, я просто подумав, що це буде більш доречним як коментар. Я не впевнений, що таке правильний етикет, я вважаю, що це було трохи необачно, тому що це хороша відповідь, але це не дозволить мені скасувати це.
День

41

Просто встановлення значення, що повертається на ім’я функції, все ще не зовсім те саме, що returnоператор Java (або інший) , оскільки в java returnвиходить з функції, як це:

public int test(int x) {
    if (x == 1) {
        return 1; // exits immediately
    }

    // still here? return 0 as default.
    return 0;
}

У VB точний еквівалент займає два рядки, якщо ви не встановлюєте значення повернення в кінці функції . Отже, у VB точний слід буде виглядати так:

Public Function test(ByVal x As Integer) As Integer
    If x = 1 Then
        test = 1 ' does not exit immediately. You must manually terminate...
        Exit Function ' to exit
    End If

    ' Still here? return 0 as default.
    test = 0
    ' no need for an Exit Function because we're about to exit anyway.
End Function 

Оскільки це так, також приємно знати, що ви можете використовувати змінну return, як і будь-яку іншу змінну в методі. Подобається це:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test <> 1 Then ' Test the currently set return value
        test = 0 ' Reset the return value to a *new* value
    End If

End Function 

Або крайній приклад того, як працює змінна повернення (але не обов'язково - хороший приклад того, як ви насправді повинні кодувати) - той, який буде підтримувати вас вночі:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test > 0 Then

        ' RECURSIVE CALL...WITH THE RETURN VALUE AS AN ARGUMENT,
        ' AND THE RESULT RESETTING THE RETURN VALUE.
        test = test(test - 1)

    End If

End Function

2
"також приємно знати, що ви можете використовувати змінну повернення, як і будь-яку іншу змінну в методі", в основному, правда - але, наприклад, якщо тип повернення є Variantі ваша мета - повернути масив, то щось подібне ReDim test(1 to 100)призведе до помилки. Крім того , незважаючи на те, що це можна розглядати як основний тип , Integersяк , що вона вважається кілька unidiomatic. Це робить код важче читати. Програмісти VBA сканують рядки, які присвоюють ім'я функції, щоб зрозуміти, що робить функція. Використання назви функції як звичайної змінної непотрібно це приховувати.
Джон Коулман

@JohnColeman, цілком згодні з обох питань. Останній приклад жодним чином не повинен бути одним із рекомендованих методологій. Але питання теми стосується того, як повернути змінну, і це лише спроба повного пояснення результату повернення VB та розширення того, як вони працюють. Звичайно, останній випадок не є рекомендацією. (Я, звичайно, не став би це прикладом, ніж прикладом.) Отже, ваші бали добре сприйняті і хороші доповнення. Дякую.
LimaNightHawk

Це є корисним для занизька функцій, і це те , що будь-який VBA програміст повинен знати про, так що я не мав ніяких проблем з вами згадка про нього. Я просто думав, що слід включити попередження.
Джон Коулман

Дякуємо, пояснивши, що Exit Functionстосуєтьсяreturn
Austin D

@JohnColeman, Очевидно, що ви не можете ReDim test(1 to 100)без спроби помилки просто тому, що 'test' не оголошено як масив! і зовсім без жодної причини! Ви не можете оголосити функцію як масив. Оголосіть це як Variant, а потім просто побудуйте свій вихідний масив (він може бути динамічним або статичним) всередині цієї функції, testа потім призначте ("=") цьому масиву testяк повернене значення. Для подальшого маніпулювання, як-от ReDim, вам потрібно присвоїти повернене значення змінній, наприклад, Dim x as Variantі викликати x = test, після чого xсаме це ви зробили test!
Гена

-6

Наведений нижче код зберігає повернене значення у змінну, retValа потім MsgBoxможе бути використаний для відображення значення:

Dim retVal As Integer
retVal = test()
Msgbox retVal
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.