VBA Loop : Copy / Paste destination offsetting - excel

First of all thanks for your help. I need to copy / paste datas. The idea is the next : depending on the cells content from the sheet AAA I want to copy / paste the datas to the corresponding sheet (XXX if XXX or to ZZZ if ZZZ).My macro worked but the issue is that I have an offset bothering me. Imagine , the first lap will paste the data to XXX , but the second lap will copy to ZZZ , in this case I have an issue because it will copy paste to the 3rd cells (3,1) whereas the cell(2,1) is empty
Sub CopyPastingMyDate()
Dim i As Long
Dim lrow As Long
Dim lcol As Long
Dim RngOne As Range
Dim RngTwo As Range
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("AAA")
lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
lcol = ws.Cells(1, Columns.Count).End(xlToLeft).Column
Set RngOne = ws.Range(ws.Cells(lrow, 1), ws.Cells(1, lcol))
For i = 2 To lrow
Set RngOne = ws.Range(ws.Cells(lrow, 1), ws.Cells(1, lcol))
If ws.Cells(i, 1) = "XXX" Then
Set RngTwo = ThisWorkbook.Worksheets("SheetXXX").Range(ThisWorkbook.Worksheets("SheetXXX").Cells(i, 1), ThisWorkbook.Worksheets("SheetXXX").Cells(i, lcol))
RngOne.Copy
RngTwo.PasteSpecial xlAll
End If
If ws.Cells(i, 1) = "ZZZ" Then
Set RngTwo = ThisWorkbook.Worksheets("SheetZZZ").Range(ThisWorkbook.Worksheets("SheetZZZ").Cells(i, 1), ThisWorkbook.Worksheets("SheetZZZ").Cells(i, lcol))
RngOne.Copy
RngTwo.PasteSpecial xlAll
End If
Next i
End Sub
How to fix it please ? I want to copy paste to from the first available cell. Thanks to all of you.
JaNa

