2017-07-19 25 views
0

仕事のために、私はいくつかの事前に書き込まれたVBAコードを調整する必要があります。しかし、私はむしろ初心者なので、私にとってはかなり挑戦的です。Excel VBA:多次元配列の最小1次元を取得

コードは、ターゲットと呼ばれる2次元配列を作成します。それは、(可変数の)KPIと、各KPIの10年間の値(固定数)に及んでいます。例:

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ライン(1次元配列)あたりの最小を計算するために必要。

私の醜い作業コード:kは正しいKPIに指示され
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、:)またはターゲット(k、0〜9))

ボーナスの質問:これらの配列内の値の中にはtbdのようにゼロがあります。それらは最低から除外されるはずです。したがって、最小>ゼロが必要です。あなたもそれを理解できますか?

おそらく超簡単です。しかし、私はそれを動作させるように見えることはできません。

ありがとうございます!

+0

https:// stackoverflow。com/questions/7031416/return-index-of-an-element-in-an-array-excel-vba/7031744#7031744 –

答えて

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 

EDIT

を作り直して、それをテストしました。これはあなたのニーズに合わせて調整するのに十分なものです。

+0

これは機能しますが、時間はO(n^2)です。別のソート(quicksortやmergesortのような)を実装して、プロセスを大幅に高速化してみてください。 – Jsleshem

+0

@Jsleshem私はとてもシンプルなもののためにあまりにも複雑になるつもりはありませんでした。彼は配列を使って作業していたと言いました.... –

+0

フェア、私は理解します – Jsleshem

0

この

(例えば、あなたがValueを使用してワークシートの範囲から得るかもしれないような)2次元配列を考えると、あなたがアプリケーションを使用することができますゼロを除くに関するご質問の後半部分に対処しますが...ありませんReturn Index of an Element in an Array Excel VBA

:このアプローチのパフォーマンスはしかし一種の悪いことは注目に値する

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 

:.INDEXは、その配列の「スライス」を取得します

0

配列のサイズが大きすぎる場合、これは非常に遅いことがわかります。 Evaluateメソッドを使用して各行の最小値を返します。しかし、これらのターゲット値を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 

これが役に立ちます。