Excel VBA, как вернуть 2 разных массива в функцию - PullRequest
1 голос
/ 01 мая 2020

Мне интересно, может ли VBA вернуть более 1 массива в функции. Я создал функцию с именем 'getStats ()', и я хотел бы вернуть 2 массива с именами 'returnVal' и 'a', как показано ниже. Я попробовал методы ниже, но я только возвращаю значение для массива 'a', которое равно 10. Это не дает мне массив для returnVal. Есть ли способ сделать это? Пожалуйста, помогите. Я попытался сделать это: "getStats = returnVal & a", но произошла ошибка как несоответствие типов

    Sub mysub()
        Dim i As Integer
        Dim myArray() As Integer 
        myArray() = getStats() 'calling for function

        MsgBox myArray(0)
        MsgBox myArray(1)
        MsgBox myArray(2)
     End Sub

     Function getStats() As Integer() 
        Dim returnVal(1 To 2) As Integer 
        Dim a(0) As Integer
        returnVal(1) = 7
        returnVal(2) = 8
        a(0) = 5 + 5

        getStats = returnVal 'returning value
        getStats = a 'returning value

    End Function

Ответы [ 3 ]

3 голосов
/ 01 мая 2020

A Function процедура может вернуть один единственный результат.

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

Или вы можете принять ByRef параметров - это должно работать (не проверено):

Public Sub GimmeTwoArrays(ByRef outArray1 As Variant, ByRef outArray2 As Variant)
    ReDim outArray1(1 To 10)
    ReDim outArray2(1 To 10)
    Dim i As Long
    For i = 1 To 10
        outArray1(i) = i
        outArray2(i) = Chr$(64 + i)
    Next
End Sub

вызывающей стороне нужно только передать указатели вариантов, неважно, инициализируете ли вы их или нет:

Dim values1 As Variant
Dim values2 As Variant
GimmeTwoArrays values1, values2
Debug.Print values1(1), values2(1)

У вас нет , чтобы объявить их As Variant, но обернуть массивы в Variant обычно облегчают их передачу и работу с ними.

1 голос
/ 01 мая 2020

Возвращает результаты функции в виде содержимого ParamArray

В дополнение к правильному ответу Матье, ссылающемуся на массив массивов (или массив с зубцами ) Я демонстрирую способ получения результатов функции, когда содержимое ParamArray передается как пустой аргумент массива. Результат функции, присвоенный arr, имеет возможное преимущество, заключающееся в том, что можно использовать несколько способов адресации содержимого отдельного или всего массива:

  1. получить весь набор (например, имя массива arr) в соответствии с ParamArray структура
  2. получает подмножества напрямую, даже по оригинальным именам массивов (здесь a и b)
Sub ExampleCall()
'[0] declare empty arrays and assign array to function results via ParamArray argument
Dim arr, a(1 To 10), b(1 To 10)
arr = GetBoth(a, b)                      ' << function GetBoth()

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Two options to display results:
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'[1] get the whole set conform to ParamArray structure
'    shows: arr(0) ~> 1,2,3,4,5,6,7,8,9,10            arr(1) ~> A,B,C,D,E,F,G,H,I,J
Debug.Print "arr(0) ~> " & Join(arr(0), ","), _
            "arr(1) ~> " & Join(arr(1), ",")

'[2] get the sub sets directly, even by the original array names
'    shows: a      ~> 1|2|3|4|5|6|7|8|9|10            b      ~> A|B|C|D|E|F|G|H|I|J
Debug.Print "a      ~> " & Join(a, "|"), _
            "b      ~> " & Join(b, "|")
'[ad) 1/2] get individual values, e.g. the first item of the second array
'    note that sub sets a and b got a 1-base declaration here,
'    whereas the array of the subset arrays remains 0-based
Debug.Print "arr(1)(2) = " & arr(1)(2)          ' // shows: arr(1)(2) = B
Debug.Print "b(2) = " & b(2)                    ' // shows: b(2)      = B

End Sub

Функция GetBoth() через ParamArray аргументов

Function GetBoth(ParamArray arr()) As Variant
    Dim i As Long
    For i = 1 To 10
        arr(0)(i) = i
        arr(1)(i) = Chr$(64 + i)
    Next
GetBoth = arr
End Function
0 голосов
/ 01 мая 2020

Объединение двух длинных массивов

Option Explicit

Sub mysub()

    Dim i As Long
    Dim myArray() As Long
    myArray() = getStats() 'calling for function

    For i = LBound(myArray) To UBound(myArray)
        Debug.Print myArray(i)
        ' MsgBox myArray(i)
    Next i

 End Sub

 Function getStats() As Long()

    Dim returnVal(1 To 2) As Long
    Dim a(0) As Long

    returnVal(1) = 7
    returnVal(2) = 8
    a(0) = 5 + 5

    getStats = mergeTwoLongArrays(returnVal, a)

End Function

Function mergeTwoLongArrays(Array1, Array2, Optional Base As Long = 0)

    Dim arr() As Long
    Dim NoE As Long
    Dim countNew As Long

    NoE = UBound(Array1) - LBound(Array1) + UBound(Array2) - UBound(Array2) + 2

    ReDim arr(Base To NoE - Base - 1)

    countNew = LBound(arr)
    For NoE = LBound(Array1) To UBound(Array1)
        arr(countNew) = Array1(NoE)
        countNew = countNew + 1
    Next NoE
    For NoE = LBound(Array2) To UBound(Array2)
        arr(countNew) = Array2(NoE)
        countNew = countNew + 1
    Next NoE

    mergeTwoLongArrays = arr

End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...