Я бы просто использовал встроенную функцию проверки данных.Укажите на список, и тогда пользователям будет представлен раскрывающийся список с плавающим уровнем. Редактировать: Хорошо, тогда основной принцип здесь - это связанные списки.Для каждой подкатегории будет текст категории и родительская категория.Каждый раз, когда изменяется основная категория, вы повторно фильтруете подкатегорию, чтобы показать только элементы, принадлежащие этой родительской категории.
Есть много способов реализовать эту идею.Вот тривиальный пример.Чтобы использовать его, создайте пользовательскую форму с двумя выпадающими списками и вставьте код.
Option Explicit
Private masCat2() As String
Private Sub UserForm_Initialize()
Me.ComboBox1.List = CreateTestData(0)
With Me.ComboBox2
masCat2 = CreateTestData(1)
End With
End Sub
Private Sub ComboBox1_Change()
Me.ComboBox2.List = FilterArray(masCat2, Me.ComboBox1.Value)
End Sub
Private Function FilterArray(ByRef vals() As String, ByVal match As String) As String()
Dim i As Long, j As Long
Dim asVals() As String
ReDim asVals(UBound(vals, 1)) As String
For i = 0 To UBound(vals, 1)
If vals(i, 0) = match Then
asVals(j) = vals(i, 1)
j = j + 1
End If
Next
ReDim Preserve asVals(j - 1)
FilterArray = asVals
End Function
Private Function CreateTestData(ByVal series As Long) As String()
Dim asRtnVal() As String
Select Case series
Case 0
ReDim asRtnVal(1) As String
asRtnVal(0) = "Thing1"
asRtnVal(1) = "Thing2"
Case 1
ReDim asRtnVal(3, 1) As String
asRtnVal(0, 0) = "Thing1"
asRtnVal(1, 0) = "Thing1"
asRtnVal(2, 0) = "Thing2"
asRtnVal(3, 0) = "Thing2"
asRtnVal(0, 1) = "ThingA"
asRtnVal(1, 1) = "ThingB"
asRtnVal(2, 1) = "ThingC"
asRtnVal(3, 1) = "ThingD"
End Select
CreateTestData = asRtnVal
End Function