excel vba заполнение массива

У меня следующая проблема. У меня есть пользовательская форма с полями ввода. Пользователь собирается ввести номер для участников. У меня четыре группы участников:

Group A: 5
Group B: 6
Group C: 1
Group D: 2

Имя каждого участника должно быть таким: {GA1, GA2, ..., GD2} Я хотел записать это в массив в таком порядке, а затем использовать этот массив для заполнения ячеек именами, но все, что я придумал, это четыре для -loops, чтобы записать его в массив, и это тоже не удалось. Есть лучший способ это сделать?

Dim GA As Integer
Dim GB As Integer
Dim GC As Integer
Dim GD As Integer
Dim PartSum As Integer


GA = TextBox32.Value
GB = TextBox33.Value
GC = TextBox34.Value
GD = TextBox35.Value

PartSum = GA + GB + GC + GD

Dim NamingArray() As String

ReDim NamingArray(1 To PartSum)

For i = 0 To GA
    NamingArray(i) = "GA " & CStr(i)
Next i

For j = GA To GA + GB
    NamingArray(i) = "GB " & CStr(j)
Next j

For k = GA + GB To GA + GB + GC
    NamingArray(i) = "GC " & CStr(k)
Next k

For l = GA + GB + GC To GA + GB + GC + GD
    NamingArray(i) = "GD " & CStr(l)
Next l

'check entries
For i = LBound(NamingArray) To UBound(NamingArray)

    MsgBox (NamingArray(i))

Next i

person user366121    schedule 17.06.2011    source источник
comment
Можете ли вы опубликовать код, который не удалось?   -  person jonsca    schedule 17.06.2011


Ответы (4)


Я вижу три причины, по которым ваш код ведет себя не так, как вы ожидаете.

Во-первых, переменные, которые вы используете в качестве индексов в своих циклах For ... Next, несовместимы. В этом цикле, например, вы увеличиваете k, но используете i для индексации в NamingArray. Обратите внимание, что i все еще имеет значение GA+1, оставшееся от первого цикла.

For k = GA + GB To GA + GB + GC
    NamingArray(i) = "GC " & CStr(k)
Next k

Просто используйте i для всех ваших петель. Не нужно каждый раз использовать другую букву.

Во-вторых, вы пытаетесь получить доступ к элементу 0 из NamingArray, которого не существует.

ReDim NamingArray(1 To PartSum) ' starts at 1

For i = 0 To GA 
    NamingArray(i) = "GA " & CStr(i) ' attempt to refer to NamingArray(0)
Next i

В-третьих, ваша индексация вообще полностью запуталась. Например, NamingArray(GA) будет записано в конце вашего первого цикла, а затем перезаписано в начале вашего второго цикла. Это происходит для всех ваших циклов; их «юрисдикции» пересекаются (извините, я канадец). Я исправил это (и все остальные ошибки) ниже. Это работает:

For i = 1 To GA
    NamingArray(i) = "GA " & CStr(i)
Next i

For i = 1 + GA To GA + GB
    NamingArray(i) = "GB " & CStr(i - GA)
Next i

For i = 1 + GA + GB To GA + GB + GC
    NamingArray(i) = "GC " & CStr(i - GA - GB)
Next i

For i = 1 + GA + GB + GC To GA + GB + GC + GD
    NamingArray(i) = "GD " & CStr(i - GA - GB - GC)
Next i

Теперь, чтобы ответить на ваш вопрос: есть ли лучший способ сделать это? Да. Но это прекрасно работает, и хотя это не очень красиво, это никоим образом не неэффективно.

person Jean-François Corbett    schedule 17.06.2011

Зачем возиться с массивом? Объявить int как курсор

Предполагая, что вы хотите их в строке 1

dim col as integer
dim Acount as integer (etc)
'get Acount, Bcount etc from form
for col 1 =1 to Acount
    cells(1,col).value = "GA" & col
next
for col =1 Acount to Bcount-1
    cells(1,col).value = "GB" & col
next

и т.д

person Wudang    schedule 17.06.2011

Если список не будет меняться, ваш массив может быть просто объявлен примерно так:

Dim participantNames
participantNames = Array("GA1","GA2","GA3","GA4","GA5","GB1","GB2","GB3","GB4","GB5","GB6","GC1","GD1","GD2")

Если список букв и счетов может отличаться, то вам, вероятно, нужна функция, например:

Option Explicit

Public Function GroupIDs(grpNames, grpCounts) As Variant

Dim grpIndex
Dim countIndex
Dim output As New Collection

    For grpIndex = LBound(grpNames) To UBound(grpNames)
        For countIndex = 1 To grpCounts(grpIndex)
            output.Add "G" & grpNames(grpIndex) & countIndex
        Next
    Next

ReDim outputArray(1 To output.Count)

    For countIndex = 1 To output.Count
        outputArray(countIndex) = output(countIndex)
    Next

    GroupIDs = outputArray

End Function

... который вы можете вызвать с помощью:

GroupIds(Array("A", "B", "C", "D"),Array(5, 6, 1, 2))
person Mike Woodhouse    schedule 17.06.2011
comment
Я попробовал ваш код, но когда я пытаюсь просмотреть массив, чтобы увидеть вывод, я получаю ошибку несоответствия типов. - person user366121; 17.06.2011

Назовите свои текстовые поля tbxGA, tbxGB, tbxGC и tbxGD и используйте этот код для записи в диапазон.

Private Sub cmdWrite_Click()

    Dim i As Long, j As Long
    Dim ctl As Control
    Dim lCnt As Long
    Dim aOutput() As String
    Dim lTotal As Long

    For i = 65 To 68
        Set ctl = Me.Controls("tbxG" & Chr$(i))
        lTotal = lTotal + Val(ctl.Text)
    Next i

    ReDim aOutput(1 To lTotal, 1 To 1)

    For i = 65 To 68
        Set ctl = Me.Controls("tbxG" & Chr$(i))
        For j = 1 To Val(ctl.Text)
            lCnt = lCnt + 1
            aOutput(lCnt, 1) = "G" & Chr$(i) & j
        Next j
    Next i

    Sheet1.Range("A1").Resize(UBound(aOutput, 1), UBound(aOutput, 2)).Value = aOutput

    Unload Me

End Sub
person Dick Kusleika    schedule 17.06.2011