looping copy from multiple rows pasting them individually in the same row.... - excel

.....on a separate workbook indefinitely.
Hello First off I am new here and very new to VBA. I have a workbook that has a list that will grow indefinitely named "book1" and the code i pieced together grabs data from a range in that book and pastes it into another book "DMAutocalcs"in one specific row one at a time and the the code executes a refresh and wait time, after which it copy certain pricing date from a specific range in "DMautoCalcs" back into Book1. As of Now i am manually copying the code and modifying it for each range of calls it needs to transfer. so there in lies the issue, inherently it will be limited by the number of times i wish to copy what i have existing. I intend to modify the code to loop and perform the copy paste between the workbooks until it reaches an empty cell in "book1" however every attempt i have made has failed, it only continually works the same ranges over and over unless i manually copy the code and modify for each new line. i fear i do not fully understand the range rows and cell aspects when it comes to relatives and absolutes and the proper syntax on how to call the out accurately.
how do i achieve this? Any help would be appreciated.
Public Sub macro_54()
' Keyboard Shortcut: Ctrl+p
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
Workbooks.Open ("C:\Users\Legacy\Desktop\DMAutoCalcs.xlsm")
Windows("Book1.xlsm").Activate
Range("a2:l2").Select
Selection.Copy
Windows("DMAutoCalcs.xlsm").Activate
Range("a1:q1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Refresh
ActiveWorkbook.RefreshAll
Application.Wait (Now + TimeValue("0:00:03"))
ActiveWorkbook.RefreshAll
Windows("DMAutoCalcs.xlsm").Activate
Range("T2:x2").Select
'Application.CutCopyMode = False
Selection.Copy
Windows("Book1.xlsm").Activate
Range("M2:q2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' copy from calcs pricing info and past into pricelist
' return to pricelist
' Selects cell down 1 row from active cell.
'New Line
Windows("Book1.xlsm").Activate
Range("a3:l3").Select
Selection.Copy
Windows("DMAutoCalcs.xlsm").Activate
Range("a1:q1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' Refresh
ActiveWorkbook.RefreshAll
Application.Wait (Now + TimeValue("0:00:03"))
ActiveWorkbook.RefreshAll
Windows("DMAutoCalcs.xlsm").Activate
Range("T2:x2").Select
'Application.CutCopyMode = False
Selection.Copy
Windows("Book1.xlsm").Activate
Range("M3:q3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' copy from calcs pricing info and past into pricelist
' return to pricelist
' Selects cell down 1 row from active cell.
'New Line
Windows("Book1.xlsm").Activate
Range("a4:l4").Select
Selection.Copy
Windows("DMAutoCalcs.xlsm").Activate
Range("a1:q1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' Refresh
ActiveWorkbook.RefreshAll
Application.Wait (Now + TimeValue("0:00:03"))
ActiveWorkbook.RefreshAll
Windows("DMAutoCalcs.xlsm").Activate
Range("T2:x2").Select
'Application.CutCopyMode = False
Selection.Copy
Windows("Book1.xlsm").Activate
Range("M4:q4").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' copy from calcs pricing info and past into pricelist
' return to pricelist
'
' Selects cell down 1 row from active cell.
' And so on and so forth....
Windows("DMAutoCalcs.xlsm").Activate
ActiveWorkbook.Close savechanges:=False
Windows("Book1.xlsm").Activate
'Determine how many seconds code took to run
SecondsElapsed = Round(Timer - StartTime, 2)
'Notify user in seconds
MsgBox "All Ranges Updated, Calc sheet closed successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub

You need not to select or activate a range or window before copying and pasting. Below is the modified code from I can understand you.
Sub macro_54_Modified()
'Let your working sheets in Book1 and DMAutoCalcs are Sheet1 and Sheet2, respectively
Workbooks.Open "C:\Users\Legacy\Desktop\DMAutoCalcs.xlsm"
Dim wsDm As Worksheet, wsB1 As Worksheet, lastRow As Long, i As Long
Set wsB1 = Workbooks("Book1.xlsm").Sheets("Sheet1")
Set wsDm = Workbooks("DMAutoCalcs.xlsm").Sheets("Sheet2")
'Last row number in column A
lastRow = wsB1.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
wsB1.Range("A2:L2").Offset(i - 2).Copy wsDm.Range("a1:q1")
'VBA code for Refresh ... ?
wsDm.Range("T2:X2").Copy wsB1.Range("M2:q2").Offset(i - 2)
Next i
End Sub

Related

How do I exclude cells where the formula returns zero?

My file has four sheets.
From all of them, I want to copy and paste column A (from A:10) (which contains a concat formula) when some other rows are populated and then save into a csv.
All rows from A10 onwards have the concat formula which is then filled in depending on the other columns (the same applies for the other sheets).
I have it currently creating sheet1, and pasting there, then saving as a csv.
However, from the first sheet it looks at, it takes only the first line (but the second line - J11 (and so A11) are populated.
In the other sheets, it is copy and pasting the 2 rows that are populated, but also all the other rows as there are formulas there that return zero.
As I have the .End(xlDown) and technically all the other rows are populated.
I tried an IF statement for the last sheet only as a test, and currently it only copies the first populated line, and not the second (but at least it also doesn't copy all the other cells with zero).
Essentially, for each sheet I'd like to loop through with for example E10 is populated, copy and paste A10 into Sheet1, etc., if E10 is not zero.
Sub Output_test1()
'
' Output_test1 Macro
'
'
Sheets("Create").Select
Range("A10", Range("J10").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets.Add.Name = "Sheet1"
Sheets("Sheet1").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Assign").Select
Range("A10", Range("E10").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A1").End(xlDown).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Date & Time").Select
Range("A10", Range("E10").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A1").End(xlDown).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Event Type").Select
Dim rg As Range
For Each rg In Range("E10").End(xlDown)
If rg.Value > 0 Then
End If
Range("A10").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("A1").End(xlDown).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Application.CutCopyMode = False
Next
Sheets("Sheet1").Move
myTime = Format(Now, ("dd.mm.yy"))
ChDir "C:\Users\"
ActiveWorkbook.SaveAs Filename:= _
"Recruit_" & myTime & ".csv", FileFormat:=xlCSVUTF8, _
CreateBackup:=False
End Sub
There is no loop in your code not are you checking any values. I assumed you need to check column J in the source sheet and copy column A to the destination sheet.
This is a possible starting point:
k = 1
For i = 10 to 20
If Sheets("Source").Range("J" & i).Value = 0 then
Sheets("Destination").Range("A" & k).Value = Sheets("Source").Range("A" & i).Value
k = k + 1
End if
Next i
This only copies the value, not the formula. Not sure how much to explain, comment on the answer if any questions

Paste transposed data to new row

I am trying to create a form in excel in Sheet 1 (named Form) where the data copied from Sheet 1 (Form) is pasted to Sheet 2 (Data).
The form is vertical; however, the data is horizontal.
As such, I am using PasteSpecial.
When I use the macro button to paste and clear the data from the "Form" to the "Data", it is works for the first and second use. On the third use, the data is pasted on the second set of data rather than in a new row.
Sub Submit()
'
' Submit Macro
'
'
Range("C2:C14").Select
Selection.Copy
Sheets("Data").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
Range("A3").Select
Sheets("Form").Select
Application.CutCopyMode = False
Selection.ClearContents
Range("C2").Select
End Sub
Does this work?
Sub Submit()
Sheets("Form").Range("C2:C14").Copy
Sheets("Data").Range("A" & Rows.Count).End(xlUp)(2).PasteSpecial Paste:=xlPasteValues, Transpose:=True
End Sub
You can read this to find out how to avoid using Select/Activate.

How to repeat code to apply merged cell formatting to multiple rows?

I'm creating a button that will allow the user to add a new record to the very top of the list, and move all records one row below (to keep the newest records at the top). The code I've written works perfectly as-is. However, I have to write a lot of repeating code to apply it to all rows within the range. Here is my code:
Sub Test2()
' Stop screen from following macro actions & disable alerts
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' If more than 1 record, copy all rows and paste 1 row below, apply merged cell formatting, clear data from first row, and re-enable alerts/screen updating
If WorksheetFunction.CountA(Range("AM5:AN21")) > 1 Then
Range("CW28:DJ28").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("CW29:DJ29").Select
ActiveSheet.Paste
Range("CW28:DJ28").Select
Selection.Copy
Range("CW29").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
...
Range("CW1277").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("CW28:DJ28").Select
Selection.ClearContents
Range("CW28:CX28").Select
Application.DisplayAlerts = True
Application.ScreenUpdating = True
' If only 1 record, copy first row and paste 1 row below, apply merged cell formatting, clear data from first row, and re-enable alerts/screen updating
ElseIf WorksheetFunction.CountA(Range("AM5:AN21")) = 1 Then
Range("CW28:DJ28").Select
Selection.Copy
Range("CW29:DJ29").Select
ActiveSheet.Paste
Range("CW28:DJ28").Select
Selection.Copy
Range("CW29").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
...
Range("CW1277").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("CW28:DJ28").Select
Selection.ClearContents
Range("CW28:CX28").Select
Application.DisplayAlerts = True
Application.ScreenUpdating = True
' If zero records, re-enable alerts/screen updating
Else
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End If
End Sub
As you can see, the two spots where the "..." I need to apply to rows 29 through 1277. I know there's got to be a better way to do this with For ... Next, but what I've tried hasn't worked (code that I used is below, it would give me an error saying I can't do that to merged cells, even though my current code works).
Dim rng As Range: Set rng = Application.Range("CW28:CX1277")
Dim i As Integer
For i = 1 To 1248
rng.Cells(RowIndex:=i, ColumnIndex:="CW").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next
I know my entire issue is that we have merged cells, but we need to keep them if at all possible. Knowing that my current, repetitive coding works... is there a way to make the For ... Next function work?
What I understand of your code is that you copy the format of line N to line N+1 for columns CW to DJ, from lines 28 to 1277, by block.
(I strongly suppose it is not as much simple).
What you could do is (I replace your 28 by beginRow) :
dim beginRow as long, endRow as long
dim strRange as string
beginRow=28
while (beginRow<<1277)
strRange = "CW" & beginRow & ":DJ" & beginRow
Range(strRange).select
endRow=Selection.End(xlDown).row
strRange = "CW" & beginRow & ":DJ" & endRow
Range(strRange).Copy
strRange = "CW" & (beginRow+1) & ":DJ" & (endRow+1)
Range(strRange).Select
ActiveSheet.Paste
strRange = "CW" & (beginRow) & ":DJ" & (beginRow+1)
Range(strRange).Copy
Range("CW" & (beginRow+1)).Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
' find next block
beginRow=Range("CW" & (endRow+1)).End(xlDown).row
wend
Could this help ?
Pierre.
I figured it out!
Dim rng As Range
Dim cell As Range
Range("CW28:DJ28").Select
Selection.Copy
Set rng = Range("CW29:1277")
For Each cell In rng.Cells
cell.Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next cell
Application.CutCopyMode = False
Now, I need to focus on how to get rid of .Select and .Activate throughout my code. Thank you so much for your help, all!

Information regarding the Run time error 9

I am trying to copy the range of value from one sheet in excel to another. I have copied this formula from another part of my sheet that works however i cam coming up with the run time error 9.
Sub SaveJambStudEC()
'
' SaveCalcsJambEC Macro
'
Dim page As Integer
page = Cells(4, "T").Value
Range("A70:AN70").Select
Selection.Copy
Range("A71").Select
ActiveCell.Offset(page, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1:O63").Select
Selection.Copy
Sheets("10.3 JambCalcs EC").Select
Range("A1").Select
ActiveCell.Offset((page - 1) * 63, 0).Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone _
, SkipBlanks:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats
Sheets("9.3 Jamb Design EC").Select
Range("T5").Select
Selection.Copy
Range("N9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("T31").Value = 0
Call JambECsetDesignOptions
Call CopyJambOptiValues
Range("J9").Activate
End Sub
using the below code you will check if there is a sheet with that name. if you dont receive any message box means that there is no sheet with such name
Option Explicit
Sub test()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name = "10.3 JambCalcs EC" Then
MsgBox "Sheet Appears"
Exit Sub
End If
Next ws
End Sub
Note
'ThisWorkbook' refer to the workbook that the code included. If you want to clearly declare the workbook you could declare a variable 'Dim wb as Workbook' and then set the workbook 'Set wb=Workbooks("workbook name")'

VB to Post to New Line per Button Click

I recorded a macro, linked to a button, on say sheet1. The object of what I need done:
When the button is pressed, certain cells are selected and copied to a "summary" page on another sheet.
Sheet1 has a drop down that shows certain information. So after data is selected from the drop down, the user will push the button and post that data to the summary sheet.
The macro works fine (please note I am a VBA noob), but I need assistance in adding functionality that after every button press, it copies the data on the next line - in other words, if data is in row 1 already, it must place the data in row 2, and so on.
The VB code I have is as follows:
Sub Test()
'
' Test Macro
'
'
Range("C32:N32").Select
Selection.Copy
Sheets("Summary").Select
Range("D3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks
_
:=False, Transpose:=False
Sheets("Comm Payable").Select
Range("C3:D3").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Summary").Select
Range("B3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks
_
:=False, Transpose:=False
Sheets("Comm Payable").Select
Range("N1").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Summary").Select
Range("C3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks
_
:=False, Transpose:=False
Range("B4").Select
Sheets("Comm Payable").Select
Range("O1").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = ""
Range("O1").Select
End Sub
Please could someone assist with the addition described above?
Much appreciated!
It's imperative you read the link posted by PEH as you can considerably shorten and speed up your code. I think this does what you want.
Sub Test()
Dim r As Long
r = WorksheetFunction.Max(Sheets("Summary").Range("D" & Rows.Count).End(xlUp).Row + 1, 3)
Sheets("Comm Payable").Range("C32:N32").Copy
Sheets("Summary").Range("D" & r).PasteSpecial Paste:=xlPasteValues
Sheets("Comm Payable").Range("C3:D3").Copy
Sheets("Summary").Range("B" & r).PasteSpecial Paste:=xlPasteValues
Sheets("Comm Payable").Range("N1").Copy
Sheets("Summary").Range("C" & r).PasteSpecial Paste:=xlPasteValues
Sheets("Comm Payable").Range("O1").ClearContents
End Sub
As an aside, transferring values directly is more efficient than copying and pasting and here is an example of that.
With Sheets("Comm Payable").Range("C32:N32")
Sheets("Summary").Range("D" & r).Resize(.Rows.Count, .Columns.Count).Value = Value
End With

Resources