Excel VBA:在多维数组中获取最小1维

时间:2017-07-19 17:54:41

标签: arrays excel vba excel-vba

为了工作,我需要调整一些预先编写的VBA代码。但我相当初学者,因此对我来说非常具有挑战性。

代码创建一个名为Targets的2D数组。它跨越(可变数量)KPI,每个KPI跨越10年(固定数量)的值。 E.g:

KPI 1 year_1 year_2 ... year_10
KPI 2 year_1 year_2 ... year_10
............ ............ ....... ....... KPI n year_1 year_2 ... year_10

我现在需要计算每个KPI线的最小值(1D阵列)。

我丑陋的工作代码:
WorksheetFunction.Min(Targets(k, 0), Targets(k , 1), Targets(k, 2), Targets(k, 3), Targets(k , 4), Targets(k , 5), Targets(k, 6), Targets(k, 7), Targets(k, 8), Targets(k , 9))

其中k指向正确的KPI。

如何让它工作,以便它基本上占用整行,而不必将代码指向每个特定的单元格? (例如,目标(k,:)或目标(k,0到9))

额外问题:这些数组中的某些值为零,因为它们是tbd。应该将这些排除在最低限度之外。所以我需要最小值>零。你能想出来吗?

这可能非常简单。但我似乎无法使其发挥作用。

提前非常感谢!

3 个答案:

答案 0 :(得分:0)

Private Sub this()
    Dim Targets As Variant
    Dim minValuePerRow As String
    minValuePerRow = ""
    Targets = ThisWorkbook.Sheets("Sheet3").UsedRange
    For i = LBound(Targets, 1) To UBound(Targets, 1)
        For j = LBound(Targets, 2) To UBound(Targets, 2)
            If (Targets(i, j) <> 0 Or Targets(i, j) <> "") And minValuePerRow = "" Then minValuePerRow = Targets(i, j)
            If Targets(i, j) <> 0 And Targets(i, j) < minValuePerRow Then
                 minValuePerRow = Targets(i, j)
            End If
        Next j
        Debug.Print ; i
        Debug.Print ; minValuePerRow
        minValuePerRow = ""
    Next i
End Sub

修改

重做并测试过它。这应该足以帮助您适应您的需求。

答案 1 :(得分:0)

这并没有解决关于排除零的问题的第二部分,但是......

给定一个二维数组(例如您可能使用Value从工作表范围获得),您可以使用Application.Index来获得一个&#34;切片&#34;那个数组:

enter image description here

Sub Tester()

    Dim arr, slice
    arr = Range("A1:C3").Value

    'get a "row"
    slice = Application.Index(arr, 1, 0)
    Debug.Print Join(slice, "-") '>> 1-2-3

    'get a "column" (note use of Transpose here)
    slice = Application.Transpose(Application.Index(arr, 0, 1))
    Debug.Print Join(slice, "-") '>> 1-4-7
    'col 2...
    slice = Application.Transpose(Application.Index(arr, 0, 2))
    Debug.Print Join(slice, "-") '>> 2-5-8

    Debug.Print Application.Min(slice) '>> 2


End Sub

值得注意的是,这种方法的表现有点糟糕:Return Index of an Element in an Array Excel VBA

答案 2 :(得分:0)

如果数组太大,您会发现这个速度非常慢。它使用Evaluate方法返回每行的最小值。但是,您会注意到我已经包含了一个功能,可以使这些目标值可用于评估方法。此外,您会注意到目标是在模块级别声明的。

Dim Targets As Variant

Public Function Values() As Variant
    Values = Targets
End Function

Sub test()
    Dim i As Long

    Targets = Range("A1:J10").Value

    For i = LBound(Targets, 1) To UBound(Targets)
        Debug.Print Application.Evaluate("MIN(IF(INDEX(Values()," & i & ",0)>0,INDEX(Values()," & i & ",0)))")
    Next i
End Sub

希望这有帮助!