Tony Gong的技术Blog  
技术旅途中蹒跚的行者

完整的一张成绩一览帐票

 


环境:

vs2005+ActiveReportsNet2

本节代码下载:http://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.Click

        
If Me.listClass.SelectedIndex = -1 OrElse Me.listSubject.SelectedIndex = -1 Then

            
Return

        
End 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 & ","

        
Next

        
For 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 DataSet

        
Try

 

            
' 創建DA

            
Dim objDA As New DA.daScore()

 

            
Dim ds As DataSet = objDA.GetData(classID, subjectID)

 

            
' 返回値

            
Return ds

 

        
Catch ex As Exception

 

            
' 抛出異常

            
Throw ex

 

        
End Try

    
End 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 frmShowAR

    
Sub New(ByVal ds As DataSet)

 

        
Me.finalDS = ds

 

        
' 此调用是 Windows 窗体设计器所必需的。

        InitializeComponent()

 

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

    
End Sub

 

    
Private finalDS As DataSet

 

    
Private Sub frmShowAR_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load

        
Dim 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.Document

    
End Sub

End 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.5

        
Me.lblYear.Top = 0.5

        
Me.txtClassNo.Left = Me.lblYear.Left

        
Me.txtClassNo.Top = Me.lblYear.Top + Me.lblYear.Height

        
Me.Label3.Left = Me.txtClassNo.Left + Me.txtClassNo.Width * 2

        
Me.Label3.Top = Me.txtClassNo.Top

        
Me.txtTeacher.Left = Me.Label3.Left + Me.Label3.Width

        
Me.txtTeacher.Top = Me.Label3.Top

 

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

 

 

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

        
Dim sub1 As New sub1

        
Me.subReport1.Width = sub1.ReportWidth

 

        
Dim sub2 As New sub2

        
With CType(Me.DataSource, DataSet)

            
Me.subReport2.Width = sub2.ReportWidth * CInt(.Tables(1).Rows.Count / .Tables(0).Rows.Count)

        
End With

 

        
Dim sub3 As New sub3

        
Me.subReport3.Width = sub3.reportWidth

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

 

 

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

        
Me.subReport1.Left = Me.txtClassNo.Left

        
Me.subReport1.Top = Me.txtClassNo.Top + Me.txtClassNo.Height

 

        
Me.subReport2.Left = Me.subReport1.Left + Me.subReport1.Width

        
Me.subReport2.Top = Me.subReport1.Top

 

        
Me.subReport3.Left = Me.subReport2.Left + Me.subReport2.Width

        
Me.subReport3.Top = Me.subReport1.Top

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

 

 

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

        
'Set all sections & PrintWidth

        
Me.PageHeader.Height = Me.TextBox2.Height

        
Me.Detail.Height = 0

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

 

 

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

        
'Set PrintWidth

        
Dim realWidth As Single = Me.subReport3.Left + Me.subReport3.Width

 

        
Dim defaultWidth As Single

        
If PageSettings.Orientation = PageOrientation.Portrait Then

            defaultWidth 
= PageSettings.PaperWidth - PageSettings.Margins.Left - PageSettings.Margins.Right

        
Else

            defaultWidth 
= PageSettings.PaperHeight - PageSettings.Margins.Left - PageSettings.Margins.Right

        
End If

 

        
If realWidth > defaultWidth Then

            
Me.PrintWidth = realWidth

        
Else

 

            
Me.PrintWidth = defaultWidth

        
End 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 sub1

        
Me.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 sub2

        
Me.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 sub3

        
Me.subReport3.Report = sub3

        
Me.subReport3.Report.DataSource = dvStudent

End Sub

 

 

2),Sub1


       txtIDDataField=”No”

       txtNameDataField=”Name”

 

3),Sub2


       GroupHeader1DataField=” SubjectID”

                              NewPage=”Before”

       lblSubjectDataField=”SubjectName”

       txtScoreDatafield=”Score”

       txtOrderDatafield=”gradeOrder”

 

4),Sub3


 

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


posted on 2007-03-02 09:10 Tony.Gong 阅读(...) 评论(...) 编辑 收藏
 
Copyright © Tony.Gong Powered by: 博客园 模板提供:沪江博客