Excel - 字典对象的奇怪行为

时间:2017-01-24 05:26:13

标签: excel excel-vba excel-2010 vba

我遇到以下代码行的问题:

    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。我在" End Function"在RowMap中检查监视窗口中的rv和RowMap的计数。两个计数都应该是84。然而,只要我按F8将我带到主程序并检查DICT的计数,它就是85,而不是84.

DICT不应该与RowMap或rv完全相同吗?为什么DICT的计数增加1?哪一行代码可以做到这一点?我完全迷失了。

我不知道这些信息是否会有所帮助。上面的Set DICT行包含在"对于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

2 个答案:

答案 0 :(得分:0)

由于我没有足够的声誉,因此无法发表评论:

我想我以前见过这个,并怀疑它是调试的结果。您是否尝试在函数调用之后输出(例如msgboxRowMap.Count ,而不是在调试时检查以查看您获得的内容?

答案 1 :(得分:0)

以下是在使用词典时如果不小心使用“监视”窗口会发生什么情况的示例。

在模块中输入此代码,并按照指示设置中断和两个监视:

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

现在运行到休息并检查Watch窗口 - 即使你的代码仍在等待休息(并且&#34; C&#34;键尚未添加),你的字典已经空了&# 34; d&#34; slot(和count是 3 ,而不是2)。

enter image description here

即使您从代码中删除dict.Add "D", 4dict("D")上的监视仍会保留在监视窗口中(除非您主动删除它),并且会继续添加&#34;额外&#34 ;键...