Как вставить значение в не предварительно определенный размер массива? - PullRequest
5 голосов
/ 08 марта 2011

Мне нужна помощь для добавления анализа значения из XML на основе определенного фильтра / соответствия слов в arraylist. Однако этот массив не должен иметь заранее определенный размер массива, поскольку входные данные XML являются динамическими от файла к файлу. То есть XML-файл1 может иметь 10 таких входов, а XML-файл2 может иметь 15 входов. Может кто-нибудь, пожалуйста, посоветуйте, как я могу сделать ниже 2 вещи:

  1. Как определить список массивов с предварительным определением размера массива? Размер зависит от списка ввода XML, когда пользователь читает узел за узлом
  2. Когда найдено совпадение слов XML, произойдет синтаксический анализ ввода / значения XML в Excel VBA и сохранение в этом массиве.

Ответы [ 3 ]

14 голосов
/ 08 марта 2011

Массивы могут быть определены как

Dim MyArray() as string

, а затем измерены и изменены в размере во время выполнения

Redim MyArray(lb to ub)

или, чтобы сохранить любые существующие данные, которые находятся в массиве

Redim Preserve MyArray(lb to ub)

lb и ub являются границами массива и могут быть определены кодом, например,

lb = 1
ub = <number of matched found in xml>

для постепенного изменения размера

redim MyArray (0 to 0)
For each line in xml
    if Match then
        MyArray(ubound(MyArray)) = Match
        Redim Preserve MyArray(0 to ubound(MyArray) + 1)
    end if
Next
' Array ends up 1 size larger than number of matches '
if ubound(MyArray) > 0 then
    redim Preserve MyArray (0 to ubound(MyArray) - 1)
end if
6 голосов
/ 22 января 2015

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

Temp = ""
Separator = ","
For A = 1 to 155
    If Temp <> "" Then
        Temp = Temp & Separator
    End If
    Temp = Temp & CStr(A)
Next 'A
myArray = Split(Temp, Separator)
'now myArray has the elements 1, 2, ..., 155 (which are strings!)

Это может быть полезно при определенных особых обстоятельствах, поскольку это несколько более интуитивный способ.Помните, что массив, который вы создаете таким образом, является массивом строк!

0 голосов
/ 08 июля 2019

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


Функция для отправки в массив

Вот функция, которая может добавить элемент или даже несколько элементов в конец массива.Я основал это на том, как работает метод JavaScripts push.

' Mutates array by adding element(s) to the end of an array. Returns the new array length.
Public Function ArrayPush(ByRef sourceArray As Variant, ParamArray elements() As Variant) As Long
    '@author: Robert Todar <https://github.com/todar>
    '@param: <SourceArray> must be a single dimensional array.
    '@param: <elements> are the elementss to be added.

    ' Change this if you prefer to work with option base 1
    Const optionBase As Long = 0

    Dim firstEmptyBound As Long
    Select Case ArrayDimensionLength(sourceArray)
        Case 0
            firstEmptyBound = optionBase
            ' Create space for new elements in empty array.
            ReDim sourceArray(optionBase To UBound(elements, 1) + optionBase)

        Case 1
            firstEmptyBound = UBound(sourceArray) + 1
            ' Add more space for new elements.
            ReDim Preserve sourceArray( _
                LBound(sourceArray) To UBound(sourceArray) + UBound(elements) + 1)

        Case Else
            Err.Raise 5, "ArrayPush", "ArrayPush function only works with single dimension arrays."

    End Select

    Dim index As Long
    For index = LBound(elements) To UBound(elements)

        ' Add elements to the end of the array. Assign is to 'set' or 'let' depending on type.
        If IsObject(elements(index)) Then
            Set sourceArray(firstEmptyBound) = elements(index)
        Else
            Let sourceArray(firstEmptyBound) = elements(index)
        End If

        ' Increment to the next empty index
        firstEmptyBound = firstEmptyBound + 1

    Next index

    ' Return new array length
    ArrayPush = UBound(sourceArray) + (Int(optionBase = 0) * -1) - LBound(sourceArray)

End Function

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

' Returns the length of the dimension of an array.
Public Function ArrayDimensionLength(ByVal sourceArray As Variant) As Long

    On Error GoTo Catch
    Do
        Dim boundIndex As Long
        boundIndex = boundIndex + 1

        ' Loop until this line errors out.
        Dim test As Long
        test = UBound(sourceArray, boundIndex)
    Loop
Catch:
    ' Must remove one, this gives the proper dimension length.
    ArrayDimensionLength = boundIndex - 1

End Function

Пример использования этой функции

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

Private Sub testArrayPush()

    Dim data() As String

    ' Single element
    ArrayPush data, "apple"

    ' Multiple elements
    ArrayPush data, "banana", "carrot"

    Debug.Print Join(data, ", ") '<~ apple, banana, carrot

End Sub

Вы можете найти эту функцию и другие подобные функции массива на моем GitHubPage .

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