报表打印的问题,请教各位 我的程序中经常需要打印动态生成的记录集的内容,且通常字段较长,A4纸竖着打印不下,请教各位我应该选用什么方法打印呢?因为以前没接触过VB的打印,希望各位能稍稍详细的解释解释,谢谢啊 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 一. 用VB创建外部EXCEL对象 大多数大型 ActiveX-enabled 应用程序和其它 ActiveX 部件,在它们的对象层次中都提供了一个顶层外部可创建对象。该对象提供了对该层次中其它对象的访问,并且还提供对整个应用程序起作用的方法和属性。 例如,每个 Microsoft Office 应用程序提供一个顶层 Application 对象。下面语句显示了对Microsoft Excel的 Application 对象的引用: Dim xlApp As Excel.Application Set xlApp = New Excel.Application 然后,可以用这些变量来访问在EXCEL应用程序中的从属对象、以及这些对象的属性和方法。例如: Set xlApp = CreateObject("Excel.Application") ‘激活EXCEL应用程序 xlApp.Visible = False ‘隐藏EXCEL应用程序窗口 Set xlBook = xlApp.Workbooks.Open(strDestination) ‘打开工作簿,strDestination为一个EXCEL报表文件 Set xlSheet = xlBook.Worksheets(1) ‘设定工作表 二. 用EXCEL 97设计报表的模版文件 EXCEL 97是一个非常优秀的创建报表的工具。它提供的单元格任意合并、拆分和绘图功能基本上能够满足设计所有复杂报表的需求。它对任意一个单元格的格式随意控制,更为随心所欲地设计报表提供了强大的支持。 根据用户提供的报表,我们可以很快在EXCEL里生成模版文件。所谓生成模版文件只是为了满足用户多方面的需求而设计的。也是为了适合报表以后的更改而做的一点预备工作。例如用户需要打印几百张职工履历表,但其格式都是一致的,并且随着时间和实际情况的变化,表格格式有可能需要改变,我们设计一个模版文件显然可以“以不变应万变”了。 生成工作表时我们应当记录下要填充内容的单元格编号和该单元格内要填充的数据字段。这样形成一个表格,在写程序时一目了然。如: Cell(4,2) 职工姓名 Cell(6,6) 毕业学校 Cell(4,4) 职工性别 Cell(6,7) 所学专业 Cell(4,6) 职工民族 Cell(6,9) 工作时间 (表一) 在程序里我们当然不要对模版文件进行操作了,我们只需要对模版文件的一个拷贝进行操作就行(这也是我们设计模版文件的一个目的和好处)。如下面的例子: Dim strSource, strDestination As String strSource = App.Path & "\Excels\RegisterFee.xls" ‘RegisterFee.xls就是一个模版文件 strDestination = App.Path & "\Excels\Temp.xls" FileCopy strSource, strDestination ‘将模版文件拷贝到一个临时文件 三. 生成工作表内容 有了上述两步工作的铺垫,我们下面接着就只要根据(表一)的格式给各单元格赋值了。如: datPrimaryRS.Recordset.MoveFirst ‘datPrimaryRS为Data控件 If IsNull(datPrimaryRS.Recordset!姓名) = False Then xlSheet.Cells(4, 2) = datPrimaryRS.Recordset!姓名 End If If IsNull(datPrimaryRS.Recordset!性别) = False Then xlSheet.Cells(4, 4) = datPrimaryRS.Recordset!性别 End If If IsNull(datPrimaryRS.Recordset!民族) = False Then xlSheet.Cells(4, 6) = datPrimaryRS.Recordset!民族 End If 四. 打印报表 生成了工作表后,就可以对EXCEL发出打印指令了。 注意在执行打印操作之前应该对EXCEL临时文件执行一次保存操作,以免在退出应用程序后EXCEL还提示用户是否保存已修改的文件,让用户觉得莫名其妙。如下语句: xlBook.Save ‘保存文件 xlSheet.PrintOut ‘执行打印 xlApp.Quit ‘退出EXCEL 至此读者应该看到,我们设计的报表打印是通过EXCEL程序来后台实现的。用户根本看不到具体过程,他们只看到一张张漂亮的报表轻易地被打印出来了。 一. 概述 ---- 几乎所有数据库应用软件,都需要打印单证和报表。常见的方法是利用VB的Crystal Reports(水晶报表)方式,通过TextBox等数据绑定控件,调用Print方法直接输出。虽然Crystal Report这一个功能强大、样式丰富且无编程方式的报表编制程序能适应大部分单证、报表打印的需要,但是Crystal Reports引擎是一个动态链接库,需许多文件支持和调用更多系统资源,大大增加系统负担。 ---- 另一种解决办法是通过Printer对象的Print方法,直接打印字符串。这虽然减少了系统资源的开销,但它不能直接用于打印复杂的单证和报表。本文通过两个实例,阐述一个通用折行打印程序的编程和在单证及报表的应用。 ---- 二. 编程实现及实例 ---- 为便于阐述的方便,我们先建立一个Access数据库Standards.mdb,其内SN表由以下几个字段组成: ---- 标准号(文本,17) ---- 标准名称(文本,255) ---- 英文名称(文本,255) ---- 实施日期(日期,8) ---- 修定日期(日期,8) ---- 发布日期(日期,8) ---- 代替标准(文本,50) ---- 通用折行打印程序编制操作如下: ---- 1.在VB5.0编程环境中,新建一个工程Project1; ---- 2. 在Project1中添加Moduel,在Moduel模块中定义一个记录最大折行数的公用变量Rowlab和Function函数(以下程序都经过实际运行测试,可以原样复制使用); Public rowlab As Integer '定义一个公用变量Function prnt11(X As Integer, Y As Integer,Font As Single, Txt As String, Val As Integer)Dim str As String, str1 As String, str2 As String ,i As IntegerPrinter.CurrentX = XPrinter.CurrentY = YPrinter.FontBold = FalsePrinter.FontSize = fontstr = txtstr2 = stri = 0rowlab = 0If Len(Trim(str)) = 0 Then rowlab = 1 '待打印字符串为空的标志Else Do While Len(str) > 0 Printer.CurrentX = X Printer.CurrentY = Y + rowlab * 240 rowlab = rowlab + 1 If Len(str) >= val Then str1 = Mid(str, 1, val) Printer.Print str1 i = i + 1 str = Mid(str2, i * val + 1) Else Printer.Print str Exit Do End If LoopEnd IfEnd Function---- 3. 在Project1中新建一个窗体Form1,窗体上添加一个Data控件Data1,一个MSFlexGrid控件MSFGrid1,7个TextBox和两个命令按钮CmdPrnt1、CmdPrnt2。设置Data控件的属性: .. DatabaseName="Standards.mdb"..RecordSourse="SN" MSFGrid1属性: .DataSource="Data1" Text1属性: .DataSource="Data1" .DataField="标准号" Text2~Text7类同。---- CmdPrnt1、CmdPrnt2分别为打印单条记录和多条记录的按钮。 ---- 实例1:文字串定位折行打印在口岸联检部门中应用非常广泛。下述例子是用CmdPrnt1的Click事件代码实现了对文字串定位折行打印: Private Sub CmdPrnt1_Click()Dim str As String, str1 As String ,txt As StringDim strx As Integer, stry As Integer,i As Integerstrx = 200stry = 0 txt = Space(20) + "中国出入境检验检疫标准目录检索STEMS 2000"Printer.FontName = "黑体"dd = prnt11(strx, stry, 10, txt, 50)stry = stry + rowlab * 240Printer.Line (0, stry)-(9000, stry)Printer.FontName = "宋体"txt = "标准号:" + Space(2) + Trim(Text1) + Space(3) + "发布日期:" + Trim(Text4) + Space(3) + "实施日期:" + Trim(Text6) + Space(3) + "修定日期:" + Trim(Text5) '+ Chr(13)stry = stry + 240dd = prnt11(strx, stry, 10, txt, 70)stry = stry + rowlab * 240txt = "代替标准:"dd = prnt11(strx, stry, 10, txt, 10)dd = prnt11(strx + 1000, stry, 10, Trim(Text7), 60)stry = stry + rowlab * 240txt = "标准名称:"dd = prnt11(strx, stry, 10, txt, 10)dd = prnt11(strx + 1000, stry, 10, Trim(Text4), 38)stry = stry + rowlab * 240txt = "英文名称:"dd = prnt11(strx, stry, 10, txt, 10)dd = prnt11(strx + 1000, stry, 10, Text5, 72)Printer.EndDocEnd Sub---- 注: Prnt11函数原形:prnt11(X As Integer, Y As Integer, Font As Single, Txt As String, Val As Integer),其各参数含义如下: ---- X、Y为待打印字符串左上角起始座标; ---- Font为字体大小; ---- Txt为待打印字符串; ---- Val为字符串打印折行长度。 ---- 实例2:直接打印表格式窗体显示的多记录多字段,往往因某些字段的字节太多而造成纸张宽度不足。以下CmdPrnt2的Click事件中的代码,实现了对上述MSFGrid1表格记录的打印: Private Sub CmdPrnt2_Click()Dim fnt As SingleDim pp As IntegerDim stry As Integer, strx As IntegerDim stry1 As Integer, strx1 As Integer, linw As IntegerDim page1 As Integer, p As Integer,gridrow As Integer, ii As Integerp = 0ii = 1 'ii记录MSFGRID1表格同一记录内字段最大打印行pp = 0 '开始页码ss$ = "中国出入境检验检疫标准目录检索STEMS 2000" ' 表头Static a(4) As Integerkan = 0a(2) = 1680 a(3) = 2800a(4) = 5300page1 = 46 '定义每页行数 strx = 200 strx1 = 200 stry = 1400 stry1 = 1400 linw = 240 '定义行宽 fnt = 10 '定义字体大小 For i = 2 To 4 kan = kan + a(i) Next gridrow = Datdatact1.Recordset.RecordCount If gridrow = 0 Then MsgBox "无满足条件记录打印!" Exit SubEnd If Printer.FontName = "黑体" dd = prnt11(3300, 700, fnt, ss$, 26) '打印标题 dd = prnt11(500, stry - 250, fnt, "标准号", 26) dd = prnt11(2690, stry - 250, fnt, "标准名称", 26) dd = prnt11(6690, stry - 250, fnt, "英文名称", 26) Printer.Line (strx - 20, stry - 30)-(10460, stry - 30) Printer.FontName = "宋体" For j = 1 To gridrow '打印gridrow条记录 MSFGrid1.Row = j strx = strx1 For i = 2 To 4 '假设只打印2-3 列 MSFGrid1.Col = i dd = prnt11(strx, stry, fnt,MSFGrid1.Text, IIf(i = 3, 13, 55)) If ii < rowlab Then 'ii记录同一记录内字段最大打印行 ii = rowlab End If strx = strx + a(i) Next p = p + ii rowlab = ii ii = 1 '重新初始化 If p > page1 Then p = 0 strx = strx1 For n = 2 To 4 strx = strx + a(n) Next pp = pp + 1 stry = stry + rowlab * linw foot$ = "第" + CStr(pp) + "页" dd = prnt11(strx / 2, stry + 3 * linw, 10, foot$, 26) stry = stry1 Printer.NewPage Printer.FontName = "黑体" dd = prnt11(3300, 700, fnt, ss$, 26) dd = prnt11(500, stry - 250, fnt, "标准号", 26) dd = prnt11(2690, stry - 250, fnt, "标准名称", 26) dd = prnt11(6690, stry - 250, fnt, "英文名称", 26) Printer.Line (-20, stry - 30)-(10460, stry - 30) '打印起始线 Printer.FontName = "宋体" strx = strx1 Else stry = stry + rowlab * linw End If Next If p < page1 Then For p = 0 To page1 + 1 strx = strx1 Next End If strx = strx1 For n = 2 To 4 strx = strx + a(n) Next pp = pp + 1 foot$ = "第" + CStr(pp) + "页" dd = prnt11(strx / 2, stry + 3 * linw, 10, foot$, 26) Printer.EndDoc End Sub---- 以上程序在简体中文Windows98、VB5.0环境中调试通过。 http://vbworld.sxnw.gov.cn/articles/forms/htm7.htm DbFileName = App.Path & "\mydata.mdb" connectstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _ DbFileName & ";Persist Security Info=False;" DataEnvironment1.Connection1.Open connectstring'DataEnvironment1.Connection1.Execute "select * from mz"DataEnvironment1.rsCommand1.Open "select * from mz where ID='111'"DataReport1.Show 工具:vb6.0 问题:报表打印时,编程控制纸张纵向和横向的打印方式。但当我设定 Printer.Orientation = vbPRORLandscape 后,程序运行显示Orientation为 只读属性不能修改。请问该如何用编程控制纸张纵向和横向的打印? 回答: 方法一:用一个CommonDialog: Private Sub Command1_Click() CommonDialog1.Flags = cdlPDPrintSetup CommonDialog1.CancelError = True On Error GoTo ErrorHandle: CommonDialog1.ShowPrinter '必须Show出来且"确定"才能修改纸方向 'Me.Refresh 'Command1.Refresh On Error GoTo 0 DataReport1.Show vbModal ErrorHandle: End Sub 一个晚上没解决的问题~希望早上有人能帮我解决一下` 谁有个COM+的简单实例啊?看书看得一个头三个大也只是明白了原理 请教一个打开vb程序遇到的问题。 一条sql语句引起的问题,情大家帮忙! 请教datagrid控件的初级问题 在vb中如何调用oracle的带返回参数的过程?在线等....... 关于文本处理的初级问题 寻求帮助~~~~ 关于密码,一个让我郁闷的问提,也许大家都会。 一个关于顺序表的问题 如何实现把文件拖动到VB程序的窗口或者图标上来获得文件名呢?急问。 dataReport设定DataSource的问题
Set xlApp = New Excel.Application 然后,可以用这些变量来访问在EXCEL应用程序中的从属对象、以及这些对象的属性和方法。例如: Set xlApp = CreateObject("Excel.Application")
‘激活EXCEL应用程序
xlApp.Visible = False ‘隐藏EXCEL应用程序窗口
Set xlBook = xlApp.Workbooks.Open(strDestination)
‘打开工作簿,strDestination为一个EXCEL报表文件
Set xlSheet = xlBook.Worksheets(1)
‘设定工作表 二. 用EXCEL 97设计报表的模版文件 EXCEL 97是一个非常优秀的创建报表的工具。它提供的单元格任意合并、拆分和绘图功能基本上能够满足设计所有复杂报表的需求。它对任意一个单元格的格式随意控制,更为随心所欲地设计报表提供了强大的支持。 根据用户提供的报表,我们可以很快在EXCEL里生成模版文件。所谓生成模版文件只是为了满足用户多方面的需求而设计的。也是为了适合报表以后的更改而做的一点预备工作。例如用户需要打印几百张职工履历表,但其格式都是一致的,并且随着时间和实际情况的变化,表格格式有可能需要改变,我们设计一个模版文件显然可以“以不变应万变”了。 生成工作表时我们应当记录下要填充内容的单元格编号和该单元格内要填充的数据字段。这样形成一个表格,在写程序时一目了然。如: Cell(4,2) 职工姓名 Cell(6,6) 毕业学校
Cell(4,4) 职工性别 Cell(6,7) 所学专业
Cell(4,6) 职工民族 Cell(6,9) 工作时间
(表一) 在程序里我们当然不要对模版文件进行操作了,我们只需要对模版文件的一个拷贝进行操作就行(这也是我们设计模版文件的一个目的和好处)。如下面的例子: Dim strSource, strDestination As String
strSource = App.Path & "\Excels\RegisterFee.xls"
‘RegisterFee.xls就是一个模版文件
strDestination = App.Path & "\Excels\Temp.xls"
FileCopy strSource, strDestination
‘将模版文件拷贝到一个临时文件 三. 生成工作表内容 有了上述两步工作的铺垫,我们下面接着就只要根据(表一)的格式给各单元格赋值了。如: datPrimaryRS.Recordset.MoveFirst
‘datPrimaryRS为Data控件
If IsNull(datPrimaryRS.Recordset!姓名) = False Then
xlSheet.Cells(4, 2) = datPrimaryRS.Recordset!姓名
End If
If IsNull(datPrimaryRS.Recordset!性别) = False Then
xlSheet.Cells(4, 4) = datPrimaryRS.Recordset!性别
End If
If IsNull(datPrimaryRS.Recordset!民族) = False Then
xlSheet.Cells(4, 6) = datPrimaryRS.Recordset!民族
End If 四. 打印报表 生成了工作表后,就可以对EXCEL发出打印指令了。 注意在执行打印操作之前应该对EXCEL临时文件执行一次保存操作,以免在退出应用程序后EXCEL还提示用户是否保存已修改的文件,让用户觉得莫名其妙。如下语句: xlBook.Save ‘保存文件
xlSheet.PrintOut ‘执行打印
xlApp.Quit ‘退出EXCEL 至此读者应该看到,我们设计的报表打印是通过EXCEL程序来后台实现的。用户根本看不到具体过程,他们只看到一张张漂亮的报表轻易地被打印出来了。
'定义一个公用变量
Function prnt11(X As Integer, Y As
Integer,Font As Single, Txt As String, Val As Integer)
Dim str As String, str1 As String,
str2 As String ,i As Integer
Printer.CurrentX = X
Printer.CurrentY = Y
Printer.FontBold = False
Printer.FontSize = font
str = txt
str2 = str
i = 0
rowlab = 0
If Len(Trim(str)) = 0 Then
rowlab = 1 '待打印字符串为空的标志
Else
Do While Len(str) > 0
Printer.CurrentX = X
Printer.CurrentY = Y + rowlab * 240
rowlab = rowlab + 1
If Len(str) >= val Then
str1 = Mid(str, 1, val)
Printer.Print str1
i = i + 1
str = Mid(str2, i * val + 1)
Else
Printer.Print str
Exit Do
End If
Loop
End If
End Function---- 3. 在Project1中新建一个窗体Form1,窗体上添加一个Data控件Data1,一个MSFlexGrid控件MSFGrid1,7个TextBox和两个命令按钮CmdPrnt1、CmdPrnt2。设置Data控件的属性: .. DatabaseName="Standards.mdb"
..RecordSourse="SN"
MSFGrid1属性:
.DataSource="Data1"
Text1属性:
.DataSource="Data1"
.DataField="标准号"
Text2~Text7类同。---- CmdPrnt1、CmdPrnt2分别为打印单条记录和多条记录的按钮。 ---- 实例1:文字串定位折行打印在口岸联检部门中应用非常广泛。下述例子是用CmdPrnt1的Click事件代码实现了对文字串定位折行打印: Private Sub CmdPrnt1_Click()
Dim str As String, str1 As String ,txt As String
Dim strx As Integer, stry As Integer,i As Integer
strx = 200
stry = 0
txt = Space(20) + "中国出入境检验检疫标准目录检索STEMS 2000"
Printer.FontName = "黑体"
dd = prnt11(strx, stry, 10, txt, 50)
stry = stry + rowlab * 240
Printer.Line (0, stry)-(9000, stry)
Printer.FontName = "宋体"
txt = "标准号:" + Space(2) + Trim(Text1) + Space(3) +
"发布日期:" + Trim(Text4) + Space(3) + "实施日期:"
+ Trim(Text6) + Space(3) + "修定日期:" + Trim(Text5) '+ Chr(13)
stry = stry + 240
dd = prnt11(strx, stry, 10, txt, 70)
stry = stry + rowlab * 240
txt = "代替标准:"
dd = prnt11(strx, stry, 10, txt, 10)
dd = prnt11(strx + 1000, stry, 10, Trim(Text7), 60)
stry = stry + rowlab * 240
txt = "标准名称:"
dd = prnt11(strx, stry, 10, txt, 10)
dd = prnt11(strx + 1000, stry, 10, Trim(Text4), 38)
stry = stry + rowlab * 240
txt = "英文名称:"
dd = prnt11(strx, stry, 10, txt, 10)
dd = prnt11(strx + 1000, stry, 10, Text5, 72)
Printer.EndDoc
End Sub---- 注: Prnt11函数原形:prnt11(X As Integer, Y As Integer, Font As Single, Txt As String, Val As Integer),其各参数含义如下: ---- X、Y为待打印字符串左上角起始座标; ---- Font为字体大小; ---- Txt为待打印字符串; ---- Val为字符串打印折行长度。 ---- 实例2:直接打印表格式窗体显示的多记录多字段,往往因某些字段的字节太多而造成纸张宽度不足。以下CmdPrnt2的Click事件中的代码,实现了对上述MSFGrid1表格记录的打印: Private Sub CmdPrnt2_Click()
Dim fnt As Single
Dim pp As Integer
Dim stry As Integer, strx As Integer
Dim stry1 As Integer,
strx1 As Integer, linw As Integer
Dim page1 As Integer, p As Integer,
gridrow As Integer, ii As Integer
p = 0
ii = 1 'ii记录MSFGRID1表格同一记录内字段最大打印行
pp = 0 '开始页码
ss$ = "中国出入境检验检疫标准目录检索STEMS 2000" ' 表头
Static a(4) As Integer
kan = 0
a(2) = 1680
a(3) = 2800
a(4) = 5300
page1 = 46 '定义每页行数
strx = 200
strx1 = 200
stry = 1400
stry1 = 1400
linw = 240 '定义行宽
fnt = 10 '定义字体大小
For i = 2 To 4
kan = kan + a(i)
Next
gridrow = Datdatact1.Recordset.RecordCount
If gridrow = 0 Then
MsgBox "无满足条件记录打印!"
Exit Sub
End If
Printer.FontName = "黑体"
dd = prnt11(3300, 700, fnt, ss$, 26) '打印标题
dd = prnt11(500, stry - 250, fnt, "标准号", 26)
dd = prnt11(2690, stry - 250, fnt, "标准名称", 26)
dd = prnt11(6690, stry - 250, fnt, "英文名称", 26)
Printer.Line (strx - 20, stry - 30)-(10460, stry - 30)
Printer.FontName = "宋体"
For j = 1 To gridrow '打印gridrow条记录
MSFGrid1.Row = j
strx = strx1
For i = 2 To 4 '假设只打印2-3 列
MSFGrid1.Col = i
dd = prnt11(strx, stry, fnt,
MSFGrid1.Text, IIf(i = 3, 13, 55))
If ii < rowlab Then
'ii记录同一记录内字段最大打印行
ii = rowlab
End If
strx = strx + a(i)
Next
p = p + ii
rowlab = ii
ii = 1 '重新初始化
If p > page1 Then
p = 0
strx = strx1
For n = 2 To 4
strx = strx + a(n)
Next
pp = pp + 1
stry = stry + rowlab * linw
foot$ = "第" + CStr(pp) + "页"
dd = prnt11(strx / 2, stry + 3 * linw, 10, foot$, 26)
stry = stry1
Printer.NewPage
Printer.FontName = "黑体"
dd = prnt11(3300, 700, fnt, ss$, 26)
dd = prnt11(500, stry - 250, fnt, "标准号", 26)
dd = prnt11(2690, stry - 250, fnt, "标准名称", 26)
dd = prnt11(6690, stry - 250, fnt, "英文名称", 26)
Printer.Line (-20, stry - 30)-(10460, stry - 30)
'打印起始线
Printer.FontName = "宋体"
strx = strx1
Else
stry = stry + rowlab * linw
End If
Next
If p < page1 Then
For p = 0 To page1 + 1
strx = strx1
Next
End If
strx = strx1
For n = 2 To 4
strx = strx + a(n)
Next
pp = pp + 1
foot$ = "第" + CStr(pp) + "页"
dd = prnt11(strx / 2, stry + 3 * linw, 10, foot$, 26)
Printer.EndDoc
End Sub---- 以上程序在简体中文Windows98、VB5.0环境中调试通过。
connectstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
DbFileName & ";Persist Security Info=False;"
DataEnvironment1.Connection1.Open connectstring
'DataEnvironment1.Connection1.Execute "select * from mz"
DataEnvironment1.rsCommand1.Open "select * from mz where ID='111'"
DataReport1.Show
问题:报表打印时,编程控制纸张纵向和横向的打印方式。但当我设定
Printer.Orientation = vbPRORLandscape 后,程序运行显示Orientation为
只读属性不能修改。请问该如何用编程控制纸张纵向和横向的打印? 回答: 方法一:用一个CommonDialog:
Private Sub Command1_Click()
CommonDialog1.Flags = cdlPDPrintSetup
CommonDialog1.CancelError = True
On Error GoTo ErrorHandle:
CommonDialog1.ShowPrinter '必须Show出来且"确定"才能修改纸方向
'Me.Refresh
'Command1.Refresh
On Error GoTo 0
DataReport1.Show vbModal
ErrorHandle:
End Sub