运行时错误“7”:移动列时内存不足

提前感谢任何和所有的帮助。 我的macros的这部分应该做的是移动一些“关键”列。 我试图以尽可能less的内存密集的方式来实现这一点。 而不是削减列和插入他们,我做了以下。 为什么我会陷入一个荒谬的内存不足错误呢? 这甚至不是很多数据。 目前,Excel正在占用大约3.3GB的内存。

任何build议清理我的代码?

'Moves Critical Columns' Sheets("A").Select Application.CutCopyMode = False Columns("H").Insert XlDirection.xlToRight Columns("H").Value = Columns("X").Value Columns("X").Delete Sheets("B").Select Application.CutCopyMode = False Columns("H").Insert XlDirection.xlToRight Columns("H").Value = Columns("X").Value Columns("X").Delete Sheets("C").Select Application.CutCopyMode = False Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("AA").Value Columns("F").Value = Columns("Z").Value Columns("Z").Delete Columns("Z").Delete Sheets("D").Select Application.CutCopyMode = False Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("AA").Value Columns("F").Value = Columns("Z").Value Columns("Z").Delete Columns("Z").Delete Sheets("E").Select Application.CutCopyMode = False Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("AG").Value Columns("AG").Delete Sheets("F").Select Application.CutCopyMode = False Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("AG").Value Columns("AG").Delete Sheets("G").Select Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("AT").Value Columns("F").Value = Columns("AU").Value Columns("AU").Delete Columns("AU").Delete Sheets("H").Select Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("AT").Value Columns("F").Value = Columns("AU").Value Columns("AU").Delete Columns("AU").Delete Sheets("I").Select Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("T").Value Columns("F").Value = Columns("BT").Value Columns("G").Value = Columns("BU").Value Columns("BU").Delete Columns("BU").Delete Columns("BU").Delete Sheets("J").Select Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("T").Value Columns("F").Value = Columns("BT").Value Columns("G").Value = Columns("BU").Value Columns("BU").Delete Columns("BU").Delete Columns("BU").Delete Sheets("K").Select Columns("E").Insert XlDirection.xlToRight Columns("E").Insert XlDirection.xlToRight Columns("E").Value = Columns("BS").Value Columns("F").Value = Columns("BA").Value Columns("BA").Delete Columns("BA").Delete 

DoEVENTS行可能会帮助 – 把它放在一个数组中,并运行DoEvents将工作或将其放在每一列之间。

简单来说,它允许操作系统在你的代码运行之间完成它的工作 – 我发现将它插入更长或更长的运行代码往往会帮助解决内存不足错误。

https://msdn.microsoft.com/zh-cn/library/office/gg264522.aspx有关DoEvents的更多信息

按照@ASH提供的解决scheme中的build议,剪切和插入是非常高效的,因为它不复制格式。 相反,它使用在目标上find的格式,无论是从插入的列的右侧还是左侧。 如果这是一个问题,这意味着单元格格式必须从源代码复制,下面的代码提供了一个替代scheme。

 Sub MoveColumn(Ws As Worksheet, _ Targets As String, _ Sources As String) ' insert columns specified by "Targets" ' copy contents of "Sources" to the inserted columns ' and delete the "Sources" columns Dim SourceRange As Range Dim TargetRange As Range Dim ClmCount As Integer With Ws.UsedRange Set SourceRange = .Columns(Sources) Set TargetRange = .Columns(Targets) ClmCount = TargetRange.Columns.Count If ClmCount < SourceRange.Columns.Count Then MsgBox "The number of columns specified as 'Source'" & vbCr & _ "exceeds the available space in the specified" & vbCr & _ "'Target' range.", vbCritical, "Invalid specification" Exit Sub End If .Columns(Targets).Insert Shift:=xlToRight Set TargetRange = .Cells(1, TargetRange.Column - ClmCount) SourceRange.Copy TargetRange.PasteSpecial Application.CutCopyMode = False SourceRange.Delete Shift:=xlToLeft End With End Sub 

这个子可以处理单个列或任意数量的相邻列。 这是将代替原始代码中第一批列移动的代码示例。 请注意, ActiveSheet的使用是危险的(您的原始代码是这样做的),因为在查看代码时很容易忘记哪个表是活动的。

Private Sub TestMove()Application.ScreenUpdating = False MoveColumn ActiveSheet,“E:F”,“AT:AU”Application.ScreenUpdating = True End Sub

第二批需要两个过程调用,因为列不是连续的。 将这个批次添加到调用过程后,它看起来像这样:

 Private Sub TestMove() Application.ScreenUpdating = False MoveColumn ActiveSheet, "E:F", "AT:AU" MoveColumn Sheets("I"), "E:F", "BT:BU" MoveColumn Sheets("I"), "E", "T" Application.ScreenUpdating = True End Sub 

我不确定这是否会消除你遇到的内存问题,因为我无法复制它,这可能是由于你的环境中的东西。 但是,尝试限制您的工作UsedRange ,并使用“剪切插入”技术,而不是copy/insert/paste/delete

以下代码中的例程moveColumn就是这样做的。 分解常见任务并简化代码总是很好的。 请注意, moveColumn可用于同时移动多个邻居列; 但是如果他们的顺序会改变,在这种情况下,你需要逐一移动它们(从移动到最左边的位置开始)。

最后,代码执行过程中不需要Select任何东西,这也是麻烦的根源。 考虑到这一切,你的代码可以写成如下:

 Sub MoveCriticalColumns() moveColumn Sheets("A"), "X", "H" moveColumn Sheets("B"), "X", "H" moveColumn Sheets("C"), "AA", "E" moveColumn Sheets("C"), "Z", "F" moveColumn Sheets("D"), "AA", "E" moveColumn Sheets("D"), "Z", "F" moveColumn Sheets("E"), "AG", "E" moveColumn Sheets("F"), "AG", "E" moveColumn Sheets("G"), "AT:AU", "E:F" ' in one operation moveColumn Sheets("H"), "AT:AU", "E:F" ' in one operation moveColumn Sheets("I"), "T", "E" moveColumn Sheets("I"), "BT:BU", "F:G" ' in one operation moveColumn Sheets("J"), "T", "E" moveColumn Sheets("I"), "BT:BU", "F:G" ' in one operation moveColumn Sheets("K"), "BS", "E" moveColumn Sheets("K"), "BA", "F" End Sub Sub moveColumn(sh As Worksheet, oldPosition As String, newPosition As String) With sh.UsedRange .Columns(oldPosition).Cut .Columns(newPosition).Insert Shift:=xlToRight End With End Sub