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





0/5 (0投票)
填充 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
当您在包含名为 List1
的 ListBox
控件和名为 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
的示例,包括此方法。
实施此方法中的步骤
- 在页面级别范围,创建一个多维数组来包含您的数据
- 在
OnClick
事件中,用您的数据填充数组 - 初始化
ListBox
控件 - 用户定义的函数
Dim arr(0 To 1, 0 To 2) As String ' array with two rows and two columns
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"
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
”并获取有关如何构建控件的指令。
系统期望找到一个具有特定格式和特定参数集的函数。这就是为什么您不应该更改以下函数中的命名约定。
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。
祝你好运。