危机:对账宏-Excel 2010每次都挂起

危机:对账宏-Excel 2010每次都挂起,excel,vba,crash,excel-2010,Excel,Vba,Crash,Excel 2010,晚上好 两个月前,我开始在Excel2010中开发一个宏,目的是协调两组不同的信息。我在一个月前搁置了这个项目,到那时,宏可以毫无怨言地仔细阅读每一行信息 几天前,我恢复了我在项目中的工作,我实现了一些非常小的长数组的使用,以包含符合特定条件的行的位置。现在,每当我试图运行宏时,Excel总是挂在我身上,这让我感到毛骨悚然。只要我不做得太快,一步一步地完成代码是没有任何问题的,但是一旦我让它自己运行,它就会崩溃。状态栏更新是主循环的一部分,它告诉我宏在停止响应之前处理了大约1%的行 这是一个令人

晚上好

两个月前,我开始在Excel2010中开发一个宏,目的是协调两组不同的信息。我在一个月前搁置了这个项目,到那时,宏可以毫无怨言地仔细阅读每一行信息

几天前,我恢复了我在项目中的工作,我实现了一些非常小的长数组的使用,以包含符合特定条件的行的位置。现在,每当我试图运行宏时,Excel总是挂在我身上,这让我感到毛骨悚然。只要我不做得太快,一步一步地完成代码是没有任何问题的,但是一旦我让它自己运行,它就会崩溃。状态栏更新是主循环的一部分,它告诉我宏在停止响应之前处理了大约1%的行

这是一个令人难以置信的令人沮丧的问题,因为据我所知,它根本不应该发生,而且一定是由于Excel在处理大量数据时受到了一些限制。也许它把我的循环解释为无限循环

有一个超拱形循环,它运行在两个数据集中的一个数据集中,它包含第二个循环,该循环运行在第二个数据集中相对较小的部分,以查找匹配项。在崩溃发生之前,宏能够处理大约11倍于我现在使用的数据集大小的数据集。将数据集的当前大小减小到上述默认值的10%左右仍然会导致宏使Excel挂起,但有趣的是,它能够处理11%的数据。从中得出的合理结论是,数据集中的某个地方有一段实际数据,不知何故导致Excel挂起,但1):如果是这种情况,我预计会出现一条错误消息,2)在构成1%的数据集附近检查数据集,没有导致任何异常发现

所以我转向你。我真诚地希望你能提出一些建议,看看是什么导致了这一问题,以及我如何尝试解决它

下面是有问题的子过程:

我一直在想,如果把它分成几个子过程,是否会使Excel更容易理解,从而解决我的问题?如果是这样,如果有人能向我解释原因,我将不胜感激

我想我应该提到一件重要的事情:在我实现阵列的小用途之前,我之前写过,宏能够处理比当前数据集大11倍的数据集,没有任何问题。但这只是在我添加了DoEvents的定期执行(每次状态栏更新时)之后;在此之前,Excel将像现在一样挂起

Sub MainRecon()

Dim row_MSPS As Long, row_FPMS As Long, rowStart_FPMS As Long, rowEnd_FPMS As Long, row_FPMS_lastMatch As Long
Dim row_midFPMS As Long, row_midMSPS As Long, IMO_Number As Long, size_MSPS As Long, row_MSPS_next As Long
Dim n_matches As Integer, I_sup As Integer, temp_FPMS_Row As Long

Dim match_Array() As Long
Dim supreme_match_Array() As Long: ReDim supreme_match_Array(30)
Dim IMO_FPMS_Pos_Array() As Long: ReDim IMO_FPMS_Pos_Array(30)

Dim row_first_FPMS As Integer, I As Integer, IMO_matches As Integer, supreme_Size As Integer

Dim order_no_FPMS As String

Dim match As Boolean, quantity_MSPS As Boolean, IMO_next_match As Boolean, stock_update As Boolean
Dim MSPS_duplicate As Boolean, FPMS_noMatches As Boolean, empty_FPMS As Boolean

Dim deliveryDate_MSPS As Date, deliveryDate_FPMS As Date, deliveryDate_MSPS_next As Date


