使用VBA在Access 2010中显示表单上的记录集

时间:2011-06-01 00:22:44

标签: forms ms-access recordset

我正在Access 2010中开发一个数据检索应用程序,用户通过选择列表框条目来选择要查看的表,列和行。 VBA代码从这些选项中生成SQL语句,然后从中创建ADBDB.Recordset对象。

如何在Access中显示记录集记录? Access 2010中没有网格控件可用,并且子窗体不是为此目的而设计的。有人可以推荐另一种策略吗?

4 个答案:

答案 0 :(得分:1)

您可以将SELECT语句保存为命名查询,然后将查询作为数据表打开。它不是一种形式,而是一种形式。

Call DatasheetFromSql(strSql)

Public Sub DatasheetFromSql(ByVal pSql As String)
    Const cstrQuery As String = "qryDiscardMe"
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim strMsg As String

On Error GoTo ErrorHandler

    Set db = CurrentDb
    db.QueryDefs.Delete cstrQuery
    Set qdf = db.CreateQueryDef(cstrQuery, pSql)
    DoCmd.OpenQuery cstrQuery, , acReadOnly

ExitHere:
    On Error GoTo 0
    Set qdf = Nothing
    Set db = Nothing
    Exit Sub

ErrorHandler:
    Select Case Err.Number
    Case 3265 ' Item not found in this collection. '
        Resume Next
    Case Else
        strMsg = "Error " & Err.Number & " (" & Err.description _
            & ") in procedure DatasheetFromSql"
        MsgBox strMsg
        GoTo ExitHere
    End Select
End Sub

我以只读方式打开查询。如果您想允许用户编辑自定义查询返回的数据,我不建议使用此方法。相反,我会投入HK1提供的方法,因为它可以支持更好地控制用户数据的变化。

将查询作为数据表打开,您可以使用Screen.ActiveDatasheet检查其属性。至少有一些方法也可供您使用。例如,您可以像这样调整数据表的大小/重新定位:

Screen.ActiveDatasheet.Move Left:=0, Top:=0, Width:=(4 * 1440), Height:=(3 * 1440)

单位为缇(1440缇/英寸),因此宽度为4英寸,高度为3英寸,并将其移动到Access窗口的左上角。

答案 1 :(得分:0)

以下是我认为你必须要做的才能获得这种功能。

首先,您需要在表单上创建足够的正确控件来处理每个可能的场景。然后,您需要将表单设置为数据表表单,以使其显示为网格。

现在将控件上的controlsource设置为与记录集中的某个字段对应。在每个未使用的控件上,需要将其ColumnHidden属性设置为true。您还必须更改关联标签的标题,以显示每个可见的控件的相应列名称。

现在,将该表单绑定到您的ADO记录集对象。

Me.Recordset = rst
'or
Me.Subform1.Form.Recordset = rst

这是一个完美的解决方案吗?当然不是。 Access没有任何与.Net中的DataGridView或VB6中使用的Grid控件相比的东西。在我看来,你真的在​​推动Access的极限,试图获得这种功能。这就像游泳上游。你会发现你所做的一切都会相当困难,有些事情是不可能的。

答案 2 :(得分:0)

对于您不能拥有本地MS Access查询定义的ADP项目,您可以创建一个数据表表单,其中包含多个名为txt1,txt2,... txt30的文本框和标签名称lbl1 ... lb30,此代码将设置form.recordsource并将textbox.controlsource和label.caption设置为ADO记录集对象中的相应字段。此表单允许您以类似于Docmd.OpenQuery方法的方式查看ADO Recordset。

您必须使用表单的OpenArgs属性将ADO记录集的SQL语句传递给表单。下面的代码显示了调用\打开表单的VBA代码(它像查询一样显示ADO Recordset)并传递你的sql字符串。表单的load事件上的vba代码将设置所有控件属性,调整包含数据的列的大小并隐藏ado记录集中没有相应字段的列:

'stevekirchner 09/29/2012  Replace Access parameterized query with SQL Server in-line function 
'DoCmd.OpenQuery "qry_SearchMaster_CaseTitles", , acReadOnly

 strsql = "Select * from dbo.UDF__qry_SearchMaster_CaseTitles ('%" & Me.tbxSearchTerm.Value & "%') "

Call Display_ADO_Recordset_from_Datasheet_Form(strsql, "frm_Display_ADO_Recordset_Result1")

