VBA to filter IP addresses based on first 2 octets

addistexan

New Member
Joined
Oct 30, 2023
Messages
8
Office Version
  1. 365
Platform
  1. Windows
Hello,
I've been trying to figure out how easily filter out IP addresses based on their first 2 octets. By using this platform and tweeking a formula, I was able to filter out IP addresses with an exact match. However, there are so many IP addresses in each range that I think it makes more sense to filter based on the first 2 octets instead. My original formula that works for match on full IP address is: =LET(x,FILTERXML("<x><y>"&SUBSTITUTE(A5,", ","</y><y>")&"</y></x>","//y"),TEXTJOIN(" ",1,FILTER(x,ISERROR(MATCH(x,FILTERXML("<x><y>"&SUBSTITUTE(TEXTJOIN(" ",1,CloudflareIP)," ","</y><y>")&"</y> </x>","//y"),0)),"")))

To make it more complicated, some cells have 1 IP address, and some may have up to 200 IP addresses in a single cell, all seperated by commas.

Now I've been trying to use a macro to look at each cell in my range (A1:A3000) in worksheet1, take each IP address, read the first 2 octets (e.g., 123.123.) and compare that to my list in worksheet2. I there is a match, I want the entire IP address from worksheet1 deleted, otherwise, go to the next. By the end, I want each cell to contain all the IP addresses is started with (with the matched ones removed), and all separated by a comma. Here are a couple of my attempts:

Sub FilterIPAddress1()

Dim Cell As Range
Dim cell2 As Range
Dim SearchRange As Range
Dim IPAddress As String
Dim OctetsSearchRange As Range
Dim OctetsToMatch As String


' OctetsToMatch = "" ' Replace with your desired first 2 octets

' Define the range to search for IP addresses (change this to match your actual range)
Set SearchRange = Worksheets("Sheet1").Range("A1:A3000")

'Define the range where Octets to search will be kept
Set OctetsSearchRange = Worksheets("Sheet2").Range("A1:D5000")

' Loop through each cell in worksheet 1
For Each Cell In SearchRange
If Cell.Value <> "" Then
' Extract the IP address in the first 2 octets
IPAddress = Left(Cell.Value, InStr(Cell.Value, ".") - 1)
' Loop through each Octet in worksheet 2
For Each cell2 In OctetsSearchRange
' Check if the Octet in Worksheet 1 matches an Octet in Worksheet 2
If IPAddress = OctetsToMatch Then
' If it matches, delete the entire IP address
Cell.ClearContents
End If
End If
Next Cell

End Sub
And another:
Sub FilterIPAddresses2()

Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim cell1 As Range
Dim cell2 As Range
Dim sentence As String
Dim ipParts() As String
Dim ipPart As Variant
Dim firstTwoOctets As String
Dim opticsToDelete As String

' Set the worksheets you want to work with
Set ws1 = ThisWorkbook.Worksheets("Sheet1") ' Change "Sheet1" to your first worksheet name
Set ws2 = ThisWorkbook.Worksheets("Sheet2") ' Change "Sheet2" to your second worksheet name

' Loop through each cell in the first worksheet
For Each cell1 In ws1.UsedRange
sentence = cell1.Value
opticsToDelete = ""

' Split the sentence into individual IP addresses based on commas
ipParts = Split(sentence, ",")

' Loop through each IP address
For Each ipPart In ipParts
' Extract the first two octets
firstTwoOctets = Left(ipPart, InStr(ipPart, ".", InStr(ipPart, ".") + 1) - 1)

' Check if the firstTwoOctets exist in the second worksheet
If WorksheetFunction.CountIf(ws2.UsedRange, firstTwoOctets) > 0 Then
' If it exists, add the entire IP address to the list to delete
opticsToDelete = opticsToDelete & ipPart & ","
End If
Next ipPart

Of course I'm not getting proper reults or errors and I am way beyond my ability. Thank you for any suggestions or assistance!
 

Excel Facts

How can you automate Excel?
Press Alt+F11 from Windows Excel to open the Visual Basic for Applications (VBA) editor.
Hello,

I didn't get the last part.
For example;
A1:123.123.456.456,123.123.456.456,456.456.789.789,456.456.789.789
A2:123.123.456.456,123.123.456.456,456.456.789.789,456.456.789.789
In the end do you want:
A1: 456.456.789.789,456.456.789.789
A2: 456.456.789.789,456.456.789.789
??

