В VBA, как вернуть массив/или записать в ячейки с помощью функции?

Используя эту очень простую функцию:

Function WriteArray() as Variant
 Dim array(0 To 2)
 array(0) = "A"
 array(1) = "B"
 array(2) = "C"
 WriteArray = array
End Function

Я ожидал увидеть в результате весь массив в своей электронной таблице Excel, но это не так: я получаю только первую строку. Я знаю, что есть трюк, чтобы показать весь массив в электронной таблице (выбрав диапазон ячеек с помощью формулы + F2 + CTRL + SHIFT + ENTER), но я бы предпочел, чтобы VBA справился со всем этим.

Я также пытался использовать переменную Application.Caller для записи непосредственно в диапазоне "Caller", но код ломается.

Спасибо большое за вашу помощь!

РЕДАКТИРОВАТЬ: Вот еще один код, который я пытался использовать:

Function WriteArray() As Variant
     Dim arr(0 To 2)
     arr(0) = "A"
     arr(1) = "B"
     arr(2) = "C"
     WriteArray = arr
     Dim StartRow, i As Integer
     For i = 0 To UBound(arr)
        Range("A" & i).Value = arr(i)
     Next
End Function

Он прерывается на строке «Range("A" & i).Value = arr(i)". Мой Excel сломался?!


person Community    schedule 11.05.2009    source источник


Ответы (4)


Следующий код красиво записывает массив в диапазон ячеек:

Function WriteArray() As Variant
    Dim AbcList(0 To 2) as Variant
    AbcList(0) = "A"
    AbcList(1) = "B"
    AbcList(2) = "C"
    WriteArray = AbcList
End Function

Function WriteArrayToSpreadsheet()
    Dim MyArray As Variant
    MyArray = WriteArray()

    Dim StartRow, i As Integer
    StartRow = 1
    For i = 0 To UBound(MyArray)
        Range("A" & i + StartRow).Value = MyArray(i)
    Next
End Function

При этом я хотел бы увидеть часть кода, где вы на самом деле пытаетесь поместить его в электронную таблицу, а не там, где вы строите массив. Тогда я могу вам помочь!

person Eric    schedule 11.05.2009
comment
На самом деле это не работает, код VBA ломается в Range(A & i + StartRow).Value = MyArray(i)... это и моя проблема. Этот код работает на вашем Excel!? Я использую Эксель 2003. - person ; 11.05.2009
comment
Это отлично работало в Excel 2003. Измените каждый массив в вашем начальном коде на другое имя переменной, которое НЕ является зарезервированным словом, например AbcList или что-то в этом роде. - person Eric; 11.05.2009
comment
Тем не менее, это ломается... Я использую именно этот код: Функция WriteArray() As Variant Dim arr(0 To 2) arr(0) = A arr(1) = B arr(2) = C WriteArray = arr Dim StartRow, i As Integer For i = 0 To UBound(arr) Range(A & i).Value = arr(i) Next End Function At Range(A & i).Value = arr(i), он просто выходит из кода, даже без каких-либо ошибок... для меня это не имеет смысла :( - person ; 11.05.2009
comment
Я отредактировал свой вопрос с помощью этого кода, так как он здесь отображается неправильно :) - person ; 11.05.2009
comment
Нет, вам нужно установить StartRow и добавить его в i. Ваш код пытается записать в A0, который не существует, и выдает ошибку. - person Eric; 11.05.2009

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

Если вы хотите использовать функцию массива (используя Shift-Ctrl-Enter), вам нужно изменить свой код на:

Function WriteArray() As Variant
    Dim arr(0 To 2, 0 To 1)
    arr(0, 0) = "A"
    arr(1, 0) = "B"
    arr(2, 0) = "C"
    WriteArray = arr
End Function

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

person JDunkerley    schedule 14.05.2009

Секрет в том, чтобы определить двумерный массив. Два измерения массива — это просто диапазон, который необходимо определить для набора данных. Первое измерение массива — это смещение строки, а второе измерение — смещение столбца.

В вашем примере второе измерение просто не "используется":

 Sub Ente()

   Dim myArray(0 To 3, 0) As String
   myArray(0, 0) = "A"
   myArray(1, 0) = "B"
   myArray(2, 0) = "C"

   Range("B7:B" & UBound(myArray) + 6) = myArray

End Sub

Так что никаких петель не надо! Просто и быстро.

person JFS    schedule 12.05.2015

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

Следующим образом:

Sub LoadArray(ByRef oRange, ByRef vArray)
    Dim I
    For I = 0 To UBound(vArray)
        oRange.Offset(I, 0).Value = vArray(I)
    Next
End Sub

'How to call:
Dim anyArray
anyArray = Array(1,2,3)

Call LoadArray(Range("anyRange"), anyArray)

Надеюсь, поможет.

person Roger Barreto    schedule 25.07.2013