MS Access 2003 - 有没有办法以编程方式定义图表的数据?

Posted

技术标签:

【中文标题】MS Access 2003 - 有没有办法以编程方式定义图表的数据?【英文标题】:MS Access 2003 - Is there a way to programmatically define the data for a chart? 【发布时间】:2010-03-05 17:34:52 【问题描述】:

所以我有一些 VBA 用于获取使用表单的图表向导构建的图表,并自动将其插入到 PowerPoint 演示文稿幻灯片中。我将这些图表表单用作较大表单中的子表单,这些表单具有用户可以选择的参数来确定图表上的内容。这个想法是用户可以确定参数,根据自己的喜好构建图表,然后单击一个按钮并将其放在带有公司背景模板的 ppt 幻灯片中,等等等等......

所以它可以工作,尽管就我必须使用的对象数量而言它非常庞大。

我使用如下表达式:

like forms!frmMain.Month&* 

将输入值放入已保存的查询中,这在我刚开始时很好,但它进行得非常好,他们需要这么多选项,以至于它推动了保存的查询/对象的数量。我需要几个带有图表的已保存表单,因为我需要处理大量不同类型的图表。

最后我的问题:

我更愿意使用一些 VBA 即时完成所有这些工作。我知道如何在表单上插入列表框和文本框,我知道如何在 VBA 中使用 SQL 从使用 VBA 的表/查询中获取我想要的值,我只是不知道是否有一些我可以的 vba用于从结果记录集中设置图表的数据值:

DIM rs AS DAO.Rescordset
DIM db AS DAO.Database
DIM sql AS String

sql = "SELECT TOP 5 Count(tblMain.TransactionID) AS Total, tblMain.Location FROM
tblMain WHERE (((tblMain.Month) = """ & me.txtMonth & """ )) ORDER BY Count 
(tblMain.TransactionID) DESC;"

set db = currentDB
set rs = db.OpenRecordSet(sql)

              rs.movefirst

            some kind of cool code in here to make this recordset
             the data of chart in frmChart ("Chart01")

感谢您的帮助。为解释的长度道歉。

【问题讨论】:

您是否考虑过将图表的 SQL 硬连线到包含月份的控件?也就是说,将 """ & me.txtMonth & """ 替换为 [Forms!YourFormName!txtMonth],然后重新查询图表以更新它以反映月份控件中的当前值。 所以表单中有很多参数/控件,上面只是举例说明。话虽如此,我可以在 SQL 语句中放入的上述表达式的数量是否有限制?谢谢大卫! 该方法的局限性取决于标准的相互作用。如果一些允许为空白,那么你就有潜在的问题。如果都填好了,那就很简单了。前一个问题可以解决,但它可能会变得非常复杂,并且可能会成为真正的性能消耗者(特别是如果您最终不得不对必须为每一行评估的表达式设置标准,这意味着索引不能使用)。 【参考方案1】:

可以直接在 vba 中更改数据集,因为我已经设法做到了。但是性能不是很好,所以我回到将结果填充到临时表并以此为基础绘制图表(请参阅我唯一提出的 *** 问题),但是如果数据集非常小,那么你当然可以让它工作。我不在办公室,但如果你想要代码,我可以在星期一发布

编辑:这是我使用的旧代码模块。这是完整的内容,但您要查看的关键部分是关于打开图形数据表然后像这样更改它的值的部分 .cells(1,0)="badger"。

我彻底放弃了这种方法并使用了一个临时表,因为在我的应用程序中,图表被重绘了很多,我需要采用尽可能快的方法来给它一种“实时”的感觉,但它可能只是满足您的需求

Public Sub Draw_graph(strGraph_type As String)
Dim objGraph As Object
Dim objDS As Object
Dim i As Byte


On Error GoTo Error_trap

