VBA Передача массива в функцию и обратно - PullRequest
0 голосов
/ 04 мая 2020

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

Sub test()

    Dim Arr() as Variant
    Dim CurrDoc as Word.Document

    ReDim Arr(0 to 39, 0 to 1)

    Arr() = FillArr(CurrDoc, Arr())

End Sub

Function FillArr(CurrentDocument As Word.Document, CurrentArray() As Variant) As Variant

    j = 1

    For Each chk In CurrentDocument.ContentControls

        If chk.Type = 8 Then

            CurrentArray(j, 1) = chk.Title
            CurrentArray(j, 2) = chk.Checked

            j = j + 1

        End If

    Next chk

FillArr() = CurrentArray()

End Function

Ответы [ 2 ]

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

Лично я бы подошел к этому по-другому.

Полезность функции, которая возвращает заголовки и "проверенное" состояние всех элементов управления содержимым типа "ceckbox", ниже, чем функции, которая просто возвращает все элементы управления содержимым определенного типа. Вот почему:

Код, который вызывает функцию, уже знает, что хочет использовать Title и Checked, поэтому ничего не теряется, когда он получает массив ContentControl экземпляров вместо нескольких размерный массив строк и логических значений. Но когда вызывающий код хочет манипулировать флажками, подход «строки и логические значения» терпит неудачу.

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

Также нам не нужно передавать массив. Просто создайте массив и верните его:

Function FindControls(Doc As Word.Document, ControlType As WdContentControlType) As Variant
    Dim cct As Variant, i As Integer

    ' figure out how many matching controls there are and allocate an array
    For Each cct In Doc.ContentControls
        If cct.Type = ControlType Then i = i + 1
    Next cct
    ReDim cctArray(i - 1)

    ' save references to matching controls in array
    i = 0
    For Each cct In Doc.ContentControls
        If cct.Type = ControlType Then
            Set cctArray(i) = cct
            i = i + 1
        End If
    Next cct

    FindControls = cctArray
End Function

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

Dim c As Variant

For Each c In FindControls(ActiveDocument, wdContentControlCheckbox)
    Debug.Print c.Title, c.Checked
Next
1 голос
/ 04 мая 2020

Мне не хочется заставлять слово делать c, чтобы точно соответствовать вашему, но вы можете передавать массивы через функции. Я собираюсь заполнить мой случайными символами.

Sub test()
    Dim arr() As Variant
    ReDim arr(1 To 40, 1 To 2)

    arr() = fillarr(arr())

    Dim i As Long

    For i = 1 To 40
        Debug.Print i, arr(i, 1)
        Debug.Print i & "* 5", arr(i, 2)
    Next i
End Sub

Function fillarr(currentarr() As Variant) As Variant
    Dim j As Long

    For j = 1 To 40
        currentarr(j, 1) = Chr(j + 64)
        currentarr(j, 2) = Chr(j * 5)
    Next j

    fillarr = currentarr
End Function

На самом деле существует неявное by ref, потому что в VBA массивы всегда передаются по ссылке, поэтому вам не нужна функция для этого, хотя Вы, вероятно, должны, как это понятно, но вы можете увидеть это здесь:

Sub test()
    Dim arr() As Variant
    ReDim arr(1 To 40, 1 To 2)

    fillarr arr() 'no value set

    Dim i As Long

    For i = 1 To 40
        Debug.Print i, arr(i, 1)
        Debug.Print i & "* 5", arr(i, 2)
    Next i
End Sub

Sub fillarr(currentarr() As Variant)
    Dim j As Long

    For j = 1 To 40
        currentarr(j, 1) = Chr(j + 64)
        currentarr(j, 2) = Chr(j * 5)
    Next j

    'Note the lack of return
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...