常用分栏帐票印刷
环境:
vs2005+ActiveReportsNet2
AR下载地址:ftp://ftp.datadynamics.com/
学习了前面的换页和换列的方法,下面我们结合这2节知识实际打印一张分栏帐票。
分栏帐票在我们系统中是经常用到的,具体式样如下:
Page 1:
Class: |
A |
|
|
|
|
Chinese |
Maths |
||||
ID |
Name |
Score |
ID |
Name |
Score |
1 |
Tony |
100 |
1 |
Tony |
99 |
2 |
Mary |
56 |
2 |
Mary |
76 |
3 |
Tom |
76 |
3 |
Tom |
54 |
4 |
John |
67 |
4 |
John |
86 |
5 |
Li |
54 |
5 |
Li |
34 |
Page 2:
Class: |
B |
|
|
|
|
Chinese |
Maths |
||||
ID |
Name |
Score |
ID |
Name |
Score |
6 |
Zhang |
3 |
6 |
Zhang |
0 |
7 |
Wang |
100 |
7 |
Wang |
2 |
8 |
Gong |
23 |
8 |
Gong |
56 |
9 |
Tian |
78 |
9 |
Tian |
99 |
10 |
Jack |
87 |
10 |
Jack |
88 |
该类型帐票有如下特点:
(1)、分栏帐票的特点是各栏的样式基本相同,只是其中的数据会有所变化。
(2)、分栏帐票的各栏可以是衔接在一起的,即栏间距为0,也可以是分开的。
(3)、Title和SubTitle通常是不分栏的,它们会跨越所有的栏。
(4)、帐票的默认栏数应该是固定的,比方说A4纸默认印刷8栏,如果超过8栏可以选择换页,也可以选择超出边界继续印刷(红线)。
这是由代码来控制的。
有如下数据源
Table1 |
||||
Class |
Subject |
ID |
Name |
Score |
A |
Chinese |
1 |
Tony |
100 |
A |
Chinese |
2 |
Mary |
56 |
A |
Chinese |
3 |
Tom |
76 |
A |
Chinese |
4 |
John |
67 |
A |
Chinese |
5 |
Li |
54 |
A |
Maths |
1 |
Tony |
99 |
A |
Maths |
2 |
Mary |
76 |
A |
Maths |
3 |
Tom |
54 |
A |
Maths |
4 |
John |
86 |
A |
Maths |
5 |
Li |
34 |
B |
Chinese |
6 |
Zhang |
3 |
B |
Chinese |
7 |
Wang |
100 |
B |
Chinese |
8 |
Gong |
23 |
B |
Chinese |
9 |
Tian |
78 |
B |
Chinese |
10 |
Jack |
87 |
B |
Maths |
6 |
Zhang |
0 |
B |
Maths |
7 |
Wang |
2 |
B |
Maths |
8 |
Gong |
56 |
B |
Maths |
9 |
Tian |
99 |
B |
Maths |
10 |
Jack |
88 |
最终希望打印成如下帐票:
(1)根据Class换行
(2)根据Subject换列
Page 1:
Class: |
A |
|
|
|
|
Chinese |
Maths |
||||
ID |
Name |
Score |
ID |
Name |
Score |
1 |
Tony |
100 |
1 |
Tony |
99 |
2 |
Mary |
56 |
2 |
Mary |
76 |
3 |
Tom |
76 |
3 |
Tom |
54 |
4 |
John |
67 |
4 |
John |
86 |
5 |
Li |
54 |
5 |
Li |
34 |
Page 2:
Class: |
B |
|
|
|
|
Chinese |
Maths |
||||
ID |
Name |
Score |
ID |
Name |
Score |
6 |
Zhang |
3 |
6 |
Zhang |
0 |
7 |
Wang |
100 |
7 |
Wang |
2 |
8 |
Gong |
23 |
8 |
Gong |
56 |
9 |
Tian |
78 |
9 |
Tian |
99 |
10 |
Jack |
87 |
10 |
Jack |
88 |
0,开始之前,先让我们回想一下第3节的内容。
用第3节的方法,
(1),添加如下控件
〔2〕,把GroupHeader的DataField设置成Subject,NewColumn设置成Before
(3),把GroupHeader中的ClassNo控件DataField设为Class
(4),Detail中3个控件的DataField 邦定到”ID”,”Name”,”Score”
(5),比较特殊的,GroupHeader1中Subject这个控件也要设置DataField,设为Subject,这样就可以从数据源中把Subject 的Name读取出来了
(6),Detail的ColumnCount设为2
ok,让我们看看结果吧!
赫赫,大致要差不多了,主要问题有2个:
(1),2个Title “Class: A” ,由于放在GroupHeader1中,换列的时候重复了2次。
(2),还有个问题可能比较难发现。我们没有设置分页,但为啥打印出来帐票分页正常呢?
恩,我们设置的分列字段是Subject,ColumnCount是2,而数据源是这样的:
A |
Chinese |
1 |
Tony |
100 |
A |
Chinese |
2 |
Mary |
56 |
A |
Chinese |
3 |
Tom |
76 |
A |
Chinese |
4 |
John |
67 |
A |
Chinese |
5 |
Li |
54 |
A |
Maths |
1 |
Tony |
99 |
A |
Maths |
2 |
Mary |
76 |
A |
Maths |
3 |
Tom |
54 |
A |
Maths |
4 |
John |
86 |
A |
Maths |
5 |
Li |
34 |
B |
Chinese |
6 |
Zhang |
3 |
B |
Chinese |
7 |
Wang |
100 |
B |
Chinese |
8 |
Gong |
23 |
B |
Chinese |
9 |
Tian |
78 |
B |
Chinese |
10 |
Jack |
87 |
B |
Maths |
6 |
Zhang |
0 |
B |
Maths |
7 |
Wang |
2 |
B |
Maths |
8 |
Gong |
56 |
B |
Maths |
9 |
Tian |
99 |
B |
Maths |
10 |
Jack |
88 |
第一页2列共10条数据打印好之后,正好Subject改变了,又要换列,而该页已经打满了,所以系统自动换页了。
让我们看看,假如Class A不学maths的话会发生什么情况?
数据源变成这样:
A |
Chinese |
1 |
Tony |
100 |
A |
Chinese |
2 |
Mary |
56 |
A |
Chinese |
3 |
Tom |
76 |
A |
Chinese |
4 |
John |
67 |
A |
Chinese |
5 |
Li |
54 |
B |
Chinese |
6 |
Zhang |
3 |
B |
Chinese |
7 |
Wang |
100 |
B |
Chinese |
8 |
Gong |
23 |
B |
Chinese |
9 |
Tian |
78 |
B |
Chinese |
10 |
Jack |
87 |
B |
Maths |
6 |
Zhang |
0 |
B |
Maths |
7 |
Wang |
2 |
B |
Maths |
8 |
Gong |
56 |
B |
Maths |
9 |
Tian |
99 |
B |
Maths |
10 |
Jack |
88 |
结果由于没有强制根据Class换页,导致Class A和Class B的数据打印在一列上了:
要解决这2个问题,一般有2种方法:
(1)增加一个GroupHeader/GroupFooter用于放Title;同时用来控制换页。这样,就有1个group换页,1个group换列了。
(2)用子报表
本节我们使用第一种方案。第二种方案下节讨论。
1,先准备数据源:
数据源可以在后台取数的时候就组织好,也可以到前台再组织数据。
2,创建一个AR模版(rpt1.rpx):
GroupHeader1:
DataField=Class
NewPage=Before
ColumnLayout=False
ColumnLayout是分栏帐票中一个很重要的属性,当ColumnLayout设置为True的时候GroupHeader将与Detail一起换栏,当设置为False时GroupHeader将跨越所有栏。
此处因为该Group不需要换列,所以设置成False
GroupHeader2:
DataField=Subject
NewColumn=Before
其余控件属性不变。
3,在form的load事件中编写如下代码,把数据源传给模版,并显示模版:
'Show the table1
Dim conn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb;Persist Security Info=False"
Dim cmd As String = "Select * from table1 order by Class,subject,ID"
Dim adapter As New OleDbDataAdapter(cmd, conn)
Dim ds As New DataSet
adapter.Fill(ds)
Dim rpt As New rpt1
rpt.DataSource = ds.Tables(0)
rpt.Run()
Me.Viewer1.Document = rpt.Document
End Sub
4,ok!再御览看看,搞定收工。
下一节用子报表的方式实现该帐票。