My second question is, in which column is the IP list located in Sheet2?
 
Last edited by a moderator:
Upvote 0
So, in worksheet 1
A1: 123.123.456.465, 321.321.255.255, 222.333.444.555, 111.111.222.222
In worksheet 2,
A1: 123.123
A2: 222.333

Result in worksheet1 A1: 321.321.255.255, 111.111.222.222

The IP list would probably be in column A but I can make it anything.

Thank you.
 
Upvote 0
Here is a formula option, although tested on 30,000+ rows - it's not fast on that amount of data:
Book1
ABCD
1IP'sFiltered IP'sSheet 2 Lookup List
2233.120.62.187233.120.62.187128.173
3116.183.221.34116.183.221.346.159
4252.37.189.35,164.204.72.127,156.20.214.50252.37.189.35,156.20.214.50164.204
5170.95.200.71170.95.200.7148.165
66.159.127.43,144.155.12.203,128.173.37.184,10.47.13.87,52.28.39.75144.155.12.203,10.47.13.87,52.28.39.75
754.120.221.14454.120.221.144
8215.94.7.125215.94.7.125
9129.147.211.17129.147.211.17
1020.97.145.24220.97.145.242
11236.186.243.214236.186.243.214
1265.55.88.5465.55.88.54
13222.236.139.102222.236.139.102
14201.55.213.224201.55.213.224
15119.193.251.143119.193.251.143
1648.165.149.15
Sheet1
Cell Formulas
RangeFormula
B2:B15B2=LET(rng,A2:A16,lu,D2:D5, sData,IFERROR(FILTERXML("<t><s>" & SUBSTITUTE(rng,",","</s><s>") & "</s></t>","//s[" & SEQUENCE(,MAX(BYROW(rng,LAMBDA(x,LEN(x)-LEN(SUBSTITUTE(x,",",""))+1)))) & "]"),""), fData,BYROW(MAP(sData,LAMBDA(x,IF(COUNTIF(lu,TEXTBEFORE(x,".",2))>0,"",x))),LAMBDA(x,TEXTJOIN(",",1,x))), FILTER(fData,fData<>""))
Dynamic array formulas.
 
Upvote 0
Here is the VBA solution. Please let me know if leftover commas bother you.
VBA Code:
Sub test()
Dim ipList As Object, ipListArr As Variant, lRow As Long, listItem As Variant, myData As Variant, tmp As Variant, j As Long, octes As String
  Set ipList = CreateObject("Scripting.Dictionary")
  With Worksheets("Sheet2")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  ipListArr = .Range("A1:A" & lRow)
  End With
  For Each listItem In ipListArr
    If Not ipList.Exists(Trim(listItem)) Then
      ipList.Add Trim(listItem), 1
    End If
  Next
  With Worksheets("Sheet1")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  myData = .Range("A1:A" & lRow)
  
  For i = 1 To UBound(myData, 1)
    tmp = Split(myData(i, 1), ",")
    For j = 0 To UBound(tmp) - 1
      octes = Split(Trim(tmp(j)), ".")(0) & "." & Split(Trim(tmp(j)), ".")(1)
      If ipList.Exists(octes) Then
        myData(i, 1) = Replace(myData(i, 1), Trim(tmp(j)), "")
      End If
    Next
  Next
  .Range("A1").Resize(UBound(myData, 1)).Value = myData
  End With
End Sub
 
Upvote 0
With eliminating commas:
VBA Code:
Sub test()
Dim ipList As Object, ipListArr As Variant, lRow As Long, listItem As Variant, myData As Variant, tmp As Variant, j As Long, octes As String
  Set ipList = CreateObject("Scripting.Dictionary")
  With Worksheets("Sheet2")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  ipListArr = .Range("A1:A" & lRow)
  End With
  For Each listItem In ipListArr
    If Not ipList.Exists(Trim(listItem)) Then
      ipList.Add Trim(listItem), 1
    End If
  Next
  With Worksheets("Sheet1")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  myData = .Range("A1:A" & lRow)
 
  For i = 1 To UBound(myData, 1)
    tmp = Split(myData(i, 1), ",")
    For j = 0 To UBound(tmp)
      octes = Split(Trim(tmp(j)), ".")(0) & "." & Split(Trim(tmp(j)), ".")(1)
      If ipList.Exists(octes) Then
        myData(i, 1) = IIf(j < UBound(tmp), Replace(myData(i, 1), Mid(myData(i, 1), InStr(myData(i, 1), tmp(j)), (InStr(InStr(myData(i, 1), tmp(j)), myData(i, 1), tmp(j + 1)) - InStr(myData(i, 1), tmp(j)))), "",,1), Replace(myData(i, 1), tmp(j), "",,1))
      End If
    Next
  Next
  .Range("A1").Resize(UBound(myData, 1)).Value = myData
  End With
