简体   繁体   English

如何将数组返回到Excel VBA范围

[英]How to return array to range excel vba

I have been trying to get data from a worksheet and put it into array and then paste the array to other worksheet. 我一直在尝试从工作表中获取数据并将其放入数组,然后将数组粘贴到其他工作表中。 However, after the loop my array return Empty . 但是,循环后,我的数组返回Empty Do I need to return something from the For Loop? 我需要从For循环中返回一些东西吗? I searched didn't find any idea. 我搜索没有找到任何想法。

Sub generate()
    Dim article_arr() As Variant
    Dim artCount As Integer
    Dim filter As Integer
    Dim RIL_itemCount As Integer

    'Set PA number
    filter = Sheet7.Range("B1").Value
    RIL_itemCount = Sheet5.Cells(Sheet5.Rows.count, "A").End(xlUp).Row

    'Count number article of PA selected
    artCount = Application.WorksheetFunction.CountIf(Sheet5.Range("R:R"), filter)

    'redim array
    ReDim article_arr(0 To artCount)
    Dim j As Integer
    j = 0

    'populate array with article number from Retail Item List
    For i = 0 To RIL_itemCount
        If (Sheet5.Cells(i + 2, 18).Value = filter) Then
            article_arr(j) = Sheet5.Cells(i + 2, 1).Value          
            Debug.Print (article_arr(j))
        End If
    Next

    'Paste Article number to range
    Sheet7.Range("A8:A" & artCount) = articleArr()


End Sub

As mentioned by David G. I forgot to increment the J. I also use the wrong variable (newbie mistake) when pasting the Array. 如David G所述。我忘了增加J。在粘贴数组时,我还使用了错误的变量(新手错误)。 It now return result but it only return the first value of the array repeated over the pasted range. 现在,它返回结果,但只返回在粘贴范围内重复的数组的第一个值。 Do I need for loop to paste Array to range? 我是否需要循环以将Array粘贴到范围?

Apparently array will be pasted horizontally in the excel, which cause repetition of the first value when pasting the array to range. 显然,数组将在Excel中水平粘贴,这会导致在将数组粘贴到范围时重复第一个值。 Adding WorksheetFunction.Transpose(array) do the magic 添加WorksheetFunction.Transpose(array)做魔术

Here is the updated code: 这是更新的代码:

Sub generate()
    Dim article_arr() As Variant
    Dim artCount As Integer
    Dim filter As Integer
    Dim RIL_itemCount As Integer

    'Set PA number
    filter = Sheet7.Range("B1").Value
    RIL_itemCount = Sheet5.Cells(Sheet5.Rows.count, "A").End(xlUp).Row

    'Count number article of PA selected
    artCount = Application.WorksheetFunction.CountIf(Sheet5.Range("R:R"), filter)

    'redim array
    ReDim article_arr(0 To artCount)
    Dim j As Integer
    j = 0

    'populate array with article number from Retail Item List
    For i = 0 To RIL_itemCount
        If (Sheet5.Cells(i + 2, 18).Value = filter) Then
            article_arr(j) = Sheet5.Cells(i + 2, 1).Value
            j = j + 1
        End If
    Next

    'Paste Article number to range
    k = 8
    Sheet7.Range("A" & k & ":A" & UBound(article_arr) + 7) = WorksheetFunction.Transpose(article_arr)
    Debug.Print (article_arr(395))


End Sub

Your array is supposed to be filled according to the j integer but you don't increment it. 您的数组应该根据j整数填充,但是您不对其进行递增。

For i = 0 To RIL_itemCount
    If (Sheet5.Cells(i + 2, 18).Value = filter) Then
        article_arr(j) = Sheet5.Cells(i + 2, 1).Value
        j = j + 1
        Debug.Print (article_arr(j))
    End If
Next

Also when pasting an array to a single cell, it will do exactly what you're describing; 同样,将数组粘贴到单个单元格时,它将完全按照您的描述进行操作。 paste the first array value everywhere for the size of the array. 将第一个数组值粘贴到各处以获取数组的大小。 To have it put the correct values, you need to send it to a range of the same size as the array. 要使其具有正确的值,您需要将其发送到与数组大小相同的范围内。 For example, for an array of size 2 by 3, you would write 例如,对于大小为2 x 3的数组,您将编写

