0

我需要一些帮助来找到我的 10x10 矩阵的每一列中的最小值。我的矩阵没有显示在电子表格中,所以我不能使用 worksheetfunction.min(cells(1,j),cells(10,j)) 例如。

另外,我想将包含最小值的单元格旁边的单元格替换为空白。

谢谢您的帮助

干杯

for j=1 to n worst=application.worksheetfunction.min(c(1,j),c(2,j),c(3,j),c(4,j),c(5,j),c(6,j),c(7,j),c(8,j),c(9,j),c(10,j)) next j

此代码运行良好,但如果我想更改矩阵的维度,它会导致问题。

4

4 回答 4

1

UBound(c, 2)将为您提供数组中的列数。

所以你的代码看起来像这样(根据Doc Brown的回答构建):

For j = LBound(c, 2) To UBound(c, 2) ' columns
  worst = c(1, j)
  For i = LBound(c) To UBound(c) ' rows
    If c(i, j) < worst Then
      worst = c(i, j)
    End If
  Next i
  ' do something with 'worst' here
Next j
于 2012-08-04T11:18:14.943 回答
0

示例 VBA 代码(未经测试,只是在我的脑海中):

for j=1 to n
 worst=c(1,j) 
 for i = 2 to 10  ' replace 10 by any other value you like
     if c(i,j)< worst then worst=c(i,j)
 next i
next j
于 2012-08-04T08:41:17.337 回答
0

以下是一些实际的时间安排,以便您了解为什么“避免循环”并不总是您正在寻找的胜利:

Sub Tester()
    Const NUM_REPS As Long = 10000
    Dim arr(1 To 10, 1 To 10)
    Dim r As Integer, c As Integer, t, l As Long, v, worst

    For r = 1 To 10
        For c = 1 To 10
            arr(r, c) = Rnd() * 10
        Next c
    Next r

    'worst (~5-6 sec)
    t = Timer
    For l = 1 To NUM_REPS
        worst = arr(1, 1)
        For c = 1 To 10
            v = Application.Min(Application.Index(arr, 0, c))
            If v < worst Then worst = v
        Next c
    Next l
    Debug.Print worst, Timer - t

    'better (0.4sec)
    t = Timer
    For l = 1 To NUM_REPS
        worst = Application.Min(arr)
    Next l
    Debug.Print worst, Timer - t

    '###best### (~0.05 sec)
    t = Timer
    worst = arr(1, 1)
    For l = 1 To NUM_REPS
        For r = 1 To 10
            For c = 1 To 10
                v = arr(r, c)
                If v < worst Then worst = v
            Next c
        Next r
    Next l
    Debug.Print worst, Timer - t

End Sub
于 2012-08-05T19:16:31.797 回答
0

第一个答案

这是我的第一个答案。我没有仔细阅读你的问题,也没有注意到你想要每列的最小值。我留下了这个答案,因为它可能仍然有价值。

一些工作表函数适用于数组。试试下面的代码。

最初,Test2 中的最小值是 1,而例程在两个不同的位置发现了该值。我从数组中删除了 1 并在最后添加了 51。然后该例程找到了 2。

我没有为这个程序计时,但如果它不比 VBA 快,我会感到惊讶。

Option Explicit
Sub Try()

  Dim InxT11 As Long
  Dim InxT12 As Long
  Dim InxT2 As Long

  Dim Test1(1 To 10, 1 To 5) As Long
  Dim Test2() As Variant

  Test2 = Array(5, 20, 27, 30, 45, 50, 4, 15, 32, 33, 47, 49, 3, 11, 12, _
                21, 34, 40, 2, 10, 13, 18, 19, 24, 25, 26, 36, 42, 43, 44, _
                6, 7, 17, 31, 39, 41, 8, 9, 14, 16, 22, 23, 28, 29, 35, 37, _
                38, 46, 48, 51)

  InxT2 = LBound(Test2)
  For InxT11 = LBound(Test1, 1) To UBound(Test1, 1)
    For InxT12 = LBound(Test1, 2) To UBound(Test1, 2)
      Test1(InxT11, InxT12) = Test2(InxT2)
      InxT2 = InxT2 + 1
    Next
  Next

  Debug.Print WorksheetFunction.Min(Test1)

End Sub

第二个答案

对于这个答案,我使用了参差不齐或参差不齐的数组。对于参差不齐的数组,每行可以有不同数量的列。我所有的行都是相同的长度,但它们可能是不同的长度,而代码没有显着变化。

我已经定义Test为一个固定大小的变体数组。它也可以很容易地成为动态的。

变体或变体数组的元素可以是数组。我已将每个元素设置Test为一个五元素数组。

循环将每行的最小值显示为字符串:5 4 3 2 13 26 6 8 22 37。

您要求每列的最小值,但我想不出一种方法(除了 VBA 循环)可以实现这一点。如果您喜欢这种方法,则必须将列设为第一个维度,将行设为第二个维度。

注意:访问不规则数组元素的语法是不同的。这是:

Debug.Print Test(InxD1)(InxD2)

希望这可以帮助。

Option Explicit
Sub Try2()

  Dim InxT As Long

  Dim Test(1 To 10) As Variant

  Test(1) = Array(5, 20, 27, 30, 45)
  Test(2) = Array(50, 4, 15, 32, 33)
  Test(3) = Array(47, 49, 3, 11, 12)
  Test(4) = Array(21, 34, 40, 2, 10)
  Test(5) = Array(13, 18, 19, 24, 25)
  Test(6) = Array(26, 36, 42, 43, 44)
  Test(7) = Array(6, 7, 17, 31, 39)
  Test(8) = Array(41, 8, 9, 14, 16)
  Test(9) = Array(22, 23, 28, 29, 35)
  Test(10) = Array(37, 38, 46, 48, 51)

  For InxT = LBound(Test) To UBound(Test)
    Debug.Print WorksheetFunction.Min(Test(InxT)) & " ";
  Next
  Debug.Print

  Debug.Print Test(1)(2)

End Sub
于 2012-08-04T17:53:35.810 回答