End Sub
 
Upvote 0
Here is a formula option, although tested on 30,000+ rows - it's not fast on that amount of data:
Book1
ABCD
1IP'sFiltered IP'sSheet 2 Lookup List
2233.120.62.187233.120.62.187128.173
3116.183.221.34116.183.221.346.159
4252.37.189.35,164.204.72.127,156.20.214.50252.37.189.35,156.20.214.50164.204
5170.95.200.71170.95.200.7148.165
66.159.127.43,144.155.12.203,128.173.37.184,10.47.13.87,52.28.39.75144.155.12.203,10.47.13.87,52.28.39.75
754.120.221.14454.120.221.144
8215.94.7.125215.94.7.125
9129.147.211.17129.147.211.17
1020.97.145.24220.97.145.242
11236.186.243.214236.186.243.214
1265.55.88.5465.55.88.54
13222.236.139.102222.236.139.102
14201.55.213.224201.55.213.224
15119.193.251.143119.193.251.143
1648.165.149.15
Sheet1
Cell Formulas
RangeFormula
B2:B15B2=LET(rng,A2:A16,lu,D2:D5, sData,IFERROR(FILTERXML("<t><s>" & SUBSTITUTE(rng,",","</s><s>") & "</s></t>","//s[" & SEQUENCE(,MAX(BYROW(rng,LAMBDA(x,LEN(x)-LEN(SUBSTITUTE(x,",",""))+1)))) & "]"),""), fData,BYROW(MAP(sData,LAMBDA(x,IF(COUNTIF(lu,TEXTBEFORE(x,".",2))>0,"",x))),LAMBDA(x,TEXTJOIN(",",1,x))), FILTER(fData,fData<>""))
Dynamic array formulas.
Thank you for taking the time to test that for me. I would love to be able to use a formula because macros are a bit of a challenge to manage, but you are correct, with so many records, I am really looking to speeding up the process. Thanks again.
 
Upvote 0
With eliminating commas:
VBA Code:
Sub test()
Dim ipList As Object, ipListArr As Variant, lRow As Long, listItem As Variant, myData As Variant, tmp As Variant, j As Long, octes As String
  Set ipList = CreateObject("Scripting.Dictionary")
  With Worksheets("Sheet2")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  ipListArr = .Range("A1:A" & lRow)
  End With
  For Each listItem In ipListArr
    If Not ipList.Exists(Trim(listItem)) Then
      ipList.Add Trim(listItem), 1
    End If
  Next
  With Worksheets("Sheet1")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  myData = .Range("A1:A" & lRow)
 
  For i = 1 To UBound(myData, 1)
    tmp = Split(myData(i, 1), ",")
    For j = 0 To UBound(tmp)
      octes = Split(Trim(tmp(j)), ".")(0) & "." & Split(Trim(tmp(j)), ".")(1)
      If ipList.Exists(octes) Then
        myData(i, 1) = IIf(j < UBound(tmp), Replace(myData(i, 1), Mid(myData(i, 1), InStr(myData(i, 1), tmp(j)), (InStr(InStr(myData(i, 1), tmp(j)), myData(i, 1), tmp(j + 1)) - InStr(myData(i, 1), tmp(j)))), "",,1), Replace(myData(i, 1), tmp(j), "",,1))
      End If
    Next
  Next
  .Range("A1").Resize(UBound(myData, 1)).Value = myData
  End With
End Sub
Wow - I'm impressed and appreciate your help. I tried both macro codes and the first one worked but left commas that I would have to delete. This second one gives me a runtime error 9. I tried to debug but it highlights the IIF statement. Were you able to run this successfully? Perhaps I did something wrong on my end?
 

