Like Kevin I usually setup UDT to also do creative concatenation scheme so it effectively has multiple columns instead of a single column and in the order you want. Extending Kevin's example you could also add separate non-key fields for Div, CustNo, etc. You could also have an M/D type add an index to the dictionary for you but then that may have to be maintained.
The essential issue is UDTs have only 1 key/index (the primary key) and it is based on a single column. You don't get to create your own separate indexes during UDT creation process. If it were a standard table and it has more than 1 index and it's useful, then you can do SetBrowseIndex() to change your search to use that index, then SetBrowseFilter() if possible, then the Find() to get a fast search result.
In your case this is how you might proceed using linear top to bottom searching but let's add SetBrowseFilter to make it go faster (also in the scripting class examples). Let's say you have UDT of famous mice (maybe your client is a Hollywood animation studio). I attached Excel file because this doesn't paste well. Assume PK is a category, Name is the famous mouse and Desc is extra info. Haven't tested this but you should get the idea.
`
'Lets say earlier you set strSearch = ""Rizzo"" because thats the non-key field you're searcing on.
'You can search by the R in Rizzo via SetBrowseFilter to make it faster
Set oUDT = oSession.AsObject(oSession.GetObject(""CM_UDT_svc"", ""SY_UDT_FAMOUS_MICE""))
retVal = oUDT.MoveFirst()
Do Until cBool(oUDT.Eof) = True
strFilter = Left(strSearch,1) : strName = """" : Found = 0
retVal = oUDT.SetBrowseFilter(strFilter) 'This filters the pending MoveNext and makes it MUCH faster
retVal = oUDT.GetValue(""UDF_NAME$"", strName)
If UCase(strName) = UCase(strSearch) Then
PK = oUDT.GetKey() 'gets the PK value
retVal = oUDT.SetBrowseFilter("""") 'Important to reset this for next attempt
Found = 1
Exit Do
Else
retMove = oUDT.MoveNext()
End If
Loop
If Found = 0 Then 'show messageBox no results found
`