惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
小众软件
小众软件
F
Fortinet All Blogs
博客园 - 叶小钗
博客园_首页
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
U
Unit 42
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家
M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog

博客园 - Tony.Gong

新项目中的CC.Net每日编译环境 ActiveReports工作总结12——用Designer控件实现用户自定义报表印刷 ActiveReports工作总结11——麻烦的线线框框 ActiveReports工作总结9——打印参数设置 ActiveReports工作总结8——用代码控制布局 ActiveReports工作总结7——常用一览表印刷 今天还有多少人在上班啊? ActiveReports工作总结6——使用子报表 ActiveReports工作总结5——常用分栏帐票印刷 ActiveReports工作总结4——换页打印 ActiveReports工作总结3——换列打印 公司现有产品数据层切换的随想 .net发送邮件的一些技巧 ActiveReports工作总结2——数据源绑定 ActiveReports工作总结1——AR简介 NUnit学习笔记4--单元测试和项目结合的几种方法 成功升级成老爸。。。。 马上要当老爸了。。。。。 委托与事件学习笔记1---什么是委托?
ActiveReports工作总结10——完整的一张成绩一览帐票
Tony.Gong · 2007-03-02 · via 博客园 - Tony.Gong

完整的一张成绩一览帐票

环境:

vs2005+ActiveReportsNet2

本节代码下载:https://files.cnblogs.com/batoosai/SimpleExample10.rar

学习了前面的一些基础,我们来实际开发一张帐票吧。

1,帐票式样


2,帐票说明:

    1,抽出条件:

      1-1班级:必選,多選

1-2科目:必選, 多選                                  

    2,用紙サイズ: A4                             

    3,改頁条件:班级

    4,印刷順序:行:生徒出席番号升排序

                列:科目順位

    4,如果某学生某subject没有成绩的话,也要显示该数据(只是把格子留空)

分析下帐票,我们应该用3个子模版(如下图,其中Sub3不需要取数,老师手动填)


3,好,我们项目一般的架构如下:


在我们的示例中,方便起见,就用简单的3层架构吧,当中的web service去掉。创建Project如图:


1)表示层:Form,ARTemplate

2)业务逻辑层:BR

3)数据层:DA

4,数据库如下:


具体数据表的数据:

1Class

Class

ClassID

ClassName

TeacherName

DisplayOrder

1

A

Tony Gong

1

2

B

Tony Wang

2

3

C

Tony Li

3

2)Student

Student

StudentID

ClassID

No

Name

11

1

1

Tony

12

1

2

Zhu

13

1

3

Li

14

1

4

Zhang

15

1

5

Zha

16

1

6

Sun

21

2

1

Wang

22

2

2

Gong

23

2

3

Tian

24

2

4

Su

25

2

5

Xiao

31

3

1

Xu

32

3

2

Liu

33

3

3

Tom

34

3

4

Mary

3)Subject

Subject

SubjectID

SubjectName

DisplayOrder

1

古典

1

2

現代文

2

3

語文

3

4)Score

Score

ScoreID

StudentID

SubjectID

Score

GradeOrder

1

11

1

70

11

2

11

2

75

23

3

11

3

55

1

4

12

1

6

15

5

12

2

77

6

6

13

1

8

6

7

13

2

77

7

8

13

3

66

8

9

14

1

55

9

10

14

3

44

10

11

15

2

32

11

12

16

3

100

12

13

21

1

11

13

14

21

2

14

14

15

21

3

15

1

16

22

1

16

2

17

22

2

76

3

18

22

3

18

4

19

23

1

99

5

20

23

3

89

6

21

24

1

21

7

22

25

1

44

8

23

31

1

23

9

24

31

2

24

10

25

32

1

25

1

26

32

3

26

2

27

33

1

27

3

28

34

1

28

4

29

34

2

29

5

30

34

3

30

6

5,ok,开工,先add 如下文件


其中Form

       frmScore让用户选择抽出条件

       frmShowAR用来显示report

6,在form上放2个多选的条件控件,ClassSubject

实际项目中,这2个控件的内容应该取数据表里的值。我这里方便起见,直接把值写死在控件上。


btnPreviewclick事件如下:

    Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.ClickIf Me.listClass.SelectedIndex = -1 OrElse Me.listSubject.SelectedIndex = -1 ThenReturnEnd If'Get the Parameter

        
