(Copy if) Multiple Variables - excel

I wanted to copy data from one sheet to another. The selection part is according to date and specific value of column.
enter image description here
I tried this code from internet. So the basic logic is if 2 condition are met then copy the row. However its not working.
It actually working first when only one condition are written, when the second one written, the VBA did not do anything
Sub CopyRowsAcross()
Dim i As Integer
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Clean_Sheet")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Daily_Report")
For i = 2 To ws1.Range("P65536").End(xlUp).Row
If ws1.Cells(i, 1) = "DOWNY S.FRESH 900ML" and ws2.Range ("C2") = ws1.Cells(i,3) Then
ws1.Rows(i).Copy ws2.Rows(ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row + 1)
End If
Next i
End Sub
the ws2.Range("C2") are selected date written in cell C2 in the sheet.
The result are the row copied based on this 2 criteria

This works assuming both your data in worksheet 1 are really dates and the filter in C2 is a date also:
Option Explicit
Sub CopyRowsAcross()
Dim LastRow As Long, lrow As Long
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Clean_Sheet")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Daily_Report")
Dim DateFilter As Date
With ws2
DateFilter = .Cells(2, 3)
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
End With
With ws1
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("A1:C" & LastRow).AutoFilter Field:=1, Criteria1:="DOWNY S.FRESH 900ML"
.Range("A1:C" & LastRow).AutoFilter Field:=3, Criteria1:=Format(DateFilter, "dd-Mmm-yy")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
If LastRow > 1 Then
.Range("A2:C" & LastRow).SpecialCells(xlCellTypeVisible).Copy ws2.Cells(lrow, 1)
End If
.AutoFilterMode = False
End With
End Sub
Instead of looping (Time consuming) you could just filter the data you need and copy it all a t once.

Related

Increasing range for each iteration

I'm automating an Excel sheet for my work and I'm stuck in a problem.
I'm trying to copy a specific range (A3:D3) and paste it to the ending row of another workbook. I'm trying to use an if statement to filter ranges that have the number 0 in cell B3.
Please help. I'm a complete rookie and I'm just starting out. Sorry if there's a lot of questions.
I've tried to change the range to a cell (i, 2) but it only copies B3 and not the rest (A3:D3).
Edit: forgot to add the s in cells
Edit2: I just need to copy four cells (A3:D3) and increment it on my next iteration so that the copied cell would be (A4:D4)
Sub CopyData()
Dim wsCopy As Worksheet, wsDest As Worksheet
Dim iCopyLastRow As Long, iDestLastRow As Long
Set wsCopy = Workbooks("file1.xlsx").Worksheets("trend")
Set wsDest = Workbooks("file2.xlsx").Worksheets("raw data")
iCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
For i = 3 To iCopyLastRow
If wsCopy.Cells(i, 2).Value = 0 Then
Else
wsCopy.range(Cell(i,2), Cell(i,4)).Copy
'wsCopy.Cells(i, 2). Copy ##this copies just one cell
iDestLastRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Offset(1).Row
wsDest.range("A" & iDestLastRow).PasteSpecial xlPasteValues
End If
Next i
Error messages:
Run-time error '1004':
Method 'Range' of object '_Worksheet' failed
and the debug highlights wsCopy.range(Cell(i,2), Cell(i,4)).Copy, the statement after else
Try using this code:
Sub CopyData()
Dim wsCopy As Worksheet, wsDest As Worksheet
Dim iCopyLastRow As Long, iDestLastRow As Long
Set wsCopy = Workbooks("file1.xlsx").Worksheets("trend")
Set wsDest = Workbooks("file2.xlsx").Worksheets("raw data")
iCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
For i = 3 To iCopyLastRow
If wsCopy.Cells(i, 1).Value <> 0 Then
'A = 1, D = 4
wsCopy.Range(wsCopy.Cells(i, 1), wsCopy.Cells(i, 4)).Copy
iDestLastRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Offset(1).Row
wsDest.Range("A" & iDestLastRow).PasteSpecial xlPasteValues
End If
Next i
End Sub
Just make sure that iCopyLastRow and iDestLastRow are the values that you expect.
I hope this helps.
Try below code, it's ready to use in a loop:
Sub CopyAndAppend()
Dim destSheet As Worksheet, srcSheet As Worksheet, lastRow As Long
Set destSheet = Worksheets("Sheet2")
Set srcSheet = Worksheets("Sheet1")
' determine last row in Sheet2
lastRow = destSheet.Cells(destSheet.Rows.Count, 1).End(xlUp).Row
Dim i As Long
i = 3
' copy range A3:D3 and paste it right after last row in Sheet2
srcSheet.Range(srcSheet.Cells(i, 1), srcSheet.Cells(i, 4)).Copy destSheet.Cells(lastRow + 1, 1)
' increment row index
i = i + 1
' do something else
End Sub

Copy Paste works only if Range is greater then 20 rows

Would you know what is the following code adjustment needed. Range I have set up (A1:B20) changes over time. The first block of data stays be between A1:B20 and the second block of data always will be between A25:B60. Ranges will change over time. First block of data could reach 200 rows going down. After my code reaches the second block of data and my range falls between that block of data it picks up the range only if I have adjusted manually the range. Please note, Second block of data normally provides duplicates from the first block.
How could I have my code automatically select the first block of data past my range output without having to adjust the "range" manually?
Sub CopyPaste()
Dim lastRow As Long
Dim Sheet2 As Worksheet
Dim Results As Worksheet
Dim LookupLastrow As Long
'code line will set values from sheet
("Sheet1") into ("Sheet2") starting 5 rows down.
Set Results = Sheets("Sheet2")
lastRow = ThisWorkbook.Sheets("Sheet2").Cells(Rows.Count, 1).End (xlUp).row
Range("A1:B20" & lastRowcount).Copy
Results.Range("A" & lastRow + 5).PasteSpecial xlPasteValuesAndNumberFormats
Application.GoTo ActiveSheet.Range("A1"), True
Application.CutCopyMode = False
End Sub
Think simple. No need to build strings for range addresses, and no need for using the clipboard with .Copy and .Paste. Use a direct assignment to the .Value property in a table of cells.
Public Sub CopyValues()
Dim r_src As Range, r_dst As Range
' Source starts at row 20
Set r_src = Sheets("Sheet 2").Cells(20, 1)
' Destination starts at row 5
Set r_dst = Sheets("Sheet 1").Cells(5, 1)
Dim n As Long
' Count the non-empty cells
n = r_src.Range(r_src, r_src.End(xlDown)).Rows.Count
' Copy n rows and 2 columns with one command
r_dst.Resize(n, 2).Value = r_src.Resize(n, 2).Value
End Sub
Based on the picture you showed, the following code will capture the entire top and bottom sections, regardless of how many lines or columns exists. This assumes your top section will start in "A8" as shown. You can edit the code to reflect your actual sheet names.
Sub CopyPaste()
Dim OrigLastRow As Long
Dim OrigLastCol As Long
Dim DestLastRow As Long
Dim OrigRng As Range
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Origin")
Set ws2 = ThisWorkbook.Worksheets("Destination")
OrigLastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
OrigLastCol = ws1.Cells(10, Columns.Count).End(xlToLeft).Column
DestLastRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 5
Set OrigRng = ws1.Range(ws1.Cells(8, 1), ws1.Cells(OrigLastRow, OrigLastCol))
OrigRng.Copy
ws2.Cells(DestLastRow, 1).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End Sub
The version below creates a top and bottom section like your picture and copies both sections separately with a 5 row gap in the destination.
Sub CopyPaste2()
Dim OrigLastRow As Long
Dim OrigLastCol As Long
Dim TopLastRow As Long
Dim BotLastRow As Long
Dim DestLastRow As Long
Dim OrigTopRng As Range
Dim OrigBotRng As Range
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Origin")
Set ws2 = ThisWorkbook.Worksheets("Destination")
'Assumes contiguous data from row 8 down
TopLastRow = ws1.Cells(8, 1).End(xlDown).Row
BotLastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
OrigLastCol = ws1.Cells(10, Columns.Count).End(xlToLeft).Column
DestLastRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 5
'Assumes we are starting the top range in row 8
Set OrigTopRng = ws1.Range(ws1.Cells(8, 1), ws1.Cells(TopLastRow, OrigLastCol))
'Columns I & J as shown in the picture
Set OrigBotRng = ws1.Range(ws1.Cells(TopLastRow + 5, 9), ws1.Cells(BotLastRow, 10))
OrigTopRng.Copy
ws2.Cells(DestLastRow, 1).PasteSpecial xlPasteValuesAndNumberFormats
'Recalculate destination last row
DestLastRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 5
OrigBotRng.Copy
ws2.Cells(DestLastRow, 1).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End Sub

How to subtract two dynamic ranges and paste it to another cell

I have made a macro that copies two dynamic table columns from one worksheet to another. On the Second worksheet I want to subtract those two columns and paste the result on a separate column/vector. All of this needs to be dynamic since I plan on running the macro once a day.
The closest I have come is the following code:
Sub Makro2()
Dim ws_3 As Worksheet
Set ws_3 = ThisWorkbook.Worksheets(2)
Application.CutCopyMode = False
ws_3.Range("E3:E400").FormulaR1C1 = "=RC[-2]-RC[-1]"
End Sub
So all I need in reality is for E3:E400 to be dynamic since the range of the other two columns change every day.
PS. Rather new at VBA.
This is just basic, ensure you declare your variable.
Dim lRow As Long
lRow = Range("D" & Rows.Count).End(xlUp).Row
Range("E3:E" & lRow).FormulaR1C1 =
You could try:
Option Explicit
Sub test()
Dim wsSource As Worksheet, wsDestination As Worksheet
Dim LastRow1 As Long, LastRow2 As Long, rng1 As Range, rng2 As Range, LastColumn As Long
With ThisWorkbook
Set wsSource = .Worksheets("Sheet1") '<- Data appears here
Set wsDestination = .Worksheets("Sheet2") '<- Data will be copy here
End With
With wsSource
'Let's say the two columns we want to copy is column A & B. Find Last row of A & B
LastRow1 = .Cells(.Rows.Count, "A").End(xlUp).Row
LastRow2 = .Cells(.Rows.Count, "B").End(xlUp).Row
'Create the ranges you want to copy
Set rng1 = .Range("A1:A" & LastRow1)
Set rng2 = .Range("B1:B" & LastRow2)
End With
With wsDestination
'Paste column after the last column of row 1. Find last column row 1
LastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
rng1.Copy
.Cells(1, LastColumn + 1).PasteSpecial xlPasteValues
rng2.Copy
.Cells(1, LastColumn + 2).PasteSpecial xlPasteValues
End With
Application.CutCopyMode = False
End Sub

VBA- Transferring data to another work sheet if a column has certain text and pasting it in a certain cell range

I am currently trying to filter data and paste it into another sheet to a certain range but it is only posting the latest data row. How do I fix the code so that it selects all the rows with the code word and pastes it into the other sheet.
This is my code:
Private Sub CommandButton1_Click()
Dim lastrow As Long, i As Long
lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Sheets("sheet1").Cells(i, 1) = "pp" Then
Sheets("sheet1").Range(Cells(i, 2), Cells(i, 5)).Copy
ActiveSheet.Paste Destination:=Worksheets("Sheet5").Range("A11:A22")
End If
Next
End Sub
I think this is what you want.
Private Sub CommandButton1_Click()
Dim ws1 as Worksheet: Set ws1 = Thisworkbook.Sheets("Sheet1")
Dim ws2 as Worksheet: Set ws2 = Thisworkbook.Sheets("Sheet5")
Dim LRow1 As Long, LRow2 as Long, i As Long
LRow1 = ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row
LRow2 = ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If ws1.Cells(i, 1) = "pp" Then
ws1.Range(Cells(i, 1), Cells(i, 5)).Copy
ws2.Range("A" & LRow + 1).PasteSpecial xlPasteValues
End If
Next
End Sub
Here is a more effecient method using a For Each loop and one instance of Copy/Paste instead of 1 iteration for every matched cell.
Option Explicit
Sub Copy()
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
Dim TargetRange As Range, TargetCell As Range, CopyRange As Range
Set TargetRange = ws1.Range("A2:A" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)
For Each TargetCell In TargetRange
If TargetCell = "pp" Then
If CopyRange Is Nothing Then
Set CopyRange = TargetCell.Resize(1, 4)
Else
Set CopyRange = Union(CopyRange, TargetCell.Resize(1, 4))
End If
End If
Next TargetCell
CopyRange.Copy
ws2.Range("A" & ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row).PasteSpecial xlPasteValuesAndNumberFormats
End Sub
Another method would be to apply a filter for your target value pp and then copy/paste visible cells.

Copy paste a row from one sheet to another

I am trying to copy rows from Sheet1 which meet a crieteria and post the whole row at the end of the current data. I am able to copy the row but it is not pasting it. Help will be appreciated. Here is my code I have written:
Sub Button1_Click()
Dim i As Integer
'Range("H2:O65536").ClearContents
Sheets("Sheet1").Select
LastRowColA = Range("A65536").End(xlUp).Row
For i = 2 To LastRowColA
If Cells(i, 6) = "No" Then
Rows(i).Select
Rows(i).Copy
Sheets("Sheet2").Select
Dim LastRow As Long
Dim StartRow As Long
Dim Col As Long
Dim Row As Long
StartRow = 2
Col = 1
LastRow = findLastRow(1)
For Row = StartRow To LastRow
Rows(LastRow).Select
ActiveSheet.Paste
Next Row
Else
'do nothing
End If
Next i
End Sub
Function findLastRow(ByVal Col As Integer) As Long
'Find the last row with data in a given column
findLastRow = Cells(Rows.Count, Col).End(xlUp).Row
End Function
here we go: a tad shorter, but should do the job...
Sub Button1_Click()
Dim i As Integer
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
For i = 2 To ws1.Range("A65536").End(xlUp).Row
If ws1.Cells(i, 6) = "No" Then ws1.Rows(i).Copy ws2.Rows(ws2.Cells(ws2.Rows.Count, 6).End(xlUp).Row + 1)
Next i
End Sub
To add a bit more help, why spend all that (processing) time looping through a potentially large row set when you can just filter and copy all your data at once?
See code below. You may need to tweak it a bit to match your data set.
Sub Button1_Click()
Dim ws1 as Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 as Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
With ws1
.UsedRange.AutoFilter 6, "No"
'-> assumes data starts in column A, if not adjust the 6
Intersect(.UsedRange,.UsedRange(Offset(1)).SpecialCells(xlCellTypeVisible).Copy
' -> assumes No's are there, if they may not exist, will need to error trap.
End With
With ws2
.Rows(.Cells(ws2.Rows.Count, 6).End(xlUp).Row + 1).PasteSpecial xlPasteValues
End With
ws1.AutoFilterMode = False
End Sub
// Just use it.
Sheet2.Select (Sheet1.Rows(index).Copy)
Sheet2.Paste (Rows(index))
If you want to copy, paste two or more rows then use the for loop.

Resources