Try this. I might be misunderstanding what you're copying though: I'm assuming each row needs to be copied to the correct sheet?
Sub CopyPastingMyDate()
Dim i As Long
Dim lrow As Long
Dim lcol As Long
Dim RngOne As Range
Dim RngTwo As Range
Dim ws As Worksheet, dest, wsDest As Worksheet
Set ws = ThisWorkbook.Worksheets("AAA")
lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
lcol = ws.Cells(1, Columns.Count).End(xlToLeft).Column
Set RngOne = ws.Range(ws.Cells(lrow, 1), ws.Cells(1, lcol))
For i = 2 To lrow
Select Case ws.Cells(i, 1).Value 'which destination sheet?
Case "XXX": dest = "SheetXXX"
Case "ZZZ": dest = "SheetZZZ"
Case Else: dest = ""
End Select
If Len(dest) > 0 Then
ws.Cells(i, 1).Resize(1, lcol).Copy 'copy the row
Set wsDest = ThisWorkbook.Worksheets(dest)
wsDest.Cells(wsDest.Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlAll
End If
Next i
End Sub

I have found a way to solve my issue by introducing a new variable x = last_row + 1 . I replaced in i in RngTwo by x .

Related

Switch from Cells to Range

I see Range.AutoFill method (Excel) example:
Set sourceRange = Worksheets("Sheet1").Range("A1:A2")
Set fillRange = Worksheets("Sheet1").Range("A1:A20")
sourceRange.AutoFill Destination:=fillRange
I want to input a formula into the first empty column (always row 2) and then copy that down for all rows in the register (it's data copied from an outside source).
Sub SetNextEmptyFormula(strFormula As Variant)
Dim ws As Worksheet
Dim lCol As Long, lRow As Long
Set ws = Workbooks("myworkbook.xlsm").Worksheets("register")
' Always row 2 -> lRow, always in lCol
lCol = ws.Range("A1").End(xlToRight).Column
lRow = ws.Range("A1").End(xlDown).Row
ws.Cells(2, lCol + i).Value = CStr(strFormula)
Set sourceRange = ws.Range(???)
Set fillRange = ws.Range(???)
sourceRange.AutoFill Destination:=fillRange
End Sub
I'm not sure how you're going to build your formula, but if you're just looking for help referencing these cells, this will do:
Option Explicit
Sub UseSub()
Dim myFormula
myFormula = "=ROW()"
Call SetNextEmptyFormula(myFormula)
End Sub
Sub SetNextEmptyFormula(strFormula As Variant)
Dim WS As Worksheet
Dim lCol As Long, lRow As Long
Dim fillRange As Range
Set WS = Workbooks("myworkbook.xlsm").Worksheets("register")
'Set WS = Workbooks("Book1.xlsm").Worksheets("register")
With WS
' Always row 2 -> lRow, always in lCol
lCol = .Range("A1").End(xlToRight).Column
lRow = .Range("A1").End(xlDown).Row
.Cells(2, lCol + 1).Formula = CStr(strFormula)
'FillDown Only requires you reference the whole range Once, You only need "FillRange"
'Set sourceRange = ws.Range(???)
Set fillRange = .Range(.Cells(2, lCol + 1), .Cells(lRow, lCol + 1))
fillRange.FillDown
End With
End Sub

Copy/Paste Range from one sheet to another

I am trying too simply copy the cells with data in col A of a worksheet to another worksheet at row 2. With the following script the source worksheet name is entered into row 1 of Ave RLD worksheet. If that is all I try to do it will loop through all the worksheets and place their names in the next col of Ave RLD. As soon as I try to copy the data from col A and paste it to Ave RLD I get a Run time error 1004. I left in all the commented lines of things I have been trying. What am I missing?
Dim WS_count As Long
Dim I As Long
Dim ws As Worksheet
Dim ColNum As Long
Dim wksName As String
Dim NumRows As Long
ColNum = 1
Sheets.Add Type:=xlWorksheet
ActiveSheet.Name = "Ave RLD"
For Each ws In ActiveWorkbook.Worksheets
If Left(Trim(ws.Name), 3) = "RLD" Then
wksName = ws.Name
NumRows = ws.Range("A" & Rows.Count).End(xlUp).Row
MsgBox NumRows
With Worksheets("Ave RLD")
.Cells(1, ColNum).Value = wksName
ws.Range(Cells(1, 1), Cells(NumRows, 1)).Copy
.Range(Cells(2, ColNum)).Paste.Values
'.Range(Cells(2, ColNum)).Value = .Range(("A1"), Range("A1").End(xlUp))
'.Range(Cells(2, ColNum)).Value = ws.Range("A" & Rows.Count).End(xlUp).Row
'MsgBox ws.Cells(1, 26).Value
'.Cells(2, ColNum).Value = .Worksheets(wksName).Cells(1, 26)
'.Worksheets(wksName).Cells(1, 1).Copy
'Worksheets(wksName).Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Copy
'.Cells(2, ColNum).Paste
ColNum = ColNum + 1
End With
End If
Next ws
Does this do what you want?
Lots on this at this site, but this line will error if ws is not the active sheet as you do not fully qualify all the ranges
ws.Range(Cells(1, 1), Cells(NumRows, 1)).Copy
And the other line commented below just needs Range or Cells, also your paste values syntax was off - recording a macro is one way to sort out such details.
Dim WS_count As Long
Dim I As Long
Dim ws As Worksheet
Dim ColNum As Long
Dim wksName As String
Dim NumRows As Long
ColNum = 1
Sheets.Add Type:=xlWorksheet
ActiveSheet.Name = "Ave RLD"
For Each ws In ActiveWorkbook.Worksheets
If Left(Trim(ws.Name), 3) = "RLD" Then
wksName = ws.Name
NumRows = ws.Range("A" & Rows.Count).End(xlUp).Row
MsgBox NumRows
With Worksheets("Ave RLD")
.Cells(1, ColNum).Value = wksName
ws.Range(ws.Cells(1, 1), ws.Cells(NumRows, 1)).Copy 'fully qualify with ws
.Cells(2, ColNum).PasteSpecial xlpasteValues 'just Cells
ColNum = ColNum + 1
End With
End If
Next ws

Cut and Paste Blocks of Data underneath first block using VBA

I have been trying to come up with/find a VBA code that copies blocks of data under my first block. Each block is 19 columns followed by a blank. The number of rows per block can vary.
See my screenshot below:
Therefore, I would like all my data continuous in the first columns A:S. Any help is highly appreciated.
I found the following code online, but this only pastes everything into the first column
Sub Column()
Dim iLastcol As Long
Dim iLastRow As Long
Dim jLastrow As Long
Dim ColNdx As Long
Dim ws As Worksheet
Dim myRng As Range
Dim ExcludeBlanks As Boolean
Dim mycell As Range
ExcludeBlanks = (MsgBox("Exclude Blanks", vbYesNo) = vbYes)
Set ws = ActiveSheet
iLastcol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Alldata").Delete
Application.DisplayAlerts = True
Sheets.Add.Name = "Alldata"
For ColNdx = 1 To iLastcol
iLastRow = ws.Cells(ws.Rows.Count, ColNdx).End(xlUp).Row
Set myRng = ws.Range(ws.Cells(1, ColNdx), _
ws.Cells(iLastRow, ColNdx))
If ExcludeBlanks Then
For Each mycell In myRng
If mycell.Value <> "" Then
jLastrow = Sheets("Alldata").Cells(Rows.Count, 1) _
.End(xlUp).Row
mycell.Copy
Sheets("Alldata").Cells(jLastrow + 1, 1) _
.PasteSpecial xlPasteValues
End If
Next mycell
Else
myRng.Copy
jLastrow = Sheets("Alldata").Cells(Rows.Count, 1) _
.End(xlUp).Row
mycell.Copy
Sheets("Alldata").Cells(jLastrow + 1, 1) _
.PasteSpecial xlPasteValues
End If
Next
Sheets("Alldata").Rows("1:1").EntireRow.Delete
ws.Activate
End Sub
Basic approach:
Sub Tester()
Dim c As Range, addr
Set c = ActiveSheet.Range("T1")
Do
Set c = c.End(xlToRight)
If c.Column = Columns.Count Then Exit Do
addr = c.Address 'strire the address since Cut will move c
c.CurrentRegion.Cut c.Parent.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Set c = ActiveSheet.Range(addr) '<< reset c
Loop
End Sub
This is a little more basic than #TimWilliams
With ThisWorkbook.Sheets("Alldata")
Dim lRow As Long, lCol As Long, cpyrng As Range
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 21 To lCol Step 20
If .Cells(1, i).Value <> "" And .Cells(1, i).Offset(, -1).Value = "" Then
lRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set cpyrng = .Cells(1, i).CurrentRegion
cpyrng.Cut
Sheets("Sheet2").Cells(lRow, 1).Offset(2).Insert Shift:=xlDown
End If
Next i
End With

Copy to the next available line with my code

With the code I am currently using it will paste the information from Worksheet 1 to worksheet 2 in the Top line of worksheet2. What I want next is to use the same code but for different cell values and to copy the information from worksheet 1 to worksheet 2 but in the next available line in worksheet 2.
I have been researching about excel macros and vba for a while now and I am still having trouble. I have worked on not using select and activate within my excel code but I am still having trouble with my code now. I am trying to automate my excel workbook as much as I can for easier use.
Sub Copy()
Dim Cell As Range
Dim myRow As Long
myRow = 1
With Sheets("Sheet1")
For Each Cell In .Range("A1:A" & .Cells(.Rows.Count, "A").End(xlUp).Row)
If Cell.Value = "Tuck Chow" And Cell.Offset(0, 1).Value = "OPT" Then
.Rows(Cell.Row).Copy Destination:=Sheets("Sheet2").Rows(myRow)
myRow = myRow + 1
End If
Next Cell
End With
End Sub
I would do something like this:
Sub Copy()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim newRow As Long
'setting sheets
Set sh1 = ThisWorkbook.Worksheets("Sheet1")
Set sh2 = ThisWorkbook.Worksheets("Sheet2")
With sh1
For Each cel In .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp))
If cel.Value = "Tuck Chow" And cel.Offset(0, 1).Value = "OPT" Then
'getting new row on Sheet2
If sh2.Cells(1, 1) = "" Then
newRow = 1
Else
newRow = sh2.Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
'copying
cel.EntireRow.Copy Destination:=sh2.Cells(newRow, 1)
End If
Next cel
End With
'deselecting row
sh2.Cells(1, 1).Select
End Sub
Try:
Option Explicit
Sub test()
Dim LastRow1 As Long, LastRow2 As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRow1 = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 1 To LastRow1
If .Range("A" & i).Value = "Tuck Chow" And .Range("B" & i).Value = "OPT" Then
LastRow2 = ThisWorkbook.Worksheets("Sheet2").Cells(ThisWorkbook.Worksheets("Sheet2").Rows.Count, "A").End(xlUp).Row
.Rows(i).Copy ThisWorkbook.Worksheets("Sheet2").Rows(LastRow2 + 1)
End If
Next i
End With
End Sub