Dim classID As String = ""Dim subjectID As String = ""For index As Int32 = 0 To Me.listClass.SelectedIndices.Count - 1

            classID 

&= Me.listClass.SelectedIndices(index) + 1 & ","NextFor index As Int32 = 0 To Me.listSubject.SelectedIndices.Count - 1

            subjectID 

&= Me.listSubject.SelectedIndices(index) + 1 & ","Next

        classID 

= classID.TrimEnd(Convert.ToChar(","))

        subjectID 

= subjectID.TrimEnd(Convert.ToChar(","))'Send parameters to the BR and get the dataset.

        
Dim br As New BR.brScore()Dim finalDS As DataSet = br.GetData(classID, subjectID)'Send dataset to the form

        
Dim frm As New frmShowAR(finalDS)

        frm.Show()

End Sub

7br层,由于业务太简单了,代码很简单。

    Public Function GetData(ByVal classID As StringByVal subjectID As StringAs DataSetTry' 創建DA

            
Dim objDA As New DA.daScore()Dim ds As DataSet = objDA.GetData(classID, subjectID)' 返回値

            
Return dsCatch ex As Exception' 抛出異常

            
Throw exEnd TryEnd Function

8 DA层,根据参数执行sql语句,返回结果Dataset

       DA的任务,是根据参数,作select语句,得出2table,放到dsreturn

假设Class选了”B,C”Subject选了古典,现代文

其中table1(用于Sub1和主模版)数据应该如下:(9条记录)

Query1

Class.ClassID

ClassName

TeacherName

DisplayOrder

StudentID

Student.ClassID

No

Name

2

B

Tony Wang

2

21

2

1

Wang

2

B

Tony Wang

2

22

2

2

Gong

2

B

Tony Wang

2

23

2

3

Tian

2

B

Tony Wang

2

24

2

4

Su

2

B

Tony Wang

2

25

2

5

Xiao

3

C

Tony Li

3

31

3

1

Xu

3

C

Tony Li

3

32

3

2

Liu

3

C

Tony Li

3

33

3

3

Tom

3

C

Tony Li

3

34

3

4

Mary

table2(用于Sub2)数据应该这样做:

9条生徒 * 2门科目,然后left join Score的内容,最终得到18条记录(假如某人某科没成绩的话,该字段也会显示出来,只是留空而已)。


PS:由于AccessLeft join 俺实在是搞不懂,没法做left join,所以只能把Score的纪录填满,然后用普通查询。

PSAccess的参数化查询我也搞不太清楚,所以代码中直接把”@classid”等替换成字符串了。

最后的PS:假如是mssql的话,sub2的查询语句大概如下:

Select * from student,class

    cross join Subject

    left join score

           on score.subjectID=Subject.SubjectID

           and score.StudentID=student.StudentID

Where s.ClassID=c.ClassID

And c.ClassID in (@ClassID)


Sub3就不需要查寻了。

9frmShowAR接收到数据源,并显示帐票

Public Class frmShowARSub New(ByVal ds As DataSet)Me.finalDS = ds' 此调用是 Windows 窗体设计器所必需的。

        InitializeComponent()
' 在 InitializeComponent() 调用之后添加任何初始化。

    
End SubPrivate finalDS As DataSetPrivate Sub frmShowAR_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.LoadDim rpt As New ARTemplate.rptScore

        rpt.DataSource 

= finalDS

        rpt.DataMember 

= finalDS.Tables(0).TableName'A4 Landscape

        rpt.PageSettings.PaperKind 
= Printing.PaperKind.A4

        rpt.PageSettings.Orientation 

= DataDynamics.ActiveReports.Document.PageOrientation.Landscape

        rpt.Run()

Me.Viewer1.Document = rpt.DocumentEnd SubEnd Class

10,主模版和子模版主要属性及代码(完整的请看下载的代码)

1),主模版


       GroupHeader1DataFied=”ClassID”

                              NewPage=”Before”

       txtClassNo  DataField=”ClassName”

       txtTeacher   DataField=”TeacherName”

代码:

