【问题标题】:Programming a PivotTable in Access VBA在 Access VBA 中编写数据透视表
【发布时间】:2013-11-29 10:29:17
【问题描述】:

让我先把事情放在上下文中。 我有三个问题,希望能就我遇到的问题得到一些帮助。 我正在开发一个应用程序,对特定工作场所/活动组合中使用的物质进行风险评估。我想做的是创建一个矩阵报告,如下所示:

[工作场所名称](作为列标题)

[活动名称](作为行标题)

[风险评估分数](作为数据)

所有这些值都可以通过查询来检索。我尝试使用交叉表查询,但似乎它们只能用于汇总数据。如果我的假设是正确的,我是在伤害,因为这是我在查看微软网站后得出的结论。但是,由于我不是经验丰富的 Acces 程序员,我可能是错的。

根据我的假设,我认为数据透视表是可行的方法。我在http://msdn.microsoft.com/en-us/library/aa662945(office.11).aspx 上找到了一个例子 我试图复制。编程的原因是可以根据表单中的用户条件生成数据透视表。

以下代码与上述链接中给出的示例代码略有不同。

Private Sub cmdPivotTable_Click()

Dim strDefaultName As String
Dim strRecordSource As String

'Create an empty form with a PivotTable
'default view and a record source
strRecordSource = "SELECT *" _
& " FROM ((OEL RIGHT JOIN Substance ON OEL.OEL_ID = Substance.OEL_ID) INNER JOIN" _
& " ((Product INNER JOIN Proportions ON (Product.Product_Name = Proportions.Product_Name) AND (Product.Product_ID = Proportions.Product_ID) AND (Product.Product_Name = Proportions.Product_Name) AND (Product.Product_ID = Proportions.Product_ID)) INNER JOIN (STM_Workplace INNER JOIN (Respiratory_PPE INNER JOIN (STM_LocalControls INNER JOIN (STM_Diffuse INNER JOIN ((STM_Vent_NF_FF INNER JOIN Workplace ON (STM_Vent_NF_FF.STM_Vent_FF_ID = Workplace.STM_Vent_NF_ID) AND (STM_Vent_NF_FF.STM_Vent_FF_ID = Workplace.STM_Vent_NF_ID) AND (STM_Vent_NF_FF.STM_Vent_FF_ID = Workplace.STM_Vent_FF_ID)) INNER JOIN (STM_Activity_Score INNER JOIN (Activity INNER JOIN (PBMCode INNER JOIN Product_Activity ON PBMCode.ID_PBMCode = Product_Activity.ID_PBMCode) " _
& " ON Activity.Activity_ID = Product_Activity.ID_Activity) ON STM_Activity_Score.STM_ActivityScore_ID = Activity.STM_ActivityScore_ID) ON (Workplace.Workplace_ID = Product_Activity.Workplace_ID) AND (Workplace.Workplace_ID = Product_Activity.Workplace_ID)) ON STM_Diffuse.STM_Diffuse_ID = Workplace.STM_Diffuse_ID) ON STM_LocalControls.STM_LocalControls_ID = Workplace.STM_LocalControls_ID) ON (Respiratory_PPE.STM_PPE_ID = PBMCode.STM_PPE_ID) AND (Respiratory_PPE.STM_PPE_ID = PBMCode.STM_PPE_ID)) ON STM_Workplace.STM_Workplace_ID = Workplace.STM_Workplace_ID) ON (Product.Product_Name = Product_Activity.Product_Name) AND (Product.Product_ID = Product_Activity.Product_ID) " _
& " AND (Product.Product_Name = Product_Activity.Product_Name) AND (Product.Product_ID = Product_Activity.Product_ID)) ON (Substance.Substance_Name = Proportions.Substance_Name) AND (Substance.Substance_ID = Proportions.Substance_ID)) INNER JOIN Risk_Assessment ON (Substance.Substance_Name = Risk_Assessment.Substance_Name) AND (Substance.Substance_ID = Risk_Assessment.Substance_ID) " _
& " WHERE Product_Activity.ID_Product_Task = Product_Activity_ID"