'create a non-form module and put the code for the sub Display_ADO_Recordset_from_Datasheet_Form 
'and function fIsLoaded in it (this will allow you make several forms to view ADO recordset and 
'call the code from one place\module):

Sub Display_ADO_Recordset_from_Datasheet_Form(sSQL As String, sFormName As String)

On Error GoTo Error_Handler

    If fIsLoaded(sFormName) Then

        DoCmd.Close acForm, sFormName

    End If

    DoCmd.OpenForm sFormName, acFormDS, , , acFormReadOnly, , OpenArgs:=sSQL

Exit_Sub:

    Exit Sub

Error_Handler:

    MsgBox Err.Description & " Error No: " & CStr(Err.Number)

    Resume Exit_Sub

End Sub

Function fIsLoaded(ByVal strFormname As String) As Boolean

On Error GoTo Error_Handler

    'Returns False if form is not open or True if Open
    If SysCmd(acSysCmdGetObjectState, acForm, strFormname) <> 0 Then

        If Forms(strFormname).CurrentView <> 0 Then
            fIsLoaded = True
        End If

    End If

Exit_Function:

    Exit Function

Error_Handler:

    MsgBox Err.Description & " Error No: " & CStr(Err.Number)

    fIsLoaded = False

    Resume Exit_Function

End Function

'Create a datasheet view form (named frm_Display_ADO_Recordset_Result1) with 30 textboxes and 30
'30 labels named txt1 - txt30 and lbl1 - lbl30 and put this code in the form's module:

Option Compare Database

Private Sub Form_Load()

On Error GoTo Error_Handler

    Dim conn        As ADODB.Connection
    Dim rs          As ADODB.Recordset
    Dim rsClone     As ADODB.Recordset
    Dim strsql      As String

    Set conn = CurrentProject.Connection
    Set rs = New ADODB.Recordset

    strsql = Me.OpenArgs   
    rs.Open strsql, conn, adOpenStatic, adLockOptimistic

    Set rsClone = rs.Clone

    Call Update_Form_Controls("your text goes here", strsql, rsClone)

Exit_Sub:

    rs.Close
    conn.Close
    Set rs = Nothing
    Set conn = Nothing

    Exit Sub

Error_Handler:

    MsgBox Err.Description & "; Error Number : " & Err.Number, vbOKOnly

    Resume Exit_Sub
End Sub

Sub Update_Form_Controls(Header_Label As String, SQL As String, CloneRS As Recordset)

    Dim rsCount As Integer
    Dim i As Integer

On Error GoTo Error_Handler

    Me.Form.Caption = Replace(SQL, "Select * From ", "Display: ")

    rsCount = CloneRS.RecordCount

    If rsCount <= 0 Then

        MsgBox "The Query did not return any data to view", vbOKOnly

        DoCmd.Close
    Else

        Me.Form.SetFocus

        Me.RecordSource = SQL

        i = 1

        Do Until i = 31

            Me("lbl" & i).Caption = ""
            Me("txt" & i).ControlSource = ""
            Me("txt" & i).ColumnHidden = True

            i = i + 1

        Loop

        i = 1

        With CloneRS

        For Each Field In .Fields
        On Error Resume Next

            Me("lbl" & i).Caption = .Fields(i - 1).Name
            Me("txt" & i).ControlSource = .Fields(i - 1).Name
            Me("lbl" & i).Visible = True
            Me("txt" & i).ColumnHidden = False
            Me("txt" & i).SizeToFit

            i = i + 1

            'Debug.Print Field.Name

            On Error GoTo 0
        Next Field
        End With

    End If

Exit_Sub:

    Me.Requery

    Exit Sub


Error_Handler:

    MsgBox Err.Description & "; Error Number : " & Err.Number, vbOKOnly

    Resume Exit_Sub


End Sub

答案 3 :(得分:0)

我不使用ADO,而是简单地使用VBA,在这种情况下,上述方法是错误的:不需要任何方法以某种形式显示现有记录集,但应在内部定义适当的记录集 表格!

只需将表单的RecordSource 设置为相同的查询定义,而不是创建MyDataBase.OpenRecordset ("SELECT … [SQL query] ;")

Forms![MyDisplayForm].RecordSource = "SELECT … [SQL query] ;" Forms![MyDisplayForm].Requery

对我来说,这很完美(Windows 7 pro×64 / MS Office pro×64)