Adding criteria to VBA copy and paste - vba

I have the following code that works but I need to add another criteria to it. The criteria I need to add is a wildcard search for *Utilities. So if column L has the word utilities, then include the row in the copy and paste. If not, do not copy and paste.
Sub CopyData()
Dim Cl As Range
Dim SrcWbk As Workbook
Dim SrcSht As Worksheet
Dim DestSht As Worksheet
Dim Rng As Range
Application.ScreenUpdating = False
Set SrcWbk = Workbooks.Open("Transactional Activity PD 10-2017 (Expense
Accounts).xlsb")
Set SrcSht = SrcWbk.Sheets("Activity")
Set DestSht = ThisWorkbook.Sheets("Transactions")
With CreateObject("scripting.dictionary")
For Each Cl In DestSht.Range("AE2", DestSht.Range("AE" &
Rows.Count).End(xlUp))
If Not .exists(Cl.Value) Then .Add Cl.Value, Nothing
Next Cl
For Each Cl In SrcSht.Range("AE2", SrcSht.Range("AE" &
Rows.Count).End(xlUp))
If Not .exists(Cl.Value) And Cl.Offset(, -29).Value = "PV" And
Cl.Offset(, -15) Like "*Utilities" Then
If Rng Is Nothing Then
Set Rng = Cl
Else
Set Rng = Union(Rng, Cl)
End If
End If
Next Cl
End With
Rng.EntireRow.Copy DestSht.Range("A" & Rows.Count).End(xlUp).Offset(1)
End Sub
THANKS!

The following adds a criteria of only including rows where "utilities" is found in column L of the same row as the test being performed on column AE. Not tested.
Dim Cl As Range
Dim SrcWbk As Workbook
Dim SrcSht As Worksheet
Dim DestSht As Worksheet
Dim Rng As Range
Application.ScreenUpdating = False
Set SrcWbk = Workbooks.Open("Transactional Activity PD 10-2017 (Expense Accounts).xlsb")
Set SrcSht = SrcWbk.Sheets("Activity")
Set DestSht = ThisWorkbook.Sheets("Transactions")
With CreateObject("scripting.dictionary")
For Each Cl In DestSht.Range("AE2", DestSht.Range("AE" & Rows.Count).End(xlUp))
If Not .exists(Cl.Value) Then .Add Cl.Value, Nothing
Next Cl
For Each Cl In SrcSht.Range("AE2", SrcSht.Range("AE" & Rows.Count).End(xlUp))
If Not .exists(Cl.Value) And Cl.Offset(, -29).Value = "PV" And _
InStr(Cl.Offset(, -19), "utilities") > 0 Then
If Rng Is Nothing Then
Set Rng = Cl
Else
Set Rng = Union(Rng, Cl)
End If
End If
Next Cl
End With
Rng.EntireRow.Copy DestSht.Range("A" & Rows.Count).End(xlUp).Offset(1)
End Sub

Related

Select the same range in multiple workheets

