I have a project that I am working on for hardware deployment at new locations. I have a userform combo box with a list of IP addresses that will be assigned to certain hardware items(i.e. credit card machines). I am trying to find a way where once one of the IP addresses is selected for use, that the item in the combobox list is either removed or grayed out and the user cannot reuse. But if for some reason the IP comes back available, that the item is now available for use in the list. The hardware and IP and other info will be added to a table/database in excel. So I am assuming that I have to validate this IP list against that table/database. But I am lost as to how I can accomplish the validation. I have tried data validation but I would like to this in VBA based on the combobox.
And here is the current code feeding the IP address combo box. You can either enter a single IP or a range.
Private Sub Submit_Data_Click() Dim wb As Workbook, ws As Worksheet, rngTarget As Range Dim s1 As String, ip1 As Variant Dim s2 As String, ip2 As Variant Dim i As Integer, n As Integer Set wb = ThisWorkbook Set ws = wb.Sheets("Arrays") Set rngTarget = ws.Range("I" & Rows.Count).End(xlUp) If Me.Add_single_IP = True Then s1 = Me.sgle_IP_add_tb1 s2 = s1 Else s1 = Me.rge_IP_start_tb2 s2 = Me.Rge_IP_End_tb2 End If ' split string into bytes ip1 = Split(s1, ".") ip2 = Split(s2, ".") ' validate Dim msg As String If UBound(ip1) <> 3 Or UBound(ip2) <> 3 Then msg = "IP must be n.n.n.n" ElseIf ip1(3) > 255 Or ip2(3) > 255 Then msg = "Host must be 1 to 255" ElseIf ip1(3) > ip2(3) Then msg = s1 & " is greater then " & s2 ElseIf ip1(0) <> ip2(0) Or ip1(1) <> ip2(1) Or ip1(2) <> ip2(2) Then msg = "Different networks" End If ' failed validation If Len(msg) > 0 Then MsgBox msg, vbCritical, s1 & "-" & s2 Exit Sub End If ' calc range and write to sheet n = ip2(3) - ip1(3) + 1 For i = 1 To n Set rngTarget = rngTarget.Offset(1, 0) ' move down rngTarget = Join(ip1, ".") ip1(3) = ip1(3) + 1 Next MsgBox n & " addresses added ", vbInformation, s1 & "-" & s2 End Sub
Like I stated prior…If I can remove the IP’s from the selection as they are assigned so that that we do not have duplicates and then have the ability to make it available again if the hardware piece is no longer being used is great. If it’s easier then allowing it to still be visible but grayed out in the list, and of course NOT allow it to be selected and adding a MsgBox error to user that the IP is already in use will also work well.
Thanks for any and all help.
Remove Column I from the RowSource of the combo box and add the items you want when the form initializes.
Private Sub UserForm_Initialize() Dim ws As Worksheet, iLastRow As Long, i As Long Set ws = ThisWorkbook.Sheets("Arrays") Me.ComboBox1.Clear iLastRow = ws.Cells(Rows.Count, "I").End(xlUp).Row For i = 3 To iLastRow If Len(ws.Cells(i, "H")) = 0 Then ' not assigned Me.ComboBox1.AddItem ws.Cells(i, "I") End If Next End Sub
I would input all IP addresses into a separate ‘helper’ range with 2 columns. The first column would have the IP address and second column will have a Yes or No value. I’d use the combination of INDEX and MATCH to populate the 2nd column dynamically (explained below).
I would then populate the
combobox with the new column filled with IP addressed but the only IP addresses populated into the
combobox are the ones with a No in the column next to it as they are not ‘In Use’.
Example of the Helper columns: Example of your Array sheet columns: A B H I +------------+------------+ +--------------+-----------------+ 1 | IP Address | In Use? | 1 | Brand/Model | CC Machine IP | 2 | 10.0.0.1 | Yes | 2 | Model ABC | 10.0.0.1 | 3 | 10.0.0.2 | Yes | 3 | Brand 123 | 10.0.0.4 | 4 | 10.0.0.3 | No | 4 | | | 5 | 10.0.0.4 | Yes | 5 | Brand 456 | 10.0.0.2 | 6 | 10.0.0.5 | No | 6 | | | +------------+------------+ +--------------+-----------------+
This would populate the
combobox with the values;
10.0.0.5 in that order with no blank spaces between them.
But how exactly do we achieve this?
Assume I’ve set up the helper columns on a new sheet called
"HelperSheet" with the ‘IP Addresses’ in
Column A and the ‘In Use?’ Yes/No in
Column B and the IP addresses from your input userform are entered to sheet
"Arrays". You can make the necessary adjustments to these values in your own code.
First, enter all the IP addresses you want to use in
Column A. The order that you enter them in will dictate the order they will populate in the
To make it easy you can enter the first IP address and then fill down the rest. You can fill down values/formulas by clicking the bottom right corner of the cell and dragging down the sheet.
Next we need to enter the INDEX/MATCH formula into
Column B in the first row an IP address has been entered. If your first IP address is in cell A2, the first formula should be next to it in cell B2.
If you want to learn more about these sheet functions you can read about them on Microsoft Office Support Page:
Next, fill the formula down the column all the way to the last IP address row. You can fill down values/formulas by clicking the bottom right corner of the cell and dragging down the sheet.
Now each cell in
Column B that has an IP address next to in in
Column A should have the above formula in it – The only difference will be the reference to
A1 in the
MATCH function, as it is not an absolute reference (which would look like
$A$1) – as it is a relative reference, it will increment the number for each row.
As you start to fill
Column I on the
"Arrays" sheet, the values in
Column B on
"HelperSheet" will start to change to Yes as long as they match a corresponding value in
Column A. Naturally as you remove the IP address from
Column I on
, the value in
Column B on
"HelperSheet" will change to NO. Any IP address entered that doesn’t match an address on the
"HelperSheet" will be ignored.
Now to populate the
In the VBE, click on the
Arrays Sheet from the list down the left hand side and change the dropdowns to ‘Worksheet’ and ‘Change’. This is going to run the code each time a change is made on the
Here is an example code (comments have been added to the far right to help explain each line as necessary).
You will need to change the name of
UserForm2 to match the name of your userform that has the
ComboBox on it.
Private Sub Worksheet_Change(ByVal Target As Range) 'Target is the cell/cells that a change has been made on to make the code run. Dim IPRangeItem As Long Dim myArray As Variant Dim IPRange As Range Dim LastRow As Long Dim ArrayCounter As Long If Target.Column = 9 Then 'This will only run the code below if the column the cells was changed in is I (the 9th column) otherwise it will exit the subroutine. LastRow = ThisWorkbook.Sheets("HelperSheet").Cells(Rows.Count, 1).End(xlUp).Row 'Finding the last row on our helper sheet where the IP addresses are entered. Set IPRange = ThisWorkbook.Sheets("HelperSheet").Range("A1:B" & LastRow) myArray = IPRange 'This line puts the range defined above straight into an Array. UserForm2.ComboBox1.Clear 'Ensures the combobox is always empty before values are assigned. ArrayCounter = 1 For IPRangeItem = 1 To UBound(myArray) If myArray(ArrayCounter, 2) = "No" Then 'Looking to see if the value in Column B was "No" (remember we put the entire helper range into an array which is faster and easier to use) UserForm2.ComboBox1.AddItem myArray(ArrayCounter, 1) 'If it was a "Yes" the IP address value is added to the Combobox list otherwise as below nothing happens. Else 'Do nothing End If ArrayCounter = ArrayCounter + 1 Next IPRangeItem Else 'Do nothing End If End Sub
Now each time a change is made to
Column I on your
"Arrays" sheet, the combobox will be re-populated with all addresses not in use, taking into account the changes made.
NOTE: The formula entered into
Column B on
"HelperSheet" only evaluates up to row 255, if you need to extend this you will need to update the ranges in the
MATCH sections accordingly.
NOTE: As this code runs each time ANY change is made on the
"Arrays" sheet, it may cause poor performance if there are a large number of changes made to your sheet often – this code is not run when any other sheets are updated/changed.
Here is an example of both ranges and the combobox:
Notice the combobox is missing the addresses you have entered into the
"Arrays" sheet as they are ‘In Use’ based on the