Delete whitespace from Activex Excel combo box

Asked

Viewed 443 times

0

I have a default list with values and another list of "Organization" when I delete values from the default list to another organization list, organize values. The problem is that I added a combo box with the range of the organization list, I wanted the box not to display the whitespace and display only the values that correspond to the organization list, such as not displaying the whitespace of the combo box?? inserir a descrição da imagem aqui

1 answer

1

Problem

When filling the combination list by property ListFillRange, this error will occur.

ListFillRange

Solution

Then the following code can be used to remove duplicates, remove empty cells and sort (if you want to sort, read the section SortDictionary) items in your Combo Box.

Code

Sub preencher_lista()
    Dim intervalo_lista As Variant
    Dim unico As Object, u, k
    Dim i As Long
    Dim tmp As String

    Set unico = CreateObject("scripting.dictionary")

    'Objeto OLE de nome ComboBox1, este pode ser visto no parâmetro (Name) em propriedades
    ComboBox1.Clear
    'Nome da planilha utilizada
    With Sheets("Planilha1")
        'Intervalo da lista, inicia em A2 e termina na última célula preenchida
        intervalo_lista = .Range(.Cells(2, "A"), .Cells(.Rows.Count, "A").End(xlUp))
        'Único elemento
        For Each c In intervalo_lista
            tmp = Trim(c)
            'Verifica se é maior do que 0 (não vazio), se sim, adiciona ao dicionário para obter valores únicos
            If Len(tmp) > 0 Then unico(tmp) = unico(tmp) + 1
        Next c
        'Função de ordenação do dicionário
        'http://www.cpearson.com/excel/CollectionsAndDictionaries.htm
        'Descomente a linha abaixo se desejar a ordenação
        'SortDictionary unico, True

        'Adiciona na lista de combinação
        For Each k In unico.Keys
            ComboBox1.AddItem k
        Next k
    End With
End Sub

Upshot

Resultado

Sortdictionary

To use dictionary ordering SortDictionary of Cpearson, the "Microsoft Scripting Runtime" reference should be added in "Tools -> References..."

This is necessary because Early Binding is used in these dictionary functions.

Microsoft Scripting Runtime

The following code shall be added in an auxiliary functions module:

Public Sub SortDictionary(Dict As Scripting.Dictionary, _
    SortByKey As Boolean, _
    Optional Descending As Boolean = False, _
    Optional CompareMode As VbCompareMethod = vbTextCompare)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SortDictionary
' This sorts a Dictionary object. If SortByKey is False, the
' the sort is done based on the Items of the Dictionary, and
' these items must be simple data types. They may not be
' Object, Arrays, or User-Defined Types. If SortByKey is True,
' the Dictionary is sorted by Key value, and the Items in the
' Dictionary may be Object as well as simple variables.
'
' If sort by key is True, all element of the Dictionary
' must have a non-blank Key value. If Key is vbNullString
' the procedure will terminate.
'
' By defualt, sorting is done in Ascending order. You can
' sort by Descending order by setting the Descending parameter
' to True.
'
' By default, text comparisons are done case-INSENSITIVE (e.g.,
' "a" = "A"). To use case-SENSITIVE comparisons (e.g., "a" <> "A")
' set CompareMode to vbBinaryCompare.
'
' Note: This procedure requires the
' QSortInPlace function, which is described and available for
' download at www.cpearson.com/excel/qsort.htm .
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Dim Ndx As Long
Dim KeyValue As String
Dim ItemValue As Variant
Dim Arr() As Variant
Dim KeyArr() As String
Dim VTypes() As VbVarType


Dim V As Variant
Dim SplitArr As Variant

Dim TempDict As Scripting.Dictionary
'''''''''''''''''''''''''''''
' Ensure Dict is not Nothing.
'''''''''''''''''''''''''''''
If Dict Is Nothing Then
    Exit Sub
End If
''''''''''''''''''''''''''''
' If the number of elements
' in Dict is 0 or 1, no
' sorting is required.
''''''''''''''''''''''''''''
If (Dict.Count = 0) Or (Dict.Count = 1) Then
    Exit Sub
End If

''''''''''''''''''''''''''''
' Create a new TempDict.
''''''''''''''''''''''''''''
Set TempDict = New Scripting.Dictionary

If SortByKey = True Then
    ''''''''''''''''''''''''''''''''''''''''
    ' We're sorting by key. Redim the Arr
    ' to the number of elements in the
    ' Dict object, and load that array
    ' with the key names.
    ''''''''''''''''''''''''''''''''''''''''
    ReDim Arr(0 To Dict.Count - 1)

    For Ndx = 0 To Dict.Count - 1
        Arr(Ndx) = Dict.Keys(Ndx)
    Next Ndx

    ''''''''''''''''''''''''''''''''''''''
    ' Sort the key names.
    ''''''''''''''''''''''''''''''''''''''
    QSortInPlace InputArray:=Arr, LB:=-1, UB:=-1, Descending:=Descending, CompareMode:=CompareMode
    ''''''''''''''''''''''''''''''''''''''''''''
    ' Load TempDict. The key value come from
    ' our sorted array of keys Arr, and the
    ' Item comes from the original Dict object.
    ''''''''''''''''''''''''''''''''''''''''''''
    For Ndx = 0 To Dict.Count - 1
        KeyValue = Arr(Ndx)
        TempDict.Add Key:=KeyValue, Item:=Dict.Item(KeyValue)
    Next Ndx
    '''''''''''''''''''''''''''''''''
    ' Set the passed in Dict object
    ' to our TempDict object.
    '''''''''''''''''''''''''''''''''
    Set Dict = TempDict
    ''''''''''''''''''''''''''''''''
    ' This is the end of processing.
    ''''''''''''''''''''''''''''''''
