⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delphi_report.htm

📁 对于学习很有帮助
💻 HTM
字号:
 
<HTML>
<!-- #BeginTemplate "/Templates/alltips.dwt" --> 
<HEAD>
<TITLE>Delphi爱好者--技巧集</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
<!--
.font9 {  font-size: 9pt; text-decoration: none}
.font105 {  font-size: 10.5pt; text-decoration: none}
a:hover {  color: #F77C02; text-decoration: underline}
a:active {  color: #0000FF; text-decoration: none}
a {  color: #0000FF; text-decoration: none}
-->
</style>
</HEAD>
<BODY BGCOLOR="#FFFFFF" class="font9">
<!-- #BeginEditable "head" -->
<p align="center"><b>用delphi编写医院的复杂报表 </b></p>
<p><br>
  江苏省无锡市中医医院电脑房 <br>
  袁波 <br>
  ---- 我院的信息管理系统采用delphi编程,由于各科要求不同,报表形式也多种多样,编写起来让人头痛。delphi运行在WINDOWS平台下,打印同DOS下完全不同,而Quick 
  Report即难以控制又占用资源,对于一个稍复杂的、有特殊要求的报表,Quick Report无法实现。这里介绍几个在编程中遇到的比较典型的报表的实现方法。 
</p>
<p>---- 1、哪个单位的财务科都有几本厚厚的台帐,我院财务科提出打印药库的台帐,好脱掉手工帐,也算是办公现代化了,要求合情合理,院长也说应当如此。看着财务科提供的红绿相间的、统一印制的、行间距3毫米的台帐专用小卡片,我不由想到中国人节俭的美德。考虑到每个药品至少打印一张,而且表格线一个都不能少,加上中医院药品有二千多种,所以这个报表必须用激光打印机来打印(至于如何让院长同意购买激光打印机,则是另一回事,办公自动化哪能没有代价呢)。程序实现的思路基本上是把打印纸当做画布在上面画一个个小矩形,具体由以下几个过程实现:(设Form名为Ttzview)。 
</p>
<p>先在程序中定义二个类:<br>
  titlerecord=record<br>
  Currect:Trect;<br>
  Atitle:string;<br>
  end;<br>
  detailrecord=record<br>
  Arect:Trect;<br>
  alignment:word;<br>
  end;</p>
<p>---- 再建立以下四个过程; <br>
  ---- RectDraw(Acanvas:Tcanvas;s:string;R:Trect;frame:boolean;position:word); 
</p>
<p>---- 这个过程就是画矩形用的,frame决定是否画线(这里当然要画啦!); </p>
<p>---- printinitit(firsttop,firstleft:integer); </p>
<p>---- 这个过程是初始化用的,就是定义各个小矩形在纸上的位置; </p>
<p>---- printtitle(acanvas:Tcanvas); </p>
<p>---- 这个过程是打印表头的,因为表头的字总是要大一些; </p>
<p>---- printdetail(acanvas:Tcanvas;Qtz:Tdataset;acount:integer;firstpage:integer); 
</p>
<p>---- 这个过程才是打印具体内容的,一页打印40行,不够就换页,总之一页只能是一个药品; </p>
<p>---- printhj(acanvas:Tcanvas); </p>
<p>---- 一看就知道,这个过程就是打印合计的啦! </p>
<p>---- 只要建个Botton,顺序调用printinitit,printtitle,printdetail,printhj这四个过程就行了, </p>
<p>---- (调用格式:printtitle(printer.canvas);) </p>
<p>---- 对了,Qtz就是查询出来的台帐数据,如何生成的这里就不谈了。 </p>
<p>---- 具体程序如下 </p>
<p>---- 此程序在delphi1,delphi3版本WIN3.2,WIN95,WIN97,WIN98平台下运行通过,顺便提供台帐数据库的库结构 </p>
<p>---- 2、非常复杂,无法取巧的报表 </p>
<p>---- 我院肿瘤科需要打印病人的病案,这可是特色专科现代化建设的一部分,卫生局要来检查的,所以必须完成任务。每一个病案有100多个项目,若用Qreport,中间如果要加减一个项目(这事常有),几十个项目的调整排列会使人昏倒。我一下子建立100多个临时变量,在虚拟的画布上画啊画,运行在我的PII233,64M内存的机子上倒是顺顺当当的,不过换到肿瘤科的486,8M内存的机子上时(大家别笑),系统堆栈马上溢出,所以只好祭出指针大法(我的编程水平好象又有长进,窃喜),方法如下: 
</p>
<p>先建立titleprint类: <br>
  titleprint=^Titlerecord;<br>
  titlerecord=record<br>
  Currect:Trect;<br>
  Atitle:string[50];<br>
  end;<br>
  再建立过程printnow(Form的名称叫<br>
  zlk,printdot就是打印机的点数,一般针打是180);<br>
  procedure Tzlk.printnow(acanvas:Tcanvas);<br>
  var i,x,y,pc_count:integer; <br>
  myprint:array[0..200] of titleprint;<br>
  begin<br>
  firsttop:=round(int(0.5/2.54*printdot));<br>
  firstleft:=round(int(0.1/2.54*printdot));<br>
  rowheight:=round(int(0.7/2.54*printdot));<br>
  x:=0+firstleft;y:=round(int<br>
  (1.3/2.54*printdot))+firsttop;<br>
  pc_count:=0;<br>
  inc(pc_count); new(myprint[pc_count]);<br>
  myprint[pc_count]^.currect:=rect<br>
  (x+round(int(0.1/2.54*printdot))+firstleft,y,<br>
  x+round(int(3.0/2.54*printdot))+firstleft,<br>
  y+firsttop+round(int(0.5/2.54*printdot)));<br>
  myprint[pc_count]^.atitle:=Lname.<br>
  caption+DBname.text;<br>
  ACanvas.MoveTo(myprint[pc_count]^.<br>
  currect.left,<br>
  myprint[pc_count]^.currect.top-round<br>
  (rowheight/5));<br>
  {下面的四行还要重复100多次,基本差不多,<br>
  就不都写出来赚稿费了}<br>
  inc(pc_count); new(myprint[pc_count]);<br>
  myprint[pc_count]^.currect:=scalerect(<br>
  myprint[pc_count-1]^.currect,round(int<br>
  (2.5/2.54*printdot)),0);<br>
  myprint[pc_count]^.atitle:=Lxb.caption+Cxb.text;<br>
  ACanvas.LineTo(myprint[i]^.currect.right, <br>
  myprint[i]^.currect.top-round(rowheight/5));<br>
  .......</p>
<p> {打印}<br>
  printtitle(acanvas); <br>
  {这个函数就不提供了,表头不要也没关系}<br>
  for i:=1 to pc_count do<br>
  begin<br>
  RectDraw(Acanvas,myprint[i]^.atitle,<br>
  myprint[i]^.currect,false,<br>
  dt_left or dt_singleline or dt_vcenter);<br>
  end;<br>
  dispose(myprint[pc_count]); <br>
  {别忘了把指针占用的内存释放}<br>
  end;</p>
<p>---- 最后建个Botton,加个是否真的打印的判断,再调用这几个函数就行了。 <br>
  ---- (调用格式:printtitle(printer.canvas);) </p>
<p>---- 看了以上两个例子,是不是觉得WINDOWS下的打印其实很简单,就跟你手工画表一样,而且表格内容的位置是居中、居左、还是居右,全由打印内容的Alignment决定,打印格式由内容的Display 
  Format决定,用不着自己去算,方便极了。 </p>
<br>
<div align="center" class="font9"><span class="font9">『Site:<a href="../index.html" target="_top">delphi爱好者</a> 
  | E-mail:<a href="mailto:delphifan@990.net%20">delphifan@990.net </a>| Webmaster:<a href="../aboutme.htm" target="_top">梁 
  明</a>』</span> <br>
  <span class="font9">---------------------------------------------------------------------------</span> 
</div>
<div align="center"> </div>
<div align="center"> 
  <input type="button" value="返 回" onClick="history.go( -1 );return true;" name="button">
</div>
<!-- #EndEditable --> 
</BODY>
<!-- #EndTemplate -->
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -