VBA-对列表框中的数据进行排序,排序有效但列表框中的数据未改变。

3

传递一个列表框,将其数据放置在数组中,对数组进行排序,然后将数据重新放回列表框中。目前有一部分功能可以实现,即将数据放回列表框中。问题在于,好像列表框是按值而不是按引用传递的。

以下是执行排序的sub以及调用排序sub的代码行:

Private Sub SortListBox(ByRef LB As MSForms.ListBox)

Dim First As Integer
Dim Last As Integer
Dim NumItems As Integer
Dim i As Integer
Dim j As Integer
Dim Temp As String
Dim TempArray() As Variant

ReDim TempArray(LB.ListCount)

First = LBound(TempArray)               ' this works correctly
Last = UBound(TempArray) - 1            ' this works correctly

For i = First To Last
    TempArray(i) = LB.List(i)           ' this works correctly
Next i

For i = First To Last
    For j = i + 1 To Last
        If TempArray(i) > TempArray(j) Then
            Temp = TempArray(j)
            TempArray(j) = TempArray(i)
            TempArray(i) = Temp
        End If
    Next j
Next i                               ! data is now sorted

LB.Clear                             ! this doesn't clear the items in the listbox

For i = First To Last
    LB.AddItem TempArray(i)          ! this doesn't work either
Next i

End Sub

Private Sub InitializeForm()

'   There's code here to put data in the list box    

Call SortListBox(FieldSelect.CompleteList)

End Sub

感谢您的帮助。
4个回答

1

这对我来说在Excel 2003上运行良好,使用了一个非常基本的UserForm和一个名为ListBox1的单个ListBox:

Private Sub UserForm_Initialize()

ListBox1.AddItem "john"
ListBox1.AddItem "paul"
ListBox1.AddItem "george"
ListBox1.AddItem "ringo"

SortListBox ListBox1

End Sub

然后按照原样编写 SortListBox,除了修复以感叹号开头而不是“

”的三个注释之外。

您初始化器的唯一区别是名称(UserForm_InitializeInitializeForm)。确保在用户窗体的代码页顶部使用对象和事件选择器,以确保事件处理程序被正确命名。


0

这是我使用它的方式,例如,带有关系字典和两列:

Private Sub UserForm_Initialize()

 Call HideTitleBar(Me)

 Set ExtraFiltersDic = CreateObject("scripting.dictionary")
 ExtraFiltersDic.CompareMode = 1
 Set ExtraFiltersDic = GetExtraFiltersDic()

 Dim k
 For Each k In ExtraFiltersDic.Keys
  ListBox1.AddItem k
 Next
 
 Call SortListBox(ListBox1, ListBox2, ExtraFiltersDic)
  
End Sub

Public Sub SortListBox(ByRef ListBox As MSForms.ListBox, Optional ByRef ListBox2 As MSForms.ListBox, Optional ByRef RelationalDic As Object)

 Dim First As Integer, Last As Integer, NumItems As Integer
 Dim i As Integer, j As Integer
 Dim TempArray() As Variant, Temp As String

 ReDim TempArray(ListBox.ListCount)

 First = LBound(TempArray)
 Last = UBound(TempArray) - 1
 For i = First To Last
    TempArray(i) = ListBox.List(i)
 Next i
 
 For i = First To Last
    For j = i + 1 To Last
        If TempArray(i) > TempArray(j) Then
            Temp = TempArray(j)
            TempArray(j) = TempArray(i)
            TempArray(i) = Temp
        End If
    Next j
 Next i

 ListBox.Clear

 If Not ListBox2 Is Nothing And Not RelationalDic Is Nothing Then
  Set KeyValDic = CreateObject("scripting.dictionary")
  Set KeyValDic = RelationalDic
 End If

 For i = First To Last
    ListBox.AddItem TempArray(i)
    If Not ListBox2 Is Nothing And Not RelationalDic Is Nothing Then
     ListBox2.AddItem KeyValDic(TempArray(i))
    End If
 Next i

End Sub

0

你不能通过值传递对象。由于你不会向调用者返回另一个 listbox 实例,所以应该将 LP 声明为 ByVal。但这并不影响代码。它可以正常工作并对列表进行排序。我认为你省略了一些重要的细节。


-1

我不确定这种方法是否适用于您,但可以尝试一下。

首先,创建一个包含列表框中所有项目的数组。

将该数组传递给您的函数。

对该数组进行排序。

将该数组返回给主程序。

清除列表框。

使用新数组覆盖列表框项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接