2017-01-24 8 views
-1

私は、次のコード行に問題を抱えている:エクセル - 辞書オブジェクトの奇妙な行動

Set DICT = RowMap(Range(Workbooks("A").Sheets(1).Cells(ITEM_NO_ROW, _ 
ITEM_NO_COLUMN), Workbooks("A").Sheets(1).Cells(ITEM_NO_ROW + 1, ITEM_NO_COLUMN).End(xlDown))) 

このコードはRowMapを呼び出します。私は、RowMapの "End Function"にブレークを入れ、ウォッチウィンドウでrvとRowMapの数をチェックします。両方のカウントは、84でなければなりません。しかし、私がメインルーチンに連れて行って、DICTのカウントをチェックするF8を押すとすぐに、それは84でなく85です。

DICTはRowMapまたはrvとまったく同じであってはなりませんか?なぜDICTの数が1つ増えたのですか?どのコード行でそれができますか?私は完全に失われています。

この情報が役立つかどうかわかりません。上記のSet DICTラインは、 "For each in rng"ループで包まれ、DICTの最後に追加されるセルです。

ご協力いただきますようお願い申し上げます。

Function RowMap(rng1 As Range) As Object 
'store item no and price in dictionary 

    Dim rv As Object 
    Dim c As Range 
    Dim v As long 
    On Error Resume Next 

    Set rv = Nothing 

    Set rv = CreateObject("scripting.dictionary") 
    For Each c In rng1.Cells 
     v = c.Value 
     If Not rv.Exists(v) Then 
      rv.Add v, c.Offset(0, 4) 'add item no and price 
     Else 
      MsgBox "Duplicate value detected in " & Book_Name & "!" 
      Exit For 
     End If 
     Next c 

    Set RowMap = rv 

End Function 

For Each wk In Application.Workbooks 

    If Left(wk.Name, 6) = "All FE" Then 

     ERROR_Sheet_No = ERROR_Sheet_No + 1 

     For Each sh In wk.Sheets 

      Set Report_Last_Cell = sh.Cells(5000, 3).End(xlUp) 

      'sort the data by group code 
      Set rng = sh.Range(sh.Cells(4, 1), Report_Last_Cell.Offset(0, 4)) 

      rng.Sort key1:=sh.Cells(4, 4), order1:=xlAscending, Header:=xlNo 

      Set rng = sh.Range(sh.Cells(4, 3), Report_Last_Cell) 

      For Each cell In rng 
       If cell.Value <> "LAVENDER" And cell.Value <> "CLOSED" And cell.Value <> "VOID" And cell.Value <> "NO SALE" And _ 
        InStr(cell.Value, "DISCOUNT") = 0 And InStr(cell.Value, "DEPOSIT") = 0 And Len(cell) <> 0 Then 

        Group_Code = cell.Offset(0, 1).Value 

        If Group_Code <> Old_Group_Code Then 'open the PHOTO_QUOTE file 
         'close the old PHOTO_QUOTE file first 
         On Error Resume Next 
         Workbooks(File_Prefix & Old_Group_Code & ".xlsx").Close 
         On Error GoTo 0 

         'open the PHOTO QUOTE file if exists 
         If Len(Dir(Flower_Path & File_Prefix & Group_Code & ".xlsx")) <> 0 Then 'if file is found 
          Workbooks.Open Flower_Path & File_Prefix & Group_Code & ".xlsx" 

          Photo_Quote_Book_Name = File_Prefix & Group_Code & ".xlsx" 
          On Error Resume Next 
          DICT.RemoveAll 
          Set DICT = Nothing 

          Set DICT = RowMap(Range(Workbooks(Photo_Quote_Book_Name).Sheets(1).Cells(PHOTO_QUOTE_ITEM_NO_ROW, _ 
           PHOTO_QUOTE_ITEM_NO_COLUMN), Workbooks(Photo_Quote_Book_Name).Sheets(1).Cells(PHOTO_QUOTE_ITEM_NO_ROW + 1, PHOTO_QUOTE_ITEM_NO_COLUMN).End(xlDown))) 
          On Error GoTo 0 

          'check if ITEM NO exists 
          If Not DICT.Exists(cell.Value) Then 
           Copy_to_ERROR_sheet sh.Name, ERROR_Sheet_lastrow, 0, 0, 255 


          'check if price matches 
          ElseIf cell.Offset(0, 3).Value <> DICT(cell.Value) Then 
           Copy_to_ERROR_sheet sh.Name, ERROR_Sheet_lastrow, 0, 255, 0 
          End If 


         Else 'if the PHOTO_QUOTE file doesn't exist, copy shop, date, voucher no, item no, price to 
         ' ERROR_BOOK_NAME and change color to red 

          Copy_to_ERROR_sheet sh.Name, ERROR_Sheet_lastrow, 255, 0, 0 
         End If 'If Len(Dir(Flower_Path & File_Prefix & Group_Code & ".xlsx")) <> 0 Then 

         Old_Group_Code = Group_Code 
        End If ' If Group_Code <> Old_Group_Code Then 


       End If 'If cell.Value <> "LAVENDER" And cell.Value <> "CLOSED" And cell.Value <> "VOID" And cell.Value <> "NO SALE" And _ 
       InStr(cell.Value, "DISCOUNT") = 0 And InStr(cell.Value, "DEPOSIT") = 0 And Len(cell) <> 0 Then 

      Next 'For Each cell In rng 


     Next 'For Each sh In wk 

    End If 'If Left(wk.Name, 6) = "All FE" Then 