Else
    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Here, we're sorting by items. The Items must
    ' be simple data types. They may NOT be Objects,
    ' arrays, or UserDefineTypes.
    ' First, ReDim Arr and VTypes to the number
    ' of elements in the Dict object. Arr will
    ' hold a string containing
    '   Item & vbNullChar & Key
    ' This keeps the association between the
    ' item and its key.
    '''''''''''''''''''''''''''''''''''''''''''''''
    ReDim Arr(0 To Dict.Count - 1)
    ReDim VTypes(0 To Dict.Count - 1)

    For Ndx = 0 To Dict.Count - 1
        If (IsObject(Dict.Items(Ndx)) = True) Or _
            (IsArray(Dict.Items(Ndx)) = True) Or _
            VarType(Dict.Items(Ndx)) = vbUserDefinedType Then
            Debug.Print "***** ITEM IN DICTIONARY WAS OBJECT OR ARRAY OR UDT"
            Exit Sub
        End If
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Here, we create a string containing
        '       Item & vbNullChar & Key
        ' This preserves the associate between an item and its
        ' key. Store the VarType of the Item in the VTypes
        ' array. We'll use these values later to convert
        ' back to the proper data type for Item.
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            Arr(Ndx) = Dict.Items(Ndx) & vbNullChar & Dict.Keys(Ndx)
            VTypes(Ndx) = VarType(Dict.Items(Ndx))

    Next Ndx
    ''''''''''''''''''''''''''''''''''
    ' Sort the array that contains the
    ' items of the Dictionary along
    ' with their associated keys
    ''''''''''''''''''''''''''''''''''
    QSortInPlace InputArray:=Arr, LB:=-1, UB:=-1, Descending:=Descending, CompareMode:=vbTextCompare

    For Ndx = LBound(Arr) To UBound(Arr)
        '''''''''''''''''''''''''''''''''''''
        ' Loop trhogh the array of sorted
        ' Items, Split based on vbNullChar
        ' to get the Key from the element
        ' of the array Arr.
        SplitArr = Split(Arr(Ndx), vbNullChar)
        ''''''''''''''''''''''''''''''''''''''''''
        ' It may have been possible that item in
        ' the dictionary contains a vbNullChar.
        ' Therefore, use UBound to get the
        ' key value, which will necessarily
        ' be the last item of SplitArr.
        ' Then Redim Preserve SplitArr
        ' to UBound - 1 to get rid of the
        ' Key element, and use Join
        ' to reassemble to original value
        ' of the Item.
        '''''''''''''''''''''''''''''''''''''''''
        KeyValue = SplitArr(UBound(SplitArr))
        ReDim Preserve SplitArr(LBound(SplitArr) To UBound(SplitArr) - 1)
        ItemValue = Join(SplitArr, vbNullChar)
        '''''''''''''''''''''''''''''''''''''''
        ' Join will set ItemValue to a string
        ' regardless of what the original
        ' data type was. Test the VTypes(Ndx)
        ' value to convert ItemValue back to
        ' the proper data type.
        '''''''''''''''''''''''''''''''''''''''
        Select Case VTypes(Ndx)
            Case vbBoolean
                ItemValue = CBool(ItemValue)
            Case vbByte
                ItemValue = CByte(ItemValue)
            Case vbCurrency
                ItemValue = CCur(ItemValue)
            Case vbDate
                ItemValue = CDate(ItemValue)
            Case vbDecimal
                ItemValue = CDec(ItemValue)
            Case vbDouble
                ItemValue = CDbl(ItemValue)
            Case vbInteger
                ItemValue = CInt(ItemValue)
            Case vbLong
                ItemValue = CLng(ItemValue)
            Case vbSingle
                ItemValue = CSng(ItemValue)
            Case vbString
                ItemValue = CStr(ItemValue)
            Case Else
                ItemValue = ItemValue
        End Select
        ''''''''''''''''''''''''''''''''''''''
        ' Finally, add the Item and Key to
        ' our TempDict dictionary.

        TempDict.Add Key:=KeyValue, Item:=ItemValue
    Next Ndx
End If


'''''''''''''''''''''''''''''''''
' Set the passed in Dict object
' to our TempDict object.
'''''''''''''''''''''''''''''''''
Set Dict = TempDict
End Sub

And all functions of the Qsortinplace in the section "The Code".

Note: It is not possible to insert more than 30,000 characters into answer, so it was not possible to enter the entire code. The functions are found in Sortingarrays of the Cpearson

  • Generated an error initializing the code. "Runtime error '-2147467259 (80004005)': "Automation error" "Unspecified error"

  • Are you trying to sort? On which line? Right-click on the Combobox and selected View Code?

  • There would be a way to create a simple code followed by a button, just to clear the empty spaces of Combobox by pressing the button. For this you would have to reduce the interval the moment the button is pressed and then somehow the range accept more content when I type add values in the "list"

  • This is simple, the hard part is commented . That is the part of Sortdictionary. Enter the code in the Worksheet used and not in a module. Don’t forget to change the sheet name in Spreadsheet 1

  • Yes but the list is already being ordered in the "Organization" range I made a formula for it to organize. The values are added in the "List" range and are organized in the "Organization", so the combobox organizes the remaining results. The problem is that it is presenting empty spaces

  • Make sure the worksheet is correct in the code, don’t forget to rename the worksheet in Worksheet 1 and if the name of Combobox is Combobox1 in properties. But this is not a technical support site, the answers are created to help multiple users, so the answer should be complete.

  • Yes, I’ll check on...

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.