row_MSPS = 2
row_FPMS = 2

row_midFPMS = 3
row_midMSPS = 3

size_MSPS = 2

'Index for supreme match array.
I_sup = 0

Do While MSPS_RawWS.Cells(size_MSPS, 1) <> ""
    size_MSPS = size_MSPS + 1
Loop


MainProcedure:
Do While MSPS_RawWS.Cells(row_MSPS, 1) <> "" 'Stops at the end of the records

    'Boolean variables defined
    empty_FPMS = False
    match = False
    quantity_MSPS = False
    IMO_next_match = False
    stock_update = False
    FPMS_noMatches = False

    If IsNumeric(Left(MSPS_RawWS.Cells(row_MSPS, 7), 2)) = True _
        And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS, 7), 4, 2)) = True _
        And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS, 7), 7, 4)) = True Then 'Confirms date format DD-MM-YYYY of 'Time for Bunker' of MSPS

        'Crew updated stock by reporting a new delivery instead of following proper procedure.
        'Stock-Delivery difference smaller than 60 will be picked up as a stock update
        'as well as delivery quantities under 10 [mt]
        If ((60 > Abs(MSPS_RawWS.Cells(row_MSPS, 6) - MSPS_RawWS.Cells(row_MSPS, 8)) And _
            Abs(MSPS_RawWS.Cells(row_MSPS, 6) - MSPS_RawWS.Cells(row_MSPS, 8)) >= 0) Or (0 < MSPS_RawWS.Cells(row_MSPS, 8) And MSPS_RawWS.Cells(row_MSPS, 8) <= 10)) And _
            (MSPS_RawWS.Cells(row_MSPS, 6) + MSPS_RawWS.Cells(row_MSPS, 8) > 0) Then

                    MSPS_RawWS.Range("A" & row_MSPS, "H" & row_MSPS).Copy
                    mid_ReportWS.Cells(row_midMSPS, 11).PasteSpecial

                    mid_ReportWS.Cells(row_midMSPS, 9) = "Error 40. Updated stock reported as delivery."

                    row_midMSPS = row_midMSPS + 1
                    row_midFPMS = row_midFPMS + 1

                    Call UpdateProgress("", 4, row_MSPS, size_MSPS)


        Else 'Proceed if it passes the stock update check

            Call UpdateProgress("", 4, row_MSPS, size_MSPS)

            quantity_MSPS = False

            If MSPS_RawWS.Cells(row_MSPS, 8) > 0 Then 'If MSPS quantity is above 0, proceed

            quantity_MSPS = True

                If IsNumeric(Left(MSPS_RawWS.Cells(row_MSPS, 7), 2)) = True _
                And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS, 7), 4, 2)) = True _
                And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS, 7), 7, 4)) = True Then 'Confirms date format DD-MM-YYYY

                deliveryDate_MSPS = Left(MSPS_RawWS.Cells(row_MSPS, 7), 10) 'Cuts away HH:MM:SS
                IMO_Number = MSPS_RawWS.Cells(row_MSPS, 2)

                'Finds the next MSPS record with quantity and date.
                row_MSPS_next = row_MSPS + 1
                Do While (MSPS_RawWS.Cells(row_MSPS_next, 7) = "" Or Not MSPS_RawWS.Cells(row_MSPS_next, 8) > 0) And row_MSPS_next <= size_MSPS _
                And Not (IsNumeric(Left(MSPS_RawWS.Cells(row_MSPS_next, 7), 2)) = True _
                And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS_next, 7), 4, 2)) = True _
                And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS_next, 7), 7, 4)) = True)

                    row_MSPS_next = row_MSPS_next + 1

                Loop


                'Checks if the next MSPS record has an IMO that matches the current one, and gets the date of the next record
                IMO_next_match = False
                If IMO_Number = MSPS_RawWS.Cells(row_MSPS_next, 2) And (IsNumeric(Left(MSPS_RawWS.Cells(row_MSPS_next, 7), 2)) = True _
                And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS_next, 7), 4, 2)) = True _
                And IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS_next, 7), 7, 4)) = True) And MSPS_RawWS.Cells(row_MSPS_next, 8) > 0 Then

                    deliveryDate_MSPS_next = Left(MSPS_RawWS.Cells(row_MSPS_next, 7), 10)
                    IMO_next_match = True

                End If

                'Checks if the MSPS record is a duplicate
                If IMO_next_match = True And deliveryDate_MSPS = deliveryDate_MSPS_next And _
                MSPS_RawWS.Cells(row_MSPS, 8) = MSPS_RawWS.Cells(row_MSPS_next, 8) Then

                            MSPS_RawWS.Range("A" & row_MSPS, "H" & row_MSPS).Copy
                            mid_ReportWS.Cells(row_midMSPS, 11).Paste

                            mid_ReportWS.Cells(row_midMSPS, 9) = "Duplicate entry."

                            row_midMSPS = row_midMSPS + 1
                            row_midFPMS = row_midFPMS + 1

                            Call UpdateProgress("", 4, row_MSPS, size_MSPS)

                            row_MSPS = row_MSPS + 1

                            'Proceed prematurely to the next iteration in the all-encompassing 'Do While'-loop
                            'if the current MSPS-record is a duplicate
                            GoTo MainProcedure
                End If

                match = False
                row_first_FPMS = 0

                    Do While IsEmpty(FPMS_RawWS.Cells(row_FPMS, 1)) = False And (IMO_Number > FPMS_RawWS.Cells(row_FPMS, 1) _
                    Or IMO_Number = FPMS_RawWS.Cells(row_FPMS, 1)) 'Search for FPMS records with matching IMO number

                        If IMO_Number = FPMS_RawWS.Cells(row_FPMS, 1) Then

                            If row_first_FPMS > 0 Then
                                If FPMS_RawWS.Cells(row_first_FPMS, 1) <> FPMS_RawWS.Cells(row_FPMS, 1) Then

                                    row_first_FPMS = row_FPMS 'This is the very first of the matching FPMS records
                                    'For use later in connection with the arrays.

                                End If

                            Else

                                row_first_FPMS = row_FPMS

                            End If


                            If deliveryDate_MSPS = FPMS_RawWS.Cells(row_FPMS, 5) Or deliveryDate_MSPS = FPMS_RawWS.Cells(row_FPMS, 5) - 1 Or deliveryDate_MSPS = FPMS_RawWS.Cells(row_FPMS, 5) + 1 Then

                                match = True

                                Exit Do

                            End If
                        End If

                        row_FPMS = row_FPMS + 1

                    Loop

                If match = True Then

                'The following array will contain the location (row) of all FPMS records matching the current MSPS record
                ReDim match_Array(30)

                match_Array(0) = row_FPMS
                n_matches = 1

                row_FPMS_lastMatch = row_FPMS
                order_no_FPMS = FPMS_RawWS.Cells(row_FPMS, 4)

                rowStart_FPMS = row_FPMS 'Multiple entries can exist in FPMS for a single entry in MSPS. This is the lower boundary

                row_FPMS = row_FPMS + 1

                Do While IMO_Number = FPMS_RawWS.Cells(row_FPMS, 1)

                    'The FPMS order numbers are made up of 8 ciphers: XXXXXXXN
                    'The 7 first ciphers are used to tie orders together. MSPS usually has a single entry for all FPMS
                    'entries under XXXXXXX.
                    If Left(order_no_FPMS, 7) = Left(FPMS_RawWS.Cells(row_FPMS, 4), 7) And order_no_FPMS = FPMS_RawWS.Cells(row_FPMS, 4) Then

                        match_Array(n_matches) = row_FPMS
                        n_matches = n_matches + 1

                        row_FPMS = row_FPMS + 1

                    ElseIf deliveryDate_MSPS = FPMS_RawWS.Cells(row_FPMS, 5) Or deliveryDate_MSPS = FPMS_RawWS.Cells(row_FPMS, 5) - 1 Or deliveryDate_MSPS = FPMS_RawWS.Cells(row_FPMS, 5) + 1 Then

                        match_Array(n_matches) = row_FPMS
                        n_matches = n_matches + 1

                        row_FPMS = row_FPMS + 1

                        'If the next valid MSPS record is on the date after the current one, and the next FPMS record is as well, exit loop
                        If IMO_next_match = True And deliveryDate_MSPS_next = FPMS_RawWS.Cells(row_FPMS, 5) Then

                            Exit Do

                        End If

                    End If
                    Loop

                    'Upper boundary of range.
                    rowEnd_FPMS = row_FPMS - 1

                    If n_matches = 1 Then

                        FPMS_RawWS.Range("A" & match_Array(0), "H" & match_Array(0)).Copy
                        mid_ReportWS.Cells(row_midFPMS, 1).PasteSpecial

                        MSPS_RawWS.Range("A" & row_MSPS, "H" & row_MSPS).Copy
                        mid_ReportWS.Cells(row_midMSPS, 11).PasteSpecial

                    ElseIf n_matches > 1 Then

                        For I = 0 To n_matches - 1

                            FPMS_RawWS.Range("A" & match_Array(I), "H" & match_Array(I)).Copy
                            mid_ReportWS.Range("A" & row_midFPMS + I).PasteSpecial

                        Next I

                        MSPS_RawWS.Range("A" & row_MSPS, "H" & row_MSPS).Copy
                        mid_ReportWS.Range("K" & row_midMSPS).PasteSpecial

                    End If

                    'Next free rows in mid-report
                    row_midMSPS = row_midMSPS + n_matches
                    row_midFPMS = row_midFPMS + n_matches

                    'The supreme_match_Array contains the row-position of all FPMS records that have been matched with an MSPS partner
                    'Empty the contents of the match_Array into the supreme array.
                    'The match_Array is recycled for every MSPS record - not every IMO number.

                    I = 0

                    Do Until match_Array(I) = 0

                        supreme_match_Array(I_sup) = match_Array(I)

                        I_sup = I_sup + 1
                        I = I + 1

                    Loop


                    'When the next MSPS record has a different IMO number than the current one, check supreme_match_Array against IMO_FPMS_Pos_Array
                    'to find out which FPMS records have not been paired with their MSPS counterparties, and copy these to the mid-report.
                    If IMO_next_match = False Then

                        temp_FPMS_Row = row_first_FPMS

                        IMO_matches = 0

                        'Find position of all FPMS records with matching IMO, and save this
                        Do While IMO_Number = FPMS_RawWS.Cells(temp_FPMS_Row, 1)

                            IMO_matches = IMO_matches + 1

                            IMO_FPMS_Pos_Array(IMO_matches - 1) = temp_FPMS_Row

                            temp_FPMS_Row = temp_FPMS_Row + 1

                        Loop

                        supreme_Size = 0

                        Do While supreme_match_Array(supreme_Size) > 0 'Find size of array

                            supreme_Size = supreme_Size + 1

                        Loop


                        For I = 0 To IMO_matches - 1

                            For I_sup = 0 To supreme_Size - 1

                                If IMO_FPMS_Pos_Array(I) = supreme_match_Array(I_sup) Then

                                    IMO_FPMS_Pos_Array(I) = 0
                                    GoTo NextIteration_I

                                End If

                            Next I_sup