Attachments

  • Lineerror.png
    Lineerror.png
    38 KB · Views: 7
  • Specific Error.png
    Specific Error.png
    10.2 KB · Views: 8
Upvote 0
You are right,
Not elegant as before but this should work. String manipulation is not my strongest part.
VBA Code:
Sub test()
  Dim ipList As Object, ipListArr As Variant, lRow As Long, listItem As Variant, myData As Variant, tmp As Variant, j As Long, octes As String
  Set ipList = CreateObject("Scripting.Dictionary")
  With Worksheets("Sheet2")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  ipListArr = .Range("A1:A" & lRow)
  End With
  For Each listItem In ipListArr
    If Not ipList.Exists(Trim(listItem)) Then
      ipList.Add Trim(listItem), 1
    End If
  Next
  With Worksheets("Sheet1")
  lRow = .Cells(Rows.Count, "A").End(xlUp).Row
  myData = .Range("A1:A" & lRow)
 
  For i = 1 To UBound(myData, 1)
    tmp = Split(myData(i, 1), ",")
    For j = 0 To UBound(tmp)
      octes = Split(Trim(tmp(j)), ".")(0) & "." & Split(Trim(tmp(j)), ".")(1)
      If ipList.Exists(octes) Then
        If j < UBound(tmp) Then
          myData(i, 1) = Replace(myData(i, 1), Mid(myData(i, 1), InStr(myData(i, 1), tmp(j)), (InStr(InStr(myData(i, 1), tmp(j)), myData(i, 1), tmp(j + 1)) - InStr(myData(i, 1), tmp(j)))), "", , 1)
        Else
          myData(i, 1) = Replace(myData(i, 1), tmp(j), "")
        End If
        If Right(Trim(myData(i, 1)), 1) = "," Then
          myData(i, 1) = Left(Trim(myData(i, 1)), Len(Trim(myData(i, 1))) - 1)
        End If
      End If
    Next
  Next
  .Range("A1").Resize(UBound(myData, 1)).Value = myData
  End With
End Sub
 
Upvote 0
Perhaps the below UDF will be faster than my previous formula effort:
NOTE: I had to format the list in column D to be TEXT so as to keep the trailing 0's

VBA Code:
Function FilterIPs(IPs As Range, rList As Range) As Variant
    Dim var As Variant, x As Long, y As Long, z As Long
    Dim rVar As Variant, tVar As Variant
  
    var = IPs.Value
    rVar = rList.Value
  
    For x = 1 To UBound(var)
        tVar = Split(var(x, 1), ",")
        For y = 0 To UBound(tVar)
            For z = 1 To UBound(rVar)
                If Left(tVar(y), Len(rVar(z, 1))) = rVar(z, 1) Then tVar(y) = "": Exit For
            Next z
        Next y
        var(x, 1) = Application.TextJoin(",", True, tVar)
    Next x
    FilterIPs = var
End Function

Used on your sheet as below:
zzzz.xlsm
ABCD
1IP'sFiltered IP'sSheet 2 Lookup List
2119.193.251.143,233.120.62.187,233.120.62.187,236.186.243.215119.193.251.143,236.186.243.215233.120
3116.183.221.34116.183.221.346.159
4252.37.189.35,164.204.72.127,156.20.214.50252.37.189.35,156.20.214.50164.204
5170.95.200.71170.95.200.71201.55
66.159.127.43,144.155.12.203,128.173.37.184,10.47.13.87,52.28.39.75144.155.12.203,128.173.37.184,10.47.13.87,52.28.39.75
754.120.221.14454.120.221.144
8215.94.7.125215.94.7.125
9129.147.211.17129.147.211.17
1020.97.145.24220.97.145.242
11236.186.243.214236.186.243.214
1265.55.88.5465.55.88.54
13222.236.139.102222.236.139.102
14201.55.213.224119.193.251.143
15119.193.251.14348.165.149.15
1648.165.149.15
Sheet1
Cell Formulas
RangeFormula
B2:B15B2=LET( d,FilterIPs(A2:A16,D2:D5), FILTER(d,d<>"") )
Dynamic array formulas.
 
Upvote 1

Forum statistics

Threads
1,224,812
Messages
6,181,084
Members
453,021
Latest member
Justyna P

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top