Access中ListView控件选中行获取列值报错,求解决方法
解决Access ListView Report View中获取列值的“无效属性值”异常
这个问题我之前在Access里折腾ListView控件时也踩过坑,核心是你对ListView的列值访问逻辑理解错了——Access里的ListView,SubItems集合的索引是从1开始的,而不是0。
错误原因详解
ListView的结构里,第一列(你要的FormID)的值是存储在Item.Text属性里的,而SubItems集合对应的是从第二列开始的所有列,索引从1开始:
- 第一列(列索引0)→
Item.Text - 第二列(列索引1)→
Item.SubItems(1) - 第三列(列索引2)→
Item.SubItems(2)
你代码里用Item.SubItems(0)访问一个不存在的索引,自然会抛出“无效属性值”的异常。另外还有个小坑:你变量声明的写法Dim FormID, FilingID, RowIndex As Integer其实只有RowIndex是Integer类型,FormID和FilingID会被默认声明为Variant,可能导致后续类型转换问题,建议逐个指定类型。
修正后的代码
Private Sub ListView1_ItemClick(ByVal Item As Object) ' 逐个指定变量类型,避免默认Variant的问题 Dim FormID As Integer, FilingID As Integer, RowIndex As Integer Dim FilingName As String RowIndex = Item.Index FormID = Item.Text ' 第一列的值用Item.Text获取 FilingID = Item.SubItems(1) ' 第二列对应SubItems(1) FilingName = Item.SubItems(2) ' 第三列对应SubItems(2) If MsgBox("Do you want to open up filing " & FilingName & "?", vbYesNo, "Confirmation") = vbYes Then DoCmd.OpenForm "frmFiling", acNormal, , , , , "FormID=" & FormID & ";FilingID=" & FilingID End If End Sub
替代方案(更健壮的列名匹配)
如果担心后续列顺序调整导致代码失效,可以先通过列名找到对应的索引,再获取值:
Private Function GetListViewColumnIndex(lv As ListView, colName As String) As Integer Dim col As ColumnHeader For Each col In lv.ColumnHeaders If col.Text = colName Then GetListViewColumnIndex = col.Index Exit Function End If Next GetListViewColumnIndex = -1 ' 未找到返回-1 End Function ' 在ItemClick事件中使用 Private Sub ListView1_ItemClick(ByVal Item As Object) Dim FormID As Integer, FilingID As Integer Dim FilingName As String Dim formColIndex As Integer, filingIdColIndex As Integer, filingNameColIndex As Integer formColIndex = GetListViewColumnIndex(ListView1, "FormID") filingIdColIndex = GetListViewColumnIndex(ListView1, "FilingID") filingNameColIndex = GetListViewColumnIndex(ListView1, "FilingName") If formColIndex = -1 Or filingIdColIndex = -1 Or filingNameColIndex = -1 Then MsgBox "列名配置错误,请检查ListView的列设置", vbExclamation Exit Sub End If ' 根据列索引获取值:第一列用Item.Text,其他列用SubItems(索引) If formColIndex = 0 Then FormID = Item.Text Else FormID = Item.SubItems(formColIndex) End If FilingID = Item.SubItems(filingIdColIndex) FilingName = Item.SubItems(filingNameColIndex) If MsgBox("Do you want to open up filing " & FilingName & "?", vbYesNo, "Confirmation") = vbYes Then DoCmd.OpenForm "frmFiling", acNormal, , , , , "FormID=" & FormID & ";FilingID=" & FilingID End If End Sub
这个方案更灵活,后续调整列顺序只要列名不变,代码就不用修改。
内容的提问来源于stack exchange,提问作者dfranczyk
相关产品推荐
相关产品推荐

