Filter in Excel VBA - vba

I have a loop in VBA that loops through about 3000+ records and hides the ones that don't fit the criteria. It works just fine but it runs SUPER slow. Is there a faster or more efficient way to filter based on the following criteria? Any help would be greatly appreciated.
Dim i As Long, rng1 As Range, rng2 As Range, rng3 As Range, rng4 As Range, rng5 As Range, j As Long, sheetName As String, rng6 As Range, rng7 As Range, rng8 As Range, rng9 As Range
Set rng1 = FindHeader("Client Exclusion List", Sheet8.Name)
Set rng2 = FindHeader("CLIENT NAME", Sheet5.Name)
Set rng3 = FindHeader("MARKET SEGMENT", Sheet5.Name)
Set rng4 = FindHeader("ARCHIVED", Sheet5.Name)
Set rng5 = FindHeader("FORMULARY NAME", Sheet5.Name)
Set rng6 = FindHeader("WEBSITE", Sheet5.Name)
Set rng7 = FindHeader("PDF", Sheet5.Name)
Set rng8 = FindHeader("HPMS EXPORTED", Sheet5.Name)
Set rng9 = FindHeader("SERFF EXPORTED", Sheet5.Name)
For i = 1 To rng2.Rows.Count
'Checks to see if the Client Name is in the Excluded list
For j = 1 To rng1.Rows.Count
If rng2.Cells(i, 1).Value = rng1.Cells(j, 1).Value Then
rng2.Cells(i, 1).EntireRow.Hidden = True
End If
Next j
'Checks For all CMS records and hides the ones that are not from current year
If Left(rng3.Cells(i, 1).Value, 8) = "CMS Part" Then
If rng3.Cells(i, 1).Value <> "CMS Part D (CY " & Year(Date) & ")" Then
rng3.Cells(i, 1).EntireRow.Hidden = True
End If
End If
'Checks if record is archived
If rng4.Cells(i, 1).Value = "Yes" Then
rng4.Cells(i, 1).EntireRow.Hidden = True
End If
'Checks if record contains "Test" or "Demo" in the Name
If InStr(1, CStr(rng5.Cells(i, 1).Value), "test") > 0 Or InStr(1, CStr(rng5.Cells(i, 1).Value), "Test") > 0 Or InStr(1, CStr(rng5.Cells(i, 1).Value), "demo") > 0 Or InStr(1, CStr(rng5.Cells(i, 1).Value), "Demo") > 0 Or InStr(1, CStr(rng5.Cells(i, 1).Value), "TEST") > 0 Or InStr(1, CStr(rng5.Cells(i, 1).Value), "DO NOT USE") > 0 Then
rng5.Cells(i, 1).EntireRow.Hidden = True
End If
Next i

Here's an example that should be faster. It uses array, autofilter and doesn't process all the other ranges for each row of rng2:
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rng4 As Range
Dim rng5 As Range
Dim rng6 As Range
Dim rng7 As Range
Dim rng8 As Range
Dim rng9 As Range
Dim i As Long
Dim j As Long
Dim sheetName As String
Dim vData1
Set rng1 = FindHeader("Client Exclusion List", Sheet8.Name)
Set rng2 = FindHeader("CLIENT NAME", Sheet5.Name)
Set rng3 = FindHeader("MARKET SEGMENT", Sheet5.Name)
Set rng4 = FindHeader("ARCHIVED", Sheet5.Name)
Set rng5 = FindHeader("FORMULARY NAME", Sheet5.Name)
Set rng6 = FindHeader("WEBSITE", Sheet5.Name)
Set rng7 = FindHeader("PDF", Sheet5.Name)
Set rng8 = FindHeader("HPMS EXPORTED", Sheet5.Name)
Set rng9 = FindHeader("SERFF EXPORTED", Sheet5.Name)
Application.ScreenUpdating = False
vData1 = rng1.Value
For i = 1 To rng2.Rows.Count
'Checks to see if the Client Name is in the Excluded list
For j = LBound(vdata1, 1) To UBound(vdata1, 1)
If rng2.Cells(i, 1).Value = vdata1(j, 1) Then
rng2.Cells(i, 1).EntireRow.Hidden = True
Exit For
End If
Next j
Next i
'Checks For all CMS records and hides the ones that are not from current year
rng3.AutoFilter 1, "<>CMS Part*", xlOr, "CMS Part D (CY " & Year(Date) & ")"
'Checks if record is archived
rng4.AutoFilter 1, "<>Yes"
'Checks if record contains "Test" or "Demo" in the Name
rng5.AutoFilter 1, "<>*test*", xlAnd, "<>*demo*"
Application.ScreenUpdating = True