So I need to select the same range in all worksheets except "Sheet1". The range is dinamic based on the value "s1" on the column A. So I want to select what is in column B for the value s1, make it bold, then to count the s1 values in column C.
This is what I have so far
Sub test()
Dim ws As Worksheet
Dim lastrow As Long
Dim xRg As Range, yRg As Range, zRg As Range
Dim cell As Range
Dim C1 As Range
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Sheet1" Then
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Application.ScreenUpdating = False
For Each xRg In Range("A1:A" & lastrow)
If xRg.Text = "s1" Then
If yRg Is Nothing Then
Set yRg = Range("B" & xRg.Row).Resize(, 1)
k = 1
For Each cell In yRg
yRg.Cells(k, 2) = k
yRg.Cells.Select
k = k + 1
Next cell
Else
Set yRg = Union(yRg, Range("B" & xRg.Row).Resize(, 1))
If Not yRg Is Nothing Then yRg.Select
For Each C1 In yRg
C1.EntireRow.Font.Bold = True
Next C1
End Sub
Try this code:
Option Explicit
Sub test()
Dim ws As Worksheet
Dim xRg As Range, yRg As Range
Application.ScreenUpdating = False
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Sheet1" Then
ws.Cells.Font.Bold = False ' clear bold formatting for debugging purposes
Set yRg = Nothing
For Each xRg In ws.Range("A1", ws.Cells(ws.Rows.Count, "A").End(xlUp))
If xRg.Text = "s1" Then
If yRg Is Nothing Then
Set yRg = xRg.Offset(0, 1)
Else
Set yRg = Union(yRg, xRg.Offset(0, 1))
End If
xRg.Offset(0, 2) = yRg.Cells.Count 'set entry number
End If
Next xRg
If Not yRg Is Nothing Then yRg.Font.Bold = True
End If
Next ws
Application.ScreenUpdating = True
End Sub
Before
After
A selection or a range does not extend across multiple sheets; there is a selection per sheet. So you need to work within each sheet.
You had a lot of unclosed loops and conditions. This is my best guess at what you were trying to do:
Sub test()
Dim ws As Worksheet
Dim lastrow As Long
Dim xRg As Range, yRg As Range
Dim cell As Range
Dim s1count As Long
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Sheet1" Then
Set yRg = Nothing
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
For Each xRg In Range("A1:A" & lastrow)
If xRg.Text = "s1" Then
If yRg Is Nothing Then
Set yRg = xRg.Offset(0, 1)
Else
Set yRg = Union(yRg, xRg.Offset(0, 1))
End If
End If
Next xRg
If Not yRg Is Nothing Then
s1count = 0
For Each cell In yRg
cell.EntireRow.Font.Bold = True
s1count = s1count + 1
cell.Offset(0, 1) = s1count
Next cell
End If
End If
Next ws
End Sub

If cel.Val = "A0_" & A Then

I have an excel workbook where I want to find the cell that contains "A0_" & A where A is the value from another worksheet. The end goal is to copy the column with "A0_" & A to another sheet titled. Here is my code so far.
Sub Copy_A()
Dim A As String
Dim iRng As Range
Dim cel As Range
Dim dataws As Worksheet
Dim Rng1, Rng2, Rng3, NewRng As Range
Set dataws = Worksheets("Data Importation Sheet")
Set iRng = dataws.Range(dataws.Cells(1, 1), dataws.Cells(1, dataws.Cells(1, Columns.Count).End(xlToLeft).Column))
A = Worksheets("Information Sheet").Range("E12").Value
For Each cel In iRng
If cel.Value = "A0_" & A Then
Set Rng1 = cel.EntireColumn.Find(What:="", LookIn:=xlValues, lookat:=xlPart)
Debug.Print Rng1.FormulaR1C1
Set Rng2 = dataws.Cells(Rng1.Row - 1, Rng1.Column + 1)
Debug.Print Rng2.FormulaR1C1
Set Rng3 = Cells(cel.Row + 1, cel.Column)
Debug.Print Rng3.FormulaR1C1
End If
Next cel
With dataws
Set NewRng = .Range(Rng3.Address & ":" & Rng1.Address)
Debug.Print NewRng.Address
NewRng.Select
End With
End Sub
For some reason the code does not recognize "A0_" & A when it reaches that cell. The code goes through each column but does not execute setting the ranges. Any tips/help would be greatly appreciated! Here is a picture of my workbook to give you a better idea of what is happening

vlookup split value VBA

