1

これは、私が他の誰かを助けようとして、困惑したときに始まりました。したがって、基本的には、列 B、C、および D に値があります。H2 と I2 に基準があり、H2 と I2 の基準が B と C で一致する場合、D に対応する回答があり、J2 に入力されます。基本的に 2 つの基準を持つ vlookup です。私はこのようなものを持っています。

Sub test()
Dim rngCrit1 As Range
Dim rngCrit2 As Range
Dim rngAnswer As Range
Dim strTarget As String

Set rngCrit1 = Range("H2")
Set rngCrit2 = Range("I2")
Set rngAnswer = Range("J2")


Range("B2").Select
strTarget = ActiveCell.Value

Do While strTarget <> ""
    With ActiveCell
        If strTarget = rngCrit1 Then
            If .Offset(0, 1).Value = rngCrit2 Then
            rngAnswer.Value = .Offset(0, 2)
        Else
    .Offset(1, 0).Select
    strTarget = ActiveCell.Value
    End If
    End If
    End With
Loop



End Sub

今、これはクラッシュするだけで、デバッグも何もありません。私は独学なので、ここのどこかで犬をねじ込んだと確信しています。

*これは、私自身の関心を満たすためのものであり、それほど重要ではないことに注意してください.5分以上かかる場合は、私よりも必要な人を助けてください.

Val1    Val2    Val3                Crit1   Crit2   Answer
a           r   12              g       v        22
b           r   14                      
c           s   15                      
d           s    16                     
e           t    18                     
f           t   19                      
g           y   20                      
g           v   22                      

サンプルデータ

4

3 に答える 3

3

VBA のスキルを向上させようとしているのは素晴らしいことです。あなたが書いたマクロを改善するために私が最初に提案したいことは、.Select. 範囲オブジェクトを直接操作します。例えば:

Range("B2").Select
strTarget = ActiveCell.Value

になる

strTarget = Range("B2").Value

また、一般に、「空の」値をチェックする場合は、 の代わりにvbNullStringorを使用します。プログラムがクラッシュする理由については、. のように、ほとんどの場合 (これは間違いなく) 避けるべきです。を更新しても、それはステートメントのスコープ内にあるため、ステートメントを閉じると ( )、これらの変更は取り消されます (マクロをステップ実行して、 と の値を監視することをお勧めします) 。これは当てはまらないかもしれませんが、他の変数にも当てはまることはわかっています。そのため、ステートメントで値を再割り当てすることを避けていますLen(variable)=0""WithSelectActiveCellWithEnd WithActiveCellstrTargetActiveCellWithWith

とにかく、次のコードを追加して、ループを次のように書き直します。

Dim r as range
set r = Range("B2") 'keep in mind this range is on the ActiveSheet, so you're better
                'off explicitly naming the Sheet e.g. Sheet1.Range("B2")

strTarget1 = Range("B2").Value
strTarget2 = Range("C2").Value

Do While Len(strTarget) <> 0
    If strTarget1 = rngCrit1 Then
      If strTarget2 = rngCrit2 Then
        rngAnswer.Value = r.Offset(0,2)
        Exit Do
      End If
    End If

    set r = r.Offset(1,0)
    strTarget1 = r.Value
    strTarget2 = r.Offset(0,1).Value
Loop

Long行のカウンターを使用してループし、その行のさまざまな列の値に対して を呼び出すこともできることに注意してください (範囲オブジェクトとを使用する代わりにi)Sheet1.Cells(i,1).ValueSheet1.Cells(i,2).Value.Offset

編集:コードを実行した後、クラッシュの理由はIfステートメントによるものです。とにかく次のセルに行きたい。を削除し、ステートメントを の前にElse置きます。2 つの列が基準を満たしている場合にループを停止するため、2 番目の代入ステートメントの後に を追加します。これも表示するようにコードを更新しました。End IfSelectExit DoIf

于 2012-05-25T18:37:25.700 に答える
1

INDEXおよびMATCH、またはSUMPRODUCTは、このためにうまく機能する傾向があります。前者の例:

http://support.microsoft.com/kb/59482
于 2012-05-25T01:40:59.087 に答える
1

val1 と val2 が一意であることを保証できる場合 (たとえば、g & v を検索する場合、g と v を含む行は 1 行しかない場合)、sumif
を使用できます。そしてE、Fへの検索とGの答え、そして
=SUMIFS(C2:C9,A2:A9,E2,B2:B9,F2)
もちろんこの式を思いつきました.val3が数値でない場合、または探している文字を含む行が複数ある場合、これは失敗します

于 2012-05-25T15:34:14.073 に答える