One small change that should help is adding
Application.ScreenUpdating = False
at the beginning and
Application.ScreenUpdating = True
at the end
The screen updating time can be much more substantial than the logic.
Edit as an alternative to the array loop. Creates a dictionary filled with the excluded items as keys before the big loop. A set would be better here since you have a useless item to go with each key but I don't think VBA has those.
Instead of the loop through the range or an array you just check for the existence of the key in the dictionary.
'before loop
Dim excludedList As Object
Set excludedList = CreateObject("Scripting.Dictionary")
For i = 1 To rng1.Rows.Count
excludedList.Add rng1.Cells(i, 1).value, 1
Next i
'****************************************
'in loop
If excludedList.exists(rng2.Cells(i, 1).Value) Then
rng2.Cells(i, 1).EntireRow.Hidden = True
End If

Related

Loop through the range and then sheets and delete rows based on cell value

I'm working on a loop that will feed of a cell in sheet "Results" and go through number of worksheets (at the moment set to 1-3) and delete the row where it finds the value from sheet "Results". At the moment it fails, can you please advise?
Sub Del_Rows()
Dim rng As Range, cell As Range, del As Range
Dim sht As Worksheet
For x = 1 To 3
Set sht = Sheets(x)
Set del = Sheets("Results").Range("A13")
Set rng = Intersect(sht.Range("A1:A2000"), sht.UsedRange)
For Each cell In rng.Cells
If (cell.Value) = Sheets("Results").Range("A13") Then
If del Is Nothing Then
Set del = cell
Else
Set del = Union(del, cell)
End If
End If
Next cell
If del Is del Then del.EntireRow.Delete
Next x
End Sub
Also, I understand it might be a lot trickier to do but is it possible for the code to have a look at the dynamic range in sheet("Results") one by one?
What I mean is e.g. the code takes the value of Sheets("Results").Range("A13") and does the search for the value across the sheets 1-3 deleting rows when it finds it, and then it moves to Sheets("Results").Range("A14") and does the same thing.
Since the data in [Sheets("Results").Range("A13") + last row] is dynamic it simply does the same thing until it reaches the end (e.g. Sheets("Results").Range("A20").
Thanks a lot
I didn't test the code, so maybe there's some syntax error or typo.
Dim wb as workbook
Set wb = ActiveWorkbook
set rsws = wb.worksheets("Results")
dim lastResult as Long
lastResult = rsws.Usedrange.SpecialCells(xlCelltypeLastcell).Row 'count the last row of ResultSheet.
dim lastrowCheck as Long
for each ws in wb.worksheets 'loop through each worksheet
lastrowCheck = ws.Usedrange.SpecialCells(xlCelltypeLastcell).Row
if ws.name <> "Results" then
for i = 1 to lastResult 'loop through each Result range cell
for j = 1 to lastrowCheck 'loop throught and check value
if rsws.cells(i,13) <> vbNullString then
if rsws.cells(i,13) = ws.cells(j,1) then 'I suppose that it's in the first column.
'your deleting code here
end if
end if
next j
next i
end if
next ws
Below is the actual code in my excel which includes some debug print.
Sub testtesttest()
Dim wb As Workbook
Set wb = ActiveWorkbook
Set rsws = wb.Worksheets("Results")
Dim lastResult As Long
lastResult = rsws.UsedRange.SpecialCells(xlCellTypeLastCell).Row 'count the last row of ResultSheet.
Dim lastrowCheck As Long
For Each ws In wb.Worksheets 'loop through each worksheet
lastrowCheck = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row
Debug.Print "lastrowCheck "; lastrowCheck
Debug.Print ws.name
If ws.name <> "Results" Then
For i = 1 To lastResult 'loop through each Result range cell
For j = 1 To lastrowCheck 'loop throught and check value
If rsws.Cells(i, 13) = ws.Cells(j, 1) Then 'I suppose that it's in the first column.
'your deleting code here
Debug.Print "good good good"
End If
Next j
Next i
End If
Next ws
End Sub
I have managed to work on my initial code and came up with the following solution, which works for me.
Public Sub Loop_DEL()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'----------------------------------------------------------------------
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
'----------------------------------------------------------------------
Dim rng1 As Range, rng2 As Range, rng3 As Range, rng4 As Range, rng5 As Range, rng6 As Range, rng7 As Range, rng8 As Range, c As Range
Dim rngToDel2 As Range, rngToDel3 As Range, rngToDel4 As Range, rngToDel5 As Range, rngToDel6 As Range, rngToDel7 As Range, rngToDel8 As Range
Dim lastRow As Long
With Worksheets("Results")
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rng1 = .Range("A3:A" & lastRow)
End With
Set rng2 = Worksheets("ANY SCORE").Range("A:A")
Set rng3 = Worksheets("Page1").Range("A:A")
Set rng4 = Worksheets("Page2").Range("A:A")
Set rng5 = Worksheets("Page3").Range("A:A")
Set rng6 = Worksheets("Page4").Range("A:A")
Set rng7 = Worksheets("Page5").Range("A:A")
Set rng8 = Worksheets("Page6").Range("A:A")
For Each c In rng2
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel2 Is Nothing Then
Set rngToDel2 = c
Else
Set rngToDel2 = Union(rngToDel2, c)
End If
End If
Next c
If Not rngToDel2 Is Nothing Then rngToDel2.EntireRow.Delete
For Each c In rng3
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel3 Is Nothing Then
Set rngToDel3 = c
Else
Set rngToDel3 = Union(rngToDel3, c)
End If
End If
Next c
If Not rngToDel3 Is Nothing Then rngToDel3.EntireRow.Delete
For Each c In rng4
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel4 Is Nothing Then
Set rngToDel4 = c
Else
Set rngToDel4 = Union(rngToDel4, c)
End If
End If
Next c
If Not rngToDel4 Is Nothing Then rngToDel4.EntireRow.Delete
For Each c In rng5
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel5 Is Nothing Then
Set rngToDel5 = c
Else
Set rngToDel5 = Union(rngToDel5, c)
End If
End If
Next c
If Not rngToDel5 Is Nothing Then rngToDel5.EntireRow.Delete
For Each c In rng6
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel6 Is Nothing Then
Set rngToDel6 = c
Else
Set rngToDel6 = Union(rngToDel6, c)
End If
End If
Next c
If Not rngToDel6 Is Nothing Then rngToDel6.EntireRow.Delete
For Each c In rng7
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel7 Is Nothing Then
Set rngToDel7 = c
Else
Set rngToDel7 = Union(rngToDel7, c)
End If
End If
Next c
If Not rngToDel7 Is Nothing Then rngToDel7.EntireRow.Delete
For Each c In rng8
If Not IsError(Application.Match(c.Value, rng1, 0)) Then
If rngToDel8 Is Nothing Then
Set rngToDel8 = c
Else
Set rngToDel8 = Union(rngToDel8, c)
End If
End If
Next c
If Not rngToDel8 Is Nothing Then rngToDel8.EntireRow.Delete
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

populate listbox with specific rows from an excel sheet

I have an excel sheet named ("PPSBoarded") with 15 columns. I want to select rows based on similar values in column B and then display it in listbox on a VBA form. I tried this but it's not working:
Dim FoundCell As Range
Dim LastCell As Range
Dim FirstAddr As String
With Range("B1:B2")
Set LastCell = .Cells(.Cells.Count)
End With
Set FoundCell = Range("B1:B").Find(what:="EK261/GRU", after:=LastCell)
If Not FoundCell Is Nothing Then
FirstAddr = FoundCell.Address
End If
Do Until FoundCell Is Nothing
Debug.Print FoundCell.Address
Set FoundCell = Range("B1:B").FindNext(after:=FoundCell)
If FoundCell.Address = FirstAddr Then
Exit Do
End If
Loop
Me.ListBox1.List = FirstAddr
Your code should look like this:
Dim arrLstBox()
Dim rng, FoundCell, tmpCell As Range
Dim i, j, numRows, lastColumn, lastRow As Long
Dim FirstAddress, searchFor, colWidth As String
Set rng = ActiveSheet.UsedRange
numRow = 0
With rng
lastRow = .Rows.Count
lastColumn = .Columns.Count
End With
Me.ListBox1.ColumnCount = lastColumn
For x = 1 To lastColumn
If x = lastColumn Then
colWidth = colWidth & "1,5cm"
Exit For
End If
colWidth = colWidth & "1,5cm;"
Next x
Me.ListBox1.ColumnWidths = colWidth
searchFor = InputBox("Your word:")
Set FoundCell = rng.Find(what:=searchFor)
If Not FoundCell Is Nothing Then _
FirstAddress = FoundCell.Address
Do Until FoundCell Is Nothing
Set FoundCell = rng.FindNext(after:=FoundCell)
If FoundCell.Address = FirstAddress Then
numRow = numRow + 1
Exit Do
ElseIf FoundCell.Row <> rng.FindNext(after:=FoundCell).Row Then
numRow = numRow + 1
End If
Loop
ReDim arrLstBox(1 To numRow, 1 To lastColumn)
Do Until FoundCell Is Nothing
For i = 1 To numRow
For j = 1 To lastColumn
If Not IsEmpty(Cells(FoundCell.Row, j).Value) Then
arrLstBox(i, j) = Cells(FoundCell.Row, j).Value
End If
Set FoundCell = rng.FindNext(after:=FoundCell)
Next j
If FoundCell.Address = FirstAddress Then _
Exit For
Next i
If FoundCell.Address = FirstAddress Then _
Exit Do
Loop
Me.ListBox1.List = arrLstBox()

Conditional loop with running sum is skipping values

I have created this code with the purpose of:
First Loop:
Loop through cells in column O to find anything that starts with DAAP.
If Cell 5 columns left of DAAP is empty then add the cell 1 column to the right (which is a number) to Total. Then rename the cell to GAAF
If Cell 5 columns left is not empty then just rename the cell to GAAF
Second Loop:
Find all GAAF cells in column O and then change the cell 1 column to the right to Total
Here is the code I have, it runs with no errors but just does nothing. I'm assuming something is syntax'ed wrong so it's looking in the wrong place but I can't find it! Any help is greatly appreciated :)
Dim rng As Range
Dim lstRow As Long
Dim AUMCell As Range
Dim Total As Long
lstRow = Cells(Rows.Count, "O").End(xlUp).Row
Set rng = Range("O2", Cells(lstRow, "O"))
Total = 0
For Each AUMCell In rng
If AUMCell.value = "DAAP" & "*" And AUMCell.Offset(0, -5).value = "" Then
Total = Total + AUMCell.Offset(0, 1).Value
AUMCell.value = "GAAF"
ElseIf AUMCell.value = "DAAP" & "*" And AUMCell.Offset(0, -5).value <> "" Then
AUMCell.value = "GAAF"
End If
Next AUMCell
For Each AUMCell In rng
If AUMCell.Value = "GAAF" Then
AUMCell.Offset(0, 1).Value = Total
End If
Next AUMCell
While the code is longer the execution of Find will be much quicker than a loop through each cell.
Sub Recut()
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim aCell As Range
Dim bCell As Range
Dim ws As Worksheet
Dim SearchString As String
Set ws = ActiveSheet
Set rng1 = ws.Range("O:O")
SearchString = "DAAP"
Set aCell = rng1.Find(SearchString, , xlFormulas, xlPart, xlByRows, xlNext)
If Not aCell Is Nothing Then
Set bCell = aCell
If Left$(aCell.Value, 4) = SearchString Then Set rng2 = aCell
Do
Set aCell = rng1.FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
If Left$(aCell.Value, 4) = SearchString Then
If Not rng2 Is Nothing Then
Set rng2 = Union(rng2, aCell)
Else
Set rng2 = aCell
End If
End If
Else
Exit Do
End If
Loop
Else
MsgBox SearchString & " not Found"
Exit Sub
End If
If rng2 Is Nothing Then Exit Sub
For Each rng3 In rng2
If Len(rng3.Offset(0, -5)) = 0 Then Total = Total + rng3.Offset(0, 1).Value
rng3.Value = "GAFF"
Next
MsgBox Total
End Sub
Try to replace this code
For Each AUMCell In rng
If AUMCell.value = "DAAP" & "*" And AUMCell.Offset(0, -5).value = "" Then
Total = Total + AUMCell.Offset(0, 1).Value
AUMCell.value = "GAAF"
ElseIf AUMCell.value = "DAAP" & "*" And AUMCell.Offset(0, -5).value <> "" Then
AUMCell.value = "GAAF"
End If
Next AUMCell
by this code
For Each AUMCell In rng
If AUMCell.value like "DAAP*" Then
If AUMCell.Offset(0, -5).value = "" Then
Total = Total + AUMCell.Offset(0, 1).Value
End If
AUMCell.value = "GAAF"
End If
Next AUMCell
P.S.: Sorry my english