Range("A1:B3") = array

In your case you would want the size to be dynamic, just like the size of your array. 在您的情况下,您希望大小是动态的,就像数组的大小一样。

k = 8
Range("A" & k & ":A" & k + Ubound(article_arr, 1)) = article_arr

Should do the trick. 应该做到的。 As you can see it will paste the range starting at A8 and going down the same length as the number of values in the array. 如您所见,它将粘贴从A8开始并向下与数组中的值数相同长度的范围。

The most efficient/dynamic method for ArrayRange : ArrayRange的最有效/动态方法:

There's an significantly more efficient way of placing data from a one- or two-dimensional array of values onto a worksheet, as long as it's a single area (ie., "no skipped cells" ). 只要是单个区域(即“无跳过的单元格” ),就有一种将一维或二维值数组中的数据放置到工作表上的更为有效的方法。

A worksheet is basically a two-dimensional array. 工作表基本上是二维数组。
However, interacting with the worksheet repeatedly (such as looping through every element in the array to populate one cell at a time) is an extremely expensive operation . 但是,与工作表重复进行交互(例如循环遍历数组中的每个元素以一次填充一个单元格)是极其昂贵的 操作


Call this procedure, passing it only an array and a single-cell range representing the desired "top-left corner" of the output data. 调用此过程,仅将其传递给表示输出数据所需的“左上角”的数组和单单元格范围 Input array can be two-dimensional, or: one-dimension from a range." 输入数组可以是二维的,也可以是:范围的一维。”

Sub Array2Range(arr, destTL As Range)
    'dumps [arr] (1D/2D) onto a sheet where [destTL] is the top-left output cell.
    destTL.Resize(UBound(arr, 1) - LBound(arr, 1) + 1, _
        UBound(arr, 2) - LBound(arr, 2) + 1) = arr
End Sub

Examples: 例子:

Sub test_A2R()
    Dim myArr 'dimension a variant (variants can also hold implicit arrays!)

    'create a static two-dimensional (6x3) array
    myArr = [{1, 2, 3, "A", "D", "G"; 4, 5, 6, "B","E","H"; 7, 8, 9,"C","F","I"}]

    'dump the array onto the activesheet starting starting at cell [A1]
    Array2Range myArr, Range("A1")

End Sub

Sub test_R2A2R()
    Dim a 'dimension a variant
    a = Range("A1:E3")

    'do "something" to the data here (otherwise we should just use `Range.Copy`)
    'let's transpose the data, for no particular reason
    a = Application.WorksheetFunction.Transpose(a)

    Array2Range a, Range("C6") 'dump the array starting at Top-Left of [C5]
End Sub

Example Output: 示例输出:

Run both of the example subs and you'll get: 运行两个示例子,您将获得:

img

(Inspired by Chip Pearson ) (受Chip Pearson启发)

Following my comment, above (handling a one-dimensional array), suggesting this modest change to the answer by @ashleeDawg, above: 在上面我的评论(处理一维数组)之后,建议对上述@ashleeDawg的答案进行适度更改:

Sub sub_Array2Range(arrArray, rngSingleAreaTopLeftCell As Range)
    'dumps [arrArray] (1D/2D) onto a sheet
    ' where [rngSingleAreaTopLeftCell] is the top-left output cell.
On Error GoTo OneDimension
rngSingleAreaTopLeftCell.Resize(UBound(arrArray, 1) - LBound(arrArray, 1) + 1, _
        UBound(arrArray, 2) - LBound(arrArray, 2) + 1) = arrArray
Exit Sub

OneDimension:
    rngSingleAreaTopLeftCell _
       .Resize(UBound(arrArray, 1) - LBound(arrArray, 1) + 1) _
            = Application.Transpose(arrArray)
End Sub

See this question, for the problem cured by the transpose (without it, the the statement populates each cell in the range with the first array element): 请参见此问题,以了解通过转置解决的问题(没有此问题,该语句将使用第一个数组元素填充范围内的每个单元格):

Writing an array to a range. 将数组写入范围。 Only getting first value of array 仅获取数组的第一个值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM