简体   繁体   中英

Excel VBA - Range.Copy Increasing filesize and causing slowdowns

From the title my problem may sound obvious, but hear me out.

I'm working on a spreadsheet that tracks sick days for employees and its laid out with the rows being employee name and the columns being each day of the year.

I'm working on a macro that shifts the data back by one month allowing for new data to be entered. My current order of operations is to copy the data (2nd month to last month) and move it one month to the left, then clear the data in the last month. This photo might explain it better.

Due to this layout, I'm moving an array of data that is roughly 50 rows by 330 columns. So far I've been using the following code and functionality wise, it is working as intended:

(C1 to C8 are corner points of the calendar as illustrated in the photo)

Main subroutine:

'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

"Undo" subroutine:

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

The problem is every time the code is run, the file size gets bigger and the code runs slower. From what I'm aware of this type of Range.Copy does not require the "Application.CutCopyMode=False" flag and it did not seem to make a difference when I used it anyways.

The reason I'm using the copy function rather than the cut function is because I want to leave the formatting (borders, colors, etc) untouched at the very right of the calendar.

Would there be a better way of achieving my results, because right now it seems like there is some hidden data as a result of the code execution that's piling up somewhere I cant see.

Thanks to all the help I got from the answers to this post and some extra analysis of the spreadsheet I was working on, I believe I've found a way to achieve the desired results without the slowdown and file size increase I was experiencing. I figured it would be a good idea to post my results here in case anyone else faces the same problems.

The root problem causing the slowdown and file size increase was not the code itself but the way the spreadsheet itself was laid out, like @Absinthe suggested. There was conditional formatting rules in the data entry section of the calendar to color in dates that were weekends, holidays etc. The problems I was facing stemmed from the fact that the initial code in the original post was copying everything including the conditional formatting rules back 31 cells.

Since it looked like the copy command was overwriting data in the first month, I thought it would be redundant to delete the contents of that month, however the conditional formatting rules were just stacking on top of each other every time the code was run. This lead to a snowball effect since the number of conditional formatting rules in the starting months would increase exponentially. This did not strike me as being an issue, since I was not fully aware of how the formatting rules worked and was under the assumption that they were tied to a cell and would not be copied by the copy command.

To get around this issue, I used a combination of sheets.range.value=sheets.range.value and sheets.range.copy sheets.range.paste special xlPasteComments to result in the following code. (C1 to C8 are corner points of the calendar which is illustrated in the photo attached to the original post)

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

The with loops at the start and end is something that seems to speed up code by not updating the screen while the code is running.

I'm certain that this is very sloppy code, but in its current form it only copies the values and comments while leaving the conditional formatting rules untouched. I've tested running the subroutine a few dozen times and the execution time and file size don't change significantly from run to run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM