I have code for matching values in column 'B' with the value in Cell 'M15' and copy and delete those rows.
I only need to copy and delete a range (A to J) and not the entire row.
Sub MoveRows()
Dim Sht1 As Worksheet, Sht3 As Worksheet
Dim tfRow As Range, C As Range
Dim CopyRng As Range
Dim LastRow As Long
Application.ScreenUpdating = False
Set Sht1 = Sheets("Sheet1")
Set Sht3 = Sheets("Sheet3")
With Sht1
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
Set tfRow = .Range("B2:B" & LastRow)
For Each C In tfRow
If IsEmpty(C) Then
Exit Sub
End If
If C.Value = .Range("M15").Value Then
If Not CopyRng Is Nothing Then
Set CopyRng = Application.Union(CopyRng, C)
Else
Set CopyRng = C
End If
End If
Next C
End With
If Not CopyRng Is Nothing Then
LastRow = Sht3.Cells(Sht3.Rows.Count, "B").End(xlUp).Row
CopyRng.EntireRow.Copy Destination:=Sht3.Range("A" & LastRow + 1)
CopyRng.EntireRow.Delete (xlShiftUp)
End If
The basic code below uses an auto-filter(much faster then looping) and copies the visible cells in the range to the first empty cell in column A.
Deleting part of your data will cause the rows to shift and possible screw up your data. I also provided a line of code to only clear you range.
Dim ws1 As Worksheet, ws3 As Worksheet, lRow As Long, Rng As Range
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws3 = ThisWorkbook.Sheets("Sheet3")
lRow = ws3.Cells(Rows.Count, 1).End(xlUp).Row
Set Rng = ws1.Range("A1").CurrentRegion
Rng.AutoFilter Field:=2, Criteria1:=ws1.Range("M15").Value
ws1.Range(Cells(2, 1), Cells(Rng.Rows.Count, 10)).SpecialCells(xlCellTypeVisible).Copy _
Destination:=ws3.Range("A" & lRow + 1)
'You must clear the range and then remove the filter before deleting blank cells.
ws1.Range(Cells(2, 1), Cells(Rng.Rows.Count, 10)).SpecialCells(xlCellTypeVisible).Clear
ws1.Cells.AutoFilter
ws1.Range(Cells(2, 1), Cells(Rng.Rows.Count, 10)).SpecialCells(xlCellTypeBlanks).Delete Shift:=xlUp
Related
I have this code which cuts and pastes an entire row to another sheet. When i set values as = it works, but when i set to like or contains, the loop doesnt happen. The value of the filter i'm looking for would keep changing including with a unique phrase. Eg: 1. Overlap error: 1234, 1. Overlap error:1235 etc.
Sub loopMe()
Dim sh As Worksheet, ws As Worksheet
Dim LstR As Long, rng As Range, c As Range
Set sh = Sheets("Sheet1") 'set the sheet to loop
Set ws = Sheets("Sheet2") 'set the sheet to paste
With sh 'do something with the sheet
LstR = .Cells(.Rows.Count, "BE").End(xlUp).Row 'find last row
Set rng = .Range("BE5:BE" & LstR) 'set range to loop
End With
'start the loop
For Each c In rng.Cells
'If c = "1. Overlap error:" Then
If c.Value Like "*1. Overlap error:*" Then
'If Left(c.Value, 17) = "1. Overlap error:" Then
'If InStr(1, c, "1. Overlap error:") > 0 Then
c.EntireRow.Copy ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(1) 'copy row to first empty row in sheet2
c.EntireRow.Delete Shift:=xlUp
End If
Next c
End Sub
You can use a filter to find the data, move it and delete the rows.
Sub ed()
Dim sh As Worksheet, ws As Worksheet
Dim rng As Range
Set sh = Sheets("Sheet1")
Set ws = Sheets("Sheet2")
With sh
.Range("BE4").AutoFilter Field:=1, Criteria1:= _
"=*1. Overlap error:*", Operator:=xlAnd
Set rng = .Range("BE5:BE" & .Cells(.Rows.Count, "BE").End(xlUp).Row)
With ws
rng.SpecialCells(xlCellTypeVisible).EntireRow.Copy ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(1)
End With
rng.EntireRow.Delete
.AutoFilterMode = False
End With
End Sub
So if you prefer your original approach,
Sub loopMe()
Dim sh As Worksheet, ws As Worksheet
Dim LstR As Long, c As Range
Set sh = Sheets("Sheet1")
Set ws = Sheets("Sheet2")
'find last row
LstR = sh.Range("BE65000").End(xlUp).Row
Dim irow
For irow = LstR To 5 Step -1
Set c = sh.Range("BE" & irow)
If c.Value Like "*1. Overlap error:*" Then
'copy row to first empty row in sheet2
c.EntireRow.Copy ws.Cells(65000, 1).End(xlUp).Offset(1, 0)
c.EntireRow.Delete Shift:=xlUp
End If
Next irow
End Sub
Dim lastrow As Long, lastrow2 As Long
Dim wksSource As Worksheet, wksDest As Worksheet
Dim source1 As Range, target1 As Range, source2 As Range, target2 As Range
Set wksSource = Workbooks("2021 Tracker.xlsm").Worksheets("Sheet3")
Set wksDest = Workbooks("Jan Tracker).xlsm").Worksheets("Sheet1")
lastrow = wksSource.Cells(Rows.Count, 1).End(xlUp).row
lastrow2 = wksDest.Cells(Rows.Count, 1).End(xlUp).Offset(1,0).row
Set source1 = wksSource.Range("A2:A" & lastrow)
Set source2 = wksSource.Range("B2:B" & lastrow)
Set target1 = wksDest.Range("E" & lastrow2)
Set target2 = wksDest.Range("F" & lastrow2)
source1.Copy: target1.PasteSpecial Paste:=xlPasteValues
source2.Copy: target2.PasteSpecial Paste:=xlPasteValues
This code replaces data in columns E and F of destination workbook, but i want it to append to it. Please help.
Your code determines the next row in column A of the destination worksheet: lastrow2 = wksDest.Cells(Rows.Count, 1).End(xlUp).Offset(1,0).Row. But you are pasting to columns E and F. Therefore the last row in column A doesn't change and that results in over-writing.
I have re-written your code to make it more transparent. I think this kind of syntax will make it easier for you to spot errors like the one that you asked about. It may take a little more time to set up but the time is well invested.
Sub AppendData()
Dim wksSource As Worksheet ' Source sheet
Dim wksTarget As Worksheet ' Target sheet
Dim Source1 As Range
Dim Target As Range
Dim Rl As Long ' last row
Set wksSource = Workbooks("2021 Tracker.xlsm").Worksheets("Sheet3")
With wksSource
Rl = .Cells(.Rows.Count, "A").End(xlUp).Row
Set Source = .Range(.Cells(2, "A"), .Cells(Rl, "B"))
End With
Set wksTarget = Workbooks("Jan Tracker).xlsm").Worksheets("Sheet1")
With wksTarget
Set Target = .Cells(.Rows.Count, "E").End(xlUp).Offset(1)
End With
Source.Copy Deestination:=Target
Application.CutCopyMode = False
End Sub
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
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.
Sub iterateThroughAll()
ScreenUpdating = False
Dim wks As Worksheet
Set wks = ActiveSheet
Dim rowRange As Range
Dim colRange As Range
Dim LastCol As Long
Dim LastRow As Long
LastRow = wks.Cells(wks.Rows.Count, "A").End(xlUp).Row
Set rowRange = wks.Range("A1:A" & LastRow)
'Loop through each row
For Each rrow In rowRange
'Find Last column in current row
LastCol = 1 'wks.Cells(rrow, wks.Columns.Count).End(xlToLeft).Column
Set colRange = wks.Range(wks.Cells(rrow, 1), wks.Cells(rrow, LastCol)) <-------------- I get a Run-time error 1004 Application defined or object defined error.
'Loop through all cells in row up to last col
For Each cell In colRange
'Do something to each cell
Debug.Print (cell.Value)
Next cell
Next rrow
ScreenUpdating = True
End Sub
I get an Application-defined or object-defined error. The code looks okay but not sure why its not working here.
I am trying to get all the used cells in Column A
Option Explicit
Sub iterateThroughAll()
Application.ScreenUpdating = False
Dim wks As Worksheet
Set wks = ActiveSheet
Dim rowRange As Range, rrow As Range
Dim colRange As Range, Cell As Range
Dim LastCol As Long
Dim LastRow As Long
LastRow = wks.Cells(wks.Rows.Count, "A").End(xlUp).Row
Set rowRange = wks.Range("A1:A" & LastRow)
'Loop through each row
For Each rrow In rowRange
'Find Last column in current row
LastCol = 1 'wks.Cells(rrow, wks.Columns.Count).End(xlToLeft).Column
Set colRange = wks.Range(wks.Cells(rrow.Row, 1), wks.Cells(rrow.Row, LastCol))
'Loop through all cells in row up to last col
For Each Cell In colRange
'Do something to each cell
Debug.Print (Cell.Value)
Next Cell
Next rrow
Application.ScreenUpdating = True
End Sub