【问题标题】:how to find minimum value of each column in a 10x10 matrix vba excel如何在10x10矩阵vba excel中找到每列的最小值
【发布时间】:2012-08-04 08:20:35
【问题描述】:

我需要一些帮助来找到我的 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

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

【问题讨论】:

  • 为了获得更好的帮助,您应该解释 what you have tried 以及您遇到的问题,例如通过显示无法按预期工作的代码。
  • My matrix is not displayed in the spreadsheet -- 这是什么意思? Cells 属性可以访问每个工作表上的每个单元格,即使该单元格是隐藏的。 i want to replace the cell next to the cell which contains the minimum value as blank. 我们需要查看样本输入和预期输出。
  • 你试过只使用Application.Min(c) - 没有用吗?

标签: excel vba


【解决方案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

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

    • 有什么方法可以做到不循环?谢谢你的回复:)
    • @user1525225:在纯 VBA 中?我不这么认为。为什么?
    • 因为当我将此代码与 worksheetfunction.min 进行比较时,使用循环运行我的模拟需要更长的时间..
    • @user1525225:您测量了它还是只是胡乱猜测?您的原始代码必须检查该列的所有十个值,就像我的一样。我预计不会有任何显着的性能差异。
    • 我用计时器测量它。可能是因为我运行它进行了 10,000 次模拟,所以它慢了大约 1 秒
    【解决方案3】:

    第一个答案

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

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

    最初 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
    

    【讨论】:

      【解决方案4】:

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

      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
      

      【讨论】:

        猜你喜欢
        • 2015-04-28
        • 2020-10-11
        • 2012-07-30
        • 2013-11-20
        • 2020-11-29
        • 2021-04-27
        • 2012-06-29
        • 2019-04-25
        • 1970-01-01
        相关资源
        最近更新 更多