Vba 使用多个列组访问报表

Vba 使用多个列组访问报表,vba,ms-access,report,Vba,Ms Access,Report,因此,我正在致力于自动化一个繁琐的过程,山姆大叔让我们在部署时完成这个过程。我有一个数据库,我们在其中输入我们部署到表中的每一天的日期。例如,我列出了2017年4月10日至2017年7月11日。 每天都需要显示日期和位置,我需要将六个结果垂直堆叠,然后向右移动,再执行下六个三次 我有一份名为2282report的报告,它是主报告,在适当的位置有四个子位置[1-4]。最初我让它做TOP 6,然后下一个会做TOP 6,但是ID>6,但后来我移动了,使日期成为ID,因为日期无论如何都不能复制。我不确定

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

我有一份名为2282report的报告,它是主报告,在适当的位置有四个子位置[1-4]。最初我让它做TOP 6,然后下一个会做TOP 6,但是ID>6,但后来我移动了,使日期成为ID,因为日期无论如何都不能复制。我不确定如何将它们链接起来,以便下一个子报告将显示“继续”其余部分

运行时,报告看起来是这样的。我通常还有超过90天的时间可以列出,所以我需要创建主报告的第二页

我想我要做的是为整个位置块创建一个新的子报告,但我不知道如何在报告显示6个结果后将报告的详细信息移动到一个新列

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


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

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

关于分报告:

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

  • RecordSource属性:
    从SubReportTable中选择SubReportTable.PageNum,其中(((SubReportTable.LastPage)=False))按SubReportTable分组。PageNum按SubReportTable排序。PageNum
  • 详细信息节属性强制新页面到节后的
    
    
  • 子报表对象的链接主字段和链接子字段都链接到
    PageNum
  • 调整子报表对象的大小以适合所有列
在单独的“最后一页”报告中复制主报告上的行为。设置此报告以根据报告表中的分页数据选择适当的记录子集(即
LastPage=True
)。根据包含16条记录的最后一页的格式不同,可能还需要仅为16条记录创建一个单独的子报表,但您可以使用与主报表相同的子报表。。。那将是你要决定的问题

  • RecordSource属性:
    从SubReportTable中选择SubReportTable.PageNum,其中((SubReportTable.LastPage=True))按SubReportTable分组。PageNum按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,因为在打印预览期间,这似乎会导致子报表绑定出现问题。。。可能是因为Page是报表的现有变量/函数的名称。

为什么您的示例两次显示20170408-20170413?只是在构建示例时的疏忽?为什么只有6行?这不会在工作表上留下很多未使用的空白吗?你能为分析和测试提供数据库吗?我推荐Box.com文件共享站点和文件的链接。一个建议是:您可以创建一个多列报告,至少处理这四列。这仍然保留了在页面之间继续报告的任务,但至少减少了列的工作量。对于Access 2013,请转到“报告设计”,然后转到“页面设置”功能区,并单击各个选项的列图标。关于最后一页,交叉张贴的是16而不是24,这是绝对给定值吗?即使子报表行数的精确倍数为24,这是真的吗?在这种情况下,这会使最后一页上的16个条目保持空白,还是需要平衡条目的数量,以便没有一个页面具有完全空白的子报表?不管你们的具体解决方案是什么,我猜这将需要在最后一页创建一个单独的报告。这个响应是惊人的。非常详细和翔实。我意识到,当我发布这篇文章时,我可能没有传达16个区块的部分将与24个区块在同一页上。我是埃森
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