I have created macro that works like a vlookup but has split values. I would like to find value from second sheet of split values (separated by semicolon ) and copy and paste the description to new sheet.
The first loop goes through the list in sheet 2 and sets the value in a variable, the second loop through split values checks when there is exact match and the description is copied and pasted to the second sheet.
However - it doesn't work and I don't know what the problem is.
I have notification "type mismatch".
I tried vlookup with part text string but it doesn't work either.
Sub Metadane()
Dim ws As Worksheet
Dim aCell As Range, rng As Range
Dim Lrow As Long, i As Long
Dim myAr
Dim ws2 As Worksheet
Dim bCell As Range, rng2 As Range
Dim variable As String
'~~> Change this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("A1:A" & Lrow)
Set ws2 = ThisWorkbook.Sheets("Sheet2")
With ws2
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Set your range
Set rng2 = .Range("A1:A" & Lrow)
'~~> Loop trhough your range
For Each bCell In rng2
If Len(Trim(bCell.Value)) <> 0 Then
variable = bCell.Value
For Each aCell In rng
'~~> Skip the row if value in cell A is blank
If Len(Trim(aCell.Value)) <> 0 Then
'~~> Check if the cell has ";"
'~~> If it has ";" then loop through values
If InStr(1, aCell.Value, ";") Then
myAr = Split(aCell.Value, ";")
For i = LBound(myAr) To UBound(myAr)
If myAr = variable Then
Worksheets("sheet2").bCell(, 2).PasteSpecial xlPasteValues
Next i
Else
Worksheets("sheet2").bCell(, 2).PasteSpecial xlPasteValues
End If
End If
Next
End If
Next
End With
End Sub
I changed my code but it is still not work properly, I have a result:
try this
Sub test()
Dim Cl As Range, Key As Variant
Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")
Dic.CompareMode = vbTextCompare
With Sheets("Sheet1")
For Each Cl In .Range("A1:A" & .Cells.SpecialCells(xlCellTypeLastCell).Row)
If Cl.Value <> "" Then
Dic.Add Cl.Row & "|" & Replace(LCase(Cl.Value), ";", "||") & "|", Cl.Offset(, 1).Text
End If
Next Cl
End With
With Sheets("Sheet2")
For Each Cl In .Range("A1:A" & .Cells.SpecialCells(xlCellTypeLastCell).Row)
For Each Key In Dic
If Key Like "*|" & LCase(Cl.Value) & "|*" And Cl.Value <> "" Then
Cl.Offset(, 1).Value = Dic(Key)
Exit For
End If
Next Key
Next Cl
End With
End Sub
Output Result
Sub YourVLookup()
Dim rng As Variant, rng2 As Variant
Dim lastRow As Long, i As Long, j As Long, k As Long
Dim aCell As Variant, bCell As Variant
Dim myAr() As String, variable As String
lastRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:B"&lastRow)
lastRow = ThisWorkbook.Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
Set rng2 = ThisWorkbook.Worksheets("Sheet2").Range("A1:B"&lastRow)
For i = LBound(rng2, 1) To UBound(rng2, 1)
If Len(Trim(rng2(i, 1))) <> 0 Then
variable = rng2(i, 1)
For j = LBound(rng, 1) To UBound(rng, 1)
If Len(Trim(rng(j, 1))) <> 0 Then
If InStr(1, rng(j, 1), ";") > 0 Then
myAr = Split(rng(j, 1))
For k = LBound(myAr) To UBound(myAr)
If myAr(k) = variable Then
rng2(i, 2) = myAr(k)
End If
Next k
ElseIf rng(j, 1) = rng2(i, 1) Then
rng2(i, 2) = rng(j, 2)
End If
End if
Next j
End If
Next i
lastRow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Worksheets("Sheet1").Range("A1:B"&lastRow) = rng
lastRow = ThisWorkbook.Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Worksheets("Sheet2").Range("A1:B"&lastRow) = rng2
End Sub
You were pasting something that you don't have copied already, you forgot to close a With, and you can't use bCell(,2), so
Try this :
Sub Metadane()
Dim ws As Worksheet
Dim aCell As Range, rng As Range
Dim Lrow As Long, i As Long
Dim myAr() As String
Dim ws2 As Worksheet
Dim bCell As Range, rng2 As Range
Dim variable As String
'~~> Change this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("A1:A" & Lrow)
End With
Set ws2 = ThisWorkbook.Sheets("Sheet2")
With ws2
'~~> Find the last row in Col A
Lrow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Set your range
Set rng2 = .Range("A1:A" & Lrow)
'~~> Loop trhough your range
For Each bCell In rng2
If Len(Trim(bCell.Value)) <> 0 Then
variable = bCell.Value
For Each aCell In rng
'~~> Skip the row if value in cell A is blank
If Len(Trim(aCell.Value)) <> 0 Then
'~~> Check if the cell has ";"
'~~> If it has ";" then loop through values
If InStr(1, aCell.Value, ";") Then
myAr = Split(aCell.Value, ";")
For i = LBound(myAr) To UBound(myAr)
If myAr(i) <> variable Then
Else
'You were pasting nothing with that
'.bCell(, 2).PasteSpecial xlPasteValues
.Cells(bCell.Row, 2) = aCell.Offset(0, 1).Value
End If
Next i
Else
'Same here
'.bCell(, 2).PasteSpecial xlPasteValues
.Cells(bCell.Row, 2) = aCell.Offset(0, 1).Value
End If
End If
Next aCell
End If
Next bCell
End With
End Sub

