VBA copying data between sheets to irregular range - excel

data set
Hi All,
I know its abasic stuff but trying to learn VBA and encountered this issue while building my first macro. I have completely no idea how to pull this through.
I have a data set in sheet1 - an array of 9 columns with headers (the range is not definite and will vary month to month) out of which I need to populate the data into a form in sheet2. The problem is that the form is just built manually across spreadsheet2. Someone just drew a table and adapted it as a form and it cannot be changed (just some requirement) Another thing is that table was created in a way where some cells are one above the other so 2 rows would contain the data of one in the source. I placed the photos that should paint the picture of what Im trying to say. So the only thing I knew is how to copy one row of data but have no idea how to loop it so that each next row from spread sheet1 will populate itself accordingly among these two other rows. So the idea is for the macro to copy data from the source and create necessary number of these double rows until the source data runs out(dependantly on how bit source range will be as its dynamic) At the end there must be that summary of TOtal from last row.
Ive tried it like this
Sub sbCopyRangeToAnotherSheet()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
ws1.Sheets("51").Range("H2").Copy
Sheets("Add 51").Range("A11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Sheets("51").Range("C2").Copy
Sheets("Add 51").Range("B11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Sheets("51").Range("E2").Copy
Sheets("Add 51").Range("D10").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Sheets("51").Range("F2").Copy
Sheets("Add 51").Range("D11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Sheets("51").Range("D2").Copy
Sheets("Add 51").Range("E11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Sheets("51").Range("I2").Copy
Sheets("Add 51").Range("I11").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End Sub

Untested:
Sub Tester()
Dim rngDest As Range, rwSrc As Range, arr, i As Long
Set rwSrc = ThisWorkbook.Worksheets("51").Range("C2:H2") 'first row of source data
Set rngDest = ThisWorkbook.Worksheets("Add 51").Range("A5:I6") 'destination for first row
arr = Array("B2", "D2", "D1", "E1", "E2", "I2") 'array of *relative* addresses
Do While Application.CountA(rwSrc) > 0 'while there's any data in the source row
For i = 1 To rwSrc.Cells.Count 'loop over cells in source row
'set value of a cell in `rngDest` using relative range address from `arr`
rngDest.Range(arr(i - 1)).Value = rwSrc.Cells(i).Value 'i-1 because arr is zero-based
Next i
Set rwSrc = rwSrc.Offset(1) 'next source row
Set rngDest = rngDest.Offset(rngDest.Rows.Count) 'next destination block
Loop
End Sub
Relies on Range() being relative to the object it's called on, so for example
Range("B2:C4").Range("A1") is B2
Range("B2:C4").Range("B2") is C3

Related

Append data to last row

I am quite new to VBA, hence unable to understand the scripts at this moment.
I tried recording a macro and it does quite a good job. However, it's not dynamic.
Here is my use case:
I have an excel workbook and it has two sheets named "Sheet1" & "FinalData". All I want to do is copy the data from a specific cell range of let's say C2:P2 from "sheet1" and append it to the "FinalData" sheet.
Basically, find the last empty row and paste the data there. Below is my recorded piece of vba code that indicates this function.
Can anyone help me with fixing the below code or sharing a new code, please? I will be grateful to you.
Thanks!
Application.CutCopyMode = False
Range("C2").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Sheets("FinalData").Select
Range("A2").Select
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Try this code, to select the last empty row, just sum + 1 to the total used rows
Application.CutCopyMode = False
Range("C2").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Sheets("FinalData").Select
Cells(Sheets("FinalData").UsedRange.Rows.Count + 1, 1).Select ' Select last empty row
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sub copyData()
Dim sheet1 As Worksheet
Dim finalDataSheet As Worksheet
Set sheet1 = Sheets("Sheet1")
Set finalDataSheet = Sheets("FinalData")
'Get the last column based on the second row.
lastcolumn = sheet1.Cells(2, Columns.Count).End(xlToLeft).Column
'Get last row based on column C.
lastrow = sheet1.Cells(Rows.Count, 3).End(xlUp).Row
'Option A:
'Only transfer row 2 with dynamic columns from C to end column.
finalDataSheet.Range(finalDataSheet.Cells(2, 3), finalDataSheet.Cells(2,
lastcolumn)).Value = _
sheet1.Range(sheet1.Cells(2, 3), sheet1.Cells(2, lastcolumn)).Value
'Option B:
'Transfer entire dynamic table structure starting at c2.
'Get the values from sheet 1 data range and copy values over to final data
sheet into the same position.
finalDataSheet.Range(finalDataSheet.Cells(2, 3),
finalDataSheet.Cells(lastrow, lastcolumn)).Value = _
sheet1.Range(sheet1.Cells(2, 3), sheet1.Cells(lastrow, lastcolumn)).Value
End Sub

Debugging Error while generating multiple templates from master sheet

I am trying to loop through a range of cells in a column and find non-blank cells to generate multiple template worksheets based on cell value in that specific range for further data transfer. however I am getting a debugging error, can anyone solve a problem? In the attached code "CETIN is the template worksheet
Sub generateSheet()
Dim sh1 As Worksheet, sh2 As Worksheet, c As Range
Set sh1 = Sheets("CETIN")
Set sh2 = Sheets("Combine")
Range("A4:A600").Select
Selection.AutoFilter
ActiveSheet.Range("$A$5:$A$116").AutoFilter Field:=1, Criteria1:="<>"
Range("A4:A64").Select
Range("A4:A64").Select
Range("A4:A600").Select
Range("A116").Activate
Selection.Copy
Range("AT5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.AutoFilter
For Each c In sh2.Range("AT5", sh2.Cells(Rows.Count, 46).End(xlUp))
sh1.Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = c.Value
Next
End Sub

How to paste data from one sheet to another and add a new row if there's already a value in using VBA Excel?

I'm extremely new to VBAs and cannot figure out how to add a value to the next row if there's already data previous row. I'm sure I'm overthinking it, but I cannot seem to figure it out. Any help would be appreciated.
Below is the macro I'm using. Not sure if I need to offset the data or maybe add an if then statement of some sort.
Sub Archive_2()
Range("A2").Select
Selection.Copy
Sheets("Campaign Rate").Select
Range("A3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Use below sub-
Sub CopyPaste()
Dim sh As Worksheet
Dim lRng As Range
Set sh = Worksheets("Campaign Rate")
Set lRng = sh.Cells(sh.Rows.Count, 1).End(xlUp)
Range("A2").Copy
lRng.Offset(1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Set sh = Nothing
Set lRng = Nothing
End Sub

Macro will work in developer and with hot key but not with button... any idea why?

As mentioned above, the code works just fine both in the developer and with the hot keys but when I use the button, it seems like the "go to last row + 1" doesn't work. When I select the button, the data keeps being copied and recopied into row 2.
Sub Entry_Schedule()
' Entry_Schedule Macro
Dim FrstEmptCll As Range
FrstEmtCll = Range("A" & Rows.Count).End(xlUp).Row
Sheets("Sheet2").Range("D4:I4").Copy
Sheets("Data").Range("A" & FrstEmtCll + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
You need to qualify every Range, Rows, Columns, etc with a worksheet:
FrstEmtCll = Worksheets("Data").Range("A" & Worksheets("Data").Rows.Count).End(xlUp).Row
The second issue is that you declare Dim FrstEmptCll As Range but you try to put the row number into a range object .End(xlUp).Row.
So either Set the range to the cell and offset:
Option Explicit
Sub Entry_Schedule()
' Entry_Schedule Macro
Dim FrstEmtCll As Range
Set FrstEmtCll = Worksheets("Data").Range("A" & Worksheets("Data").Rows.Count).End(xlUp).Offset(RowOffset:=1)
Worksheets("Sheet2").Range("D4:I4").Copy
FrstEmtCll.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Or use the row number (as Long):
Option Explicit
Sub Entry_Schedule()
' Entry_Schedule Macro
Dim FrstEmptRow As Long
FrstEmptRow = Worksheets("Data").Range("A" & Worksheets("Data").Rows.Count).End(xlUp).Row + 1
Worksheets("Sheet2").Range("D4:I4").Copy
Worksheets("Data").Range("A" & FrstEmptRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Additionally you mistyped your variable name FrstEmptCll vs FrstEmtCll (missing p). This means you actually have 2 different variables now (which easily blows up your code). To avoid such errors I highly recommend to activate Option Explicit: In the VBA editor go to Tools › Options › Require Variable Declaration.

How to cycle through a block of code and operate on non-contiguous columns?

I have researched this issue on several different sites with no clear way to do what I want:
I have a spreadsheet with 68 pairs of columns from 'B' to 'EG' and one leading column of data in 'A'.
I want create a new worksheet and name it for the header for the first column of each pair of columns, then copy the column of data in 'A' and the pair of columns into the new worksheet, and do the same for each succeeding pair of columns. I can create the new worksheets from the existing spreadsheet data, but not sure how to name the new worksheets to match the header field.
The following code will create a new worksheet and copy the data, but it won't name the worksheet, and I have to create 68 separate blocks for each succeeding pair of columns! Can anyone suggest a mod to the code to loop through the columns and do what I want? Generated code is below! And any real help would be very much appreciated.
Thanks Mike
Code:
Sub testcopy()
testcopy Macro
Keyboard Shortcut: Ctrl+f
Range("A5:A17,B5:B17,C5:C17").Select
Range("C5").Activate
Application.CutCopyMode = False
Selection.Copy
Sheets.Add After:=Sheets(Sheets.Count)
Range("A5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Range("A5:A17,D5:D17,E5:E17").Select
Range("E5").Activate
Application.CutCopyMode = False
Selection.Copy
Sheets.Add After:=Sheets(Sheets.Count)
Range("A5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
.
.
.
End Sub
Something like this:
Sub testcopy()
Dim shtSrc As Worksheet, sht As Worksheet
Dim i As Long, rngA As Range, rngTwo As Range
Set rngA = ActiveSheet.Range("A5:A17")
Set rngTwo = ActiveSheet.Range("B5:C17")
For i = 1 To 68
Set sht = Sheets.Add(After:=Sheets(Sheets.Count))
sht.Name = rngTwo.Cells(1).Value
Application.Union(rngA, rngTwo).Copy
sht.Range("A5").PasteSpecial Paste:=xlPasteValues
Set rngTwo = rngTwo.Offset(0, 2)
Next i
End Sub

Resources