NextIteration_I:
                        Next I

                        For I = 0 To IMO_matches - 1

                            If IMO_FPMS_Pos_Array(I) > 0 Then

                                FPMS_RawWS.Range("A" & IMO_FPMS_Pos_Array(I), "H" & IMO_FPMS_Pos_Array(I)).Copy
                                mid_ReportWS.Cells(row_midFPMS, 1).PasteSpecial

                                mid_ReportWS.Cells(row_midFPMS, 9).Hyperlinks.Add Anchor:=mid_ReportWS.Cells(row_midFPMS, 9), Address:="", SubAddress:= _
                               "'MSPS Raw'!A" & row_MSPS & ":R" & row_MSPS, TextToDisplay:="FPMS missing MSPS counter."


'                                Cells(row_midFPMS, 9).Select
'                                ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:="", SubAddress:= _
'                                "'MSPS Raw'!A" & row_MSPS & ":R" & row_MSPS, TextToDisplay:="FPMS missing MSPS counter."

                                row_midFPMS = row_midFPMS + 1

                                FPMS_noMatches = True

                            End If

                        Next I

                        If FPMS_noMatches = True Then

                            'Next free rows in mid-report
                            row_midMSPS = row_midFPMS

                            FPMS_noMatches = False

                        End If

                        'The supreme array should be purged since we are moving on to another IMO-number
                        ReDim supreme_match_Array(30)
                        I_sup = 0

                    End If

            ElseIf quantity_MSPS = True Then


                        Sheets("MSPS Raw").Activate
                        Range("A" & row_MSPS, "H" & row_MSPS).Copy
                        Sheets("Mid-Report").Activate
                        Cells(row_midMSPS, 11).Select
                        ActiveSheet.Paste

                        'Cells(row_midMSPS, 9) = "MSPS missing partner."

                        Cells(row_midMSPS, 9).Select
                        ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:="", SubAddress:= _
                        "'FPMS Raw'!A" & row_FPMS_lastMatch & ":R" & row_FPMS_lastMatch, TextToDisplay:="MSPS missing partner."

                        row_midMSPS = row_midMSPS + 1
                        row_midFPMS = row_midFPMS + 1

                        row_FPMS = row_FPMS_lastMatch + 1


            End If 'Match check
            End If 'Date check
            End If 'Quantity > 0 check
    End If 'Error 40: Stock Update
    End If 'Date format check

    row_MSPS = row_MSPS + 1

