2015-11-06 102 views
0

一个宏(不是我的,但我“继承”它)运行多个循环。该代码有几千行,所以我只提供片段中循环的部分。随机'1004应用程序定义或对象定义的错误'/'1004范围类的PasteSpecial方法失败'

Dim repoLastRow As Integer, repoLastCol As Integer 
Worksheets("ATT_LEV").Activate 
With ActiveSheet 
    repoLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 
End With 
repoLastCol = ActiveSheet.Cells(3, Columns.Count).End(xlToLeft).Column 
Cells(repoLastRow + 1, 1).Value = xmlAgreement1 
Cells(repoLastRow + 1, 2).Value = repoLastRow + 1 
Cells(repoLastRow + 1, 5).Value = pubCurrCNID 

Cells(repoLastRow + 1, 4).Formula = "=IF(IFERROR(FIND(""MASTER"",'Import xml 0'!A2,1),0)>0,""MASTER"",IF(IFERROR(FIND(""ANNEX"",'Import xml 0'!A2,1),0)>0,""ANNEX"",""""))" 
Cells(repoLastRow + 1, 4).Value = Cells(repoLastRow + 1, 4).Value 

Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, repoLastCol)).Dirty 
For i = 5 To repoLastCol 
    column_letter = Split(Columns(i + 1).Address, ":")(0) 
    Cells(repoLastRow + 1, i + 1).Formula = "=IFERROR(IF(VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)=0,"""",VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,8,FALSE)),"""")" 
    Cells(repoLastRow + 1, i + 2).Formula = "=IFERROR(IF(VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)=0,"""",VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)),"""")" 
    i = i + 1 
Next i 
Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, 3)).Formula = "=CompareSingle!C1" 

Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, repoLastCol)).Value = _ 
Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, repoLastCol)).Value 

这是崩溃的具体部分。

Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, repoLastCol)).Value = _ 
Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, repoLastCol)).Value 

的事情是,这个特定的行给我的“1004应用程序定义或对象定义的错误”,但只有一对夫妇的循环迭代后,让40后的这么说了41次宏通过这部分代码,它只是打破。有时它几乎是完美循环的50倍,但最终总会崩溃 - 而且我从来没有超过50次循环。有时最终会导致完整的Excel冻结,但更多时候它只是一个调试器弹出窗口。有趣的是,如果我停止了宏并从它发生崩溃的循环中启动它,它将顺利地通过这个声明,并在经过另外几十次通过后再次破坏。然而,最有趣的是,它总是在整个宏中断行,尽管类似的模式(.value=.value)已成功应用于宏的其他部分(类似范围,类似表单,相似类型的数据)。

我想了马车部分的解决方法是以下几点:

Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, repoLastCol)).Copy 
Range(Cells(repoLastRow + 1, 3), Cells(repoLastRow + 1, 3)).PasteSpecial xlPasteValues 
Application.CutCopyMode = False 

而是我收到“1004 Range类的PasteSpecial方法失败”(当然,一段时间后,开始它的工作原理确定太)。也试过.Value2=.Value2,但同样的废话。

我提到,在停止宏并从最后一个正确的循环重新运行之后,它就会正常运行。这是真的,但在这一行崩溃后,Excel通常会变得对VBA调用没有响应,我只能在保存后退出并重新打开工作表。例如,Worksheet.Activate方法没有任何影响(没有任何反应,被调用的工作表没有被激活),或者Cells.Clear也不起作用,并呈现错误。重新打开工作簿后,一切恢复正常,我可以运行该程序。该宏存储在.xlsb(如果重要的话)是在Excel 2010中创建和运行的(最初位于.xlsm)。

任何人都可能有一个想法,为什么这会继续发生?为什么随机?

PS。我意识到代码可能未被优化(例如,您可能会选择使用的Worsksheet.Activate方法),但是,再次,这是我已经给予的工作,我宁可不重写代码,至少现在除非必要使它工作。

编辑

我已经解决了我的问题,至少部分。我所做的是细胞转换为已填充公式后,立即值,现在我可以一直循环下去:

For i = 5 To repoLastCol 
     column_letter = Split(Columns(i + 1).Address, ":")(0) 
     Cells(repoLastRow + 1, i + 1).Formula = "=IFERROR(IF(VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)=0,"""",VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,8,FALSE)),"""")" 
     Cells(repoLastRow + 1, i + 1).Value = Cells(repoLastRow + 1, i + 1).Value 
     Cells(repoLastRow + 1, i + 2).Formula = "=IFERROR(IF(VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)=0,"""",VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)),"""")" 
     Cells(repoLastRow + 1, i + 2).Value = Cells(repoLastRow + 1, i + 2).Value 
     i = i + 1 
    Next i 

我并不完全满意,这种解决方法,因为它仍然没有解释是什么导致的错误。您可能会发现它很有趣,但在最后几次运行中,错误发生在第40个循环(当然总是处于同一行)恰好为。当excel崩溃时(在某些场合),我试图用Visual Studio进行调试,并且一旦得到了有关VBE7.dll的问题信息。

有关问题性质的任何猜测?

+0

您现在可能会注意到,编码部分不显示粗体。哪一行产生错误? – Jeeped

+0

编辑器用**标记它。我的意思是:Range(Cells(repoLastRow + 1,3),Cells(repoLastRow + 1,repoLastCol))。Value = _ 范围(Cells(repoLastRow + 1,3),Cells(repoLastRow + 1,repoLastCol ))。值' –

+0

相关主题:您是否正在返回一个字符串或一个包含该'VLOOKUP(“&column_letter&”1&“&column_letter&”2,...'的数字?如果您期待一个字符串并且不想要一个零时,当你打一个空白有一个更好的方法,但不建议如果你期望一个数字返回。 – Jeeped

回答

0

你正确地引用父表,

With ActiveSheet 
    repoLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 
End With 

为什么要停止呢? With ... End With statement是分配(和维护)父级工作表的最大朋友。

不管整数听起来多酷多少,行号和列号分配应始终为Long而不是Integer

Dim repoLastRow As Long, repoLastCol As Long 

With Worksheets("ATT_LEV") 
    .Activate 
    repoLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 
    repoLastCol = .Cells(3, Columns.Count).End(xlToLeft).Column 

    .Cells(repoLastRow + 1, 1).Value = xmlAgreement1 
    .Cells(repoLastRow + 1, 2).Value = repoLastRow + 1 
    .Cells(repoLastRow + 1, 5).Value = pubCurrCNID 

    .Cells(repoLastRow + 1, 4).Formula = "=IF(IFERROR(FIND(""MASTER"",'Import xml 0'!A2,1),0)>0,""MASTER"",IF(IFERROR(FIND(""ANNEX"",'Import xml 0'!A2,1),0)>0,""ANNEX"",""""))" 
    .Cells(repoLastRow + 1, 4).Value = Cells(repoLastRow + 1, 4).Value 

    .Range(.Cells(repoLastRow + 1, 3), .Cells(repoLastRow + 1, repoLastCol)).Dirty 
    For i = 5 To repoLastCol 
     column_letter = Split(.Columns(i + 1).Address, ":")(0) 
     .Cells(repoLastRow + 1, i + 1).Formula = "=IFERROR(IF(VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)=0,"""",VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,8,FALSE)),"""")" 
     .Cells(repoLastRow + 1, i + 2).Formula = "=IFERROR(IF(VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)=0,"""",VLOOKUP(" & column_letter & "1&" & column_letter & "2,CompareSingle!$A:$I,9,FALSE)),"""")" 
     i = i + 1 
    Next i 
    .Range(.Cells(repoLastRow + 1, 3), .Cells(repoLastRow + 1, 3)).Formula = "=CompareSingle!C1" 

    .Range(.Cells(repoLastRow + 1, 3), .Cells(repoLastRow + 1, repoLastCol)) = _ 
     .Range(.Cells(repoLastRow + 1, 3), .Cells(repoLastRow + 1, repoLastCol)).Value 
End With 
+0

感谢你们,我个人是'With With End With'的坚定支持者,如果我是这个工具的原始开发者,我会使用它。这不仅是关于这个特定的代码块,还有更多的可以使用这个子句,但这对我来说太耗时了。至于行/列号,我会尝试'长',但为什么它会影响假设行/列不在'整数'范围之外? –

+0

这并不重要,如果是的话,错误将会不同。这只是一件你不用担心的事情,除非你在访问超出整数范围的行时故意要抛出错误。 – Jeeped

+0

同意这一点,这将是一个溢出eroor。但是,在宏的情况下,当前的'repoLastRow'是804,'repoLastCol'是1667,所以仍然有很多空间(对于循环的每次迭代,列依赖增加1)。此外,范围始终是一个1维数组,从列3到1667,所以不能明白为什么让Excel扼杀在这一个... –

相关问题