Dim lRT_actual As Long
Dim lRT_forecast As Long
Dim Start_time As Long
Dim aCell_buffer(49, 4) As Variant
Me.acxProgress_bar.Visible = True
Me.acxProgress_bar.Value = 0
Set objGraph = Me.oleCall_graph.Object
Set objDS = objGraph.Application.datasheet
Start_time = GetTime()
With objDS
    .cells.Clear
    Select Case strGraph_type
        Case Is = "Agents"
            '**************************
            '** Draw the agent graph **
            '**************************
            .cells(1, 1) = "Start Time"
            .cells(1, 2) = "Provided"
            .cells(1, 3) = "Required"
            .cells(1, 4) = "Actual Required"
            For i = 1 To 48
                .cells(i + 1, 1) = Format(DateAdd("n", (i - 1) * 15, "08:00:00"), "HHMM")
                If Me.Controls("txtAgents_pro_" & i) > 0 Then
                    .cells(i + 1, 2) = Me.Controls("txtAgents_pro_" & i) + Me.Controls("txtAgents_add_" & i)
                Else
                    .cells(i + 1, 2) = 0
                End If
                If Me.Controls("txtAgents_req_" & i) > 0 Then
                    .cells(i + 1, 3) = Me.Controls("txtAgents_req_" & i)
                End If

                If Me.Controls("txtActual_" & i) > 0 Then
                    .cells(i + 1, 4) = Erlang_Agents(Me.txtServiceLevel, Me.txtServiceTime, Me.Controls("txtActual_" & i) * 4, Me.txtAVHT + CLng(Nz(Me.txtDaily_AVHT_DV, 0)))
                End If


                'update the progress bar
                If Me.acxProgress_bar.Value + 2 < 100 Then
                    Me.acxProgress_bar.Value = Me.acxProgress_bar.Value + 2
                Else
                    Me.acxProgress_bar.Value = 90
                End If
            Next i
        Case Is = "Calls"
            '**************************
            '** Draw the Calls graph **
            '**************************
            .cells(1, 1) = "Start Time"
            .cells(1, 2) = "Forecast"
            .cells(1, 3) = "Actual"
            For i = 1 To 48
                .cells(i + 1, 1) = Format(DateAdd("n", (i - 1) * 15, "08:00:00"), "HHMM")
                If Me.Controls("txtForecast_" & i) > 0 Then
                    .cells(i + 1, 2) = Me.Controls("txtForecast_" & i)
                Else
                    .cells(i + 1, 2) = 0
                End If
                If Me.Controls("txtActual_" & i) > 0 Then
                    .cells(i + 1, 3) = Me.Controls("txtActual_" & i)
                End If
                If Me.acxProgress_bar.Value + 2 < 100 Then
                    Me.acxProgress_bar.Value = Me.acxProgress_bar.Value + 2
                Else
                    Me.acxProgress_bar.Value = 90
                End If
            Next i

        Case Is = "Call Deviation"
            '**************************
            '** Draw the Call Deviation graph **
            '**************************
            .cells(1, 1) = "Start Time"
            .cells(1, 2) = "Deviation"
            lRT_actual = 0
            lRT_forecast = 0
            For i = 1 To 48
                lRT_actual = lRT_actual + Me.Controls("txtActual_" & i)
                lRT_forecast = lRT_forecast + Me.Controls("txtForecast_" & i)
                .cells(i + 1, 1) = Format(DateAdd("n", (i - 1) * 15, "08:00:00"), "HHMM")

                .cells(i + 1, 2) = lRT_actual - lRT_forecast

                If Me.acxProgress_bar.Value + 2 < 100 Then
                    Me.acxProgress_bar.Value = Me.acxProgress_bar.Value + 2
                Else
                    Me.acxProgress_bar.Value = 90
                End If
            Next i

        Case Is = "Call Deviation %"
            '**************************
            '** Draw the Call Deviation % graph **
            '**************************

            .cells(1, 1) = "Start Time"
            .cells(1, 2) = "Deviation"
            lRT_actual = 0
            lRT_forecast = 0


            For i = 1 To 48
                lRT_actual = lRT_actual + Me.Controls("txtActual_" & i)
                lRT_forecast = lRT_forecast + Me.Controls("txtForecast_" & i)
                .cells(i + 1, 1) = Format(DateAdd("n", (i - 1) * 15, "08:00:00"), "HHMM")
                If lRT_forecast > 0 Then
                    .cells(i + 1, 2) = (lRT_actual - lRT_forecast) / lRT_forecast
                End If

                If Me.acxProgress_bar.Value + 2 < 100 Then
                    Me.acxProgress_bar.Value = Me.acxProgress_bar.Value + 2
                Else
                    Me.acxProgress_bar.Value = 90
                End If
            Next i



        Case Is = "SLA"
            '**************************
            '*** Draw the SLA graph ***
            '**************************
            .cells(1, 1) = "Start Time"
            .cells(1, 2) = "SLA"
            .cells(1, 3) = "Actual SLA"
            For i = 1 To 48
                .cells(i + 1, 1) = Format(DateAdd("n", (i - 1) * 15, "08:00:00"), "HHMM")
                If Me.Controls("txtSLA_" & i) > 0 Then
                    .cells(i + 1, 2) = Me.Controls("txtSLA_" & i) / 100
                Else
                    .cells(i + 1, 2) = 0
                End If
                If Me.Controls("txtActual_SLA_" & i) > 0 Then
                    .cells(i + 1, 3) = Me.Controls("txtActual_SLA_" & i)
                End If
                If Me.acxProgress_bar.Value + 2 < 100 Then
                    Me.acxProgress_bar.Value = Me.acxProgress_bar.Value + 2
                Else
                    Me.acxProgress_bar.Value = 90
                End If
            Next i

    End Select
End With

Set objDS = Nothing
Set objGraph = Nothing
Me.acxProgress_bar.Visible = False


Exit Sub

Error_trap:
DoCmd.Hourglass False

MsgBox "An error happened in sub Draw_graph, error description, " & Err.Description, vbCritical, "Tracker 3"

End Sub

【讨论】:

【参考方案2】:

执行此操作的一种非常简单的方法是将图表基于查询并更新查询,例如:

strSQL = "SELECT ..."

QueryName = "qryByHospital"

If IsNull(DLookup("Name", "MsysObjects", "Name='" & QueryName & "'")) Then
    CurrentDb.CreateQueryDef QueryName, strSQL
Else
    CurrentDb.QueryDefs(QueryName).SQL = strSQL
End If

DoCmd.OpenReport "rptChartByHospital", acViewPreview

【讨论】:

只是为了强调@Remou 所说的,这实际上是在 Access 中更改图表背后的结果集的唯一方法,除非您依赖 Access/Jet 表达式服务作为标准。我遇到了这个c。 1996年,从未改变。是的,这很糟糕。 此方法是否仍需要我将“查询”保存为对象?我需要将“QueryName”定义为字符串吗?一如既往地感谢 Remou? 在本例中,QueryName 是一个字符串。如果缺少查询,它将创建查询,但最方便的做法是创建合适的查询并在表单或报表上构建图表,然后添加代码以更改 SQL,如上所示。请记住,查询是永久更改的。

以上是关于MS Access 2003 - 有没有办法以编程方式定义图表的数据?的主要内容,如果未能解决你的问题,请参考以下文章

MS Access 以编程方式引发表单事件

关于 MS Access 2003 和 VBA 编程

ms-access 2003:表单打不开!帮助!

使用 C# 动态重命名 MS Access 中的列

MS Access 2003 - 格式化导致列表框问题

计数 MS-ACCESS 2003 列中的图像