Report_start中布局代码

   Private Sub rpt1_ReportStart(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.ReportStart'<--------Step (1)---------->

        
'Set contols' width

        
'me.lblClass.Width=xxx

        
'

        
'

        
'<--------Step (1)---------->

 
'<--------Step (2)---------->

        
'Arrange Controls.

        
Me.lblYear.Left = 0.5Me.lblYear.Top = 0.5Me.txtClassNo.Left = Me.lblYear.LeftMe.txtClassNo.Top = Me.lblYear.Top + Me.lblYear.HeightMe.Label3.Left = Me.txtClassNo.Left + Me.txtClassNo.Width * 2Me.Label3.Top = Me.txtClassNo.TopMe.txtTeacher.Left = Me.Label3.Left + Me.Label3.WidthMe.txtTeacher.Top = Me.Label3.Top'<--------Step (2)---------->

 
'<--------Step (3)---------->

        
Dim sub1 As New sub1Me.subReport1.Width = sub1.ReportWidthDim sub2 As New sub2With CType(Me.DataSource, DataSet)Me.subReport2.Width = sub2.ReportWidth * CInt(.Tables(1).Rows.Count / .Tables(0).Rows.Count)End WithDim sub3 As New sub3Me.subReport3.Width = sub3.reportWidth'<--------Step (3)---------->

 
'<--------Step (4)---------->

        
Me.subReport1.Left = Me.txtClassNo.LeftMe.subReport1.Top = Me.txtClassNo.Top + Me.txtClassNo.HeightMe.subReport2.Left = Me.subReport1.Left + Me.subReport1.WidthMe.subReport2.Top = Me.subReport1.TopMe.subReport3.Left = Me.subReport2.Left + Me.subReport2.WidthMe.subReport3.Top = Me.subReport1.Top'<--------Step (4)---------->

 
'<--------Step (5)---------->

        
'Set all sections & PrintWidth

        
Me.PageHeader.Height = Me.TextBox2.HeightMe.Detail.Height = 0'<--------Step (5)---------->

 
'<--------Step (6)---------->

        
'Set PrintWidth

        
Dim realWidth As Single = Me.subReport3.Left + Me.subReport3.WidthDim defaultWidth As SingleIf PageSettings.Orientation = PageOrientation.Portrait Then

            defaultWidth 

= PageSettings.PaperWidth - PageSettings.Margins.Left - PageSettings.Margins.RightElse

            defaultWidth 

= PageSettings.PaperHeight - PageSettings.Margins.Left - PageSettings.Margins.RightEnd IfIf realWidth > defaultWidth ThenMe.PrintWidth = realWidthElseMe.PrintWidth = defaultWidthEnd If'<--------Step (6)---------->

End Sub

Detail_Format里的生成子模版的代码:

   Private Sub GroupHeader1_Format(ByVal sender As ObjectByVal e As System.EventArgs) Handles GroupHeader1.Format'subReport1

        
Dim sub1 As New sub1Me.subReport1.Report = sub1'為子報表設置数据源

        
Dim dvStudent As DataView = New DataView(CType(Me.DataSource, DataSet).Tables(0), "ClassID='" & Me.Fields("ClassID").Value.ToString & "'""", DataViewRowState.CurrentRows)Me.subReport1.Report.DataSource = dvStudent'subReport2

        
Dim sub2 As New sub2Me.subReport2.Report = sub2'為子報表設置数据源

        
Dim dvScore As DataView = New DataView(CType(Me.DataSource, DataSet).Tables(1), "ClassID='" & Me.Fields("ClassID").Value.ToString & "'""", DataViewRowState.CurrentRows)With CType(Me.subReport2.Report, sub2)

            .DataSource 

= dvScore'Set subReport's ColumnCount

            .RealColumnCount 
= CInt(dvScore.Count / dvStudent.Count)End With'subReport3

        
Dim sub3 As New sub3Me.subReport3.Report = sub3Me.subReport3.Report.DataSource = dvStudentEnd Sub

2),Sub1


       txtIDDataField=”No”

       txtNameDataField=”Name”

3),Sub2


       GroupHeader1DataField=” SubjectID”

                              NewPage=”Before”

       lblSubjectDataField=”SubjectName”

       txtScoreDatafield=”Score”

       txtOrderDatafield=”gradeOrder”

4),Sub3


11,最终效果,比较粗糙,大家自己改进吧。