65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 VB6 和解决逗号 bug 填充 Access 2003 ListBox

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2008年12月10日

CPOL

4分钟阅读

viewsIcon

40123

downloadIcon

358

填充 Access 中列表框的不同方法。

引言

本文介绍了填充列表框控件的几种方法,我将解释字符串值中包含逗号的问题,以及在使用 ListBox 控件时应考虑的其他限制。附件包含一个小型应用程序,演示了不同的方法及其在代码中的实现。

填充方法

可以使用以下方法填充列表框:

  • 手动
  • 用户定义函数
  • 记录集
  • 外部文件

手动

您可以使用 ListBox AddItem 方法手动填充控件。该方法接受一个 String 参数,并将其添加到列表的末尾。

List1.AddItem "111;222;333"

对于多列 ListBox,您可以使用分号 (;) 分隔符指定一个字符串,这将把输入转换为多列结构。

考虑这段代码:

Private Sub Command1_Click()
    ' clear the listbox
    List1.RowSource = ""
    ' set the rowsorce to a value list type
    List1.RowSourceType = "Value List"
    ' set the number of colums
    List1.ColumnCount = 3
    ' set the columns width
    List1.ColumnWidths = "500;500;500"
    ' the data
    List1.AddItem "111;222;333"
    List1.AddItem "444;555;666"
End Sub

当您在包含名为 List1ListBox 控件和名为 command1 的命令按钮的窗体上运行此代码时,您将能够看到一个格式精美、三列的列表框。但是,如果您添加以下额外的一行:

List1.AddItem "4,4,4;555;666"

您会发现 4,4,4 被分成三列而不是一列。VB 帮助并未指出逗号是分隔符字符。在 Access VB 编辑器中选择 AddItem 方法时按 F1 键提供的帮助页面中,它说明了以下内容:“对于多列列表,使用分号分隔每列的字符串(例如,三列列表的“1010;red;large”)。因此,即使未指定,逗号也被视为分隔符字符。有两种方法可以解决此问题:第一种是使用旧的、混乱的 Replace 方法,您用一个字符替换另一个字符,在本例中,例如用“@”替换“,”。但是,您需要在之后清理,将其替换回“,”。一个更有用的技巧是简单地将值括在引号中;这将阻止 AddItem 方法将逗号解释为分隔符,而是将字符串视为一个整体。示例

List1.AddItem """5,0,0"";""500"";""500"""

用户定义函数

也称为回调函数,它提供了一组规则和值供控件使用来构建自身。每次需要填充控件内的单元格时,都会调用用户定义的函数,并将值返回给调用者(控件)。为了实现此解决方案,我们需要将 ListBox 行的源类型声明为新的用户函数。

请注意,函数需要遵守 MS VB 规则,关于传递给函数的参数数量及其类型,并且还需要包含一个具有特定命名约定的特定参数。在附件文件中,有本文中所有不同方法如何填充 ListBox 的示例,包括此方法。

实施此方法中的步骤

  1. 在页面级别范围,创建一个多维数组来包含您的数据
  2. Dim arr(0 To 1, 0 To 2) As String ' array with two rows and two columns
  3. OnClick 事件中,用您的数据填充数组
  4. populate the array
    arr(0, 0) = "111"
    arr(0, 1) = "222"
    arr(0, 2) = "3,3,3" 
    
    arr(1, 0) = "4,4,4" 
    arr(1, 1) = "555"
    arr(1, 2) = "666"
  5. 初始化 ListBox 控件
  6. List1.RowSource = ""        ' clear the list box ctr
    List1.RowSourceType = "ListFill1"    ' your function name
    List1.ColumnCount = 3        ' specify the number of columns
    List1.ColumnWidths = "500;500;500"    ' specify the columns width

    重要的一行是我们定义 rowSourceType 的地方。在这一行,我们实际上告诉系统去我们的函数“ListFill1”并获取有关如何构建控件的指令。

  7. 用户定义的函数
  8. 系统期望找到一个具有特定格式和特定参数集的函数。这就是为什么您不应该更改以下函数中的命名约定。

    Private Function ListFill1( _
     ctl As Control, varId As Variant, lngRow As Long, _
     lngCol As Long, intCode As Integer)
        
        Select Case intCode
            Case acLBInitialize
                  ListFill1 = True ' initialize
            Case acLBOpen
                 ListFill1 = Timer  ' row key
            Case acLBGetRowCount
                ListFill1 = 2 ' record count
            Case acLBGetColumnCount
                ListFill1 = 3 ' column count
            Case acLBGetColumnWidth
                ' columns size !! strarts from zero?
                'If lngCol = 1 Then ListFill1 = 0
            Case acLBGetFormat
               ' column format
            Case acLBGetValue
                ' the data
                ListFill1 = arr(lngRow, lngCol)
            Case acLBEnd
                ' Just clean up, if necessary.
        End Select
    End Function

记录集

使用记录集对象,您可以直接绑定控件,而无需循环遍历每个记录。为了实现此解决方案,您需要创建一个断开连接的记录集对象并将其绑定到控件。请注意,通过使用记录集,您可以从不同来源(数据库、数组、外部文件等)填充记录集对象。

Dim columnCount As Integer  ' number of fields/columns in the recordset
' set the list record source type to table and query
pObj.RowSourceType = "Table/Query"
' clear the listbox
pObj.RowSource = ""
' set columns width
pObj.ColumnWidths = pcolumnsWidth ' "500;500;500;500"
' set the number of columns
pObj.columnCount = UBound(Split(pcolumnsWidth, ";"))
Dim rss As New ADODB.Recordset
rss.CursorLocation = adUseClient
Dim connec As New ADODB.Connection
connec.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
"Data Source=C:\Documents and   Settings\XXXXyourLocation\Desktop\listbox.mdb;"
rss.ActiveConnection = Nothing
rss.Open ssql, connec, adOpenKeyset, adLockBatchOptimistic
rss.ActiveConnection = Nothing

Set pObj.Recordset = rss

rss.Close
Set rss = Nothing
Set connec = Nothing

外部文件

在此方法中,我们使用带或不带 schema.ini 文件的分隔文本格式作为控件的源。分隔文本文件是一个扩展名为 txt 的文件,其中包含数据行,值之间用分隔符符号(通常是逗号)分隔。但是,如果您需要使用其他分隔符,则需要使用 schema.ini 文件,其中包含分隔符符号的定义。

pObj.RowSourceType = "Table/Query"
' clear the listbox
pObj.RowSource = ""
' set columns width
pObj.ColumnWidths = pcolumnsWidth
' set the number of columns
pObj.columnCount = UBound(Split(pcolumnsWidth, ";"))
    
Dim connCSV As New ADODB.Connection
Dim rsTest As New ADODB.Recordset
Dim adcomm As New ADODB.Command
Dim path As String

path = p_filePath
'This is connection for a text file without Header

If p_firsLineHeaders Then
    connCSV.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" _
       & path & ";Extensions=asc,csv,tab,txt;HDR=NO;Persist Security Info=False"
Else
    connCSV.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
    & path & ";Extended Properties='text;HDR=NO;FMT=Delimited'"
End If

rsTest.Open "Select * From list.txt", _
connCSV, adOpenStatic, adLockReadOnly, adCmdText

Set pObj.Recordset = rsTest

rsTest.Close
Set rsTest = Nothing
Set connCSV = Nothing

此示例的“list.txt”文本文件内容是

"1111";"2222";"3333"
"11,11";"2222";"2222"
"1111";"2222";"3333"

schema 文件必须与文本文件位于同一目录中,并且文件名称必须为“Schema.ini”。

[list.txt] 
ColNameHeader=False 
Format=Delimited(;)

此示例与所有其他示例一样,位于附件文件中。

ListBox 控件的其他限制

ListBox 控件每个子项(列)最多只能包含 255 个字符。在大多数情况下,您不会使用 ListBox 来显示长字符串数据,但如果您需要在隐藏列中存储大量数据,请注意此限制:超过 255 个字符的字符串将被截断。

附件文件

共有三种文件类型:MDB、txt 和 ini。将它们放在您选择的任何目录中,然后更改 MDB 文件中的代码以指向新目录。只需替换 xxx_yourLoation

祝你好运。

© . All rights reserved.