Vba 使用多个列组访问报表
因此,我正在致力于自动化一个繁琐的过程,山姆大叔让我们在部署时完成这个过程。我有一个数据库,我们在其中输入我们部署到表中的每一天的日期。例如,我列出了2017年4月10日至2017年7月11日。 每天都需要显示日期和位置,我需要将六个结果垂直堆叠,然后向右移动,再执行下六个三次 我有一份名为2282report的报告,它是主报告,在适当的位置有四个子位置[1-4]。最初我让它做TOP 6,然后下一个会做TOP 6,但是ID>6,但后来我移动了,使日期成为ID,因为日期无论如何都不能复制。我不确定如何将它们链接起来,以便下一个子报告将显示“继续”其余部分 运行时,报告看起来是这样的。我通常还有超过90天的时间可以列出,所以我需要创建主报告的第二页 我想我要做的是为整个位置块创建一个新的子报告,但我不知道如何在报告显示6个结果后将报告的详细信息移动到一个新列 我刚才想到的另一个选择是将子报表留空,然后通过vba将主报表设置为每个报表的控制源。我觉得这一个可能会工作,因为它可以检查,看看是否有更多的天,然后有行,以便它可以创建一个新的页面继续。但是我需要弄清楚如何让它继续到下一页。还有一个底部的部分只有16天,而顶部只有24天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,因为日期无论如何都不能复制。我不确定
您可能会尝试在各种报表事件处理程序中使用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
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