【问题标题】:Access Report with multiple column groups访问具有多个列组的报告
【发布时间】:2017-09-12 22:54:33
【问题描述】:

因此,我正在努力将山姆大叔让我们在部署时执行的繁琐流程自动化。我有一个数据库,我们在其中为我们部署到表中的每一天输入一个日期。例如,我列出了 2017 年 4 月 10 日到 2017 年 7 月 11 日。 每天都需要显示日期和位置,我需要将六个结果垂直堆叠,然后向右移动,将接下来的六个结果再做三遍。

我有一份名为 2282report 的报告,它是主报告,在适当的位置有四个 subLocation[1-4]。最初我让它做 TOP 6,然后下一个做 TOP 6,但是 ID > 6 但后来我将日期设为 ID,因为日期无论如何都不能重复。我不确定将它们链接起来的正确方法,以便下一个子报表将继续显示。

报告在运行时如下所示。我通常还有超过 90 天的时间来列出,因此我需要在主报告中创建第二页。

我想我必须做的是为整个位置块创建一个新的子报表,但我不知道如何让 report_details 在显示 6 个结果后移动到新列。

我刚刚想到的另一个选项是将子报表留空,然后通过 vba 让主报表为每个报表设置控制源。我觉得这可能会起作用,因为它可以检查是否有更多的天数然后有行,以便它可以创建一个新页面以继续。但接下来我需要弄清楚如何让它继续到下一页。还有一个底部只有 16 天,而顶部是 24 天。

【问题讨论】:

  • 为什么您的示例显示 20170408 - 20170413 两次?只是构建示例的疏忽?为什么只有6行?这不会在工作表上留下很多未使用的空白吗?能否提供分析测试的数据库?我推荐 Box.com 文件共享网站并发布文件链接。
  • 一个建议:您可以创建一个多列报表来至少处理四列。这仍然留下了在页面之间继续报告的任务,但至少减少了列的工作量。对于 Access 2013,请转到 Report Design ,然后转到 Page Setup 功能区并单击 Columns 图标以获取各种选项。
  • 关于最后一页是 16 而不是 24,这是绝对给定的吗?即使子报表行数是 24 的精确倍数,这是否正确?在这种情况下,是否会使最后一页的 16 个条目为空白,或者这是否需要平衡条目的数量以便没有页面有完全空白的子报告?无论您的特定解决方案如何,我猜都需要为最后一页创建一个单独的报告。

标签: vba ms-access report


【解决方案1】:

您可能很想在各种报告事件处理程序中使用 VBA,但即使这可能有效,根据我的经验,这只会导致试图让所有内容正确格式化的问题。相反,我建议创建一个新的报表,每行都有一个页码。从排序后的页码列表中获取主报表,并通过页码字段绑定多列子报表。使用一个简单的 VBA 过程填充报表,该过程可以根据您的方案正确地对行进行分页。

首先是报表(根据需要添加约束):

CREATE TABLE SubReportTable (PageNum LONG, PageOrdinal LONG, _
    Ordinal LONG, LastPage BIT, [Date of Service] DATE,  [Location] TEXT)

关于子报告:

  • 设置 RecordSoucre 属性:SubReportTable(或者指定按所需字段排序的查询)
  • 将列数设置为 4 以及其他列设置(填充、方向等)。
  • 在“详细信息”部分和其他适当的控件上将 CanGrow 属性设置为 No
  • 调整列和详细信息部分的大小以适合页面上的所有列。 (这可能需要在主窗体上的打印预览和设计之间来回切换。)

在主报表上,设置以下属性:

  • RecordSource 属性:SELECT SubReportTable.PageNum FROM SubReportTable WHERE (((SubReportTable.LastPage)=False)) GROUP BY SubReportTable.PageNum ORDER BY SubReportTable.PageNum
  • 详细部分属性强制新页面After Section
  • SubReport 对象的 Link Master FieldsLink Child Fields 都与PageNum
  • 调整 SubReport 对象的大小以适合所有列。

将主报告上的行为复制到单独的“最后一页”报告中。设置此报告以根据报告表中的分页数据选择适当的记录子集(即LastPage = True)。根据具有 16 条记录的最后一页的格式不同,它可能还需要为 16 条记录创建单独的子报表,但您可能会使用与主报表相同的子报表...这将是您的问题确定。

  • RecordSource 属性:SELECT SubReportTable.PageNum FROM SubReportTable WHERE ((SubReportTable.LastPage = True)) GROUP BY SubReportTable.PageNum ORDER BY SubReportTable.PageNum

最后是一些用于填充报表的代码。您可以直接从 VBA 即时窗口运行此过程,也可以将其放在某个按钮的单击事件处理程序中。可以调整分页逻辑以在最后一页上获得适量的记录。

Public Sub PrepareSubReporTable()
  On Error GoTo Catch_PrepareSubReporTable

  Dim db As Database
  Dim rs As Recordset2
  Dim rows As Long, pgs24 As Long, rowsLast24 As Long, rows16 As Long
  Dim i As Long, p As Long, pi As Long

  Set db = CurrentDb

  db.Execute "DELETE * FROM [SubReportTable]", dbFailOnError

  db.Execute _
    "INSERT INTO SubReportTable ( PageNum, PageOrdinal, Ordinal, LastPage, [Date of Service], [Location] )" & _
    " SELECT Null AS PageNum, Null AS PageOrdinal, Null AS Ordinal, False as LastPage," & _
        " [Data].[Date of Service], [Data].[Location]" & _
    " FROM [Data]" & _
    " ORDER BY [Data].[Date of Service], [Data].[Location];", _
    dbFailOnError

  rows = db.OpenRecordset("SELECT Count(*) FROM SubReportTable").Fields(0)
  pgs24 = rows \ 24
  rows16 = rows - 24 * pgs24
  If rows16 > 16 Then
    rowsLast24 = rows16
    pgs24 = pgs24 + 1
    rows16 = 0
  Else
    rowsLast24 = 24
  End If

  Set rs = db.OpenRecordset( _
      "SELECT * FROM SubReportTable" & _
      " ORDER BY [Date of Service], [Location];")
  i = 0
  Do Until rs.EOF
    p = i \ 24 + 1

    rs.Edit
    rs![PageNum] = p
    If p > pgs24 Then
      rs![lastPage] = True
      pi = (i - pgs24 * 24) Mod 16 + 1
    Else
      pi = i Mod 24 + 1
    End If
    rs![PageOrdinal] = pi
    i = i + 1
    rs![Ordinal] = i
    rs.Update

    rs.MoveNext
  Loop
  rs.Close

  Exit Sub
Catch_PrepareSubReporTable:
  MsgBox Err.Number & ": " & Err.Description, _
      vbOKOnly Or vbExclamation, "Error in PrepareSubReporTable"
End Sub

现在生成主报告和最后一页报告,可以手动生成,也可以使用 VBA 代码生成。

注意:我使用字段名称 PageNum 而不是 Page,因为这似乎会在打印预览期间导致 SubReport 绑定出现问题...可能是因为 Page 是报表的现有变量/函数的名称。

【讨论】:

  • 这个反应太棒了。非常详细和翔实。我意识到,当我发布此内容时,我可能没有传达 16 块部分将与 24 块在同一页面上。我实际上是在重新创建一个表单 link 只是为了使其与部署的整个工作人员更加一致。在我阅读您的回复之前,我还上传了到目前为止所获得的信息,因为我从未收到过通知。你可以在这里link从我的网络服务器下载示例。
  • 只是想发布一个更新,经过几个小时的胡闹,我现在欠你一杯啤酒!谢谢大佬!
  • 我很高兴它有帮助!我对批评 Access 犹豫不决,因为我意识到“它就是这样”,但我经常希望它一开始就表现得像其他开发得更好的工具。在报告的情况下,我已经疯狂地试图让格式正确,只是为了发现 Access 以最愚蠢的方式处理事件和格式。我包括了所有细节,因为当我已经知道所有属性和方法来做这样的事情时,让你慢慢画出来是没有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多