Results 1 to 11 of 11

Thread: Useful ListBox, ComboBox and Array() Functions

  1. #1

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Useful ListBox, ComboBox and Array() Functions

    vb Code:
    1. Public Function ArrayInitialized(v_Array As Variant) As Boolean
    2. Dim X As Variant
    3.  
    4. On Error GoTo errHandler
    5.  
    6. X = UBound(v_Array)
    7.  
    8. ArrayInitialized = True
    9.  
    10. Exit Function
    11.  
    12. errHandler:
    13. ArrayInitialized = False
    14.  
    15. End Function
    16.  
    17.  
    18. ' Most functions listed here ensure you're sending a list to them.
    19. '  The next function does that.
    20.  
    21. Public Function IsList(List As Control) As Boolean
    22.  
    23. ' Determines if control is a list.
    24.  
    25. IsList = (TypeName(List) = "ListBox") Or (TypeName(List) = "ComboBox") Or (TypeName(List) = "FileListBox")
    26.  
    27. End Function
    28.  
    29. ' Takes everything in the list and puts it in an array.
    30. Public Function FillArrayFromList(List As Control, ByRef sArray() As String, Optional vItemData) As Long
    31. Dim n As Long
    32.  
    33. On Error GoTo errHandler
    34. ' Returns Error Code.
    35.  
    36. If Not IsList(List) Then Exit Function ' Return 0
    37.  
    38. If List.ListCount > 0 Then
    39.   ReDim sArray(List.ListCount - 1)
    40.   If Not IsMissing(vItemData) Then ReDim vItemData(List.ListCount - 1)
    41. Else
    42.   Erase sArray
    43.   If Not IsMissing(vItemData) Then Erase vItemData
    44.   Exit Function ' Return 0
    45. End If
    46.  
    47. For n = 0 To List.ListCount - 1
    48.  
    49.   sArray(n) = List.List(n)
    50.  
    51.   If Not IsMissing(vItemData) Then
    52.     vItemData(n) = List.ItemData(n)
    53.   End If
    54.  
    55. Next n
    56.  
    57. ' Return 0
    58.  
    59. Exit Function
    60.  
    61. errHandler:
    62. FillArrayFromList = Err
    63.  
    64. End Function
    65.  
    66. ' Puts only selected items in a multi-select list into an array.
    67. Public Function FillArrayFromListSelected(List As Control, ByRef sArray() As String) As Long
    68. Dim n As Long
    69. Dim j As Long
    70. Dim nCount As Long
    71.  
    72. ' Stuffs all selected items from a ListBox or ComboBox into an array.
    73.  
    74. On Error GoTo errHandler
    75. ' Returns Error Code.
    76.  
    77. nCount = List.SelCount
    78. If nCount = 0 Then Exit Function
    79.  
    80. ReDim sArray(nCount - 1)
    81.  
    82. For n = 0 To List.ListCount - 1
    83.   If List.Selected(n) Then
    84.     sArray(j) = List.List(n)
    85.     j = j + 1
    86.   End If
    87. Next n
    88.  
    89. ' Return 0
    90.  
    91. Exit Function
    92.  
    93. errHandler:
    94. FillArrayFromListSelected = Err
    95.  
    96. End Function
    97.  
    98. ' Fills a list from an array.
    99. Public Function FillListFromArray(List As Control, sArray() As String) As Long
    100. Dim n As Long
    101.  
    102. On Error GoTo errHandler
    103. ' Returns Error Code.
    104.  
    105. List.Clear
    106.  
    107. If Not ArrayInitialized(sArray) Then Exit Function ' Return 0
    108.  
    109. For n = LBound(sArray) To UBound(sArray)
    110.   List.AddItem sArray(n)
    111. Next n
    112.  
    113. List.ListIndex = -1
    114.  
    115. ' Return 0
    116.  
    117. Exit Function
    118.  
    119. errHandler:
    120. FillListFromArray = Err
    121.  
    122. End Function
    123.  
    124. ' This one works well when you're filling a list from a database and using the
    125. ' Primary key (Long integer) as the ItemData.
    126. Public Function ListIndexFromItemData(List As Control, ItemData As Long) As Long
    127. Dim n As Long
    128.  
    129. ' Returns the ListIndex of a List item when given ItemData.
    130.  
    131. On Error GoTo errHandler
    132.  
    133. ListIndexFromItemData = -1
    134.  
    135. If Not IsList(List) Then Exit Function ' Return -1
    136.  
    137. With List
    138.   For n = 0 To .ListCount - 1
    139.     If .ItemData(n) = ItemData Then
    140.       ListIndexFromItemData = n
    141.       Exit Function
    142.     End If
    143.   Next n
    144. End With
    145.  
    146. ' Return -1
    147.  
    148. Exit Function
    149.  
    150. errHandler:
    151. LogError Error, Err, List.Name, "bLists.ListIndexFromItemData()"
    152.  
    153. End Function
    154.  
    155. Public Function ItemDataFromListIndex(List As Control) As Variant
    156.  
    157. ' Returns the ItemData of a selected item in a ListBox or ComboBox.
    158.  
    159. On Error GoTo errHandler
    160.  
    161. ItemDataFromListIndex = 0
    162. If Not IsList(List) Then Exit Function
    163.  
    164. ItemDataFromListIndex = List.ItemData(List.ListIndex)
    165.  
    166. Exit Function
    167.  
    168. errHandler:
    169. LogError Error, Err, List.Name, "bLists.ItemDataFromListIndex()"
    170.  
    171. End Function
    172.  
    173. Public Sub MoveDownInList(ByRef List As Control)
    174. Dim iListIndex As Long
    175. Dim sItem As String
    176. Dim fSelected As Boolean
    177. Dim v_ItemData As Variant
    178.  
    179. ' Moves a list item down in the list by one item.
    180. ' Saves Selected status (Multi-Select lists) and ItemData.
    181.  
    182. If Not IsList(List) Then Exit Sub
    183.  
    184. ' If selected item is last in list then do nothing.
    185. If List.ListIndex = List.ListCount - 1 Then Exit Sub
    186.  
    187. With List
    188.   ' Save Selected property.
    189.   fSelected = .Selected(.ListIndex)
    190.  
    191.   iListIndex = .ListIndex
    192.   sItem = .List(.ListIndex)
    193.  
    194.   ' Save ItemData.
    195.   v_ItemData = .ItemData(.ListIndex)
    196.  
    197.   ' Remove item from list
    198.   .RemoveItem .ListIndex
    199.  
    200.   ' Place item back in list one index lower.
    201.   .AddItem sItem, iListIndex + 1
    202.  
    203.   ' Restore Selected property.
    204.   .Selected(.NewIndex) = fSelected
    205.  
    206.   .ListIndex = .NewIndex
    207.  
    208.   ' Restore ItemData.
    209.   .ItemData(.NewIndex) = v_ItemData
    210. End With
    211.  
    212. End Sub
    213.  
    214. Public Function MoveFromListToList(ByVal Index As Integer, ByRef FromList As Control, ByRef ToList As Control) As Long
    215.  
    216. On Error GoTo errHandler
    217.  
    218. ' Removes a selected item from one list and puts it in another list.
    219. ' Returns 0 if succesful or -1 if nothing moved.
    220.  
    221. MoveFromListToList = -1
    222.  
    223. If Index < 0 Then Exit Function ' Return -1
    224. If Not IsList(FromList) Then Exit Function ' Return -1
    225. If Not IsList(ToList) Then Exit Function  ' Return -1
    226.  
    227. With ToList
    228.   .AddItem FromList.List(Index)
    229.   .ItemData(.NewIndex) = FromList.ItemData(Index)
    230. End With
    231.  
    232. FromList.RemoveItem Index
    233.  
    234. ' Return 0
    235. MoveFromListToList = 0
    236.  
    237. Exit Function
    238.  
    239. errHandler:
    240.  
    241. MoveFromListToList = -1
    242.  
    243. End Function
    244.  
    245. Public Sub MoveUpInList(List As Control)
    246. Dim iListIndex As Long
    247. Dim sItem As String
    248. Dim fSelected As Boolean
    249. Dim v_ItemData As Variant
    250.  
    251. ' Moves a list item up in the list by one item.
    252. ' Saves Selected status (Multi-Select lists) and ItemData.
    253.  
    254. If Not IsList(List) Then Exit Sub
    255.  
    256. If List.ListIndex < 1 Then Exit Sub
    257.  
    258. With List
    259.   fSelected = .Selected(.ListIndex)
    260.  
    261.   iListIndex = .ListIndex
    262.   sItem = .List(.ListIndex)
    263.  
    264.   ' Save ItemData.
    265.   v_ItemData = .ItemData(.ListIndex)
    266.  
    267.   ' Remove item from list.
    268.   .RemoveItem .ListIndex
    269.  
    270.   ' Place item back in list one index higher.
    271.   .AddItem sItem, iListIndex - 1
    272.  
    273.   .Selected(.NewIndex) = fSelected
    274.   .ListIndex = .NewIndex
    275.  
    276.   ' Restore ItemData.
    277.   .ItemData(.NewIndex) = v_ItemData
    278. End With
    279.  
    280. End Sub
    281.  
    282. ' The next two are good for ensuring you flexgrids restore what the user set.
    283. Public Sub RestoreFlexGridColumnWidths(frm As Form, Flex As Control)
    284. Dim iCol As Integer
    285.  
    286. On Error Resume Next
    287.  
    288. If TypeName(Flex) <> "MSFlexGrid" Then Exit Sub
    289.  
    290. With Flex
    291.   .Redraw = False
    292.   For iCol = 0 To .Cols - 1
    293.     .ColWidth(iCol) = Registry.GetSetting("Windows", frm.Name & " Col " & iCol, 2400)
    294.   Next iCol
    295.   .Redraw = True
    296.   .row = 0
    297. End With
    298.  
    299. End Sub
    300.  
    301. Public Sub SaveFlexGridColumnWidths(frm As Form, Flex As Control)
    302. Dim iCol As Integer
    303.  
    304. If TypeName(Flex) <> "MSFlexGrid" Then Exit Sub
    305.  
    306. With Flex
    307.   .Redraw = False
    308.   For iCol = 0 To .Cols - 1
    309.     Registry.SaveSetting "Windows", frm.Name & " Col " & iCol, .ColWidth(iCol)
    310.   Next iCol
    311.   .Redraw = True
    312. End With
    313.  
    314. End Sub
    Last edited by cafeenman; Sep 21st, 2010 at 11:33 AM. Reason: Better thread title

  2. #2
    Freelancer akhileshbc's Avatar
    Join Date
    Jun 2008
    Location
    Trivandrum, Kerala, India
    Posts
    7,652

    Re: Useful List Functions

    I think this thread should be in CodeBank - Visual Basic 6 and earlier. I'll inform a mod to move it

    If my post was helpful to you, then express your gratitude using Rate this Post.
    And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video)
    My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet

    Social Group: VBForums - Developers from India


    Skills: PHP, MySQL, jQuery, VB.Net, Photoshop, CodeIgniter, Bootstrap,...

  3. #3

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Useful List Functions

    If my thread gets moved, the terrorists have won.

    But ok.

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Useful List Functions

    Thread moved to the 'CodeBank VB.Net' forum

    Quote Originally Posted by cafeenman View Post
    If my thread gets moved, the terrorists have won.
    O...K...


    ps: welcome back!

  5. #5
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Useful List Functions

    Hotswapping (by holding with left mousebutton or ctrl + up/down key)
    Code:
    Option Explicit
    
    Private WithEvents HotSwap As ListBox
    Private HotSwapIndex As Integer
    
    ' sample listboxes
    Private Sub Form_Load()
        List1.AddItem "One"
        List1.AddItem "Two"
        List1.AddItem "Three"
        List2.AddItem "One"
        List2.AddItem "Two"
        List2.AddItem "Three"
    End Sub
    
    Private Sub HotSwap_KeyDown(KeyCode As Integer, Shift As Integer)
        If Shift And vbCtrlMask Then
            Select Case KeyCode
            Case vbKeyDown
                If HotSwap.ListIndex + 1 < HotSwap.ListCount Then
                    HotSwapIndex = HotSwap.ListIndex
                    HotSwap.ListIndex = HotSwapIndex + 1
                    HotSwap_MouseMove vbLeftButton, 0, 0, 0
                    KeyCode = 0
                End If
            Case vbKeyUp
                If HotSwap.ListIndex > 0 Then
                    HotSwapIndex = HotSwap.ListIndex
                    HotSwap.ListIndex = HotSwapIndex - 1
                    HotSwap_MouseMove vbLeftButton, 0, 0, 0
                    KeyCode = 0
                End If
            End Select
        End If
    End Sub
    
    Private Sub HotSwap_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If Button And vbLeftButton Then HotSwapIndex = HotSwap.ListIndex
    End Sub
    
    Private Sub HotSwap_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        Dim strItem As String, lngItemData As Long
        If Button And vbLeftButton Then
            If HotSwapIndex < 0 Then Exit Sub
            If HotSwap.ListIndex < 0 Then Exit Sub
            If HotSwapIndex <> HotSwap.ListIndex Then
                strItem = HotSwap.List(HotSwapIndex)
                lngItemData = HotSwap.ItemData(HotSwapIndex)
                HotSwap.List(HotSwapIndex) = HotSwap.List(HotSwap.ListIndex)
                HotSwap.ItemData(HotSwapIndex) = HotSwap.ItemData(HotSwap.ListIndex)
                HotSwap.List(HotSwap.ListIndex) = strItem
                HotSwap.ItemData(HotSwap.ListIndex) = lngItemData
                HotSwapIndex = HotSwap.ListIndex
            End If
        End If
    End Sub
    
    ' sample listbox
    Private Sub List1_GotFocus()
        Set HotSwap = List1
    End Sub
    
    Private Sub List1_LostFocus()
        Set HotSwap = Nothing
    End Sub
    
    ' sample listbox
    Private Sub List2_GotFocus()
        Set HotSwap = List2
    End Sub
    
    Private Sub List2_LostFocus()
        Set HotSwap = Nothing
    End Sub

    Faster ArrayInitialized
    Code:
    ' usage: If ArrayInitialized(Not Not MyArrayVariable) Then
    Public Function ArrayInitialized(ByVal NotNotArray As Long) As Boolean
        ' this fixes an IDE bug with "Not ArrayVariable"
        Debug.Assert App.hInstance
        ' NotNotArray = 0 = uninitialized
        ArrayInitialized = NotNotArray
    End Function

    Faster IsList (uses Object because UserControls/ActiveX are not Controls)
    Code:
    Public Function IsList(Ctl As Object) As Boolean
        IsList = TypeOf Ctl Is ListBox
        If Not IsList Then IsList = TypeOf Ctl Is ComboBox
        If Not IsList Then IsList = TypeOf Ctl Is FileListBox
    End Function

    Issues in cafeenman's codes in the first post:
    1. FillArrayFromList always throws an error when executing vItemData(n) = List.ItemData(n) because after the For loop n = List.ListCount
    2. Functions with sArray always throw an error when passing multidimensional string arrays (simple to fix by calling Erase sArray if the array is initialized)
    3. ItemDataFromListIndex returns a Variant but ItemData is always a Long
    4. MoveDownInList & MoveUpInList for better performance could swap the item information instead of remove + add

  6. #6

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Useful List Functions

    # FillArrayFromList always throws an error when executing vItemData(n) = List.ItemData(n) because after the For loop n = List.ListCount

    Good catch!

    I was pasting in chunks. That should be thus:

    vb Code:
    1. For n = 0 To List.ListCount - 1
    2.  
    3.   sArray(n) = List.List(n)
    4.  
    5.   If Not IsMissing(vItemData) Then
    6.     vItemData(n) = List.ItemData(n)
    7.   End If
    8.  
    9. Next n

    Fixed in original post.

  7. #7

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Useful List Functions

    There is no performance problem with any of this. I'll take your word for it that some things might be faster but items swap as fast as you can click them.

    I didn't take user controls into consideration because I don't make them and haven't come across one yet that I would use. But it's a simple change so not a problem to make it.

    I know that itemdata is always a long. I don't remember why I made it a variant because I never ever use variants unless VB makes me. The code may have been different at one point and required a variant or may require a variant as written. Not sure because I haven't needed to update that code for years.

  8. #8

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Useful List Functions

    Actually, now that I think about it I think I was confusing tags (which can be strings or numbers) with itemdata. Still not sure.

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Useful List Functions

    You might consider adding a find function (commonly asked on this forum). Using SendMessage with the following messages is extremely fast: LB_FINDSTRING, LB_FINDSTRINGEXACT, CB_FINDSTRING, CB_FINDSTRINGEXACT
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Useful List Functions

    Quote Originally Posted by LaVolpe View Post
    You might consider adding a find function (commonly asked on this forum). Using SendMessage with the following messages is extremely fast: LB_FINDSTRING, LB_FINDSTRINGEXACT, CB_FINDSTRING, CB_FINDSTRINGEXACT
    OK

    vb Code:
    1. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    2. Private Declare Function SendMessageByString& Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String)
    3.  
    4. Private Const CB_FINDSTRINGEXACT As Long = &H158
    5.  
    6. Private Const LB_FINDSTRINGEXACT As Long = &H1A2&
    7. Private Const LB_GETHORIZONTALEXTENT = &H193
    8. Private Const LB_ITEMFROMPOINT = &H1A9
    9. Private Const LB_SETHORIZONTALEXTENT = &H194
    10.  
    11.  
    12. Public Function FindPartialStringInArray(sArray() As String, s As String) As Long
    13. Dim n As Long
    14.  
    15. ' Returns Index if found.
    16. ' Returns -1 if error or not found.
    17. ' Strings are not case-sensitive.
    18.  
    19. On Error GoTo errHandler ' Returns Error Code.
    20.  
    21. If Not ArrayInitialized(sArray) Then
    22.   FindPartialStringInArray = -1
    23.   Exit Function
    24. End If
    25.  
    26. For n = LBound(sArray) To UBound(sArray)
    27.   If InStr(1, sArray(n), s, vbTextCompare) Then
    28.     FindPartialStringInArray = n
    29.     Exit Function
    30.   End If
    31. Next n
    32.  
    33. ' Not found.
    34. FindPartialStringInArray = -1
    35.  
    36. Exit Function
    37.  
    38. errHandler:
    39. FindPartialStringInArray = -1
    40.  
    41. End Function
    42. Public Function FindPartialStringInList(ByRef List As Control, ByVal LastIndex As Long, ByVal sString As String) As Long
    43. Dim n As Long
    44. Dim s As String
    45.  
    46. ' Returns ListIndex if found.
    47. ' Returns -1 if not found.
    48. ' Strings are not case-sensitive.
    49.  
    50. On Error GoTo errHandler
    51.  
    52. s = LCase$(sString)
    53.  
    54. If s = vbNullString Then
    55. '  LastIndex = 0
    56.   FindPartialStringInList = -1
    57.   Exit Function
    58. End If
    59.  
    60. With List
    61.   If .ListCount = 0 Then
    62. '    LastIndex = 0
    63.     FindPartialStringInList = -1
    64.     Exit Function
    65.   End If
    66.  
    67.   For n = LastIndex To .ListCount - 1
    68.     If InStr(1, LCase$(.List(n)), s, vbTextCompare) Then
    69.       FindPartialStringInList = n
    70.       '.ListIndex = n
    71.       'LastIndex = .ListIndex + 1
    72.       '.SetFocus
    73.       '.Selected(n) = True
    74.       Exit Function
    75.     End If
    76.   Next n
    77.  
    78.   MsgBox sString & " not found.", vbInformation, APP_TITLE
    79.   LastIndex = 0
    80.  
    81. '  For n = 0 To .ListCount - 1
    82. '    .Selected(n) = False
    83. '  Next n
    84. End With
    85.  
    86. FindPartialStringInList = -1
    87.  
    88. Exit Function
    89.  
    90. errHandler:
    91. Dim nErrReturn As Long
    92.  
    93. nErrReturn = ErrorHandler(Error, Err, vbNullString, "bLists.FindPartialStringInList()")
    94.  
    95. FindPartialStringInList = -1
    96.  
    97. End Function
    98. Public Function FindStringInList(List As Control, sString As String) As Long
    99.  
    100. ' Returns ListIndex if found.
    101. ' Returns -1 if not found.
    102. ' Strings are not case-sensitive.
    103.  
    104. On Error GoTo errHandler
    105.  
    106. If Not IsList(List) Then Exit Function
    107.  
    108. Select Case TypeName(List)
    109.   Case Is = "ComboBox"
    110.     FindStringInList = SendMessageByString&(List.hWnd, CB_FINDSTRINGEXACT, -1, sString)
    111.   Case Is = "ListBox"
    112.     FindStringInList = SendMessageByString&(List.hWnd, LB_FINDSTRINGEXACT, -1, sString)
    113. End Select
    114.  
    115. Exit Function
    116.  
    117. errHandler:
    118. LogError Error, Err, List.Name, "bLists.FindStringInList()"
    119.  
    120. End Function

  11. #11

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Useful List Functions

    Don't know if I can upload a bas file but here's the whole thing.
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width