Next 'For Each wk In Application.Workbooks 

Close_PHOTO 

Application.Calculation = xlCalculationAutomatic 
Application.ScreenUpdating = True 

End Sub 'Check_Price 
+0

On Error Resume Nextが必要なものは何もありません。そのため、それを削除してエラーを知らせるようにします。呼び出し側のサブステップでカウントを取得している場所を正確に表示すると便利です。その手続きのいくつかの関連する行が役に立ちます –

+0

私はこのコードを実行していますが、テストではRowMapと 'DICT'、投稿されていないあなたのコードには何がありますか? 'rng1'の中に数値ではないものがありますか? –

+1

このコードには、型の不一致などのエラーが数多くある可能性がありますが、エラー値、ゼロ値と最高値のマージされたセル、キーの値としての範囲がカウントミスマッチであることは私が再現できないものです。 – cyboashu

答えて

0

ここでは、辞書を操作するときに[ウォッチ]ウィンドウを慎重に使用しない場合の例を示します。

モジュールにこのコードを入力し、指示に従ってブレークと2個の時計を設定します。

Sub Tester() 

    Dim dict As Object 
    Set dict = CreateObject("scripting.dictionary") 

    dict.Add "A", 1 
    dict.Add "B", 2 
    dict.Add "C", 3 '<<< put a break here 
    dict.Add "D", 4 

    Debug.Print dict("D") '<< put a watch on `dict("D")` 
    Debug.Print dict.Count '<< put a watch on `dict` 

End Sub 

は今休憩に実行し、ウォッチウィンドウを確認してください - あなたのコードはまだブレークを待っているにもかかわらず(と"C"キーはまだ追加されていません)、あなたの辞書にはすでに空の "D"スロットがあります(そして、カウントはで、2ではありません)。

enter image description here

あなたのコードからdict.Add "D", 4を削除しても、dict("D")上の時計が(あなたが積極的にそれを削除しない限り)ウォッチ・ウィンドウに留まり、その「エクストラ」キーを追加し続けるだろう...

0

私は十分な評判を持っていないとして、まだコメントすることはできません:

私は前にこれを見ていると思うと、それはデバッグの結果であると思います。デバッグ中に何が表示されたかを確認するのではなく、の後に出力(例:msgboxRowMap.Countを呼び出してみましたか?

+0

コメントありがとうございます。私はmsgboxを試しました、そして、それは84と言います。実際には、私はウォッチウィンドウ内の84の項目すべてを見ることができ、彼らは開いている別のファイルからのものであるべきです。だから、私はそれらをすべて見ることができます。 85番目のアイテムはそのファイルにはなく、rng1にはなく、RowMapでもrvでもありません。だからこそ私は単にF8を押して機能を終了し、DICTに1つの項目が追加された理由について困惑しています。 – joehua

+0

@ykyこれは説明です: [link] http://stackoverflow.com/questions/11400898/dictionary-object-adding-items-before-add-is-called – BoffWx

+0

ありがとう、Boffwx。私はあなたが答えを見つけたと思う。 – joehua