strDefaultName = CreatePivotTable(strRecordSource)

'Rename the form from its default name
Dim strFormName As String
strFormName = "TestCreatePivotTableForm"
If (AssignPivotTableName(strDefaultName, strFormName)) = False Then
    Exit Sub
End If

'Configure the PivotTable
ConfigurePivotTable (strFormName)
End Sub



Public Function AssignPivotTableName(strDefaultName As String, strFormName As String As Boolean
Dim acc1 As AccessObject

AssignPivotTableName = True

For Each acc1 In CurrentProject.AllForms
    If acc1.Name = strFormName Then
        MsgBox "Choose a form name other " & _
            "than '" & strFormName & "' that " & _
            "does not match an existing form."
        AssignPivotTableName = False
        DoCmd.DeleteObject acForm, strDefaultName
        Exit Function
    End If
Next acc1

DoCmd.Rename strFormName, acForm, strDefaultName
End Function



Public Function CreatePivotTable(strRecordSource As String) As String
Const acFormPivotTable = 3
Dim frm1 As Access.Form

Set frm1 = CreateForm
frm1.DefaultView = acFormPivotTable
frm1.RecordSource = strRecordSource

CreatePivotTable = frm1.Name
DoCmd.Close acForm, CreatePivotTable, acSaveYes
End Function



Public Sub ConfigurePivotTable(strFormName As String) 
Dim fst1 As PivotFieldSet

DoCmd.OpenForm strFormName, acFormPivotTable
Set frm1 = Forms.Item(strFormName)

With frm1.PivotTable.ActiveView
    ***Set fst1 = .FieldSets("Product_Name")***
    .FilterAxis.InsertFieldSet fst1
    Set fst1 = .FieldSets("WorkPlace_Name")
    .ColumnAxis.InsertFieldSet fst1
    Set fst1 = .FieldSets("Activity_Name")
    .RowAxis.InsertFieldSet fst1
    Set fst1 = .FieldSets("Imission_Score")
    .DataAxis.InsertFieldSet fst1
End With

DoCmd.Close acForm, frm1.Name, acSaveYes
End Sub

问题如下:设置 PivotFieldSet 时出现错误 13 类型不匹配,并且不知道发生了什么问题。该表单使用适当的记录集创建并在 PivotTableView 中打开,仅此而已。我希望检索一些关于问题可能是什么的建议。

另外,是否有另一种方法来实现我所描述的制作矩阵的目标?由于需要导出到 Excel 才能打印出数据透视表,所以我宁愿最终用户不必走弯路。

提前感谢您对我的帖子的任何建议或回复。

【问题讨论】:

  • 非常感谢!我之前尝试过,但没有得到预期的输出。感谢您的回答,我再次查看并发现了问题,这在我正在使用的查询中。我忘记添加导致大量重复风险比率的 where 子句。所以事实证明交叉表查询确实适合我的问题。再次原谅我的无知,谢谢!

标签: ms-access vba pivot-table


【解决方案1】:

您对使用交叉表查询的反感是没有根据的。如果您对每一行/列组合最多有一个观察结果,那么您的“汇总数据”就是值本身:使用 Min()、Max() 或 Sum() 都没有关系。

示例:对于样本数据 [Risk_Data]

Activity        Workplace        Risk_Ratio
--------------  ---------------  ----------
Activity_Name   Workplace_Name          1.2
Activity_Name   Workplace_Name2         2.3
Activity_Name2  Workplace_Name          3.4
Activity_Name2  Workplace_Name2         4.5

查询

TRANSFORM Max(Risk_Ratio) AS MaxOfRisk_Ratio
SELECT Activity
FROM Risk_Data
GROUP BY Activity
PIVOT Workplace

返回

Activity        Workplace_Name  Workplace_Name2
--------------  --------------  ---------------
Activity_Name              1.2              2.3
Activity_Name2             3.4              4.5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多