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

ここにいくつかの実際のタイミングがあります。これは、「ループの回避」が必ずしも探している勝利とは限らない理由を理解するためです。

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 で、ルーチンはその値を 2 つの異なる場所で見つけました。配列から 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

2番目の答え

この回答では、不規則またはギザギザの配列を使用しました。不規則な配列では、各行に異なる数の列を含めることができます。私の行はすべて同じ長さですが、コードを大幅に変更しなくても長さが異なる可能性があります。

Test固定サイズのバリアント配列として定義しました。動的にすることも簡単にできます。

バリアント、またはバリアント配列の要素は、配列にすることができます。の各要素をTest5 つの要素配列に設定しました。

ループは、各行の最小値を文字列として表示します: 5 4 3 2 13 26 6 8 22 37.

各列の最小値を求めましたが、それを達成するアプローチ (VBA ループ以外) は考えられません。このアプローチが気に入った場合は、列を最初の次元にし、行を 2 番目の次元にする必要があります。

注: 不規則配列の要素にアクセスするための構文は異なります。それは:

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 に答える