Используйте в новом модуле не-publi c массив из другого модуля - PullRequest
1 голос
/ 25 мая 2020

Я следую руководству по массивам VBA stati c. Я хочу убедиться, что мой мыслительный процесс верен для чего-то простого, что я sh должен сделать.

У меня есть код, который собирает все 12 месяцев и помещает его в stati c массив строк типа . На практике я хотел проверить, можно ли скопировать эти значения в другое место, используя другой модуль, который действует как «вставка» месяцев при выборе курсора, но не использует массив publi c. Я новичок в VBA, поэтому, возможно, мой взгляд на кодирование ошибочен, и для этой цели я должен использовать публично определенный массив.

Sub PopulateStaticArray()
Dim months(11) As String
Dim ndx As Integer
Dim xrow As Long
ndx = 0
xrow = 2
Do Until Cells(xrow, 1).Value = ""
    months(ndx) = Cells(xrow, 1).Value
ndx = ndx + 1
xrow = xrow + 1
Loop
End Sub

Чего я хочу достичь избыточным образом. (По сути, я воссоздаю массив с нуля.) Конечно, это не настоящий проект, он просто для того, чтобы лучше понять взаимодействие между модулями в VBA для Excel. Мне не нужен какой-либо код, а просто общее концептуальное руководство о том, следует ли мне использовать какой-либо другой метод для достижения этой задачи (например, Publi c defined Array or Functions и т.д. c.) Спасибо.

1 Ответ

0 голосов
/ 26 мая 2020

@ GSerg упомянуто правильно

«Вы не создаете массив c stati внутри PopulateStaticArray. Если вы хотите передать уже существующий массив в InsertMonthsArray (), независимо от того, откуда он , тогда да, это должен быть Sub InsertMonthsArray (months () as string) "

Вам нужно передать ваш массив - объявленный на уровне процедуры - как (неявный) ByRef аргумент, что означает, что вы можете присвоить названия месяцев каждому элементу массива в пределах вызываемой подпроцедуры createMonths, чтобы вызывающая процедура могла фактически использовать их, например, для записи их в вертикальный диапазон (например, начиная с ячейки A7 ).

Option Explicit                             ' declaration head of code module

Sub PopulateMonthArray()
'[0] declare array at procedure level
Dim months(11) As String                    ' equals Dim months(0 to 11)
'Dim months(1 To 12) As String              ' alternative: declare a 1-based array

'[1] fill array items with month names passing array as (implicit) ByRef argument 
createMonths months                         ' << call sub createMonths 
'[2] write 1-dim array vertically to sheet (transposing output from a "flat" to a 2-dim array)   
Sheet1.Range("A7").Resize(Rowsize:=12).Value = Application.Transpose(months)
End Sub

Подпроцедура createMonths

Поскольку вы определяете массив на основе 0 months(0 To 11) и количество месяцев обычно от 1 до 12, я добавил функциональность чтобы также можно было создать массив на основе 1.

Sub createMonths(months)                     ' equals Sub createMonths(ByRef months)
    Dim countOffset As Long
    countOffset = IIf(LBound(months), 0, 1)  ' allow calculation of 0-based AND 1-based arrays
    Dim i As Long
    For i = LBound(months) To UBound(months) ' loop through each array element
        months(i) = Application.Text(DateSerial(0, i + countOffset, 1), "mmmm")
    Next i
End Sub

Простая альтернатива / Редактировать 2020-05-27

Если ваш намерение, однако, сделать ваши месяцы y доступен в других процедурах без необходимости объявлять его в каждой процедуре (ни в глобальной области, ни в определении класса), вы можете просто воспользоваться простым обходным путем : вставить Property Get также можно использовать в стандартных модулях - не только в модулях классов, кстати. - Но учтите, что вы на самом деле не сохраняете («сохраняете») массив, вы бы перестроили его и, возможно, в более удобочитаемом виде.

Public Property Get Months()
    Dim tmp(1 To 12)                        ' I'd prefer a 1-based months array :-)
    createMonths tmp                        ' use the same procedure as above (or rebuild it code)
    Months = tmp                            ' return the Get value
End Property

Sub AnyOtherProcedure()
'no further declaration needed
Debug.Print Months(1)                       ' ~> January
Debug.Print Join(Months, ", ")              ' ~> January, February, ..., December
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...