VBA Используйте два одномерных массива для создания двумерного массива и вызовите значение для заполнения аргументов

У меня есть 2 массива, которые я хочу объединить в один массив всех возможных комбинаций. Затем мне нужно перебрать все комбинации и популярные аргументы для функции. Мои массивы не равны по размеру, и мои попытки до сих пор приводили к объединенному массиву, имеющему только 1 пару значений. Это VBA в PowerPoint, а не Excel, если это имеет значение для доступного синтаксиса.

Как я могу уйти от этого:

arrayColor = Array("Blue","Green","Red")
arraySize = Array("XS","S","M","L","XL")

К этому:

arrayCombo(0,0) = "Blue"
arrayCombo(0,1) = "XS"
arrayCombo(1,0) = "Blue"
arrayCombo(1,1) = "S"
...
arrayCombo(15,0) = "Red"
arrayCombo(15,1) = "XL"

А затем используйте цикл для вызова каждой пары значений и заполнения значений аргументов. Этот код просто для иллюстрации концепции; это конечно не законно. Уверен, что мне нужен вложенный цикл здесь?

For i = 0 To UBound(arrayCombo(i))  
    nextSubToFire(color, size)
Next i

Это то, что у меня есть до сих пор, но это приводит только к одной паре в моем объединенном массиве. Он основан на этот вопрос, но я думаю, что либо что-то упускаю, либо единственный ответ не совсем правильный. Я просмотрел другие подобные вопросы, но не могу понять, как это сделать с массивом, скомпилированным в коде, а не с другими примерами, адаптированными для Excel.

Option Explicit
Dim arrayColorSize, arrayCombo

Sub CoreRoutine()
    Dim arrayColor, arraySize
    arrayColor = Array("Blue","Green","Red")
    arraySize = Array("XS","S","M","L","XL")
    arrayColorSize = Array(arrayColor, arraySize)
    arrayCombo = Array(0, 0)
    DoCombinations (0)
    Dim a As Integer
    Dim b As Integer
    'For loop comes next once I figure out how to populate the full arrayCombo
    
End Sub

Sub DoCombinations(ia)
    Dim i
    For i = 0 To UBound(arrayColorSize(ia)) ' for each item
        arrayCombo(ia) = arrayColorSize(ia)(i) ' add this item
        If ia = UBound(arrayColorSize) Then
        Else
            DoCombinations (ia + 1)
        End If
    Next i
End Sub

Используя окно Locals, я вижу, что arrayCombo существует, но в нем есть только 1 пара значений, которая является последним набором параметров сопряжения. Я вижу, что arrayColorSize имеет 2 набора массивов, как я и ожидал, поэтому я подозреваю, что в подразделе DoCombinations чего-то не хватает. VBA Используйте два одномерных массива для создания двумерного массива и вызовите значение для заполнения аргументов

Любое руководство высоко ценится!

См. также: stackoverflow.com/questions/19780016/…

Tim Williams 22.03.2022 02:10

Спасибо, @TimWilliams. Я еще раз взгляну на это, но я изо всех сил пытался интерпретировать это в моем сценарии (по общему признанию, здесь очень слабые навыки VBA). Я вижу, что ReDim (и, возможно, Preserve) — это, возможно, то, чего мне не хватает в моем сабвуфере DoCombinations? Я думаю, что то, как я это написал, возможно, перезаписывает массив каждым значением, пока оно не достигнет последнего?

BobbyScon 22.03.2022 02:15
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из способов сделать это - объединить два массива 1D в массив 2D с двумя столбцами (как в вашем примере):

Private Function Combine1DArrays(ByRef arr1 As Variant, ByRef arr2 As Variant) As Variant
    If GetArrayDimsCount(arr1) <> 1 Or GetArrayDimsCount(arr2) <> 1 Then
        Err.Raise 5, "Combine1DArrays", "Expected 1D arrays"
    End If
    '
    Dim count1 As Long: count1 = UBound(arr1) - LBound(arr1) + 1
    Dim count2 As Long: count2 = UBound(arr2) - LBound(arr2) + 1
    Dim i As Long, j As Long, r As Long
    Dim result() As Variant
    '
    ReDim result(0 To count1 * count2 - 1, 0 To 1)
    r = 0
    For i = LBound(arr1) To UBound(arr1)
        For j = LBound(arr2) To UBound(arr2)
            result(r, 0) = arr1(i)
            result(r, 1) = arr2(j)
            r = r + 1
        Next j
    Next i
    Combine1DArrays = result
End Function

Public Function GetArrayDimsCount(ByRef arr As Variant) As Long
    Const MAX_DIMENSION As Long = 60
    Dim dimension As Long
    Dim tempBound As Long
    '
    On Error GoTo FinalDimension
    For dimension = 1 To MAX_DIMENSION
        tempBound = LBound(arr, dimension)
    Next dimension
FinalDimension:
    GetArrayDimsCount = dimension - 1
End Function

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

Sub CoreRoutine()
    Dim arrayColorSize As Variant
    Dim i As Long
    Dim color As String
    Dim size As String
    '
    arrayColorSize = Combine1DArrays(Array("Blue", "Green", "Red") _
                                   , Array("XS", "S", "M", "L", "XL"))
    For i = LBound(arrayColorSize, 1) To UBound(arrayColorSize, 1)
        color = arrayColorSize(i, 0)
        size = arrayColorSize(i, 1)
        NextSubToFire color, size
    Next i
End Sub

Sub NextSubToFire(ByVal color As String, ByVal size As String)
    Debug.Print color, size
End Sub

Сделал быстрый пробег с этим, и похоже, что он работает хорошо. Спасибо за это! Не могли бы вы отредактировать свой ответ и добавить в код несколько комментариев, кратко объясняющих различные компоненты?

BobbyScon 22.03.2022 14:07

@BobbyScon Для меня код не требует пояснений, поэтому я не добавлял лишних комментариев. Но, если у вас есть какие-то конкретные вопросы, то спрашивайте, и я на них отвечу. Короче говоря, метод Combine1DArrays получает в качестве входных данных два одномерных массива, которые затем проверяет, являются ли они на самом деле одномерными, с помощью функции GetArrayDimsCount. Затем массив result измеряется как двумерный массив с достаточным количеством строк для всех комбинаций и двумя столбцами (один для цвета, один для размера). Наконец, массив result заполняется и возвращается. В примере CoreRoutine 2D-массив просматривается построчно.

Cristian Buse 22.03.2022 15:51

Другие вопросы по теме