Delete rows from one sheet based on values from another sheet

I have total email ids in COL A of Sheet 1 and bounced email ids in COL A of Sheet 2. I want to delete Sheet 1 values or entire rows based on values on Sheet 2.
I tried the following code but doesn't work.
Public Sub delete_selected_rows()
'look at sheet2, A1 through A3 for search values
For Each search_value In Worksheets("Sheet2").Range("A1:A3")
'as long as there is something to delete...
Do While Not Worksheets("Sheet1").Range("A1:A3"). _
Find(search_value.Value, lookat:=xlWhole) Is Nothing
'...delete that row
Worksheets("Sheet1").Range("A1:A3").Find(search_value.Value, _
lookat:=xlWhole).EntireRow.Delete
Loop
Next
End Sub
Any help ?
I would use this one:
Public Sub delete_selected_rows()
Dim rng1 As Range, rng2 As Range, rngToDel As Range, c As Range
Dim lastRow as Long
With Worksheets("Sheet1")
lastRow = .Cells(.Rows.Count,"A").End(xlUp).Row
Set rng1 = .Range("A1:A" & lastRow)
End With
Set rng2 = Worksheets("Sheet2").Range("A:A")
For Each c In rng1
If Not IsError(Application.Match(c.Value, rng2, 0)) Then
'if value from rng1 is found in rng2 then remember this cell for deleting
If rngToDel Is Nothing Then
Set rngToDel = c
Else
Set rngToDel = Union(rngToDel, c)
End If
End If
Next c
If Not rngToDel Is Nothing Then rngToDel.EntireRow.Delete
End Sub
Try this:
Sub Macro1()
Dim lrow As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
With ws1
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("B1:B" & lrow)
.Formula = "=IFERROR(MATCH(A1," & ws2.Name & "!A:A,0),"""")"
.Value = .Value
.AutoFilter 1, "<>"
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
.AutoFilterMode = False
End With
End Sub

Search column for 0, copy to new sheet, and delete row - help needed

This is what I have already, and it works great in removing #N/As from the range. I am now looking to modify it to do the same thing for cells that contain 0.
Sub DeleteErrorRows()
Dim r As Range
Set r = Range("B:B").SpecialCells(xlCellTypeConstants, 16).EntireRow
r.Copy Sheets("Sheet2").Range("A1")
r.Delete
End Sub
Thanks :)
Try this. It autofilters your column and keeps rows that have the findMe value in your source worksheet. You can set it to 0 as I have in the example or to whatever else you want. It copies those rows (except for the header row) to the target sheet and then deletes them from the source sheet.
Note that this also finds the first empty row on the target sheet so that you can run it multiple times without overwriting what you've already moved to the target sheet.
Sub CopyThenDeleteRowsWithMatch()
Dim wb As Workbook
Dim ws As Worksheet
Dim tgt As Worksheet
Dim rng As Range
Dim lastRow As Long
Dim firstPasteRow As Long
Dim findMe As String
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
Set tgt = wb.Sheets("Sheet2")
lastRow = ws.Range("B" & ws.Rows.Count).End(xlUp).Row
firstPasteRow = tgt.Range("B" & tgt.Rows.Count).End(xlUp).Row + 1
findMe = "0"
Set rng = ws.Range("B1:B" & lastRow)
' filter and delete all but header row
With rng
.AutoFilter Field:=1, Criteria1:="=" & findMe
With .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
.Copy tgt.Range("A" & firstPasteRow)
.Delete
End With
End With
' turn off the filters
ActiveSheet.AutoFilterMode = False
End Sub
Consider:
Sub DeleteZeroRows()
Dim r As Range, rTemp As Range, rB As Range
Set rB = Intersect(Range("B:B"), ActiveSheet.UsedRange)
Set r = Nothing
For Each rTemp In rB
If Not IsEmpty(rTemp) And rTemp.Value = 0 Then
If r Is Nothing Then
Set r = rTemp
Else
Set r = Union(r, rTemp)
End If
End If
Next rTemp
Set r = r.EntireRow
r.Copy Sheets("Sheet2").Range("A1")
r.Delete
End Sub