【问题标题】:Excel VBA - Range.Copy Increasing filesize and causing slowdownsExcel VBA - Range.Copy 增加文件大小并导致速度变慢
【发布时间】:2019-03-19 18:26:32
【问题描述】:

从标题来看,我的问题可能听起来很明显,但请听我说完。

我正在制作一个电子表格,用于跟踪员工的病假,其布局为员工姓名,列是一年中的每一天。

我正在开发一个宏,它将数据向后移动一个月,以便输入新数据。我目前的操作顺序是复制数据(第2个月到上个月)并将其向左移动一个月,然后清除上个月的数据。这个photo 可能会更好地解释它。

由于这种布局,我正在移动一个大约 50 行 x 330 列的数据数组。到目前为止,我一直在明智地使用以下代码和功能,它按预期工作:

(图中C1到C8是日历的角点)

主子程序:

'Copying entire calender into undo tab for the undo subroutine to use
Sheets(1).Range(C1 & ":" & C8).Copy Sheets(5).Range(C1)

'Moving the "moving zone" months 31 cells to the left
Sheets(1).Range(C2 & ":" & C8).Copy Sheets(1).Range(C1)

'Clearing the last month to make room for new information
Sheets(1).Range(C3 & ":" & C8).ClearContents
Sheets(1).Range(C3 & ":" & C8).ClearComments

“撤消”子程序:

'Copies information from undo tab back into sheet 1
Sheets(5).Range(C1 & ":" & C8).Copy Sheets(1).Range(C1)

问题是每次运行代码时,文件都会变大,代码运行速度会变慢。据我所知,这种类型的 Range.Copy 不需要“Application.CutCopyMode=False”标志,而且在我使用它时似乎并没有什么不同。

我使用复制功能而不是剪切功能的原因是因为我想保留日历最右侧的格式(边框、颜色等)不变。

是否有更好的方法来实现我的结果,因为现在似乎有一些隐藏的数据是代码执行的结果,这些数据堆积在我看不到的地方。

【问题讨论】:

  • 欢迎来到 SO。您的代码看起来不错,我怀疑问题出在其他地方。还有更多代码吗?文件大小增加了多少?您是否尝试过通常的消肿技巧?例如techrepublic.com/blog/microsoft-office/…
  • 为什么不为每个新月插入(使用 CopyOrigin:=xlFormatFromRightOrBelow)31 个新列?
  • @Absinthe 感谢您的欢迎!这是我的大部分代码......我有几行额外的代码首先将所有内容复制到一个单独的选项卡中以供我的“撤消”代码使用。文件大小最初从 100kb 左右开始,当它开始爬行停止时达到 300-400kb。不仅代码变慢,整个电子表格也很难使用。
  • 最好发布所有代码,以防万一 - 很多时候问题是由看起来不相关的代码部分引起的。工作簿中有很多公式吗?关闭自动计算有帮助吗?你使用的是 xlsm 还是 xls 文件格式?
  • @user11217663 电子表格本身是由其他人创建的,其中包含许多令我头疼的公式,因此我尽量避免过多地弄乱布局。据我了解,需要对过去一年的病假进行统计,因此我的想法是将数据改组一个月而不是插入新列。

标签: excel vba range move


【解决方案1】:

感谢我从这篇文章的答案中获得的所有帮助,以及对我正在处理的电子表格的一些额外分析,我相信我已经找到了一种方法来实现预期的结果,而不会减慢和增加文件大小经历。我认为将我的结果发布在这里是个好主意,以防其他人面临同样的问题。

导致速度变慢和文件大小增加的根本问题不是代码本身,而是电子表格本身的布局方式,就像@Absinthe 建议的那样。日历的数据输入部分有条件格式规则,可以为周末、节假日等日期着色。我面临的问题源于原始帖子中的初始代码正在复制包括条件格式规则在内的所有内容31 个细胞。

由于看起来复制命令在第一个月覆盖了数据,我认为删除该月的内容是多余的,但是条件格式规则只是在每次代码时堆叠在一起跑。这会导致滚雪球效应,因为开始月份的条件格式规则的数量会呈指数增长。这并没有让我觉得这是个问题,因为我并不完全了解格式化规则是如何工作的,并且假设它们被绑定到一个单元格并且不会被复制命令复制。

为了解决这个问题,我使用了sheets.range.value=sheets.range.valuesheets.range.copy sheets.range.paste special xlPasteComments 的组合来生成以下代码。 (C1到C8是日历的角点,如原帖所附照片所示)

With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With

'Copying entire calender into undo tab for the undo subroutine to use
Sheets(4).Range(C1 & ":" & C8).ClearContents
Sheets(4).Range(C1 & ":" & C8).ClearComments
Sheets(4).Range(C1 & ":" & C8).Value = Sheets(1).Range(C1 & ":" & C8).Value
Sheets(1).Range(C1 & ":" & C8).Copy
Sheets(4).Range(C1).PasteSpecial xlPasteComments
Application.CutCopyMode = False

'Moving the "moving zone" months 31 cells to the left
Sheets(1).Range(C1 & ":" & C6).ClearContents
Sheets(1).Range(C1 & ":" & C6).ClearComments
Sheets(1).Range(C2 & ":" & C8).Copy
Sheets(1).Range(C1).PasteSpecial xlPasteValues
Sheets(1).Range(C2 & ":" & C8).Copy
Sheets(1).Range(C1).PasteSpecial xlPasteComments
Application.CutCopyMode = False

'Clearing the last month to make room for new information
Sheets(1).Range(C3 & ":" & C8).ClearContents
Sheets(1).Range(C3 & ":" & C8).ClearComments

With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With

开始和结束处的 with 循环似乎通过在代码运行时不更新屏幕来加速代码。

我确信这是非常草率的代码,但在当前形式下,它只复制值和 cmets,而条件格式规则不受影响。我已经测试了运行该子程序几十次,每次运行的执行时间和文件大小没有显着变化。

【讨论】:

    猜你喜欢
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    相关资源
    最近更新 更多