从动态交叉表查询和vba访问报告以“手动”生成报告

时间:2010-02-02 16:52:01

标签: sql ms-access vba report

我遇到了生成复杂访问报告的问题(复杂的意思是数据处理,可变数量的字段等)。
让我更详细地解释一下我需要实现的一些事项:

  • 某些字段不应根据查询中的某些值显示
  • 如果某个记录不存在,应该出现一条漂亮的彩色(非常明显)的消息,而不是那里的值(假设,例如,日期字段中存在03/04/2009的记录,日期字段中的03/06/2009的记录也存在,但没有03/05/2009的记录。在显示与最后一条记录相关的数据之前,我应该打印类似“未显示在03/05”的内容/ 2009“)
  • 条形图,它将数据视为记录中的值,而不是通过一组记录计算的其他内容(例如某个日期的所有成绩的平均值)。此图表中的系列数量也会根据记录中的值而有所不同,此图表不在详细信息部分中,而是在页面标题或某种组标题中。

还应该提到的是,查询是TRANSFORM查询(更准确地说,是许多TRANSFORM查询的INNER JOIN),因此查询返回的列数会有所不同。虽然在过去我一直无法将此查询绑定为报告的记录源,但是Access现在停止了抱怨(有人可以澄清一下吗?这是正常的,我应该不担心它并将其用作记录源或我该避免吗?)

有两种方法可以实现我想要的(我现在可以看到):

  1. 创建一个没有记录源和大量未绑定字段的报告,并通过几个事件(Report_Open,Section_Format等)并在DAO的帮助下,手动设置这些字段的值。通过VBA也可以更改图表的数据系列。
  2. 将记录源设置为查询,并创建一些疯狂且令人困惑的VBA代码来处理数据并实现我需要的一切。
  3. 在我看来,选项2将是一个巨大的麻烦和浪费时间,我认为选项1非常类似于写入Excel文件(因为所有数据都是通过DAO获得的),这将是因为我对那里的几乎所有东西都有更多的控制权(但由于许多其他原因,我们希望访问报告中的所有内容),这样更容易了。

    虽然我有偏见并且打算选择选项1,但我发现此选项存在一些问题,例如:

    1. 我找不到使用VBA在报表中创建新页面的方法,因此我仅限于第一页。
    2. 缺乏关于VBA和访问报告的某种免费,在线,体面和完整的文档
    3. 另外,如果选项2更可行,我当然愿意接受它,但我也需要一些建议,也许还有一些提示来解决我在这个问题中提到的问题。

      所以,问题是:

      • 我在哪里可以找到关于Access Reports和VBA的一些体面和完整的文档?
      • 如何在访问报告中创建页面,并选择要写入的页面?
      • 由于我手中的问题,我是否会遇到任何我应该知道的瓶颈?我是否应该考虑访问报告的替代方法(例如写入电子表格?)

2 个答案:

答案 0 :(得分:1)

听起来你想要dynamically create the report并避免使用所有虚拟文本框。

答案 1 :(得分:0)

关于:

  

我找不到创建新网页的方法   在与VBA的报告中,因此我   仅限于第一页。

您的解决方案#1似乎假设未提交报告。

我认为我所做的是将交叉表作为rowsource,因此您将拥有生成页面的记录,然后在没有ControlSource的情况下定义报表的控件(绑定到字段的控件除外)始终存在于CrossTab中。然后,您可以根据特定列在运行时分配ControlSources。这是从我正在处理的应用程序中抓取的交叉表的SQL:

  TRANSFORM First(impNoMatch.PersonID) AS FirstOfPersonID
  SELECT impNoMatch.LastName, impNoMatch.FirstBame
  FROM impNoMatch
  GROUP BY impNoMatch.LastName, impNoMatch.FirstName
  PIVOT impNoMatch.Status;

现在,您知道SELECT子句中的字段将始终存在,因此如果您在使用的SQL字符串上打开记录集并计算记录集的Fields集合中的字段数(您不能使用报告的Recordset,除非它是一个ADO记录集,即没有绑定到Recordsource):

  Dim strSQL As String
  Dim rsFields As DAO.Recordset
  Dim lngFieldCount As Long

  strSQL = Me.Recordsource
  Set rsFields = CurrentDB.OpenRecordset(strSQL)
  lngFieldCount = rsFields.Fields.Count

由此您知道SELECT语句中的字段数(即行标题),您可以计算要分配的动态控件的数量,并且可以使用此记录集的字段集来分配ControlSources并取消隐藏控件。

您将从所有控件开始,这些控件将显示动态字段集,因此其Visible属性为FALSE。您还将为这些控件使用命名约定。在下面的代码中,我使用了txtNN,其中NN是Fields集合中的数字索引,格式为2位数。这是代码(它添加了上面列出的内容,并在OnOpen事件中运行):

  Dim strSQL As String
  Dim rsFields As DAO.Recordset
  Dim lngFieldCount As Long
  Dim l As Long
  Dim strControlName As String

  strSQL = Me.RecordSource
  Set rsFields = CurrentDb.OpenRecordset(strSQL)
  lngFieldCount = rsFields.Fields.Count
  For l = 2 To lngFieldCount - 1
    strControlName = "txt" & Format(l, "00")
    Me(strControlName).ControlSource = rsFields.Fields(l).Name
    Me(strControlName).Visible = True
  Next l
  rsFields.Close
  Set rsFields = Nothing

现在,如果你想获得幻想,你可以重新格式化控件,改变宽度和水平/垂直位置。如果你这样做,你必须在不同的事件中这样做,选择它有点棘手。放在它的唯一好处是在报告组的标题的OnFormat事件中。如果您没有任何分组,则可以添加一个不执行任何操作的分组。对于我的交叉表,Lastname和Firstname上的两级排序以及Firstname组中没有任何内容的标题是使用OnFormat事件更改报表上控件的外观/布局的好地方。 / p>

关于如何学习如何操作的问题,我建议您选择一本中级/高级Access编程手册。 Access开发者手册是此的黄金标准,包括大量的报告程序控制示例。