使用后组合框列表中的项目变灰,这样用户就无法 select 它们
Gray out items in a Combo Box list after use so users cannot select them
我有一个项目正在处理新地点的硬件部署。我有一个用户表单组合框,其中包含将分配给某些硬件项目(即信用卡机器)的 IP 地址列表。我正在尝试找到一种方法,一旦选择了其中一个 IP 地址进行使用,组合框列表中的项目就会被删除或变灰,并且用户无法重复使用。但是,如果由于某种原因 IP 恢复可用,则该项目现在可以在列表中使用。硬件和 IP 等信息将添加到 excel 中的 table/database。所以我假设我必须根据 table/database 验证此 IP 列表。但是我不知道如何完成验证。我已经尝试过数据验证,但我想在 VBA 中基于组合框进行验证。
这里是输入 IP 地址组合框的当前代码。您可以输入单个 IP 或范围。
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
就像我之前说的那样......如果我可以在分配 IP 时从选择中删除 IP,这样我们就没有重复项,然后如果硬件不再使用就可以再次使用它,那就太好了。如果允许它仍然可见但在列表中变灰更容易,当然不允许选择它并向用户添加 IP 已被使用的 MsgBox 错误也可以正常工作。
组合框应将 available/unused IP 写入数据库 table 上的 sheet 名为 MstrInv 的 M 列。
感谢所有帮助。
从组合框的 RowSource 中删除第 I 列,并在表单初始化时添加所需的项目。
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
我会将所有 IP 地址输入一个单独的 'helper' 范围,有 2 列。第一列将包含 IP 地址,第二列将包含 Yes 或 No 值。我会结合使用 INDEX 和 MATCH 来动态填充第二列(如下所述)。
然后我会在 combobox
中填充 IP 地址 的新列,但是 填充到 combobox
中的唯一 IP 地址是那些a No 在它旁边的列中,因为它们不是 '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 | | |
+------------+------------+ +--------------+-----------------+
这将用值填充 combobox
; 10.0.0.3
和 10.0.0.5
之间没有空格的顺序。
但是我们究竟是如何做到这一点的呢?
假设我已经在名为 "HelperSheet"
的新 sheet 上设置了辅助列,其中 'IP Addresses' in Column A
和 'In Use?' Yes/No in Column B
并且您输入的用户表单中的 IP 地址被输入到 sheet "Arrays"
。 您可以在自己的代码中对这些值进行必要的调整。
首先,在Column A
中输入您要使用的所有IP地址。 您输入它们的顺序将决定它们在 combobox
中的填充顺序。
为方便起见,您可以输入第一个 IP 地址,然后填写其余部分。 您可以通过单击单元格右下角并向下拖动 sheet 来填充 values/formulas。
接下来我们需要将INDEX/MATCH公式输入到Column B
中,第一行已经输入了一个IP地址。 如果您的第一个 IP 地址位于单元格 A2 中,则单元格 B2 中的第一个公式应该位于它旁边。
=IFERROR(IF(INDEX(Arrays!$I:$I5,MATCH(A1,Arrays!$I:$I5,0))=A1,"Yes"),"No")
如果您想了解更多关于这些 sheet 函数的信息,您可以在 Microsoft Office Support Page:
上阅读它们
接下来,将公式向下填写到 IP 地址的最后一行。 您可以通过单击单元格右下角并向下拖动 sheet 来填充 values/formulas。
现在 Column B
中的每个单元格在 Column A
中的旁边都有一个 IP 地址,其中应该包含上面的公式 - 唯一的区别是对 A1
中的引用MATCH
函数,因为它不是 absolute 引用(看起来像 $A
) - 因为它是 relative 引用,它将增加每一行的数字。
当您开始在 "Arrays"
sheet 上填写 Column I
时,"HelperSheet"
上的 Column B
中的值将开始变为 可以只要匹配Column A
中的对应值即可。当然,当您在 "Arrays"
上从 Column I
中删除 IP 地址时
,"HelperSheet"
上 Column B
中的值将更改为 NO。 任何与 "HelperSheet"
上的地址不匹配的 IP 地址都将被忽略。
现在填充 Combobox
在 VBE 中,单击左侧列表中的 Arrays
Sheet,然后将下拉列表更改为 'Worksheet' 和 'Change'。 每次在 "Arrays"
sheet 上进行更改时,这将转到 运行 代码。
这是一个示例代码(注释已添加到最右侧以帮助根据需要解释每一行)。
您需要更改 UserForm2
的名称,以匹配上面带有 ComboBox
的用户表单的名称。
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
现在,每次在您的 "Arrays"
sheet 上对 Column I
进行更改时,组合框将重新填充所有地址 未使用,考虑到所做的更改。
注意: 在 "HelperSheet"
上输入 Column B
的公式仅计算到第 255 行,如果您需要扩展此行,则需要更新INDEX
和 MATCH
部分中的相应范围。
注意: 因为这段代码 运行s 每次 ANY 更改 "Arrays"
sheet,如果经常对 sheet 进行大量更改,可能会导致性能不佳 - 此代码不是 运行,而其他 sheet 是 [=187] =].
这是范围和组合框的示例:
数组Sheet:
助手Sheet Sheet:
组合框列表:
请注意组合框缺少您在 "Arrays"
sheet 中输入的地址,因为它们是 'In Use' 基于 "HelperSheet"
值。
我有一个项目正在处理新地点的硬件部署。我有一个用户表单组合框,其中包含将分配给某些硬件项目(即信用卡机器)的 IP 地址列表。我正在尝试找到一种方法,一旦选择了其中一个 IP 地址进行使用,组合框列表中的项目就会被删除或变灰,并且用户无法重复使用。但是,如果由于某种原因 IP 恢复可用,则该项目现在可以在列表中使用。硬件和 IP 等信息将添加到 excel 中的 table/database。所以我假设我必须根据 table/database 验证此 IP 列表。但是我不知道如何完成验证。我已经尝试过数据验证,但我想在 VBA 中基于组合框进行验证。
这里是输入 IP 地址组合框的当前代码。您可以输入单个 IP 或范围。
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
组合框应将 available/unused IP 写入数据库 table 上的 sheet 名为 MstrInv 的 M 列。
感谢所有帮助。
从组合框的 RowSource 中删除第 I 列,并在表单初始化时添加所需的项目。
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
我会将所有 IP 地址输入一个单独的 'helper' 范围,有 2 列。第一列将包含 IP 地址,第二列将包含 Yes 或 No 值。我会结合使用 INDEX 和 MATCH 来动态填充第二列(如下所述)。
然后我会在 combobox
中填充 IP 地址 的新列,但是 填充到 combobox
中的唯一 IP 地址是那些a No 在它旁边的列中,因为它们不是 '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 | | |
+------------+------------+ +--------------+-----------------+
这将用值填充 combobox
; 10.0.0.3
和 10.0.0.5
之间没有空格的顺序。
但是我们究竟是如何做到这一点的呢?
假设我已经在名为 "HelperSheet"
的新 sheet 上设置了辅助列,其中 'IP Addresses' in Column A
和 'In Use?' Yes/No in Column B
并且您输入的用户表单中的 IP 地址被输入到 sheet "Arrays"
。 您可以在自己的代码中对这些值进行必要的调整。
首先,在Column A
中输入您要使用的所有IP地址。 您输入它们的顺序将决定它们在 combobox
中的填充顺序。
为方便起见,您可以输入第一个 IP 地址,然后填写其余部分。 您可以通过单击单元格右下角并向下拖动 sheet 来填充 values/formulas。
接下来我们需要将INDEX/MATCH公式输入到Column B
中,第一行已经输入了一个IP地址。 如果您的第一个 IP 地址位于单元格 A2 中,则单元格 B2 中的第一个公式应该位于它旁边。
=IFERROR(IF(INDEX(Arrays!$I:$I5,MATCH(A1,Arrays!$I:$I5,0))=A1,"Yes"),"No")
如果您想了解更多关于这些 sheet 函数的信息,您可以在 Microsoft Office Support Page:
上阅读它们接下来,将公式向下填写到 IP 地址的最后一行。 您可以通过单击单元格右下角并向下拖动 sheet 来填充 values/formulas。
现在 Column B
中的每个单元格在 Column A
中的旁边都有一个 IP 地址,其中应该包含上面的公式 - 唯一的区别是对 A1
中的引用MATCH
函数,因为它不是 absolute 引用(看起来像 $A
) - 因为它是 relative 引用,它将增加每一行的数字。
当您开始在 "Arrays"
sheet 上填写 Column I
时,"HelperSheet"
上的 Column B
中的值将开始变为 可以只要匹配Column A
中的对应值即可。当然,当您在 "Arrays"
上从 Column I
中删除 IP 地址时
,"HelperSheet"
上 Column B
中的值将更改为 NO。 任何与 "HelperSheet"
上的地址不匹配的 IP 地址都将被忽略。
现在填充 Combobox
在 VBE 中,单击左侧列表中的 Arrays
Sheet,然后将下拉列表更改为 'Worksheet' 和 'Change'。 每次在 "Arrays"
sheet 上进行更改时,这将转到 运行 代码。
这是一个示例代码(注释已添加到最右侧以帮助根据需要解释每一行)。
您需要更改 UserForm2
的名称,以匹配上面带有 ComboBox
的用户表单的名称。
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
现在,每次在您的 "Arrays"
sheet 上对 Column I
进行更改时,组合框将重新填充所有地址 未使用,考虑到所做的更改。
注意: 在 "HelperSheet"
上输入 Column B
的公式仅计算到第 255 行,如果您需要扩展此行,则需要更新INDEX
和 MATCH
部分中的相应范围。
注意: 因为这段代码 运行s 每次 ANY 更改 "Arrays"
sheet,如果经常对 sheet 进行大量更改,可能会导致性能不佳 - 此代码不是 运行,而其他 sheet 是 [=187] =].
这是范围和组合框的示例:
数组Sheet:
助手Sheet Sheet:
组合框列表:
请注意组合框缺少您在 "Arrays"
sheet 中输入的地址,因为它们是 'In Use' 基于 "HelperSheet"
值。