macro to copy and paste data from one Sheet to another when Header is matching

I am trying to create a macro to copy and paste data from one Sheet to another sheet when Header and Column A data is matching and want to paste into the specific cell.
below code is working fine for me when Row(headers) order is the same in both sheets. but I need a solution for when the row (Headers) are not in the order.
"I hope I was able to explain my problem"
Sub transfer()
Dim i As Long, j As Long, lastrow1 As Long, lastrow2 As Long
Dim myname As String
lastrow1 = Sheets("sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow1
myname = Sheets("sheet1").Cells(i, "A").Value
Sheets("sheet2").Activate
lastrow2 = Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row
For j = 2 To lastrow2
If Sheets("sheet2").Cells(j, "A").Value = myname Then
Sheets("sheet1").Activate
Sheets("sheet1").Range(Cells(i, "B"), Cells(i, "F")).Copy
Sheets("sheet2").Activate
Sheets("sheet2").Range(Cells(j, "D"), Cells(j, "H")).Select
ActiveSheet.Paste
End If
Next j
Application.CutCopyMode = False
Next i
Sheets("sheet1").Activate
Sheets("sheet1").Range("A1").Select
End Sub
if i understood your goal then may try something like (code is tested with makeshift data)
Sub test()
Dim SrcWs As Worksheet, TrgWs As Worksheet
Dim Col As Long, TrgLastRw As Long, SrclastRw As Long, SrcLastCol As Long, TrgLastCol As Long
Dim SrcRng As Range, TrgRng As Range, C As Range, Hd As String
Set SrcWs = ThisWorkbook.Sheets("Sheet1")
Set TrgWs = ThisWorkbook.Sheets("Sheet2")
SrcLastCol = SrcWs.Cells(1, Columns.Count).End(xlToLeft).Column
TrgLastCol = TrgWs.Cells(1, Columns.Count).End(xlToLeft).Column
For Col = 1 To SrcLastCol
Hd = SrcWs.Cells(1, Col).Value
If Hd <> "" Then
SrclastRw = SrcWs.Cells(Rows.Count, Col).End(xlUp).Row + 1
Set SrcRng = SrcWs.Range(SrcWs.Cells(2, Col), SrcWs.Cells(SrclastRw, Col))
With TrgWs.Range(TrgWs.Cells(1, 1), TrgWs.Cells(1, TrgLastCol))
Set C = .Find(Hd, LookIn:=xlValues) 'each column header is searched in trgWs
If Not C Is Nothing Then
TrgLastRw = TrgWs.Cells(Rows.Count, C.Column).End(xlUp).Row + 1
Set TrgRng = TrgWs.Cells(TrgLastRw, C.Column).Resize(SrcRng.Rows.Count, 1)
SrcRng.Copy Destination:=TrgRng
End If
End With
End If
Next Col
End Sub

Resources