VB利用DataReport做报表
首先介绍一下DataReport对象的几个常用属性。一是DataSource,用于设置一个数据源,通过该数
据源,数据使用者被绑定到一个数据库;二是DataMember,从DataSource提供的几个数据成员中设
置一个特定的数据成员;三是LeftMargin、RightMargin、TopMargin、BottomMargin等,用于指定
报表的左右上下的页边距;四是Sections,即DataReport的报表标头、页标头、细节、页脚注、报
表脚注5个区域,如果加上分组(可以有多层分组),则增加一对区域,即分组标头、分组脚注。其
中DataSource一般是一个数据环境或是ADODB.Connection类型的变量,而DataMember则对应数据环
境中的Command或是ADODB.RecordSet类型的变量,推荐使用数据环境及Command,页边界大家肯定
都很清楚,下面我主要介绍以下Sections,这也是DataReport的精髓所在。
Sections是一个集合,您可以为每一个Section指定名称,也可以用其缺省的索引,从上到下
依次为1、2…。每个Section均有Height和Visible属性,您可以在一定条件下使一个Section不可
见。在Section中可以放置各种报表控件,其中RptLabel、RptImage、RptShape和RptLine可以放在
任意的Section中,用于输出各种文字、图形及表格线;RptTextBox只能放在细节中,一般用于绑
定输出DataMemeber提供的数据字段;RptFunction只能被放置在分组注脚中,用于输出使用各种内
置函数计算出的合计、最大值、最小值、平均值、记数等等。上述报表控件中常用公共属性有用于
控制位置及高度宽度的Top、Left、Height、Width和控制可见性的Visible;其中RptTextBox还有
DataField、DataMember、DataFormat及Font属性;其他属性不再多说。
然后介绍一下我的使用经验。一是对想控制的报表控件按类型有规律的命名;二是用RptShape
的矩形框做表格线框,比用RptLine画框省事多了,只有斜线才使用RptLine;三是报表标题及报表
中的表头文字、日期及页码用RptLabel,其中Caption属性支持转义字符,%D为长格式日期,%d为
短格式日期,%P为总页数,%p为当前页码;四是对固定报表在设计窗口直接将报表控件摆放到位,
对于活报表,应首先考虑报表最大的情形,将足够的控件分别放置在不同区域,位置大小可以不必
深究,然后在报表输出前用VBA代码对所有控件的属性进行调整,包括位置、高度、宽度、字体、
对齐方式、显示格式、可见性等等,相应的对Section也应根据情况调整其高度和可见性。
最后用一个实例模板来说明其使用方法。
连接数据库
With 数据环境.rsCommand名
If .State = adStateOpen Then .Close
.Source = sql语句
.Open 打开想输出的数据库数据项以便输出
End With
With 报表名
.DataSource=数据环境
.DataMember=Command名 这两行也可固定设好而不必每次设置
设置页表头部分(RpttLabel…为报表控件名)
.Sections(2).Controls("RptLabelPage").Caption = "共%P页第%p页"
.Sections(2).Controls("RptLabelDate").Caption = "打印日期:%D"
.Sections(3).Controls("RptLabel1").Left=…
…
设置细节部分(RptShapeX、RptTextBoxX为报表控件名)
.Sections(3).Controls("RptShape1").Left=…
.Sections(3).Controls("RptShape1").Top=…
.Sections(3).Controls("RptShape1").Height=…
.Sections(3).Controls("RptShape1").Width=…
.Sections(3).Controls("RptTextBox1").DataMember=Command名
.Sections(3).Controls("RptTextBox1").DataField=字段1
.Sections(3).Controls("RptTextBox1").Font.Name=…
…
.Sections(3).Controls("RptShapeN").Visible=False
.Sections(3).Controls("RptTextBoxN").Visible=False
…
. Sections(3).Height=计算出的或固定的细节高度
动态调整报表标题(RptLabelTitle为报表标签控件名)
.Sections(2). Controls("RptLabelTitle").Left=…
…
.Sections(2). Controls("RptLabelTitle").Alignment=…
…
调整完毕后
.Show 或 .PrintReport
End With
这样做的优点是报表设计时简单,调整方便、随意,只需更改一点代码,而不必为了一点点的
修改而费神的在设计窗口调整半天。
以上代码要写在 DataReport 窗体里的Load事件。
rsCommand名 是DataReport数据环境里设置的命令名。就是Command。
2.
我们在数据库的编程中经常会用到报表的打印,
其中datareport就是一个一个打印报表的控件,
如果想要比较好的打印效果那么就要用到水晶报表了。
那么首先datareport是怎么打印出报表来的呢?
(一)首先在引用中选择mocrosoft data report designet v6.0
然后在设计器里添加控件。
(二)在窗体里调用设计器进行打印。
例子代码如下:
dim ff as instorereport
Set ff.DataSource = rs
If Cmbstore.Text <> "" Or Cmbstore.Text <> Null Then
ff.Sections("section2").Controls.Item("lostore").Caption = Cmbstore.Text
Else
ff.Sections("section2").Controls.Item("lostore").Caption = ""
End If
If Cmbistore.Text <> "" Or Cmbistore.Text <> Null Then
ff.Sections("section2").Controls.Item("listore").Caption = Cmbistore.Text
Else
ff.Sections("section2").Controls.Item("listore").Caption = ""
End If
If Tdjh.Text <> "" Or Tdjh.Text <> Null Then
ff.Sections("section2").Controls.Item("ldjh").Caption = Tdjh.Text
Else
ff.Sections("section2").Controls.Item("ldjh").Caption = ""
End If
temp.Open "select * from CompanyInfo ",cn,3,2
If temp.EOF = False Then
ff.Sections("section2").Controls.Item("LCompany").Caption = Trim(temp.Fields
(0)) '公司名称
End If
ff.Sections("section2").Controls.Item("LTitle").Caption = "单据"
ff.Caption = "打印"
temp.Close
首先介绍下DataReport对象几个常用属性是DataSource用于设置个数据源通过该数据源数据使用者被绑定到个数据库; 2是DataMember从DataSource提供几个数据成员中设置个特定数据成员;3是LeftMargin、RightMargin、TopMargin、BottomMargin等用于指定报表左右上下页边距; 4是Sections即DataaReport报表标头、页标头、细节、页脚注、报表脚注5个区域如果加上分组(可以有多层分组)则增加对区域即分组标头、分组脚注其中DataSource般是个数据环境或是ADODB.Connection类型变量而DataMember则对应数据环境中Command或是ADODB.RecordSet类型变量推荐使用数据环境及Command页边界大家肯定都很清楚下面我主要介绍以下Sections这也是DataReport精髓所在 最后用个例子模板来介绍说明其使用思路方法 |
vb6.0 中,用"datareport" 报表控件制作报表,纸张定义 A4 A3 <上一篇 | 下一篇>'在vb6.0中,当使用报表预览功能时,"datareport"
'报表控件将使用"windows系统的当前默认打印机"的打印设置,若该打印设置纸张尺寸(如A4纸)小于"datareport"
'报表控件所需纸张尺寸(如A3纸),则"datareport" 报表预览时将会出现"打印纸张尺寸小于报表宽度"错误,
'请教如何用代码设置"windows系统的当前默认打印机"的打印机纸张尺寸,而不需用"公共对话框"的打印设置方法?
Option Explicit
Public Enum PrinterOrientationConstants
OrientPortrait = 2
OrientLandscape = 1
End Enum
'Printer.PaperSize = vbPRPSA3
Private Type DEVMODE
dmDeviceName As String * 32
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * 32
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type
Private Type PRINTER_DEFAULTS
pDataType As String
pDevMode As Long
DesiredAccess As Long
End Type
Private Type PRINTER_INFO_2
pServerName As Long
pPrinterName As Long
pShareName As Long
pPortName As Long
pDriverName As Long
pComment As Long
pLocation As Long
pDevMode As Long
pSepFile As Long
pPrintProcessor As Long
pDataType As Long
pParameters As Long
pSecurityDescriptor As Long
Attributes As Long
Priority As Long
DefaultPriority As Long
StartTime As Long
UntilTime As Long
Status As Long
cJobs As Long
AveragePPM As Long
End Type
Private Const DC_PAPERNAMES = 16
Private Const DC_PAPERS = 2
Private Const DC_PAPERSIZE = 3
Private Const DM_IN_BUFFER = 8
Private Const DM_OUT_BUFFER = 2
Private Const DM_ORIENTATION = &H1
Private Const DM_PAPERSIZE = &H2&
Private Const DMPAPER_A3 = 8 ' A3 297 x 420 mm
Private Const DMPAPER_A4 = 9 ' A4 210 x 297 mm
Private Const PRINTER_ACCESS_ADMINISTER = &H4
Private Const PRINTER_ACCESS_USE = &H8
Private Const STANDARD_RIGHTS_required = &HF0000
Private Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_required Or _
PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(hpvDest As Any,hpvSource As Any,ByVal cbCopy As Long)
Private Declare Function OpenPrinter Lib "winspool.drv" Alias _
"OpenPrinterA" (ByVal pPrinterName As String,PHPrinter As _
Long,pDefault As Any) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" _
(ByVal hPrinter As Long) As Long
Private Declare Function DocumentProperties Lib "winspool.drv" _
Alias "DocumentPropertiesA" (ByVal hWnd As Long,ByVal hPrinter As Long,_
ByVal pDeviceName As String,pDevModeOutput As Any,pDevModeInput As Any,_
ByVal fMode As Long) As Long
Private Declare Function GetPrinter Lib "winspool.drv" _
Alias "GetPrinterA" (ByVal hPrinter As Long,ByVal Level As Long,_
pPrinter As Any,ByVal cbBuf As Long,pcbNeeded As Long) As Long
Private Declare Function SetPrinter Lib "winspool.drv" _
Alias "SetPrinterA" (ByVal hPrinter As Long,ByVal Command As Long) As Long
Private Declare Function DeviceCapabilities Lib "winspool.drv" _
Alias "DeviceCapabilitiesA" (ByVal lpDeviceName As String,ByVal lpPort As String,_
ByVal iIndex As Long,ByVal lpOutput As String,lpDevMode As DEVMODE) As Long
Function SetDefaultPrinterOrientation(ByVal eOrientation As _
PrinterOrientationConstants,ByVal strPaperSize As String) As Boolean
Dim bDevMode() As Byte
Dim bPrinterInfo2() As Byte
Dim hPrinter As Long
Dim lResult As Long
Dim nSize As Long
Dim sPrnName As String
Dim dm As DEVMODE
Dim pd As PRINTER_DEFAULTS
Dim pi2 As PRINTER_INFO_2
' Get device name of default printer
sPrnName = Printer.DeviceName
' PRINTER_ALL_ACCESS required under
' NT,because we're going to call
' SetPrinter
pd.DesiredAccess = PRINTER_ALL_ACCESS
' Get a handle to the printer.
If OpenPrinter(sPrnName,hPrinter,pd) Then
' Get number of bytes requires for
' PRINTER_INFO_2 structure
Call GetPrinter(hPrinter,2&,0&,nSize)
' Create a buffer of the required size
ReDim bPrinterInfo2(1 To nSize) As Byte
' Fill buffer with structure
lResult = GetPrinter(hPrinter,2,bPrinterInfo2(1),_
nSize,nSize)
' Copy fixed portion of structure
' into VB Type variable
Call CopyMemory(pi2,Len(pi2))
' Get number of bytes requires for
' DEVMODE structure
nSize = DocumentProperties(0&,sPrnName,_
0&,0)
' Create a buffer of the required size
ReDim bDevMode(1 To nSize)
' If PRINTER_INFO_2 points to a DEVMODE
' structure,copy it into our buffer
If pi2.pDevMode Then
Call CopyMemory(bDevMode(1),ByVal pi2.pDevMode,Len(dm))
Else
' Otherwise,call DocumentProperties
' to get a DEVMODE structure
Call DocumentProperties(0&,_
bDevMode(1),DM_OUT_BUFFER)
End If
' Copy fixed portion of structure
' into VB Type variable
Call CopyMemory(dm,bDevMode(1),Len(dm))
With dm
' Set new orientation
Select Case strPaperSize
Case "A3"
.dmPaperSize = DMPAPER_A3
Case "A4"
.dmPaperSize = DMPAPER_A4
End Select
.dmOrientation = eOrientation
.dmFields = DM_ORIENTATION + DM_PAPERSIZE
End With
' Copy our Type back into buffer
Call CopyMemory(bDevMode(1),dm,Len(dm))
' Set new orientation
Call DocumentProperties(0&,DM_IN_BUFFER Or _
DM_OUT_BUFFER)
' Point PRINTER_INFO_2 at our
' modified DEVMODE
pi2.pDevMode = VarPtr(bDevMode(1))
' Set new orientation system-wide
lResult = SetPrinter(hPrinter,pi2,0&)
' Clean up and exit
Call ClosePrinter(hPrinter)
SetDefaultPrinterOrientation = True
Else
SetDefaultPrinterOrientation = False
End If
End Function
''''----------------------------------
''''---njx:窗体调用的代码:打印纸选用:1:纵向 2.横向
'''SetDefaultPrinterOrientation 2,"A3"
''''-----------------------------------
1.报表的概念
利用报表可以把数据表中的数据按一定的格式输出到屏幕上或打印到纸上。
2.制作报表的方法
在VB6.0中可以利用报表设计器来制作报表,从“工程”中选择“添加data report”,将报表设计器加入到当前工程中,报表由5部分组成:
报表标头——每份报表只有一个,可以用标签建立报表名。
页标头——每页有一个,即每页的表头,如字段名。
细节——需要输出的具体数据,一行一条记录。
页脚注——每页有一个,如页码。
报表脚注——每份报表只有一个,可以用标签建立对本报表的注释、说明。
使用报表设计器处理的数据需要利用数据环境设计器创建与数据库的连接, 从“工程”菜单中选择 “添加Data Enviroment”,在连接中选择指定的数据库文件,完成与数据库的连接,然后产生Command对象连接数据库内的表。
制作报表的步骤:
(1) 新建工程,在窗体上放置两个命令按钮;
(2) 从“工程”菜单中“添加Data Enviroment”,右击Connection1,在属性中选择“MicrosoftJet 4 OLE DB Provider”,在“连接”中指定数据库;
(3) 再次右击Connection1,选则“添加命令”,创建Command1对象,右击Command1,在属性中设置该对象连接的数据源为需要打印的数据表;
(4) 在从“工程”菜单中“添加Data Report”,在属性窗口中设置DataSource为数据环境DataEnviroment1对象,DataMember为Command1对象,即指定数据报表设计器DataReport1的数据来源;
(5) 将数据环境设计器中Command1对象内的字段拖到数据报表设计器的细节区;
(6) 利用标签控件在报表标头区插入报表名,在页标头区设置报表每一页顶部的标题;
(7) 利用线条控件在报表内加入直线,利用图形控件和形状控件加入图案或图形;
(8) 利用DataReport1对象的Show方法显示报表,在窗体Click事件加代码:DataReport1.Show;
(9) 利用预览窗口按打印按钮可以打印报表;
(10)利用预览窗口工具栏上的导出按钮可以将报表内容输出成文本文件或Html文件;也可以利用DataReport1对象的ExportReport方法将报表内容输出成文本文件或Html文件。
制作报表的简单方法是从“外接程序”中选择报表向导来设计报表。
水晶报表(Crystal Report)是业内最专业、功能最强的报表系统,它除了强大的报表功能外,最大的优势是实现了与绝大多数流行开发工具的集成和接口。在VS.Net平台做过报表开发的程序员,一定都对水晶报表强大、高效、集成等特性留下了深刻印象。除了开发新程序外,在工作中我们常需要接触到很多较早的软件系统报表功能升级的需求,如果能结合水晶报表这一强大的工具,往往能事半功倍。
VB是以前流行的数据库开发平台,用其开发的C/S系统在社会上有非常大的保有量,但VB超弱的报表功能往往让程序员面对客户的升级要求一筹莫展。本文并不做水晶报表的使用和编程教学,实际上水晶报表本身的使用方法和VS.Net平台并没有太大的差别,我主要是和大家探讨一下VB和水晶报表的一种较方便的接口方式。我的开发测试平台是Windows2003 Standard简体中文版、VB6.0+sp5英文版、Crystal 9.0简体中文开发版。
关于在水晶报表中制作报表模板的方法,并非本文的探讨范围,读者可以参考Crystal Report的帮助文件和官方网站的技术资料。简单得说,首先要通过水晶报表的数据库引擎手动连接相应的表结构,制作报表模板,并保存为rpt文件,该项操作和利用VB自带的报表工具制作报表大同小异。
简单地说,用VB调用水晶报表进行报表开发的简单接口方法就是,在水晶报表中用"仅字段定义"来获得字段分布文件,用虚拟的文件创建表字段,用CRAXDRT对象来强制改变数据源(ADO.recordset),其效果相当于在VB中调用了rpt文件。下面分步骤介绍编程方法。
第一步:
在VB工程中Project菜单加入"Add Crystal Report 9",报表名使用默认即可。这时Form2(Crystal Rerport自动添加的Form,假设名为Form2)被自动分配了如下代码:
Option Explicit
dim Report as New Cystal1
Private Sub Form_Load()
Screen.MousePointer = vbHourglass
'调用水晶报表时置鼠标为沙漏状 CRViewer91.ReportSource = Report '该语句的赋值将在后面被修改
CRViewer91.ViewReport
Screen.MousePointer = vbDefault '调用水晶报表完成后置鼠标为默认形状
End Sub
Private Sub Form_Resize()
CRViewer91.Top = 0
CRViewer91.Left = 0
CRViewer91.Height = ScaleHeight
CRViewer91.Width = ScaleWidth
End Sub
第二步:
点击Crystal Report设计器的"数据库字段",选定"数据库专家…",然后点"创建新连接",再点"仅字段定义",创建"数据库定义"文件,字段名和宽度和原数据库表保持一致。最后,在数据库字段中获得了相应字段,将其置于报表上,按水晶报表的要求配置。
第三步:
该步骤非常关键,添加一个Modual到工程文件中,定义全局的ADODB变量,实现数据库和水晶报表的动态连接。代码如下:
Public conn As New ADODB.Connection
Public rs As New ADODB.Recordset
第四步:
关于VB程序的ADO数据库连接注意事项,请看下面的打印按钮例程。
Private Sub Command1_Click()
Dim connstr As String
If conn.State = adStateOpen Then conn.Close
connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "/prtest.mdb;Persist Security Info=False" 'prtest.mdb是程序当前目录的测试Access数据库
conn.ConnectionString = connstr
conn.Open
conn.CursorLocation = adUseClient
If rs.State = adStateOpen Then rs.Close
rs.Open "test",conn,adOpenKeyset,adLockReadOnly
' Report.Database.SetDataSource rs,1
Form2.Show 1 '数据库连接完成后,调用Form2水晶报表工程
End Sub
需要提请大家注意的是,上面代码中的Report.Database.SetDataSource rs,1是初用水晶报表的程序员容易犯的错误,使用该语句后将造成数据库和水晶报表的连接失败。如何动态调用水晶报表呢?请看第四步。
第五步:
创建水晶报表和数据库数据源的连接,需要修改上面Form2的代码。
Option Explicit
'dim Report as New Cystal1
'上面一行取消
Private Sub Form_Load()
Dim oApp As New CRAXDRT.Application
Dim oRpt As CRAXDRT.Report
Dim reportName As String
'上面三行是新增加的
Screen.MousePointer = vbHourglass
reportName = "/rpt/Pr1.rpt" '定义要引用的rpt文件
Set oRpt = oApp.OpenReport(App.Path & reportName,1)
oRpt.Database.SetDataSource rs '连接水晶报表和数据源
oRpt.ReadRecords
CRViewer91.ReportSource = oRpt '启用水晶报表的预览功能
CRViewer91.ViewReport
Screen.MousePointer = vbDefault
End Sub
Private Sub Form_Resize()
CRViewer91.Top = 0
CRViewer91.Left = 0
CRViewer91.Height = ScaleHeight
CRViewer91.Width = ScaleWidth
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Set Report = Nothing
Set rs = Nothing
Set conn = Nothing
Unload Form2
End Sub
上面介绍了在VB中使用水晶报表进行报表开发的一种方法,该方法简单易用,适合初学者上手。大家熟悉以后,还可以继续学习Crystal Report提供的API函数(Lib库 Crpe32.dll)进行水晶报表开发,可以获得更大的灵活性。
本文来自-编程入门网:http://www.bianceng.cn/Programming/vb/200711/5208_2.htm
本文来自-编程入门网:http://www.bianceng.cn/Programming/vb/200711/5208.htm
都用同一变量:
第一步:
在VB工程中Project菜单加入"Add Crystal Report 9",报表名使用默认即可。这时Form2(Crystal Rerport自动添加的Form,假设名为Form2)被自动分配了如下代码:
Option Explicit
dim Report as New Cystal1
Private Sub Form_Load()
Screen.MousePointer = vbHourglass
'调用水晶报表时置鼠标为沙漏状 CRViewer91.ReportSource = Report '该语句的赋值将在后面被修改
CRViewer91.ViewReport
Screen.MousePointer = vbDefault '调用水晶报表完成后置鼠标为默认形状
End Sub
Private Sub Form_Resize()
CRViewer91.Top = 0
CRViewer91.Left = 0
CRViewer91.Height = ScaleHeight
CRViewer91.Width = ScaleWidth
End Sub
第二步:
点击Crystal Report设计器的"数据库字段",选定"数据库专家…",然后点"创建新连接",再点"仅字段定义",创建"数据库定义"文件,字段名和宽度和原数据库表保持一致。最后,在数据库字段中获得了相应字段,将其置于报表上,按水晶报表的要求配置。
第三步:
该步骤非常关键,添加一个Modual到工程文件中,定义全局的ADODB变量,实现数据库和水晶报表的动态连接。代码如下:
Public conn As New ADODB.Connection
Public rs As New ADODB.Recordset
第四步:
关于VB程序的ADO数据库连接注意事项,请看下面的打印按钮例程。
Private Sub Command1_Click()
Dim connstr As String
If conn.State = adStateOpen Then conn.Close
connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "prtest.mdb;Persist Security Info=False" 'prtest.mdb是程序当前目录的测试Access数据库
conn.ConnectionString = connstr
conn.Open
conn.CursorLocation = adUseClient
If rs.State = adStateOpen Then rs.Close
rs.Open "test",adLockReadOnly
' Report.Database.SetDataSource rs,1
Form2.Show 1 '数据库连接完成后,调用Form2水晶报表工程
End Sub
需要提请大家注意的是,上面代码中的Report.Database.SetDataSource rs,1是初用水晶报表的程序员容易犯的错误,使用该语句后将造成数据库和水晶报表的连接失败。如何动态调用水晶报表呢?请看第四步。
第五步:
创建报表和数据库数据源的连接,需要修改上面Form2的代码。
Option Explicit
'dim Report as New Cystal1
'上面一行取消
Private Sub Form_Load()
Dim oApp As New CRAXDRT.Application
Dim oRpt As CRAXDRT.Report
Dim reportName As String
'上面三行是新增加的
Screen.MousePointer = vbHourglass
reportName = "rptPr1.rpt" '定义要引用的rpt文件
Set oRpt = oApp.OpenReport(App.Path & reportName,1)
oRpt.Database.SetDataSource rs '连接报表和数据源
oRpt.ReadRecords
CRViewer91.ReportSource = oRpt '启用报表的预览功能
CRViewer91.ViewReport
Screen.MousePointer = vbDefault
End Sub
Private Sub Form_Resize()
CRViewer91.Top = 0
CRViewer91.Left = 0
CRViewer91.Height = ScaleHeight
CRViewer91.Width = ScaleWidth
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Set Report = Nothing
Set rs = Nothing
Set conn = Nothing
Unload Form2
End Sub
要在数据环境设计器中创建一个简单的层次结构游标,请按照下列步骤执行:
创建一个新的“标准 EXE”工程。
在“工程”菜单上,单击“添加 Data Enviroment”向工程中添加一个设计器。如果设计器没有在“工程”菜单上列出,则单击“部件”。单击“设计器”选项卡。并单击“数据环境”把设计器添加到菜单上。
注意 最初为项目加载的四种ActiveX设计器在“工程”菜单上列出。如果加载了超过四个设计器,后面的设计器可以从“工程”菜单的“更多 ActiveX 设计器”子菜单中获得。
在“数据链接属性”对话框上单击“Microsoft Jet 3.51 OLE DB Provider”,这是为访问 Jet 数据库选择正确的 OLE DB 供应商。
单击“下一步”按钮进入“连接”选项卡。
单击第一个文本框旁边的省略按钮(…)。
用“选择 Access 数据库”对话框浏览到 nwind.mdb 文件,它被安装在 Program Files/Microsoft Visual Studio/Vb98 目录下。
单击“确定”关闭对话框。
右键单击“Connection1”图标,单击“重命名”,把图标名改为“Northwind”。
右键单击“Northwind”图标,然后单击“添加命令”显示“Command1”对话框。在对话框中,如下所示设置属性: 属性 设置值
Command Name Customers
Connection Northwind
DataBase Object Table
Object Name Customers
单击“确定”结束对话框。
右键单击“Customers”命令,并单击“添加子命令”显示“Command2”对话框。在对话框中,如下所示设置属性: 属性 设置值
Command Name Orders
Connection Northwind
DataBase Object Table
Object Name Orders
单击“关联”选项卡。应该选中“与父命令对象相关联”复选框。“父”框应该包含“Customers”;“父字段”和“子字段/参数”框都应该包含“CustomerID”。
在设计关系数据库时,对于链接字段,习惯上相关的表要使用相同的名字。在这种情况下,链接字段都被命名为 CustomerID。数据环境设计器自动地在对话框中匹配这样的对。
单击“添加”。单击“确定”关闭对话框。
单击“添加”按钮向 Command 对象添加关系。在关闭了对话框之后,数据环境设计器通过把两个命令显示为一个层次结构来反映关系。该层次结构将被用于创建数据报表。
根据下面的设置值设置工程和设计器的属性,然后保存工程: 对象 属性 设置值
Project Name PrjNwind
DataEnvironment Name DeNwind
Form Name FrmShowReport
创建数据报表
一旦创建了数据环境设计器,就可以创建一个数据报表。因为并不是数据环境中所有的字段在一个数据报表中都有用,这一系列的主题创建一个受限制的报表,只显示几个字段。
要创建一个新的数据报表,请按照下列步骤执行:
在“工程”菜单上,单击“添加 Data Report”,Visual Basic 将把它添加到您的工程中。如果设计器不在“工程”菜单上,单击“部件”。单击“设计器”选项卡,并单击“Data Report”把设计器添加到菜单上。
注意 为工程加载的前四种 ActiveX 设计器在“工程”菜单上列出。如果加载了多于四个设计器,后面的设计器可以从“工程”菜单的“更多 ActiveX 设计器”子菜单中获得。
根据下面的表设置 DataReport 对象的属性: 属性 设置值
Name rptNwind
Caption Northwind Data Report
在“属性”窗口上,单击“数据源”,然后单击“deNwind”。然后单击“DataMember”并单击“Customers”。
重点 要把 DataSource 属性设置为 deNwind,数据环境设计器必须为打开的。如果数据环境设计器是关闭的,按下 CTRL+R 键显示“工程”窗口,然后双击数据环境图标。
右键单击数据报表设计器,并单击“检索结构”。
您已经向设计器添加了一个新的分组。每一个分组都同数据环境中的 Command 对象有“一对一”对应关系;在这种情况下,新的分组与客户的 Command 对象相对应。同时也要注意分组标头有一个与之匹配的分组注脚部分。
注意 如果某个 Command 对象有多于一个的子对象 — 相互“平行”的子 Command 对象,则 Data Environment 使您可以创建该 Command 对象的层次结构。Data Report 设计器,却没有那么灵活,在同一时间不能显示多于一个的子对象。此时,当执行一个 Retrieve Structure Command命令时,Data Report 将只显示第一个子 command,其他的都不显示。所以,您应该避免创建带有“平行”子 command的 Command 层次结构。
从数据环境设计器,把“CompanyName”字段(在“Customers”命令下)拖到分组标头(Customers_Header)部分。
分组标头部分可以包含 Customers 命令的任何字段,然而,出于演示目的,此时只显示 Customer 名。
删除名为“Label1”的 Label 控件(rptLabel)。
如果不希望 Label 控件包括在 TextBox 控件中,可以在数据环境设计器的“选项...”对话框的“字段映射”选项卡上撤消对“Drag and Drop Fields Caption”选项的选择。
从数据环境设计器中,把“OrderDate”字段(在Orders命令下)拖到细节(Orders_Detail)部分。删除Label控件。
细节部分表示最内层的“重复”部分,因而与数据环境层次结构(OrdersCommand对象)中最底层的 Command 对象相对应。
重新调整数据环境设计器部分的大小,使之与下面的插图类似:
重新调整细节部分的高度,使它尽可能的矮是很重要的,因为高度将会与为每一个 CompanyName 返回的 OrderDate 相乘。OrderDate 文本框下面或上面的任何多余位置将在最后的报表中导致不必要的空间。
保存工程。
使用 Show 方法预览数据报表
既然数据环境和 Data Report 对象已经创建,就几乎准备好运行工程了。还剩下一步:写代码以显示数据报表。
要在运行时显示数据报表,请按照下列步骤执行:
在“工程资源管理器”窗口上,双击“frmShowReport”图标,显示窗体设计器。
在“工具箱”上,单击“通用”选项卡。
当把一个数据报表设计器添加到工程时,数据报表设计器的控件被添加到名为“Data Report”的选项卡上。要使用标准的 Visual Basic 控件,必须切换到“通用”选项卡。
单击“CommandButton”图标并在窗体上绘制一个“CommandButton”。
根据下面的表设置 Command1 控件的属性: 属性 设置值
Name CmdShow
Caption Show Report
在按钮的 Click 事件中,粘贴下面的代码。
Private Sub cmdShow_Click()
rptNwind.Show
End Sub
保存并运行工程。
单击“显示报表”,在打印预览方式中显示报表。
可选的—将数据报表作为启动对象设置
在没有代码的情况下,也可以显示报表。
在“工程”菜单上,单击“prjNwind”属性。
在“启动对象”框中,选择“rptNwind”。
保存并运行工程。
注意 如果使用这种方法,可以从工程中把Form对象删除。
Top
2 楼liangsiyuan(叶)回复于 2002-01-15 19:03:54 得分 0
您可以在 Microsoft 数据报表中用到的控件。
注意 虽然在“Visual Basic toolBox”中有 Data Report 设计器控件,但此控件与其他类似的 Visual Basic 控件不一样,它们只能在 Microsoft Data Report 中使用。
在设计时,您可以在“属性”窗口中更改这些控件的属性。这些可更改的属性包括:
ForeColor 和 BackColor
Caption 和 text
Fonts
Size
Location 和 alignment
Border color 和 Border style
Data Report 设计器控件
Pointer
这是 Microsoft Data Report ToolBox 中唯一一个不会画出控件的项。一旦您选择了这个指针,您将只能改变一个已经画在报表上控件的大小或者移动它的位置。
rptLabel
使您能加入不能被更改的文本,例如一副图下面的标题等。Label 控件不能用于显示一个域的内容。
rptTextBox
绑定到数据库中的一个域上。设定 DataMember 属性以后,您可以通过设定 DataField 属性来设置域。该控件通常是多行模式。
rptImage
从您报表的位图、图标、或元文件显示一个图形图象。
rptLine
用于绘制多种样式的线条,以使您能够将报表的各个部分进行分割使其容易阅读。当输出到 HTML 文件时,用水平线作为 HTML <HR> 标记。
rptShape
使您能够在报表上绘制多种形状。您可以选择长方形、圆角长方形,正方形、圆角正方形、椭圆形或圆形。
rptFunction
您可以选择下列几个内置函数之一来计算并显示结果。这些内置的函数有 Sum、Average、Minimum、Maximum、 Row Count、Value Count、Standard Error 和Standard Deviation。
在编译了一个报表之后,您或许希望重新使用它,要么作为一个大文档的一部分,要么在 intranet 或 Internet 上发行。数据报表设计器的 ExportReport 方法使您能够完成这些任务。使用 ExportReport 方法,可以将任何报表作为文本文件或 HTML 文件导出。此外,也可以使用任意的 ExportFormat 对象剪裁已导出的文件的内容或外观。
重点 ExportReport 方法不支持图像或图形形状导出。
ExportFormat 对象
ExportReport 方法被设计为与 ExportFormat 集合一同使用。集合中的每个 ExportFormat 对象表示一个单独的报表格式。例如,一个 intranet 发行格式的报表可能包含工作组或雇员的名字作为报表标头的一部分;为 Internet 发行的报表,则那些名字将被清除或替换。因此要创建至少两个 ExportFormat 对象,每一个要适应于不同的发行机制。然而,也可能不创建任何 ExportFormat对象就导出一个报表,因为已经为您提供了四个。
四个缺省 ExportFormat 对象
缺省情况下,ExportFormat 集合包含四个成员。下表列出了四个成员以及与其相关联的文件过滤器:
对象 文件过滤器 描述
ExportFormats(1) *.htm,*.html HTML
ExportFormats(2) *.htm,*.html Unicode HTML
ExportFormats(3) *.txt Text
ExportFormats(4) *.txt Unicode Text
如果需要使用任何缺省类型,也可以使用Key属性指定缺省的类型。Key属性值和常数如下所示:
对象 关键字 常数
ExportFormats(1) key_def_HTML rptKeyHTML
ExportFormats(2) key_def_UnicodeHTML_UTF8 rptKeyUnicodeHTML_UTF8
ExportFormats(3) key_def_Text rptKeyText
ExportFormats(4) key_def_UnicodeText rptKeyUnicodeText
假定缺省的成员符合您需要,通过使用四个成员之一,可以不创建另一个ExportFormat对象就导出一个报表。例如,要导出一个按日的HTML报表,可以使用下面的代码:
DataReport1.ExportReport rptKeyHTML
显示一个对话框是可选的
编程人员可以决定在导出一个报表时是否显示一个对话框。例如,如果报表在每天早晨自动创建,并写入同一个文件以便在 intranet 上发行,就没有必要显示对话框。只要提供一个有效的文件路径和关键字,并将 Overwrite 参数设置为 True,则不显示对话框。
' 作为HTML导出一个报表,覆盖任何已经存在的文件。 导出
' 所有页面到Daily_Report.htm文件。
DataReport1.ExportReport rptKeyHTML,"C:/Temp/Daily_Report",True,_
rptRangeAllPages
注意 在上面的代码中,第二个参数看起来象个目录,但实际上是一个文件名。“Daily_Report.htm”是被写的文件名。ExportFormat 对象提供文件扩展名(.htm),因此没有必要把它写在文件名参数中。
ExportFormat 提供对话信息
ExportFormat 对象也包含用户调用 ExportReport 方法时显示的信息。特别的,FileFormatString 属性设置在“导出”对话框的“Save As Type”框中显示的文本。例如,设想一个公司有一个标准的 ExportFormat 对象要用于所有报表。下面的代码将确保 ExportFormat 可以在“导出”对话框的格式类型列表中得到:
Dim strTemplate As String
' 首先为ExportFormat对象创建一个模板。
strTemplate = "MyCompany Daily Report" & vbCrLf & rptTagBody
' 添加一个ExportFormat对象。FileFormatString决定
' 将在“导出”对话框中显示什么内容。
DataReport1.ExportFormats.Add _
Key:="StandardReport",_
FormatType:=rptFmtText,_
FileFormatString:="Standard Report (*.txt)",_
FileFilter:="*.txt",_
Template:=strTemplate
' 调用ExportReport方法指定要使用的
' 名为StandardReport的ExportFormat。
DataReport1.ExportReport "StandardReport",False,_
rptRangeFromTo,1,10
被调用时,“导出”对话框类似这样:
模板代码
ExportFormat 对象的核心是它的模板。一个模板只是一个字符串,其中包括您想要显示的文本以及表示数据报表多个部分的常数。常数、值和描述如下表所示:
常数 值 描述
rptTagTitle <!--MSDBRPT_Template_Title--> 表示报表的标题,可在Title属性中找到。
rptTagBody <!--MSDBRPT_Template_Body--> 表示报表体。
要创建一个只包括作者名,然后是报表体的简单数据报表,其模板类似这样:
Dim strT As String
strT = "Author: " & InputBox("Your name") & vbCrLf & rptTagBody
drpNwind.ExportFormats.Add "AuExp",rptFmtText,_
"Author Only Text File","*.txt",strT
打印一个数据报表可以使用下面两种方法之一。用户可以单击“打印预览”中数据报表上的“打印”按钮(使用 Show 方法),也可以通过使用 PrintReport 方法编程打印。如果打印过程中发生错误,将在 Error 事件中捕获。
详细信息 请参阅“Data Report事件。”
选择显示一个“打印”对话框
当编程打印一个报表时,有两种选择:通过显示“打印”对话框打印,或不显示对话框打印。
要显示“打印”对话框,请按照下列步骤执行:
将一个 CommandButton 添加到窗体。
在按钮的 Click 事件中,放置下面的代码:
DataReport1.PrintReport True
“打印”对话框允许用户选择一个打印机、打印到文件、选择要打印的页面范围并指定要打印的份数。
注意 要显示打印机选择,打印机必须安装在计算机上。
不显示对话框打印
在有些情况下,您可能希望不需用户干预打印报表。PrintReport 方法也提供这样的选择:选择要打印的页面范围,可以是全部,也可以是一个指定的范围。
要不显示对话框地打印,请按照下列步骤执行:
将一个 CommandButton 添加到窗体
在按钮的 Click 事件中,放置下面的代码:
DataReport1.PrintReport False
或者,要指定打印的页面范围,请使用下面的代码:
DataReport1.PrintReport False,rptRangeFromTo,2
象标准的 Visual Basic 窗体一样,数据报表设计器的存在是由某些关键事件标记的。那些事件以及它们发生的顺序,如下表所示:
事件 描述
Initialize 查询完成之后发生,并且控件位于窗体上。
Resize 第一次显示设计器或一个对象的窗口状态更改时发生。
Activate 当设计器变为活动窗口时发生。
ProcessingTimeout 大约每秒钟发生一次,直到所有处理都已经结束。使用该事件可以决定处理是否占用太长时间,并取消处理。
注意 在查询完成之前该事件将不发生。请参阅下面的内容。
[Deactivate] 当设计器不再是活动窗口时发生。使用该事件决定用户是否单击了另一个窗体或设计器。
QueryClose 在设计器终止之前发生。设置 Cancel 参数为 True 以取消终止。CloseMode 参数返回引起终止的动作类型。
Terminate 当所有对设计器的引用都被设置为0时发生。
超时和异步调用事件
除设计器的存活期事件之外,DataReport 对象也以允许捕获错误和监视同步或异步函数调用的事件为特色。
ExportReport和PrintReport:查询、同步和异步处理
当调用 ExportReport 或 PrintReport 方法时,处理被分为三个阶段——查询、同步处理和异步打印或导出:
查询——当第一次创建数据报表时,发送给数据提供方一个查询。
处理——查询检索到的数据由 Visual Basic 处理以创建报表。数据被高速缓存在计算机上的一个临时文件中。这一处理是同步的。
异步打印或导出——在创建报表后,报表就被导出或打印。这一处理是异步的。
当Show方法被调用时,数据报表执行查询,然后在显示报表之前在同步处理过程中处理数据。
因为这些方法结合了同步和异步处理,有各自的事件监视每种处理。
ProcessTimeOut 事件——对于同步函数
处理一个大的数据报表也许要花费一些时间。如果想要允许您的用户取消过程较长的操作(如 Show、ExportReport 或 PrintReport),可以使用 ProcessingTimeout 事件监视已经过去了多少秒,并按照用户的命令把 cancel 参数设置为True。下面的代码显示了一个示例:
Private Sub DataReport_ProcessingTimeout(ByVal Seconds As Long,_
Cancel As Boolean,ByVal JobType As MSDataReportLib.AsyncTypeConstants,_
ByVal Cookie As Long)
Select Case Seconds
Case 30
If MsgBox("This has taken " & Seconds & "seconds. Cancel?",_
vbRetryCancel) = vbCancel Then
Cancel = True
End If
Case 45
If MsgBox("This has taken " & Seconds & "seconds. Cancel?",_
vbRetryCancel) = vbCancel Then
Cancel = True
End If
Case 60
'60秒钟后自动取消。
Cancel = True
End Select
End Sub
注意 并不保证在上面指定的间隔会发生 ProcessingTimeout 事件。例如,在后台运行的其他的 Visual Basic 代码可能会阻止这一事件的发生。在那种情况下,将 Case 语句设置为一个范围内的值;当该事件发生时,将一个模块级标志设置为 True,并在随后发生的事件中检查它。
Error 事件——对于异步函数
要捕获在没有 Visual Basic 代码执行(也就是说,一个异步函数)时发生的错误,请使用 Error 事件。例如,如果 PrintReport 或 ExportReport 方法在异步阶段失败,Error 事件将发生。下面的示例捕获异步错误:
Private Sub DataReport_Error(ByVal JobType As _
MSDataReportLib.AsyncTypeConstants,ByVal Cookie As Long,_
ByVal ErrObj As MSDataReportLib.RptError,ShowError As Boolean)
Select Case JobType ' The JobType identifies the process.
Case rptAsyncPrint
' 此处捕获 PrintReport 错误。
Case rptAsyncReport
' 此处捕获 ExportReport 错误。
End Select
End Sub
也可以使用 Error 事件捕获特定的情况,例如计算机上缺少打印机,如下面的代码中所示:
Private Sub DataReport_Error(ByVal JobType As _
MSDataReportLib.AsyncTypeConstants,ShowError As Boolean)
Case rptErrPrinterInfo ' 8555
MsgBox "A printing error has occurred. " & _
"You may not have a Printer installed."
ShowError = False
Exit Sub
Case Else
' 此处处理其他情况。
ShowError = True
End Select
End Sub
AsyncProgress 事件
AsyncProgress 事件不是为捕获错误而设计的,但允许监视异步函数的状态。到这一事件发生时,所有的数据都已经被处理过;这样,事件的两个参数是 PagesCompleted 和 TotalPages。该事件还包括标识异步操作的参数:则 JobType 和 Cookie 参数可以被用于监视任何处理的过程。
创建一个数据报表的一种方法是:
创建一个包含 Command 对象层次结构的数据环境设计器。
设置数据报表设计器的 DataSource 属性为数据环境设计器。
设置 DataMember 属性为最顶层的 Command 对象。
右键单击数据报表设计器并单击“检索结构”。
在检索结构之后,将创建适当数目的分组标头和注脚,而且每一标头/注脚对被指定一个对应于一个 Command 对象的名字。
把 Command 对象从数据环境设计器拖到数据报表设计器上的对应部分。
Command 对象包含的所有数据字段,都作为 Command 对象被放下的部分中的 TextBox 控件,被自动创建在数据报表上。每一 TextBox 的 DataMember 属性和 DataField 属性都按照 Command 对象及其数据字段设置。
从每一个 TextBox 控件创建时所在的部分上将 TextBox 控件拖动到数据报表设计器的不同部分上。
按照需要将 Function 控件添加到报表。
当数据报表被绑定到一个数据环境时,报表上控件的放置规则就不再是立即显现。该主题解释了在数据环境中创建的层次结构是如何与在数据报表中构造的分组标头和注脚系统相关联的。
对应于分组标头/注脚或细节部分的Command对象
除两个例外情况,数据环境中的每一个 Command 对象或对应于一对分组标头和注脚部分,或对应于细节部分。例外的情况在该主题稍后部分讨论。
Hierarchy 与标头、注脚和细节
下面的插图显示包含四个 Command 对象(每一对象都至少与一个其它的对象有父/子关系)的数据环境设计器的一个图解视图。属于表的数据字段未显示。
另一方面,数据报表设计器被构造为一系列的部分。并且每一部分可以按照如下四种类型归类:报表标头/注脚、页标头/注脚、分组标头/注脚和细节部分。为便于指导,可以不管报表和页标头/注脚对。这就剩下了分组标头/注脚和细节部分。
细节部分,设计器的最内层部分,对应于最低层次的 Command 对象。当在层次结构中逐渐向上时,细节部分则由成对的部分括起来,每一对与一个单个的 Command 对象相关联。下面的插图使 Command 对象和部分相互关联:
对应于 Command 对象的部分
这样插图显示了数据环境的层次结构实际上对应于一系列括号的扩展,最内层的(细节)部分对应于层次结构中的最低层次,最外层部分对应于最高层次的 Command 对象。
控件可以被放置在较低层次的部分中
控件的放置由它从属的部分(或部分对)管理。简言之,控件可以放置在产生它的部分和比它自身更低层次的所有部分中。例如,如果一个控件属于 Command1 部分对,它也可以被放置在 Commands2、3 和 4 的部分对中。第二个示例是:在部分3中产生的控件也能放置在部分4中,但不能放置在部分1和2中。总而言之,在 Command 4(细节部分)部分中产生的控件不能被放置在除细节部分以外的任何其它位置。
放置 Function 控件
对于以上有关控件位置的指南,Function 控件有三点例外。Function 控件不象 TextBox 控件那样直接绑定到记录集上。相反,Function 控件在报表生成时计算自己的值。因此,Function 控件只能被放置在报表的注脚部分中。
Function 控件的第二个例外是:它只能被放置在比自身层次高一级的任何部分对中。例如,如果Command 3 对象包含一个 Quantity 字段,可以把一个合计 Quantity 值的 Function 控件放置到Command 2的注脚部分上,或放置到 Command 1 的注脚部分上。
关于 Function 控件的第三个例外是:不象其它的数据绑定控件(TextBox 控件),Function 控件可以被放置在报表注脚部分中。当这样做时,控件的计算范围将扩大到整个报表。例如,放置在报表注脚中用来计算 Quantity 字段合计值的 Function 控件,将计算报表上每一个 Quantity 控件的合计值。
例外:分组和总计合计
有两个例外,数据环境中的每一个 Command 对象对应于一对分组标头和注脚。当您使用数据环境设计器的分组特征时第一个例外发生。
分组字段
当创建分组字段时,数据环境设计器在一个单个的 Command 对象下创建两个文件夹。第一个包含分组字段,另一个包含细节字段。尽管没有为分组字段创建一个新的 Command 对象,必须在数据报表上创建一个新的分组标头/注脚对,并且对这一需要使其成为一个例外。
总计合计字段
当在数据环境中创建一个总计合计字段时发生第二个例外。如同当创建一个分组字段一样,将为 Command 对象创建一个新的文件夹。新文件夹包含任何创建的总计合计字段,并且必须将一个新的分组标头/注脚添加到数据报表。
详细信息 有关创建合计字段的详细信息,请参阅“使用 Data Environment 设计器”中的“创建合计”。
检查层次结构
如果对于数据环境 Command 对象的层次结构存有疑问,有两种方法确保数据报表有正确的分组标头/注脚结构:
检索结构——如果还没有在数据报表设计器上放置很多控件,并且可以重新组织报表,可以使用 Retrieve Structure Command 自动创建正确数目的分组标头和注脚。
ADO层次结构信息——在数据环境设计器中右键单击最顶层的 Command 对象,并单击“层次结构信息...”显示“层次结构信息”对话框。单击“查看 ADO 层次结构”选项卡查看 Command 对象的层次结构的图形表示。
diyee(锦衣夜行)写的不错,但我刚才试了试,还有点问题
环境:sql SERVER 2000+VB6.0
我的环境设计器结构如下:
DEConnection ---设计器名称
ReportConn
cmdTotalImportCommOrder
在打印事件中代码:
With DEConnection.rscmdTotalImportCommOrder
If .State = adStateOpen Then
.Close
End If
.ActiveConnection = adoConn
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockBatchOptimistic
.Source = "SELECT RQ,JE1 FROM DJHDD " & Q_Condition
.Open
End With
With DRTotalImportCommOrder
.DataSource = DEConnection '此处发生错误,告诉我未找到方法或者是数据成员,为什么?
.DataMember = DEConnection.rscmdTotalImportCommOrder
End With
运行出错?
我不是VB熟练工,最近刚刚用VB做完一个程序,其中控制部分没费太大周折,倒是报表部分颇让我费了一翻脑筋。在网上找了半天,也没找到关于VB6的 DataReport的详细介绍,于是想借鉴"前辈"们的经验,用CrystalReport或EXCEL,感觉也不省劲,于是决定回头再去"啃"DataReport,别说,还真让有所收获,下面就简单的介绍一下我的体会,希望对大家能有所帮助。
首先介绍一下DataReport对象的几个常用属性。一是DataSource,用于设置一个数据源,通过该数据源,数据使用者被绑定到一个数据库;二是DataMember,从DataSource提供的几个数据成员中设置一个特定的数据成员;三是LeftMargin、RightMargin、TopMargin、BottomMargin等,用于指定报表的左右上下的页边距;四是Sections,即DataReport的报表标头、页标头、细节、页脚注、报表脚注5个区域,如果加上分组(可以有多层分组),则增加一对区域,即分组标头、分组脚注。其中DataSource一般是一个数据环境或是ADODB.Connection类型的变量,而DataMember则对应数据环境中的Command或是ADODB.RecordSet类型的变量,推荐使用数据环境及Command,页边界大家肯定都很清楚,下面我主要介绍以下Sections,这也是DataReport的精髓所在。
Sections是一个集合,您可以为每一个Section指定名称,也可以用其缺省的索引,从上到下依次为1、2…。每个Section均有Height和Visible属性,您可以在一定条件下使一个Section不可见。在Section中可以放置各种报表控件,其中RptLabel、RptImage、RptShape和RptLine可以放在任意的Section中,用于输出各种文字、图形及表格线;RptTextBox只能放在细节中,一般用于绑定输出DataMemeber提供的数据字段;RptFunction只能被放置在分组注脚中,用于输出使用各种内置函数计算出的合计、最大值、最小值、平均值、记数等等。上述报表控件中常用公共属性有用于控制位置及高度宽度的Top、Left、Height、Width和控制可见性的Visible;其中RptTextBox还有DataField、DataMember、DataFormat及Font属性;其他属性不再多说。
然后介绍一下我的使用经验。一是对想控制的报表控件按类型有规律的命名;二是用RptShape的矩形框做表格线框,比用RptLine画框省事多了,只有斜线才使用RptLine;三是报表标题及报表中的表头文字、日期及页码用RptLabel,其中Caption属性支持转义字符,%D为长格式日期,%d为短格式日期,%P为总页数,%p为当前页码;四是对固定报表在设计窗口直接将报表控件摆放到位,对于活报表,应首先考虑报表最大的情形,将足够的控件分别放置在不同区域,位置大小可以不必深究,然后在报表输出前用VBA代码对所有控件的属性进行调整,包括位置、高度、宽度、字体、对齐方式、显示格式、可见性等等,相应的对Section也应根据情况调整其高度和可见性。
最后用一个实例模板来说明其使用方法。
连接数据库
With 数据环境.rsCommand名
If .State = adStateOpen Then .Close
.Source = sql语句
.Open 打开想输出的数据库数据项以便输出
End With
With 报表名
.DataSource=数据环境
.DataMember=Command名 这两行也可固定设好而不必每次设置
设置页表头部分(RpttLabel…为报表控件名)
.Sections(2).Controls("RptLabelPage").Caption = "共%P页第%p页"
.Sections(2).Controls("RptLabelDate").Caption = "打印日期:%D"
.Sections(3).Controls("RptLabel1").Left=…
…
设置细节部分(RptShapeX、RptTextBoxX为报表控件名)
.Sections(3).Controls("RptShape1").Left=…
.Sections(3).Controls("RptShape1").Top=…
.Sections(3).Controls("RptShape1").Height=…
.Sections(3).Controls("RptShape1").Width=…
.Sections(3).Controls("RptTextBox1").DataMember=Command名
.Sections(3).Controls("RptTextBox1").DataField=字段1
.Sections(3).Controls("RptTextBox1").Font.Name=…
…
.Sections(3).Controls("RptShapeN").Visible=False
.Sections(3).Controls("RptTextBoxN").Visible=False
…
. Sections(3).Height=计算出的或固定的细节高度
动态调整报表标题(RptLabelTitle为报表标签控件名)
.Sections(2). Controls("RptLabelTitle").Left=…
…
.Sections(2). Controls("RptLabelTitle").Alignment=…
…
调整完毕后
.Show 或 .PrintReport
End With
这样做的优点是报表设计时简单,调整方便、随意,只需更改一点代码,而不必为了一点点的修改而费神的在设计窗口调整半天。
printer打印最快的,不用工具。
简单例子:
Option Explicit
Public Sub PrintPreview(objPrint As Object)
objPrint.ScaleMode = vbMillimeters
objPrint.CurrentX = 8
objPrint.CurrentY = 10
objPrint.Print "AAAA"
objPrint.CurrentX = 8
objPrint.CurrentY = 18
objPrint.Print "BBBB"
If objPrint Is Printer Then objPrint.EndDoc
End Sub
Private Sub Command1_Click()
‘打印预览
PrintPreview Picture1
‘真正打印
‘PrintPreview Printer
End Sub
如果你比较熟悉VB的PRINTER对象操作,可调用API函数进行字符旋转打印,参考一下老外写的如下代码:
Dim mstrContent() As String
Dim mintPage() As Integer
Dim mlngArrID() As Long
Dim mbKeyPress As Boolean
Dim mMaxPages As Integer
Dim mblnChecked() As Boolean
Dim mlngSelArchID As Long
Dim mblnItemClick As Boolean
Dim mintItemSelect As Integer
Dim mlngItemID As Long
Dim mbChecked As Boolean
Dim mstrSelArchNo As String
Dim mlngArchID() As Long
Dim mLngCnnID() As Long
Private Const LF_FACESIZE = 32
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * LF_FACESIZE
End Type
Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long,ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" _
(ByVal lpDriverName As String,ByVal lpDeviceName As String,ByVal lpOutput As Long,ByVal lpInitData As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long,ByVal x As Long,ByVal y As Long,_
ByVal lpString As String,ByVal nCount As Long) As Long ' or Boolean
Private Declare Function StartDoc Lib "gdi32" Alias "StartDocA" (ByVal hdc As Long,lpdi As DOCINFO) As Long
Private Declare Function EndDoc Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function StartPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPage Lib "gdi32" (ByVal hdc As Long) As Long
Const DESIREDFONTSIZE = 12 ' Could use variable,TextBox,etc.
Private Sub Command1_Click()
'使用API函数打印
Dim OutString As String 'String to be rotated
Dim lf As LOGFONT 'Structure for setting up rotated font
Dim temp As String 'Temp string var
Dim result As Long 'Return value for calling API functions
Dim hOldfont As Long 'Hold old font information
Dim hPrintDc As Long 'Handle to printer dc
Dim hFont As Long 'Handle to new Font
Dim di As DOCINFO 'Structure for Print Document info
OutString = "测试字符1234564" 'Set string to be rotated
' Set rotation in tenths of a degree,i.e.,1800 = 180 degrees
lf.lfEscapement = 1800 '旋转180度,也可设置为900、2700
lf.lfHeight = (DESIREDFONTSIZE * -20) / Printer.TwipsPerPixelY
hFont = CreateFontIndirect(lf) 'Create the rotated font
di.cbSize = 20 ' Size of DOCINFO structure
di.lpszDocName = "My Document" ' Set name of print job (Optional)
' Create a printer device context
hPrintDc = CreateDC(Printer.DriverName,Printer.DeviceName,0)
result = StartDoc(hPrintDc,di) 'Start a new print document
result = StartPage(hPrintDc) 'Start a new page
' Select our rotated font structure and save prevIoUs font info
hOldfont = SelectObject(hPrintDc,hFont)
' Send rotated text to printer,starting at location 1000,1000
result = TextOut(hPrintDc,2000,1000,OutString,LenB(StrConv(OutString,vbFromUnicode)))
'不旋转打印
result = SelectObject(hPrintDc,hOldfont)
' Send non-rotated text to printer at same page location
result = TextOut(hPrintDc,vbFromUnicode)))
result = EndPage(hPrintDc) 'End the page
result = EndDoc(hPrintDc) 'End the print job
result = DeleteDC(hPrintDc) 'Delete the printer device context
result = DeleteObject(hFont) 'Delete the font object
End Sub
其实也有个比较简单的解决方案:
先把要输出的东西打印到一个PICTURE控件上,然后将PICTURE控件上的图片水平翻转一次,再垂直翻转一次,这就是旋转180度了,转好之后按照图形方式打印出来. 反正图片上的白色部分是不会打印出来的.而你得到的就是旋转180度的字体了.
PICTURE控件自带的PAINTPICTURE方法就可以实现翻转(MSDN上有详细说明)
记得从PICTURE控件打印到打印机也可以用PAINTPICTURE这个命令,这样的话,你只要在控件上先一个方向翻转一次,输出的时候再另一个方向翻转一次,就可以了
补充楼上,
只要你在图片上输出的时候先考虑好位置,就一定可以实现你的要求,又不用一个API,纯技巧解决方案
引用 19 楼 WallesCai 的回复:
其实也有个比较简单的解决方案:
先把要输出的东西打印到一个PICTURE控件上,你只要在控件上…
谢谢你的回答,这个思路我也考虑过,之前也用PICBox做过位图旋转,不过效率太低了,因为打印区域比A4纸还要大些,位图旋转消耗的时间相对来说太长了。因为一般打印纸卡都是大量一次性打印,所以必须考虑效率问题。。。
再次谢谢你的关注和回复!
引用 16 楼 prcstar 的回复:
HP1020激光打印机支持转180度打印,在打印首选项中设置一下就可以了。
呵呵
不知能不能支持纸卡的厚度
HP1020驱动程序打印默认模式 模式 介质
PLAIN(普通纸) 75 至 104 g/m2
LIGHT(轻磅) < 75 g/m2
HEAVY(重磅) 90 至 105 g/m2
CARDSTOCK(卡片纸) 卡片纸或重磅介质
TRANSPARENCY(投影胶片) 4-mil、0.1 单色投影胶片 (Monochrome Overhead Transparencies,OHT)
ENVELOPE(信封) 标准信封
LABEL(标签) 标准 HP LaserJet 标签
BOND(证券纸) 证券纸
ROUGH(粗糙纸) 粗糙纸
COLOR(彩色纸) 普通介质
LETTERHEAD(信头纸) 普通介质
PREPRINTED(预打印纸) 普通介质
PREPUNCHED(预穿孔纸) 普通介质
RECYCLED(再生纸) 普通介质
VELLUM(硫酸纸) 普通介质
——————————————————————————–
引用 18 楼 prcstar 的回复:
如果你比较熟悉VB的PRINTER对象操作,参考一下老外写的如下代码:
Dim mstrContent() As String
Dim mintPage() As Integer
Dim mlngArrID() As Long
Dim mbKeyPress As Boolean
Dim mMaxPages As Integer
Dim mblnChecked() As Boolean
Dim mlngSelArchID As Long
Dim mblnItemClick As Boolean
Dim mintItemSelect As Integer
Dim mlngItemID …
谢谢!
是不错,可惜调试起来和以后修改都比较麻烦。
最后一招:向打印机厂家寻求驱动程序支持!!
TO 楼主,
180度"旋转" 其实只要两次翻转就可以了,图像翻转和旋转是绝对不同的事,翻转的速度比旋转要快N百倍,不信你去MSDN上看看PAINTPICTURE这个方法的示例
up
[调用][excel][打印]vb调用excel打印预览出错
03 24th,2009
Private Sub Print_Click()
Dim xlapp As Excel.Application
Dim xlbook As Excel.Workbook
Dim xlsheet As Excel.Worksheet
Dim i,j As Integer
Dim WT As New clsWaitableTimer
Set xlapp = CreateObject("excel.application")
Set xlbook = xlapp.Workbooks.Add
Set xlsheet = xlbook.Worksheets(1)
'On Error GoTo cls
xlsheet.Name = "数据记录"
xlsheet.Columns(1).ColumnWidth = 10
xlsheet.Columns(3).ColumnWidth = 6
xlsheet.Columns(4).ColumnWidth = 8
xlsheet.Columns(5).ColumnWidth = 8
xlsheet.Columns(9).ColumnWidth = 6
xlapp.Range("A1:I1").Merge
xlapp.Range("A1").Select
With Selection
.HorizontalAlignment = xlCenter
End With
With Selection.Font
.Size = 20
.Bold = True
End With
With xlsheet.PageSetup
.PrintTitleRows = "A2:I2"
End With
xlsheet.Cells(1,1) = "数据报告"
For i = 0 To MSFlexGrid1.Rows - 1
For j = 0 To MSFlexGrid1.Cols - 1
xlsheet.Cells(i + 2,j + 1) = MSFlexGrid1.TextMatrix(i,j)
Next j
Next i
xlsheet.PageSetup.PrintGridlines = True
xlsheet.Cells.Borders.LineStyle = xlContinuous
xlapp.Visible = True
xlsheet.PrintPreview
xlapp.DisplayAlerts = False
xlbook.Close False
Set xlbook = Nothing
xlapp.Quit
Set xlapp = Nothing
End Sub
程序运行后,此段代码第一次执行没有错误,但再次被执行时报错,在.HorizontalAlignment = xlCenter这报错,实时错误'91'对象变量或With块变量未设置,那位大侠帮忙解决一下啊 感激不尽
高人啊 问题解决了
[datareport][打印][空白]datareport如何打印空白表格
01 11th,2009
很多时候记录不会满一页,而我的记录是显示在表格当中的,那么我怎样才能在下面的空白部分打印空白的表格呢?
在datereport的recordset中作文章…..比如addnew几行空数据?
datareport好像也不能控制一页的记录数……唉,不搞了,不知道那个activereport能不能实现这个功能?
引用 3 楼 jww1986 的回复:
datareport好像也不能控制一页的记录数……唉,不搞了,不知道那个activereport能不能实现这个功能?
可以
新加一个分组字段.比如叫GID,要10行一页,就每10行数据用一个GID编号,然后按GID分组并强制分页….
[控制][打印][单面]关于控制打印方法(单面打印和双面打印)的问题
01 3rd,2009
现在我需要用VB.net+Activereport实现以下功能:
有两张报表,一张是封面,一张是明细内容。一共有5张明细,1张封面
现在我想在打印的时候前4张纸单面打印明细报表,最后一张纸一面打印明细报表,另一面打印封面。
这个怎么实现简便呢?急用,多谢各位达人!
[控制][打印][单面]关于控制打印方法(单面打印和双面打印)的问题
01 3rd,2009
现在我需要用VB.net+Activereport实现以下功能:
有两张报表,一张是封面,一张是明细内容。一共有5张明细,1张封面
现在我想在打印的时候前4张纸单面打印明细报表,最后一张纸一面打印明细报表,另一面打印封面。
这个怎么实现简便呢?急用,多谢各位达人!
[打印][图片]打印图片求肋
12 13th,2008
客户要求用A4纸打印出这样的一个图片。
XX单 XXX单
提货单位 0 日期 0 省局入帐 提货单位 0 日期 0 收货单位存根
"卸货
地点" 0 "空车
重量" 0 "卸货
地点" 0 "空车
重量" 0
毛重 0 净重 0 毛重 0 净重 0
X人 X员 X人 X员
X号 #REF! 桶数 X号 桶数
沥青过磅单 单
单位 0 日期 0 发货单位存根 单位 0 日期 0 承运人存根
"卸货
地点" 0 "空车
重量" 0 "卸货
地点" 0 "空车
重量" 0
毛重 0 净重 0 毛重 0 净重 0
X人 X员 X人 X员
X号 #REF! 桶数 0 X号 0 桶数 0
并且在文字下面有加上水印图片的一张图
十分急.
请高手指点?
QQ:67854719
[datagrid][添加][打印]datagrid 添加列 打印问题
12 13th,2008
我现在想实现,在datagrid控件中动态的增加列,然后再更改没列的数值,最后将数据打印出来。
或者是实现此种功能:在数据表中动态增加列然后打印所有数据
谢谢了 在线等
添加列
alter table 表 add 列 varchar(50)
不是现有的 需要根据实际增加
DataGrid1.Columns.Add
DataGrid1.Columns.Remove
引用 3 楼 aiguoa3 的回复:
不是现有的 需要根据实际增加
数据库结构的规划应该先于代码的编写。。即使因应用户的要求添加字段也不应该由普通客户的用户端程序完成。。
引用 5 楼 lsftest 的回复:
引用 3 楼 aiguoa3 的回复:
不是现有的 需要根据实际增加
数据库结构的规划应该先于代码的编写。。即使因应用户的要求添加字段也不应该由普通客户的用户端程序完成。。
是不是这么理解 如果定了字段 就不能修改了?
[预览][打印]在VB中怎样先预览后打印
12 13th,2008
我做的查询界面需要打印功能,我也做了将查询的数据写入EXCEL,通过EXCEL打印,但是总感觉不好,怕会占用太多系统资源
谁有好方法关于打印的?能教教我吗?
我除了写入EXCEL来打印,其他的都没有用过,最好能给个代码让我参考一下
我想实现的功能就是将查询出来的数据先打印预览,然后按预览界面上的打印,就直接打印了,最好能有打印设置功能。谢谢了!
VB自带有报表工具datareport,简单的报表可以满足需要
复杂的报表只借助第三方工具了….
我需要打印的报表很多,而且每种报表格式都不一样的,这个怎样做呢?最好能有这方面的例子或代码发给我
google 中搜索 VB datareport
示例一大堆….
datareport 不是太好用,而且我也没用过,好像是一张表就需要一个报表,还有没有别的好方法呢?
以一个初学者
报表内容是sql语句返回的记录集,并非一表一张报表…
功能强大一点的有ActiveReport,水晶报表等等,都是第三方的….
也可以自己写,比如,我见过利用浏览器作预览打印的….
pls use crystalreport
用水晶报表吧
到网上搜一个例子,用一次就明白了。
打印还是用水晶报表吧,如果做第二个选择,那就用word,直接调用word模板生成要打印的文件,然后预览
如果不是太复杂的报表..就用VB自己的报表吧
其实,自己纯手工写一个报表输出工具也不是太难,
报表类软件无非以下几个要点:
1: 数据感知能力: 即和数据库关联,运用动态添加控件数组的方法+数据库连接代码就可以显示任意数据库结构的字段.
2: 排版功能: 通过拖曳控件位置+文件保存控件位置 就可以实现自定义报表格式.
3: 打印输出: 打印机获取/打印机设置/打印输出 三个部分,前两个功能都有现成例子,最后那个打印输出实际上就是根据第2点的那个控件位置加上缩放比例输出到打印机
上述的这些东西在技术上都没有多少难度,并且很多都有成熟的源码可以在网上找到.
补充一点:
在上述的第3点中,只要把最后"打印输出"部分改成输出到PICTURE控件上,就是所谓的"打印预览"了,你甚至可以直接再把这个PICTURE控件上的内容打印出来也一样可以输出
用vb调用excel或者word生成报表,可以直接打印也可以预览,当然也可以定义打印方向,页边距。我写的预算管理系统就是用到了这个
参考一下吧!
我这有个报表程序 支持用户可以自己选择a4 b5 可以自己设定要打印的字段
On Error Resume Next
strReportCaption = " 商品库存明细表,23" & vbCrLf & _
"操 作 员: " & Czy & ",9 " & vbCrLf & _
"打印日期: " & Now & ",9 "
strstr = "SELECT 编号,名称,规格,产地,批号,有效期 FROM spxxrq order by 编号"
‘strstr = "SELECT * FROM spxxrq where 部类号='" & Combo3 & "' order by 编号" connDataReport.Open strct FrmPreview.Show 1 要打印时就执行上面的调用语句就行了