Loop

End Sub
Sub main recon()
Dim row_MSP为长,row_FPMS为长,row START_FPMS为长,rowEnd_FPMS为长,row_FPMS_lastMatch为长
Dim row_midFPMS为长,row_midMSPS为长,IMO_编号为长,size_MSPS为长,row_MSPS为长
Dim n_匹配为整数,I_sup匹配为整数,temp_FPMS_行匹配为长
Dim match_数组()的长度为
Dim supreme_match_Array()长度:ReDim supreme_match_Array(30)
Dim IMO_FPMS_Pos_数组()长度:ReDim IMO_FPMS_Pos_数组(30)
Dim row_first_FPMS为整数,I为整数,IMO_matches为整数,supreme_Size为整数
Dim订单\u无\u FPMS作为字符串
尺寸匹配为布尔值,数量匹配为布尔值,IMO\U next\U匹配为布尔值,库存更新为布尔值
Dim MSPS_duplicate为布尔值,FPMS_noMatches为布尔值,empty_FPMS为布尔值
Dim deliveryDate_MSPS作为日期,deliveryDate_FPMS作为日期,deliveryDate_MSPS_next作为日期
行\u MSPS=2
第二行FPMS=2
row_midFPMS=3
行\u midMSPS=3
大小\u MSPS=2
'最高匹配数组的索引。
I_sup=0
在MSPS_RawWS.Cells(大小为1)时执行”
大小\u MSPS=大小\u MSPS+1
环
主要程序:
当MSPS_RawWS.Cells(行_MSPS,1)“”在记录末尾停止时执行此操作
'已定义布尔变量
空\u FPMS=假
匹配=错误
数量\u MSPS=错误
IMO\u next\u match=False
股票更新=False
FPMS_noMatches=错误
如果IsNumeric(左(MSPS_RawWS.Cells(行MSPS,7),2))=True_
和IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS,7),4,2))=True_
和IsNumeric(Mid(MSPS_RawWS.Cells(row_MSPS,7),7,4))=True然后“确认MSP的“存储库时间”的日期格式DD-MM-YYYY
“机组人员通过报告新的交付而不是按照正确的程序更新库存。
“库存交付差异小于60将作为库存更新进行提取
以及10吨以下的交货数量
如果((60>Abs(MSPS_-RawWS.Cells(row_-MSPS,6)-MSPS_-RawWS.Cells(row_-MSPS,8))和_
Abs(MSPS_RawWS.Cells(row_MSPS,6)-MSPS_RawWS.Cells(row_MSPS,8))>=0)或(0