VBA search in two ranges

I'm more than new at this, and I'm having trouble sorting out For...Next loops.
I want to track to two text variables in two columns, so that when both variables are found in a row text is added to that row in a different column.
This is what I have so far:
Sub AB()
Dim Rng1 As Range
Dim Rng2 As Range
Set Rng1 = Range("B1:B100")
Set Rng2 = Range("A1:A100")
For Each cel In Rng1
If InStr(1, cel.Value, "A") > 0 Then
For Each cel In Rng2
If InStr(1, cel.Value, "B") > 0 Then
cel.Offset(0, 5).Value = "AB"
End If
Next
End If
Next cel
End Sub
You might even be able to just do this?
Sub AB()
With ActiveSheet
For I = 1 To 100
If InStr(1, .Cells(I, 2), "A") > 0 And InStr(1, .Cells(I, 1), "B") > 0 Then
.Cells(I, 6).Value = "AB" 'i think offset 5 is column F?
End If
Next
End With
End Sub
Appreciate you have an answer now, but here's a different method using Find. Always good to know several ways to do something.
Sub AB()
Dim rng As Range
Dim itemaddress As String
With Columns(1)
Set rng = .Find("A", searchorder:=xlByRows, lookat:=xlWhole)
If Not rng Is Nothing Then
itemaddress = rng.Address
Do
If rng.Offset(0, 1) = "B" Then
rng.Offset(0, 2).Value = "AB"
End If
Set rng = .FindNext(rng)
Loop While Not rng Is Nothing And itemaddress <> rng.Address
End If
End With
End Sub
You're using `cel' to step through each loop - the inner loop will get confused.
Along the vein of #findwindow answer (appeared as I was typing this). Loop just once and when a match is found check the cell next to it.
Sub AB()
Dim Rng1 As Range
Dim Rng2 As Range
Dim cel1 As Range
'Be specific about which sheet your ranges are on.
With ThisWorkbook.Worksheets("Sheet1")
Set Rng1 = .Range("B1:B100")
Set Rng2 = .Range("A1:A100")
End With
For Each cel1 In Rng1
'Check each value in column B.
If InStr(1, cel1.Value, "A") > 0 Then
'If a match is found, check the value next to it.
If InStr(1, cel1.Offset(, -1), "B") > 0 Then
cel1.Offset(, 4).Value = "AB"
End If
End If
Next cel1
End Sub

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