VBA Pass User选择2d Range vs静态数组代替Arr

时间:2014-07-22 11:49:27

标签: vba variant

我需要转换以下函数来接受用户选择的2维范围[数据类型]来代替在其中使用的Arr [任意自定义数组]。我想这样做,所以我可以在数据上运行工作表函数。我知道可以在选择范围对象时完成,但我在一个点上的数据需要转换为变量,然后重新分配到新工作表上的[新]范围(又称'放置数组值在工作表上),然后重新读回范围(也就是将工作表值重新加载到数组中)

Sub SortViaWorksheet()
    Dim Arr(1 To 5) As String ' this is the array to be sorted
    Dim WS As Worksheet ' temporary worksheet
    Dim R As Range
    Dim N As Long

    ' fill up the array with some
    ' aribtrary values.
    Arr(1) = "aaa"
    Arr(2) = "zzz"
    Arr(3) = "mmm"
    Arr(4) = "ttt"
    Arr(5) = "bbb"

    Application.ScreenUpdating = False

    ' create a new sheet
    Set WS = ThisWorkbook.Worksheets.Add

    ' put the array values on the worksheet
    Set R = WS.Range("A1").Resize(UBound(Arr) - LBound(Arr) + 1, 1)
    R = Application.Transpose(Arr)

    ' sort the range
    R.Sort key1:=R, order1:=xlAscending, MatchCase:=False

    ' load the worksheet values back into the array
    For N = 1 To R.Rows.Count
        Arr(N) = R(N, 1)
    Next N

    ' delete the temporary sheet
    Application.DisplayAlerts = False
    WS.Delete
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True

    ' test/debug/confirmation
    For N = LBound(Arr) To UBound(Arr)
        Debug.Print Arr(N)
    Next N   
End Sub

换句话说,我希望能够传入将转换为变体的用户选择的2d范围,然后将此变体导出到工作表中的2d范围,该工作表将重新加载回vba工作范围内使用和运行功能。 我理解这个例子使用.sort,这需要一个1d数组。我不打算使用sort,而是使用像这个新范围的工作表函数,比如rank,countif,average,max,min,median等

我的朋友指出,上面的示例使用1d范围作为输入,并将1d数组导出到工作表。因此,我需要能够选择2d范围作为输入,并将2d范围输出到工作表,随后将其作为新范围重新读取。

2 个答案:

答案 0 :(得分:1)

您可以使用范围的Value属性将工作表范围转换为数组并再返回。例如,要将当前工作簿选择读入数组,处理它并将其写回:

Sub Example()
    Dim myArr() As Variant
    myArr = Selection.Value

    For i = LBound(myArr, 1) To UBound(myArr, 1)
        For j = LBound(myArr, 2) To UBound(myArr, 2)
            myArr(i, j) = myArr(i, j) + 5
            Debug.Print CStr(i) & "_" & CStr(j) & ": " & myArr(i, j)
        Next j
    Next i

    Selection = myArr
End Sub

将范围传递给处理函数:

Sub TestMain()
    Selection = TestProcess(Selection)
End Sub

Function TestProcess(userRange As Range) As Variant
    Dim result() As Variant

    result = userRange.Value

    For i = LBound(result, 1) To UBound(result, 1)
        For j = LBound(result, 2) To UBound(result, 2)
            result(i, j) = result(i, j) + 5
            Debug.Print CStr(i) & "_" & CStr(j) & ": " & result(i, j)
        Next j
    Next i

    TestProcess = result
End Function

答案 1 :(得分:0)

这就是你想做的事情:

Public Sub ProcessRange(ByRef r As Range)
    Dim vals() As Variant
    vals = r.Value
    Dim rows As Integer, cols As Integer
    rows = r.rows.Count: cols = r.Columns.Count
    Dim x As Double
    x = WorksheetFunction.Average(vals)
    ' 3.66666
End Sub
SCR

中被ProcessRange Range("B4").Resize(3, 3)调用时