程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 用delphi編寫醫院的復雜報表

用delphi編寫醫院的復雜報表

編輯:Delphi
我院的信息管理系統采用delphi編程,由於各科要求不同,報表形式也多種多樣,編寫起來讓人頭痛。Delphi運行在Windows平台下,打印同DOS下完全不同,而Quick Report即難以控制又占用資源,對於一個稍復雜的、有特殊要求的報表,Quick Report無法實現。這裡介紹幾個在編程中遇到的比較典型的報表的實現方法。

  ---- 1、哪個單位的財務科都有幾本厚厚的台帳,我院財務科提出打印藥庫的台帳,好脫掉手工帳,也算是辦公現代化了,要求合情合理,院長也說應當如此。看著財務科提供的紅綠相間的、統一印制的、行間距3毫米的台帳專用小卡片,我不由想到中國人節儉的美德。考慮到每個藥品至少打印一張,而且表格線一個都不能少,加上中醫院藥品有二千多種,所以這個報表必須用激光打印機來打印(至於如何讓院長同意購買激光打印機,則是另一回事,辦公自動化哪能沒有代價呢)。程序實現的思路基本上是把打印紙當做畫布在上面畫一個個小矩形,具體由以下幾個過程實現:(設Form名為TtzvIEw)。

  先在程序中定義二個類:
  titlerecord=record
  Currect:Trect;
  Atitle:string;
  end;
  detailrecord=record
  Arect:Trect;
  alignment:Word;
  end;

  ---- 再建立以下四個過程;
  ---- RectDraw(Acanvas:Tcanvas;s:string;R:Trect;frame:boolean;position:Word);

  ---- 這個過程就是畫矩形用的,frame決定是否畫線(這裡當然要畫啦!);

  ---- printinitit(firsttop,firstleft:integer);

  ---- 這個過程是初始化用的,就是定義各個小矩形在紙上的位置;

  ---- printtitle(acanvas:Tcanvas);

  ---- 這個過程是打印表頭的,因為表頭的字總是要大一些;

  ---- printdetail(acanvas:Tcanvas;Qtz:Tdataset;acount:integer;firstpage:integer);

  ---- 這個過程才是打印具體內容的,一頁打印40行,不夠就換頁,總之一頁只能是一個藥品;

  ---- printhj(acanvas:Tcanvas);

  ---- 一看就知道,這個過程就是打印合計的啦!

  ---- 只要建個Botton,順序調用printinitit,printtitle,printdetail,printhj這四個過程就行了,

  ---- (調用格式:printtitle(printer.canvas);)

  ---- 對了,Qtz就是查詢出來的台帳數據,如何生成的這裡就不談了。

  ---- 具體程序如下

  ---- 此程序在delphi1,Delphi3版本WIN3.2,WIN95,WIN97,WIN98平台下運行通過,順便提供台帳數據庫的庫結構

  ---- 2、非常復雜,無法取巧的報表

  ---- 我院腫瘤科需要打印病人的病案,這可是特色專科現代化建設的一部分,衛生局要來檢查的,所以必須完成任務。每一個病案有100多個項目,若用Qreport,中間如果要加減一個項目(這事常有),幾十個項目的調整排列會使人昏倒。我一下子建立100多個臨時變量,在虛擬的畫布上畫啊畫,運行在我的PII233,64M內存的機子上倒是順順當當的,不過換到腫瘤科的486,8M內存的機子上時(大家別笑),系統堆棧馬上溢出,所以只好祭出指針大法(我的編程水平好象又有長進,竊喜),方法如下:

  先建立titleprint類:
  titleprint=^Titlerecord;
  titlerecord=record
  Currect:Trect;
  Atitle:string[50];
  end;
  再建立過程printnow(Form的名稱叫
  zlk,printdot就是打印機的點數,一般針打是180);
  procedure Tzlk.printnow(acanvas:Tcanvas);
  var i,x,y,pc_count:integer;
  myprint:array[0..200] of titleprint;
  begin
  firsttop:=round(int(0.5/2.54*printdot));
  firstleft:=round(int(0.1/2.54*printdot));
  rowheight:=round(int(0.7/2.54*printdot));
  x:=0+firstleft;y:=round(int
  (1.3/2.54*printdot))+firsttop;
  pc_count:=0;
  inc(pc_count); new(myprint[pc_count]);
  myprint[pc_count]^.currect:=rect
  (x+round(int(0.1/2.54*printdot))+firstleft,y,
  x+round(int(3.0/2.54*printdot))+firstleft,
  y+firsttop+round(int(0.5/2.54*printdot)));
  myprint[pc_count]^.atitle:=Lname.
  caption+DBname.text;
  ACanvas.MoveTo(myprint[pc_count]^.
  currect.left,
  myprint[pc_count]^.currect.top-round
  (rowheight/5));
  {下面的四行還要重復100多次,基本差不多,
  就不都寫出來賺稿費了}
  inc(pc_count); new(myprint[pc_count]);
  myprint[pc_count]^.currect:=scalerect(
  myprint[pc_count-1]^.currect,round(int
  (2.5/2.54*printdot)),0);
  myprint[pc_count]^.atitle:=Lxb.caption+Cxb.text;
  ACanvas.LineTo(myprint[i]^.currect.right,
  myprint[i]^.currect.top-round(rowheight/5));
  .......

  {打印}
  printtitle(acanvas);
  {這個函數就不提供了,表頭不要也沒關系}
  for i:=1 to pc_count do
  begin
  RectDraw(Acanvas,myprint[i]^.atitle,
  myprint[i]^.currect,false,
  dt_left or dt_singleline or dt_vcenter);
  end;
  dispose(myprint[pc_count]);
  {別忘了把指針占用的內存釋放}
  end;

  ---- 最後建個Botton,加個是否真的打印的判斷,再調用這幾個函數就行了。
  ---- (調用格式:printtitle(printer.canvas);)

  ---- 看了以上兩個例子,是不是覺得Windows下的打印其實很簡單,就跟你手工畫表一樣,而且表格內容的位置是居中、居左、還是居右,全由打印內容的Alignment決定,打印格式由內容的Display Format決定,用不著自己去算,方便極了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved