I have an Excel sheet which looks at performance figures for a rolling 5 week period. I created a macro which copies the data from week 4 to week 5 and repeats for each work sheet before leaving week 1 empty so I can paste in the most recent data.
The macro is slow and seems to get slower every week. To try to make it faster I put in code to clear the existing contents before pasting in the new data. This worked at first, but it has slowed again.
This is the code for the first two sheets to be copied. It does the same for the rest of the sheets but the code is the same.
Sub Move_data() ' Copies all data across to advance sheet by one week.
Application.ScreenUpdating = False
Sheets("Week 5").Select ' Clears current entry from week 5
Range("A1:S161").Select
Application.CutCopyMode = False
Selection.ClearContents
Sheets("Week 4").Select 'Selects data to copy from week 4
Range("A1:S161").Select
Selection.Copy
Sheets("Week 5").Select 'Pastes data to week 5
Range("A1").Select
ActiveSheet.Paste
Sheets("Week 4").Select 'Clears data from week 4
Application.CutCopyMode = False
Selection.ClearContents
Sheets("Week 3").Select 'Selects data to copy from week 3
Range("A1:S161").Select
Selection.Copy
Sheets("Week 4").Select 'Pastes data to week 4
Range("A1").Select
ActiveSheet.Paste
Having looked at various articles I think that part of the problem lies in using ".Select" so frequently.
I tried to replace these two lines:
Range("A1:S161").Select
Selection.Copy
with
Range("AR:S161").Copy
It didn't seem to have much impact on the time it takes for the macro to run.
How could this code work more efficiently?
If you are only interested in moving the values from one sheet to another then Value Transfer is ideal solution since it's more efficient than copy/paste. However, if you also need to copy formulas from one sheet to the next then you will need to switch to Copy/Paste.
Sub Mover()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim i As Long
For i = 5 To 1 Step -1
wb.Sheets("Week " & i).Range("A1:S161").ClearContents
If i <> 1 Then
wb.Sheets("Week " & i - 1).Range("A1:S161").Copy
wb.Sheets("Week " & i).Range("A1").PasteSpecial xlPasteAll
End If
Next i
End Sub
Try this:
Sub Move_data() ' Copies all data across to advance sheet by one week.
Const RNG As String = "A1:S161"
Dim n As Long
For n = 5 to 2 step - 1
Sheets("Weeek " & n).Range(RNG).Value = Sheets("Weeek " & (n-1)).Range(RNG).Value
Next n
End Sub
Assigning values directly is often faster.
Related
I am using a macro to pull data from 4 tabs into one tab. When the data pulls over, there are several hundred rows of zero's that I am trying to delete. The main issue I am running into and can't figure out is that the number of rows varies virtually every time I pull it, so if I use a row (like 1570:1570 in the second scenario) below I miss some data or delete some date. If I identify and run (as in the first scenario) the loop takes FOREVER to run. I have used both codes below, with reasons why I don't like them. Any help is appreciated (I am a TOTAL newbie to VBA btw).
-This is scenario 1 which takes so long to loop (usually around 8K-10K rows of data) And scenario 2 as follows: -This is scenario 2 which works quickly, but either deletes valid data or doesn't delete all rows with 0's. As you will be able to tell, this one I did recording the macro as I did it in excel.
Application.CutCopyMode = False
Dim wbkX As Workbook
Dim wksX As Worksheet
Set wbkX = ActiveWorkbook
Set wksX = wbkX.Worksheets("Merge")
lRow = wksX.UsedRange.Rows.Count
lCol = wksX.UsedRange.Columns.Count
wksX.Range(Cells(1, 1), Cells(1, lCol)).AutoFilter Field:=1
For x = 1 To lRow 'Loop's through every row from 1 to Last Row.
If wksX.Cells(x, 1).Value = 0 Then
wksX.Rows(x).Delete
x = x - 1
End If
Next x
Sub DeleteZeros()
' DeleteZeros Macro
ActiveSheet.Range("$A$1:$G$27997").AutoFilter Field:=1, Criteria1:="0"
Rows("1571:1571").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Range("A1").Select
ActiveSheet.Range("$A$1:$G$6277").AutoFilter Field:=1
End Sub
Good afternoon,
After too many hours of researching the proper code for what I am trying to do, I am finally having to ask the experts here. I am terribly new to VBA (but now hooked on conquering it!).
I am trying to copy a range of 3 cells of data I enter daily (I enter the data into columns J:L), then paste it 7 times, every 7th row below (so, I am copy/pasting Monday data to the next 7 Mondays, in their respective rows below). Each day changes, and so will the paste location (Tuesday data will be copied, then pasted to the next 7 Tuesday rows below, etc.). The data I enter will always be columns J:L.
Then, once the data is pasted, I have a button in place that uses that data, and clears it. So, columns J:L are always clear, until I add the data to the next row of 3 cells.
Any help is appreciated, as I am simply stumped. I tried several variations of "lastrow", but haven't found the proper coding that works for me (from piecing together info from here, but failing to make it work).
I tried to add a snapshot here, but apparently, I'm too noob for that even :/
The idea seems simple, so hopefully there will be a simple solution.
Thank you for your awesomeness!
Edited (sorry for making my first run at this site so difficult :/ )
Sub CopyPaste()
'
' CopyPaste Macro
' copies and pastes range for 8 total weeks
'
Dim lastrow As Long
lastrow = Range("J" & Rows.Count).End(xlUp).Row
'
Selection.Copy
Range("J27").Select
ActiveSheet.Paste
Range("J34").Select
ActiveSheet.Paste
Range("J41").Select
ActiveSheet.Paste
Range("J48").Select
ActiveSheet.Paste
Range("J55").Select
ActiveSheet.Paste
Range("J62").Select
ActiveSheet.Paste
Range("J69").Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
See if this helps. I foresee a problem though in that once you have copied values down the worksheet for say Monday, the last used row will be row 70 or something like that.
Sub x()
Dim i As Long, lastrow As Long
lastrow = Range("J" & Rows.Count).End(xlUp).Row
For i = 1 To 7
Cells(lastrow, "J").Resize(, 3).Offset(7 * i).Value = Cells(lastrow, "J").Resize(, 3).Value
Next i
End Sub
I hope someone can help me, as I know that the macro I am trying to create would save about 30 minutes' work if it comes off.
Once a month I download a financial transactions report; the search variables I need to use are in column C. The number of rows for each search variable changes from month to month. I need to search for all rows containing a given variable (e.g. VDEN, VDEM VDEF; these are exact search terms), copy all rows containing the variable and paste them into a one of five workbooks, each with several worksheets in it.
I have some code to do this with one term and one worksheet location, but I don't know how to loop it so that it goes back for a new variable and starts the whole process all over again.
This is what I have already:
Sub Macro2()
Workbooks.Open Filename:="C:\Users\jo\Desktop\Month End.xlsx"
Columns("A:L").Select
Selection.EntireColumn.Hidden = False
Application.DisplayAlerts = False
Cells.Find("Total:").Rows(1).EntireRow.Delete
Application.DisplayAlerts = True
Dim lastrow As Long
lastrow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "A").End(xlUp).Row
With ActiveSheet.Range("a1:l" & lastrow)
.AutoFilter Field:=3, Criteria1:="VDEN"
.Offset(1, 0).Copy
End With
Workbooks.Open Filename:="X:\admin\Finance\2016-17\Transaction Lists\Sample Transactions 2016-17.xlsx"
Windows("Month End.xlsx").Activate
Windows("Sample Transactions 2016-17.xlsx").Activate
Sheets("Pre-Sessional").Select
Columns("A:L").Select
Selection.EntireColumn.Hidden = False
Windows("Sample Transactions 2016-17.xlsx").Activate
Worksheets("Pre-Sessional").Activate
Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
Range("D:D,F:F,G:G,H:H,K:K").Select
Selection.EntireColumn.Hidden = True
Windows("Month End.xlsx").Activate
ActiveSheet.ShowAllData
End Sub
Can anybody help?
Many thanks
Look at the OR clause in your filter. I'd suggest recording doing a multiple selection filter, like this And Or Criteria about 2/3 down. Or use a for next loop on an array. Like so Looping Array
I've got a excel workbook that has a macro written. It takes information from one sheet and pastes it to another. However each month the data range changes. Currently tracking a 12 month roll. So current month is Feb we use data from Feb 2014 - Jan 2015.
That being said there is the current date on both sheets. Is there a way to add to my pre-existing macro to paste it into the correct cells that line up with the correct date range. Or to take the data 12 lines and paste it into the other sheet on the current month range?
Sub Paste_to_UnitProfile()
'
' Paste_to_UnitProfile Macro
'
'
Range("D2:D13").Select
Selection.Copy
ActiveWindow.ScrollWorkbookTabs Position:=xlFirst
Sheets("Unit Profile").Select
Range("G151").Select
ActiveSheet.Paste
End Sub
I'm adding the INDEX/MATCH that I tried to use on this but I'm new to this and I'm sure there's something small that I'm goofing up on:
=INDEX(PS250-'1EngineHours'!D2:D13,MATCH(E151,UnitProfile!G151:G170,0))
I'ld add this to the start to get the first last row to read from and the first row to write to.
i = 1
Do Until IsEmpty(Cells(i, 4).Value)
i = i + 1
Loop
StartRead = i - 12
EndRead = i - 1
i = 9
Do Until Sheets("Unit profile").Cells(i, 4).Value = Sheets("Unit profile").Cells(5, 2).Value
i = i + 1
Loop
StartWrite = i
Then just change the paste code to:
Range(Cells(StartRead, 4), Cells(EndRead, 4)).Select
Selection.Copy
ActiveWindow.ScrollWorkbookTabs Position:=xlFirst
Sheets("Unit Profile").Select
Cells(StartWrite, 5).Select
ActiveSheet.Paste
I'ld also add to the start:
Application.ScreenUpdating = False
And then to the end:
Application.CutCopyMode = False
Application.ScreenUpdating = True
Just to make it a bit neater
I am trying to find a way to streamline a very repetitive task.
This is the first time I am trying to build a proper macro, so things are confusing for me.
Below is an attempt to make it work.
Sub test()
Dim r As Range, j As Integer
Set r = Range("A2:C500")
Do
Sheets("Sheet1").Range(r.Offset(1, 0)).Select
Selection.Copy
Sheets("Sheet1").Select
Range("D2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("D2:F494")
Range("D2:F494").Select
ActiveWorkbook.SaveAs Filename = j, FileFormat:=xlUnicodeText, _
CreateBackup:=False
If r.Offset(1, 0) = "" Then Exit Do
Loop
End Sub
I am trying to
- copy Row A2:C2 from Sheet 3
- paste it into D2 of Sheet 1
- drag that value all the way down to the end of Sheet 1
- Save Sheet 1 as text file (any file name is fine. I was trying to save as 1, 2, 3, and so on.)
- Then go to the next row of Sheet 3 (A3:C3) and repeat the process until it reaches the last row, A500:C500.
When I recorded the macro for just the first row, it looked as follows:
Sheets("Sheet3").Select
Range("A2:C2").Select
Selection.Copy
Sheets("Sheet1").Select
Range("D2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("D2:F494")
Range("D2:F494").Select
ActiveWorkbook.SaveAs Filename:= _
"D:\Users\XXX\Desktop\XXX. XX\1.txt", FileFormat:=xlUnicodeText, _
CreateBackup:=False
ANY help would be greatly appreciated!
It's not clear what you want to do. Sounds like you are saying you want to copy a row (or some cells in a row) from one sheet to a particular single cell on another sheet and then export that sheet to a text file. This seems strange. Why not just write a macro to get all the data you want and directly write it to file in the first place? Do you just want all the data from all rows of the first three columns of "sheet3" exported to a file? Or is there boilerplate stuff in the other parts of "sheet1" that you want to be in every on of these text files?
Or do you want to create 500 text files, each with a row from sheet3?
You are saving the ActiveWorkbook so it won't save the sheets as individual files. You need to create a new workbook for each set of data using Workbooks.Add, then save and close each of these new workbooks once you've copied the data.
(A Worksheet has a SaveAs method, but it doesn't work - it doesn't save an individual sheet from a workbook.)
You can fill the entire area using Paste or PasteSpecial without having to fill it down:
Worksheets("Sheet3").Range("A2:C2").Copy
Worksheets("Sheet1").Range("D2:F494").PasteSpecial xlValues
Application.CutCopyMode = False
I'm afraid the recorder will only get you so far, and you'll need to study and modify the code that it creates.