2017-05-18 3 views
0

マクロ用のコードに問題があります。Excel用に作成しています。VBAのApplication.Matchでコレクションに項目が存在するかどうかをチェック

それは、具体的方法Application.Matchに関し、または代わりにApplication.WorksheetFunction.Match

私だけ含まれていると私はコレクションをクリート私は

Dim CompanyID() As String 
ReDim CompanyID(NumCO) 


For i = 1 To NumCO 
    CompanyID(i) = Worksheets("Sheet1").Cells(i, 1).Value 
Next i 

次にリスト内のすべての企業の名前を格納する文字列の配列を持っていますすべての異なる企業

Dim DifCO As New Collection, a 

On Error Resume Next 
For Each a In CompanyID 
    DifCO.Add a, a 
Next 

私のコードでは、後でもう一度cと関連付ける会社がコレクションDifCOに保存されている場所のインデックスが必要です。しかし、私は私のプログラムは、その行に何もすると私はMsgBoxにインデックスを印刷しようとしたが、MsgBoxが表示され、それはありませんそれを証明していないようApplication.Match

でそれを取得することができていませんエラーメッセージも送信しません。

For i to NumCO 
    MsgBox (Application.WorksheetFunction.Match(CompanyID(i), DifCO, 0)) 
Next i 

私はApplication.Matchを使用し、別の文字列の配列にコレクションの要素を移動するなど、さまざまなことを試してみましたが、結果は同じです。

私はステップバイステップのデバッグオプションでそれを観察しているので、コードループが正しく分かっています。しかし、私はこの問題になる可能性のあるアイデアがなくなったので、ここで私はこのコミュニティに尋ねています。

+1

「On Error GoTo 0」は、その上に「On Error Resume Next」があるコレクション作成ループの後に追加します。これがなければ、あなたのコードは喜んでエラーをスローするものを "スキップします"。 'Match'呼び出しを' Range'や配列の代わりに 'Collection'を使ってインクルードします。 –

+2

コレクションではMatch()を使用できません。代わりにあなたの配列をチェックしてみませんか? –

+0

マットありがとうございました、それは "スキッピング"を引き起こしていたもので、今修正されました。既に述べたように、Match()はコレクションでは機能しません。私はTImとDavidが提案したようにリストを配列に投げ捨てました!皆さん、ありがとうございました! –

答えて

2

MatがOPのコメントに示しているように、On Error GoTo 0なしでOn Error Resume Nextを使用したように見えるので、ハンドラはエラーを飲み込んでいて、表示されず、MsgBoxは表示されません。

デバッグするときには、非常に複雑なアプリケーションのお尻には痛みがありますが、すぐに問題のフラグを立ててしまいましたが、Break on All Errorsには便利なオプションがあります。 [ツール]> [オプション]> [一般の下でVBEで:

enter image description here

一般的に、あなたは非常に小さく、意図的なエラートラップを除きResume Nextを避けたいです。そのように開いたままにすると、コード内でさらにエラーが発生し、トラブルシューティングが困難になります(気づいたように!)。あなたの解決のために

、あなたは、次にArrayList

Dim list as Object 
Set list = CreateObject("System.Collections.ArrayList") 

For Each a In CompanyID 
    If Not list.Contains(a) Then list.Add(a) 
Next 

を使用ToArray方法を使用して、バリアント配列へArrayListをダンプし、その後Application.Matchでこれをテストすることによって、インデックスを取得することがあります。

Dim arr, foundAt 
arr = list.ToArray() 

For i = 1 To NumCO 
    foundAt = Application.Match(CompanyID(i), arr, 0) 
    If Not IsError(foundAt) Then 
     MsgBox foundAt 
    End If 
Next i 

それ以外の場合は、コレクションや配列からインデックスを取得する通常の方法は、項目に対する単純な強制反復です。これらの処理を行うためには、アドホック関数をスピンオフするのが最も良い方法ですより多くのループを使用してメインプロシージャを乱雑にするよりも:

Sub collExample() 
Dim c As New Collection 
c.Add "9" 
c.Add "14" 
c.Add "3" 
c.Add "15" 
c.Add "4" 
c.Add "3" 

Debug.Print colItmExists(c, "5")  '~~> False 
Debug.Print colItmExists(c, "10")  '~~> True 
Debug.Print colItmFirstIndex(c, "3") '~~> 3 
Debug.Print colItmFirstIndex(c, "17") '~~> -1 

End Sub 

Function colItmExists(col As Collection, itm) As Boolean 
    Dim i, ret As Boolean 
    For i = 1 To col.Count 
     If col(i) = itm Then 
      ret = True 
      Exit For 
     End If 
    Next 
    colItmExists = ret 
End Function 
Function colItmFirstIndex(col As Collection, itm) As Long 
    Dim ret As Long 
    If Not colItmExists(col, itm) Then 
     ret = -1 
    Else 
     For i = 1 To col.Count 
      If col(i) = itm Then 
       ret = i 
       Exit For 
      End If 
     Next 
    End If 
    colItmFirstIndex = ret 
End Function 
+0

こんにちはDavid Zemens、あなたは私がSOネットワークにいる理由です。あなたの答えはその時までずっと私を助けてくれてありがとうございます。あなたはVBA/excelに関する私のインスピレーションの一つです。別の良いアプローチ。 – Mertinc

+1

@Mertinc親切な言葉をありがとう! –

関連する問題