แสดงกระทู้

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - manoi

หน้า: 1 ... 5 6 [7]
301
ยินดีต้อนรับ / Harddisk เครื่อง server พัง
« เมื่อ: ตุลาคม 13, 2006, 09:13:53 AM »
ขออภัยที่ต้องหยุดให้บริการ hosxp.net ช่วงเวลา 17.00 - 22.30 น. วันที่ 12 ต.ค. 49 เนื่องจาก harddisk ตัวเดิมมีปัญหา (bad sector) ต้องเปลี่ยนตัวใหม่ครับ

302
Development / บริการใหม่ Bittorrent download
« เมื่อ: ตุลาคม 12, 2006, 10:36:13 AM »
ที่ http://hosxp.net/mediawiki/index.php?title=HOSxP_Wiki:Torrent_Download ครับ

ศึกษาการใช้งาน Bittorrent ได้ที่ http://www.pantip.com/tech/software/topic/SA2022522/SA2022522.html

303
โค๊ด: Delphi
  1.  
  2.  
  3. Unit Script;
  4.  
  5. const
  6.  
  7.  
  8.  
  9.   dbf_path = 'd:\statwin\';
  10.  
  11.   HoursPerDay   = 24;
  12.   MinsPerHour   = 60;
  13.   SecsPerMin    = 60;
  14.   MSecsPerSec   = 1000;
  15.   MinsPerDay    = HoursPerDay * MinsPerHour;
  16.   SecsPerDay    = MinsPerDay * SecsPerMin;
  17.   MSecsPerDay   = SecsPerDay * MSecsPerSec;
  18.  
  19. function IncTime(ATime: TDateTime; Hours, Minutes, Seconds,
  20.   MSecs: Integer): TDateTime;
  21. begin
  22.   Result := ATime + (Hours div 24) + (((Hours mod 24) * 3600000 +
  23.     Minutes * 60000 + Seconds * 1000 + MSecs) / MSecsPerDay);
  24.   if Result < 0 then
  25.     Result := Result + 1;
  26. end;
  27.  
  28. function IncHour(ATime: TDateTime; Delta: Integer): TDateTime;
  29. begin
  30.   Result := IncTime(ATime, Delta, 0, 0, 0);
  31. end;
  32.  
  33. function IncMinute(ATime: TDateTime; Delta: Integer): TDateTime;
  34. begin
  35.   Result := IncTime(ATime, 0, Delta, 0, 0);
  36. end;
  37.  
  38. function IncSecond(ATime: TDateTime; Delta: Integer): TDateTime;
  39. begin
  40.   Result := IncTime(ATime, 0, 0, Delta, 0);
  41. end;
  42.  
  43.  
  44. function addzero(s:string;i:integer):string;
  45. begin
  46.   //result:=s;
  47.   while length(s)<i do
  48.   begin
  49.     s:='0'+s;
  50.   end;
  51.   result:=s;
  52. end;
  53.  
  54. function CheckPID(pid: string): boolean;
  55. var
  56.   i: integer;
  57.   nMod, nValue, cv: integer;
  58.   snmod: string;
  59. begin
  60.   pid := replacestr(pid, '-', '');
  61.   result := false;
  62.   if length(replacestr(pid, ' ', '')) <> 13 then
  63.     exit;
  64.  
  65.   try
  66.  
  67.     cv := strtoint(copy(pid, 1, 1));
  68.     nValue := cv * 13;
  69.  
  70.     for i := 2 to 12 do
  71.     begin
  72.       cv := strtoint(copy(pid, i, 1));
  73.       nValue := nValue + (cv * (14 - i));
  74.  
  75.     end;
  76.  
  77.     nMod := 11 - (nValue mod 11);
  78.     snmod := inttostr(nmod);
  79.     snmod := copy(snmod, length(snmod), 1);
  80.     result := copy(pid, 13, 1) = snmod;
  81.  
  82.   except
  83.     result := false;
  84.  
  85.   end;
  86.  
  87. end;
  88.  
  89. function MakeFullCID(cid: string): string;
  90. begin
  91.   result := cid;
  92.   if length(cid) = 17 then
  93.     exit;
  94.   result := '';
  95.   if length(cid) <> 13 then
  96.     exit;
  97.   result := copy(cid, 1, 1) + '-' +
  98.     copy(cid, 2, 4) + '-' +
  99.     copy(cid, 6, 5) + '-' +
  100.     copy(cid, 11, 2) + '-' +
  101.     copy(cid, 13, 1);
  102. end;
  103.  
  104.  
  105.  
  106.  
  107.  
  108. Procedure DoImportPatient;
  109. var
  110.   i:integer;
  111.   card_tablename:string;
  112.   ic,ip:integer;
  113.  
  114.   fhn:string;
  115.   cid:string;
  116. begin
  117.  
  118.  
  119.  
  120.   dbf1.close;
  121.   dbf1.tablename:=dbf_path+'data\opd\mainrec.dbf';
  122.   dbf1.open;
  123.  
  124.  
  125.  
  126.   setstatuslabel('Importing... opd patient data');
  127.  
  128.   setcursorbusy(true);
  129.  
  130.   dbf1.first;
  131.   i:=0;
  132.   while not dbf1.eof do
  133.   begin
  134.     i:=i+1;
  135.     dbf1.next;
  136.   end;
  137.  
  138.   setprogressbar(0,i);
  139.  
  140.  
  141.   fcds.close;
  142.   fcds.datarequest('select * from patient');
  143.   fcds.open;
  144.  
  145.   fcds3.close;
  146.   fcds3.datarequest('select * from ptcardno');
  147.   fcds3.open;
  148.  
  149.   dbf1.first;
  150.   ic:=0;
  151.   ip:=0;
  152.  
  153.   DisableReconcileDialog;
  154.  
  155.   while not dbf1.eof do
  156.   begin
  157.     ip:=ip+1;
  158.     setprogressbar(ip,i);
  159.  
  160.     //fhn:=addzero(dbf1.fieldbyname('hn').asstring,7);
  161.     fhn:=dbf1.fieldbyname('hn').asstring;
  162.     ic:=ic+1;
  163.     if (ic mod 25)=0 then
  164.     setstatuslabel('Processing ... '+inttostr(ic)+'/'+inttostr(i));
  165.  
  166.     fcds.insert;
  167.     fcds.fieldbyname('hos_guid').asstring:=get_new_guid;
  168.     fcds.fieldbyname('hn').asstring:=fhn;
  169.     fcds.fieldbyname('pname').asstring:=dbf1.fieldbyname('status').asstrin g;
  170.     fcds.fieldbyname('fname').asstring:=dbf1.fieldbyname('fname').asstring  ;
  171.     fcds.fieldbyname('lname').asstring:=dbf1.fieldbyname('lname').asstring  ;
  172.     try fcds.fieldbyname('birthday').asdatetime:=dbf1.fieldbyname('dob').asdat etime; except end;
  173.     fcds.fieldbyname('sex').asstring:=dbf1.fieldbyname('sex').asstring;
  174.     fcds.fieldbyname('marrystatus').asstring:=dbf1.fieldbyname('marriage') .asstring;
  175.     fcds.fieldbyname('addrpart').asstring:=dbf1.fieldbyname('address').ass tring;
  176.     fcds.fieldbyname('node_id').asstring:='';
  177.     fcds.fieldbyname('road').asstring:=dbf1.fieldbyname('road').asstring;
  178.     fcds.fieldbyname('moopart').asstring:=dbf1.fieldbyname('village').asst ring;
  179.     fcds.fieldbyname('chwpart').asstring:=dbf1.fieldbyname('changwat').ass tring;
  180.     fcds.fieldbyname('amppart').asstring:=dbf1.fieldbyname('amphur').asstr ing;
  181.     fcds.fieldbyname('tmbpart').asstring:=dbf1.fieldbyname('tambon').asstr ing;
  182.     fcds.fieldbyname('po_code').asstring:=dbf1.fieldbyname('zipcode').asst ring;
  183.     fcds.fieldbyname('hometel').asstring:=dbf1.fieldbyname('phone').asstri ng;
  184.     fcds.fieldbyname('religion').asstring:='01';
  185.     fcds.fieldbyname('occupation').asstring:=dbf1.fieldbyname('occupa').as string;
  186.     fcds.fieldbyname('nationality').asstring:=dbf1.fieldbyname('nation').a sstring;
  187.     fcds.fieldbyname('citizenship').asstring:=dbf1.fieldbyname('nation').a sstring;
  188.     //fcds.fieldbyname('bloodgrp').asstring:=dbf1.fieldbyname('bl_gr').ass tring;
  189.     //fcds.fieldbyname('drugallergy').asstring:=dbf1.fieldbyname('dallergy ').asstring;
  190.  
  191.     cid:='';
  192.  
  193.     if checkpid(dbf1.fieldbyname('person_id').asstring) then
  194.        cid:=dbf1.fieldbyname('person_id').asstring;
  195.  
  196.     if cid<>'' then
  197.     begin
  198.  
  199.       fcds.fieldbyname('cid').asstring:=cid;
  200.  
  201.       fcds3.insert;
  202.       fcds3.fieldbyname('hn').asstring:=fhn;
  203.       fcds3.fieldbyname('cardtype').asstring:='01';
  204.       fcds3.fieldbyname('cardno').asstring:=MakeFullCID(cid);
  205.       fcds3.post;
  206.     end;
  207.  
  208.  
  209.  
  210.     fcds.post;
  211.  
  212.  
  213.    if (ip mod 50)=0 then
  214.    begin
  215.      fcds.datarequest('select * from patient limit 0');
  216.      applyupdate_fcds;
  217.  
  218.      fcds3.datarequest('select * from ptcardno limit 0');
  219.      applyupdate_fcds3;
  220.  
  221.    end;
  222.  
  223.    dbf1.next;
  224.   end;
  225.  
  226.   fcds.datarequest('select * from patient limit 0');
  227.   applyupdate_fcds;
  228.  
  229.   fcds3.datarequest('select * from ptcardno limit 0');
  230.   applyupdate_fcds3;
  231.   fcds3.close;
  232.   fcds.close;
  233.   dbf1.close;
  234.  
  235.   setcursorbusy(false);
  236.  
  237. end;
  238.  
  239.  
  240. Procedure Main;
  241. begin
  242.  
  243.  
  244.  
  245.  if messagedlg('Please confirm import'+#13+'patient and ptcardno data will be delete '+#13+
  246.  'Current statwin data path = '+dbf_path,mtconfirmation,[mbyes,mbno],0)=mryes then
  247.  begin
  248.  
  249.    DoImportPatient;
  250.  
  251. end;
  252.  
  253. end;
  254.  
  255. end.
  256.  
  257.  

304
Delphi / Pascal / Database development with Turbo Delphi Part I
« เมื่อ: กันยายน 24, 2006, 19:55:54 PM »
เพิ่งมีเวลาว่างมานั่งเขียนการพัฒนา Software ด้วย Turbo Delphi ครับ หัวข้อนี้สำหรับผู้ที่ต้องการศึกษาการใช้ Turbo Delphi ทำงานกับ Database โดยเฉพาะครับ

ปัจจุบัน Tools ที่ใช้ในการพัมฒนา Software มีการแข่งขันกันค่อนข้างสูงมาก ทำให้ Borland ที่เคยเป็นผู้นำในเรื่องของ RAD Tools จึงต้องเปลี่ยนกลยุทธ์ในการขายใหม่  โดยออก Delphi มา 2 รุ่น คือ Turbo Delphi Professional และ Turbo Delphi Explorer  โดยในแต่ละรุ่น ก็จะมี Compiler 4 ชนิด แยกเป็น Delphi for .Net, C#, C++ และ Delphi for Win32  และจำกัดการติดตั้งได้เพียง 1 ชนิดต่อ 1 เครื่อง (จะลง Turbo Delphi for C# และ Turbo Delphi for Win32 ในเครื่องเดียวกันไม่ได้)  และที่สำคัีญ Turbo Delphi Explorer เป็น Freeware ที่มีความสามารถเหมือนกับรุ่น Professional ต่างกันก็แค่ไม่สามารถติดตั้ง Component เพิ่มได้ และสามารถนำมาใ้ช้งานพัฒนา Commercial Application ได้โดยไม่ต้องเสียค่าใช้จ่ายใดๆ (แต่ถ้าจะเอามาทำ Commercial ผมแนะนำให้ซื้อ Turbo Delphi Professional ดีกว่าครับ ราคาประมาณ $499 )

และเนื่องจาก HOSxP ถูกพัฒนามาด้วย Delphi  แต่มีการใช้งาน 3rd party component ค่อนข้างเยอะมาก ดังนั้นจึงเป็นโอกาศอันดี หากจะนำ Source Code มาปรับปรุงใหม่ ให้สามารถใช้ Turbo Delphi Explorer พัฒนาได้ และใช้เฉพาะ GPL Component เพื่อที่ว่าหากใครอยากจะเข้ามาร่วมด้วยช่วยกันพัฒนา ก็สามารถทำได้โดยง่าย

ถึงแม้ว่า Turbo Delphi Explorer จะจำกัดการติดตั้ง 3rd Component แต่จำกัดเฉพาะในตัว IDE ครับ (ตอน Design) แต่ในขั้นตอนการทำงานสามารถเขียนคำสั่งให้สร้าง Component ที่ต้องการขึ้นมาได้ครับ โดย 3rd Component ที่ HOSxP จำเป็นต้องใช้ ได้แก่

- Zeoslib สำหรับทำหน้าที่เป็น Database Engine เชื่อมต่อกับระบบฐานข้อมูล (MySQL,PostgreSQl,Microsoft SQL, etc) และจัดการข้อมูล  http://zeos.firmos.at/
- DCPCrypt สำหรับทำหน้าที่เข้ารหัสข้อมูลบางอย่าง (เช่น User Password)  http://www.cityinthesky.co.uk/cryptography.html
- Freereport จากผู้ผลิต Fast Report สำหรับสร้างรายงาน http://freereport.sourceforge.net/en/

ในส่วนของ 3rd component ที่จำเป็น ผม upload ไว้ที่ ftp://ftp.hosxp.net/pub/delphi_component

อันดับแรกให้ทำการ Download Turbo Delphi Explorer for Win32 มาติดตั้งในเครื่องก่อนครับ โดย Download ได้จาก http://www.turboexplorer.com   (แนะนำให้ Download file ที่เป็น ISO มา Write CD เพราะจะมีไฟล์ที่จำเป็นมาครบครับ)



หลังจาก Download มาแล้วให้ทำการติดตั้ง .Net Framework 1.1, .Net Framework SDK, msxml, dotNETJSharp (ที่ต้องติดตั้ง .Net เนื่องจาก Tool บางตัวที่มากับ Delphi ถูกพัฒนาขึ้นโดยใช้ C# ครับ เช่น ECO ) จากนั้นก็ติดตั้ง Delphi และจะต้องลงทะเบียนขอ License key มาติดตั้งไว้ในเครื่องครับ (ลงทะเบียน Free  ใช้งานได้ 100 ปี ..... )

พอติดตั้งเสร็จแล้ว ก็ทำการติดตั้ง 3rd Component ที่จำเป็นลงไปครับ (จาก link ด้านบน) และระบุ Path ให้ Delphi ค้นหาแฟ้มที่จำเ็ป็นพบ ไม่อย่างงั้นจะ Compile Project File ไม่ได้ครับ



หลังจากติดตั้ง component เสร็จแล้ว ก็ให้ทำการ Download Turbo HOSxP มาจาก ftp://ftp.hosxp.net/pub/Turbo_HOSxP  ที่ตั้งชื่อ Turbo HOSxP ก็ให้คล้องจองกับ Turbo Delphi Explorer ไงครับ

ในส่วนของ Turbo HOSxP Source Code ผมได้ทำการปรับปรุงให้มี Function ที่จำเป็นในการเชื่อมต่อกับฐานข้อมูลของ HOSxP (ผ่าน zeoslib) และการตรวจสอบรหัสผู้ใช้งาน (ผ่านระบบ Login) มี Splash Screen และ Mainmenu ตัวโปรแกรมมีลักษณะเป็น MDI Application แต่ตอนนี้มีเฉพาะโครงครับ ยังไม่มีระบบงานอะไร

ในการเข้าถึงข้อมูลและจัดการข้อมูล ระบบถูกออกแบบให้ใช้ TClientDataset ครับ ยกตัวอย่างเช่น หากผมต้องการนำข้อมูลจากตาราง pttype มาใช้งาน ก็เพียงแต่เขียน Code ดังนี้

โค๊ด: Delphi
  1. Unit xxxx;
  2. interface
  3. uses .....,...
  4. implementation
  5. uses HOSxPDMU;
  6.  
  7. Procedure Button1Click(Sender:TObject);
  8. var TC : TClientDataset;
  9. begin
  10.  
  11.   TC := TClientDataset.Create(nil);
  12.   TC.Data := HOSxP_GetDataset('select * from pttype');
  13.   while not TC.eof do
  14.   begin
  15.    showmessage(TC.fieldbyname('name').asstring);
  16.    TC.next;
  17.   end;
  18.   TC.free;
  19.  
  20. end;
  21.  

จากตัวอย่าง การนำข้อมูล (ผลจากคำสั่ง SQL) มาเก็บไว้ที่ TClientDataset จะผ่าน Function HOSxP_GetDataset(sql)  ครับ (ง่ายดีไหม)  อยากได้อะไรก็ดึงมาเลยครับ

หากมีการแก้ไขข้อมูลใน TClientDataset และต้องการ Update ไปยัง Database ก็เพียงแต่เรียกใช้ Function HOSxP_UpdateDelta ครับ ดังตัวอย่าง

 
โค๊ด: Delphi
  1. Unit xxxx;
  2. interface
  3. uses .....,...
  4. implementation
  5. uses HOSxPDMU;
  6.  
  7. Procedure Button1Click(Sender:TObject);
  8. var TC : TClientDataset;
  9. begin
  10.  
  11.   TC := TClientDataset.Create(nil);
  12.   TC.Data := HOSxP_GetDataset('select * from pttype');
  13.   while not TC.eof do
  14.   begin
  15.    TC.edit;
  16.    TC.fieldbyname('name').asstring := 'New Name';
  17.    TC.post;
  18.    TC.next;
  19.   end;
  20.  
  21.   if TC.changecount > 0 then
  22.      HOSxP_UpdateDelta(TC.delta,'select * from pttype');
  23.  
  24.   TC.free;
  25.  
  26. end;
  27.  

ใน Function HOSxP_UpdateDelta จะต้องระบุ Delta packet และ คำสั่งเดิมที่ดึงข้อมูลมาครับ 

Project ที่ Compile แล้วอยู่ที่นี่ครับ ftp://ftp.hosxp.net/pub/Turbo_HOSxP/Turbo_HOSxP.exe

To be continue ....

305
การเขียน SQL Script / ฝากให้คุณ sompas รพ. ลพบุรีครับ
« เมื่อ: กันยายน 22, 2006, 00:32:00 AM »
script นำเข้าข้อมูล CSCD Member DBF มา update ในตาราง patient ครับ ให้แก้ไขบรรทัด

dbf.tablename:='O:\CSCDMEM.DBF';

โดยเปลี่ยน O:\CSCDMEM.DBF ให้เป็น ที่อยู่ของแฟ้มข้อมูลจริงๆ ครับ

306
ยินดีต้อนรับ / ขออภัยที่หายไปนาน
« เมื่อ: กันยายน 17, 2006, 05:01:46 AM »
ผมต้องขออภัยสมาชิกทุกท่านด้วยครับ ที่หายหน้าหายตาไปนาน เนื่องจากอาทิตย์นี้ทั้งอาทิตย์ ติดภาระกิจที่ รพศ.มหาราช จ.นครศรีธรรมราช ครับ กว่าจะขึ้นระบบได้ก็เหนื่อยแสนเหนี่อยครับ มีปัญหาให้แก้กันทั้งวัน ทั้ง hardware และ software และข้อมูลปริมาณมหาศาลที่เกิดขึ้นทุกวัน (ข้อมูลเก่า เฉพาะรายการยา OPD ก็ 3M  ส่วนรายการยา IPD ประมาณ 10M)   ที่นี่มีผู้ป่วยนอกมารับบริการเฉลี่ยวันละ 1,500 - 2,200 คนครับ เปิดใช้งานทุกระบบพร้อมๆ กัน ได้แก่ เวชระเบียน + จุดซักประวัติ + ห้องจ่ายยา(OPD+IPD) + ห้องชำระเงิน(OPD+IPD) + หน่วยจัดเก็บรายได้ (opd+ipd)   มี Online Work station ประมาณ 170 เครื่อง

วันแรกที่เริ่มขึ้นระบบเครื่อง Server hang ไป 3 ครั้ง วันที่สอง ดีขึ้นหน่อยครับ hang แค่ครั้งเดียว ส่วนวันที่สาม (วันนี้)เป็นวันเสาร์ (ข้อมูลยังไม่เยอะ) ยังไม่มีปัญหาใดๆ  (ใช้ยาแก้ไอไป 3 ขวด , Augmentin 30 เม็ด, Dextromethorphan 10 เม็ด, Paracetamol 20 เม็ด....)

ตอบขอบคุณ คุณวัชรินทร์ ( admit รพ.ขนอม)  , คุณพงษ์นที (admit รพ.ถ้าพรรณรา) , คุณมนชัย (admit รพ.ท่าศาลา)  ที่อุตสาห์เข้ามาช่วยเป็น staff ขึ้นระบบ  และคุณหมอสุธี และคุณจรเข้หนุ่ม ที่คอยช่วยเหลือ ประสานงานและอำนวยความสะดวกให้กับทีมงานครับ

 (เสร็จงานนี้ผมว่าจะขอลาพักร้อนสัก 3 เดือนเลย)

307
ใช้คำสั่งนี้ครับ

โค๊ด: SQL
  1. DROP TABLE incith_adjust
  2.  

และ

โค๊ด: SQL
  1. CREATE TABLE incith_adjust ("incith_adj_id" INTEGER NOT NULL );
  2. ALTER TABLE incith_adjust ADD "an" VARCHAR(9) NULL
  3. ALTER TABLE incith_adjust ADD "income" VARCHAR(2) NULL
  4. ALTER TABLE incith_adjust ADD "sum_income" FLOAT NULL
  5. ALTER TABLE incith_adjust ADD "adjust_amount" FLOAT NULL
  6. ALTER TABLE incith_adjust ADD "debt_amount" FLOAT NULL
  7. ALTER TABLE incith_adjust ADD "paid_amount" FLOAT NULL
  8. ALTER TABLE incith_adjust ADD "sum_paidst_01" FLOAT NULL
  9. ALTER TABLE incith_adjust ADD "sum_paidst_02" FLOAT NULL
  10. ALTER TABLE incith_adjust ADD "sum_paidst_03" FLOAT NULL
  11.  

เรียกใช้งานใน SQL Query analyzer นะครับ ใน MSSQL Enterprise Manager

308
Development / Turbo Delphi
« เมื่อ: กันยายน 06, 2006, 17:52:24 PM »
Free version ออกให้ Download แล้วครับ

http://www.turboexplorer.com/downloads

download เสร็จเืมื่อไรผมจะมาเขียน review ให้ดูครับ :)

309
การเขียน SQL Script / การใช้ Variable ช่วยทำรายงาน Part I
« เมื่อ: กันยายน 04, 2006, 07:05:51 AM »
มาดูวิธีการใช้ variable ช่วยทำรายงานครับ ปกติรายงานต่างๆ สามารถใช้คำสั่ง SQL ดึงข้อมูลมาจัดรูปแบบในระบบรายงานได้อยู่แล้ว แต่มีบางกรณีที่วิธีการปกติทำไม่ได้หรือทำได้แต่ใช้เวลานานครับ ยกตัวอย่างเช่น รายงานสรุปยอดการใช้ยาทุกตัวในปี 2548  แยกจำนวนใบสั่ง และ มูลค่า โดยต้องการแสดงผลลัพท์ดังนี้

-----------------------------------------
รหัส |  ชื่อ  | จำนวนใบสั่ง  | มูลค่า
-----------------------------------------

สำหรับคนที่เข้าใจ datadictionary และเขียนคำสั่ง SQL ได้คงจะยิ้มแล้วนึกในใจว่าหมูมาก แค่เขียนคำสั่งดังนี้

โค๊ด: SQL
  1. SELECT i.icode,i.name,i.strength,i.units,COUNT(DISTINCT o.vn) AS prescribe_count,COUNT(o.icode) AS item_count, SUM(o.qty) AS sum_qty,SUM(o.sum_price) AS tot_price
  2. FROM drugitems i
  3. LEFT OUTER JOIN opitemrece o ON o.icode = i.icode
  4. WHERE o.rxdate BETWEEN '2005-01-01' AND '2005-12-31'
  5. GROUP BY i.icode,i.name,i.strength,i.units
  6.  

ก็เอาไปทำรายงานได้แล้ว  แต่ปัญหาก็คือหากข้อมูลที่นำมาใช้ทำรายงานมีจำนวนเยอะมาก ระยะเวลาที่ใช้ทำรายงานก็จะนานมากเช่นเดียวกัน นั่งรอ 3 ชั่วโมง ยังไม่ได้รายงานเลย (ถาม อ.สุชัย ดูก็ได้ครับ นั่งรอทั้งคืนก็ยังไม่เสร็จ) 

ถ้างั้นลองเปลี่ยนคำสั่งด้านบนให้ดึงรายงานของยาแค่ตัวเดียวมาก่อน ด้วยคำสั่งนี้

โค๊ด: SQL
  1. SELECT i.icode,i.name,i.strength,i.units,COUNT(DISTINCT o.vn) AS prescribe_count,COUNT(o.icode) AS item_count, SUM(o.qty) AS sum_qty,SUM(o.sum_price) AS tot_price
  2. FROM drugitems i
  3. LEFT OUTER JOIN opitemrece o ON o.icode = i.icode
  4. WHERE o.icode='1470038' AND o.rxdate BETWEEN '2005-01-01' AND '2005-12-31'
  5. GROUP BY i.icode,i.name,i.strength,i.units
  6.  


ลองเอาไป run ดูใหม่ ปรากฎว่าใช้เวลาแค่อึดใจเดียวก็ได้ผลแล้ว แต่มันได้มาแค่ยาตัวเดียว มันไม่มาทั้งหมด ครั้นจะเอาไป copy แล้วเรียกใช้งานกับยาทุกตัว ก็คงจะไม่สะดวก สู้นั่งรอเหมือนเดิมดีกว่า

แล้วมาดูว่า Variable จะช่วยแก้ปัญหานี้ได้อย่างไร เริ่มต้นจากเปลี่ยนคำสั่งให้แสดงแค่ข้อมูลยาทุกตัวก่อน แล้วค่อยไปคำนวนจำนวนในระบบรายงานครับ โดยการเปลี่ยนคำสั่งที่ใช้ทำรายงานเป็นแบบ simple ๆ แบบนี้

โค๊ด: SQL
  1. SELECT icode,name,strength,units FROM drugitems ORDER BY name
  2.  

310
การเขียน SQL Script / Hello world กับ Pascal Script
« เมื่อ: กันยายน 04, 2006, 04:07:53 AM »
เพิ่งจะมีเวลาว่างครับ ก็เลยมานั่งเขียน ตัวอย่างการเขียนโปรแกรมด้วย Pascal Script ที่อยู่ใน HOSxP ดัดแปลงมาจากที่นี่ครับ http://www.delphibasics.co.uk/Article.asp?Name=FirstPgm

เป็น Script ที่มีปุ่มให้ผู้ใช้กดและจะแสดงข้อความ Hello World ครับ
ตัว Pascal Script Interpreter ที่มากับ HOSxP จะเรียกใช้ Procedure Main ใน Script ครับ ดังนั้นทุก Script จึงต้องมี Procedure Main ครับ

โค๊ด: Delphi
  1. // comment hello world script for hosxp
  2. // ชื่อ Unit จะตั้งเป็นอะไรก็ได้ ลงท้ายด้วยเครื่องหมาย เซมิโคล่อน
  3. Unit Script;  
  4.  
  5. // การประกาศตัวแปร ใช้คำว่า var  ตัวอย่างด้านล่างเป็นการประกาศตัวแปรชนิด TButton ,TLabel และ TForm โดยใช้ชื่อว่า Button1, Label1 และ Form1
  6. var
  7.   Button1 : TButton;
  8.   Label1 : TLabel;
  9.   Form1 : TForm;
  10.  
  11. Implementation
  12.  
  13. // กำหนด Procedure ชื่อ Button1Click สำหรับทำงานเมื่อมีการกดปุ่ม Button1
  14.  
  15. Procedure Button1Click(Sender : TObject);
  16. begin
  17.   Label1.caption := 'Hello World';
  18. end;
  19.  
  20. Procedure Main;
  21.  
  22. begin
  23.  
  24.   Form1 := TForm.create(nil);
  25.   Form1.Top := 100;
  26.   Form1.Left := 200;
  27.   Form1.Width := 400;
  28.   Form1.Height := 400;
  29.  
  30.   Button1 := TButton.create(Form1);
  31.   Button1.parent := Form1;
  32.   Button1.left:=100;
  33.   Button1.top:=50;
  34.   Button1.caption:='Click me';
  35.   Button1.OnClick := Button1Click;  // กำหนด Event เมื่อผู้ใช้เมาส์คลิกปุ่ม จะเรียกใช้งาน Procedure Button1Click ด้านบน
  36.  
  37.   Label1 := TLabel.create(Form1);
  38.   Label1.parent := Form1;
  39.   Label1.top:=55;
  40.   Label1.left:=200;
  41.   Label1.caption:='---';
  42.  
  43.   Form1.ShowModal;  // แสดง Form1 แบบ Modal Form
  44.  
  45.   Form1.Free;
  46. end;
  47. end.
  48.  
  49.  
  50.  
  51.  

311
Development / Print server utility
« เมื่อ: กันยายน 03, 2006, 19:18:50 PM »
Print server สำหรับเรียกใช้งานนอกโปรแกรม HOSxP ครับ  นอกจากจะทำหน้าที่เป็น Sticker Print Server แล้วยังทำหน้าที่เป็น Print server สำหรับพิมพ์ใบสั่งยาได้ด้วยครับ (กำหนดให้พิมพ์จากห้องตรวจแพทย์)

ftp://ftp.hosxp.net/pub/tools/HOSxP_PrintServer.zip

312
MySQL / HOSxP MySQL Server Upgrade Utility
« เมื่อ: กันยายน 02, 2006, 12:41:43 PM »
ผมได้พัฒนาโปรแกรมช่วย upgrade mysql server สำหรับ รพ. ที่มีข้อมูลเยอะมากๆ และต้องการ upgrade server หลัก โดยที่ไม่ต้องหยุดทำงานครับ โดยการใช้ Standby server เข้ามาทำหน้าที่แทน server หลัก และหลังจากที่ทำกาีร upgrade server หลักเสร็จแล้ว ก็นำ transaction log จาก standby server เข้ามาเก็บไว้ที่ server หลักครับ แต่เดิมผมจะทำด้วยมือ แต่เนื่องจากมีกระบวนการทำงานค่อนข้างซับซ้อน  ก็เลยทำเป็นโปรแกรมช่วยครับ

download ได้จากที่นี่ ftp://ftp.hosxp.net/pub/tools/HOSxP_Server_Upgrade_Helper.zip

มีขั้นตอนทั้งหมด 5 ขั้นตอนครับ
1. Transfer ข้อมูลจาก master server -> standby server
2. นำข้อมูลที่เกิดขึ้นในระหว่าง Transfer มาเก็บไว้ที่ Standby server
3. เปลี่ยน IP address ของ standby server -> master server และเปลี่ยน IP address ของ master server เป็น IP อื่น
4. ทำการ Upgrade master server
5. เปลี่ยน IP Address กลับมาเหมือนเดิม และ นำข้อมูลที่เกิดขึ้นใน standby server -> master server

313
Development / มีอะไรใหม่ใน 2.49.8.30
« เมื่อ: สิงหาคม 31, 2006, 19:31:18 PM »
อย่างแรก ระบบค้นหาข้อมูล (Drug Search) โดยใช้ Local search (SQLite) เพื่อช่วยลด Server Workload กำหนดได้ที่หน้าจอตั้งค่าการเชื่อมต่อครับ  (หลังจากกำหนดแล้วในการเข้าใช้งานครั้งแรกจะทำการ synchronize ข้อมูลจากเครื่อง server มายัง localhost จะใช้เวลาสักครู่ จากนั้นครั้งต่อๆ ไปจะเร็วขึ้นครับ)

การใช้ Local Search จะช่วยให้บางหน้าจอทำงานได้เร็วขึ้นครับ โดยเฉพาะระบบการสั่งจ่ายยา ที่จะทำการค้นหารายการยาจากเครื่องตนเอง ทำให้การแสดงข้อมูลทำได้เร็วขึ้น และยังเป็นการลดภาระการทำงานของเครื่อง Server ด้วยครับ

314
Development / 2.49.8.29
« เมื่อ: สิงหาคม 30, 2006, 21:17:24 PM »
ออกให้ download แล้วครับ (ขออภัยที่ล่าช้าครับ เื่นื่องจากใช้เวลา upload นานกว่าเดิม)

315
สำหรับผู้ที่เพิ่งจะเข้ามาใหม่ จะเห็นว่าหน้าตาของ hosxp.net ได้ถูกแปลงโฉมใหม่นะครับ แต่อาจจะรู้สึกรำคาญหรือไม่ชอบกับโทนสีแดง และขนาดของการแสดงผลที่แสดงค่อนข้างแคบ มีวิธีการแก้ไขดังรูปครับ

1. คลิกที่ปุ่มมุมบนขวา เพื่อขยายขนาดการแสดงผล
2. เลือกสีที่ต้องการ (แนะนำสีน้ำเงินครับ สบายตาดี)

316
แจ้งข้อผิดพลาดการทำงานของ HOSxP V3 / 2.49.8.24
« เมื่อ: สิงหาคม 25, 2006, 04:32:22 AM »
มี bug นิดหน่อยครับ บางหน้าจอจะแสดง dialog แสดง error ขึ้นมา (แต่จะทำงานได้) ครับ (ผมลืมปิดไป)

317
Development / ฝากให้ อ.ทวีทองครับ
« เมื่อ: สิงหาคม 23, 2006, 21:27:16 PM »
ผมได้ export ข้อมูลจากตาราง icd10 และ icd9 เป็น excel และบีบเป็น zip file แนบมาให้แล้วครับ

318
Development / มีอะไรใหม่ใน 2.49.8.18
« เมื่อ: สิงหาคม 20, 2006, 21:28:46 PM »
ใน version 2.49.8.18 สิ่งที่ได้รับการปรับปรุงคือระบบการตรวจสอบสิทธิ NHSO online ครับ แต่เดิมระบบจะตรวจสอบสิทธิและแสดงข้อมูลสิทธิปัจจุบันขึ้นมา แต่ใน 2.49.8.18 จะนำสิทธิที่ได้ตรวจสอบมาใส่ในช่องสิทธิการรักษาด้วยครับ

319
ยินดีต้อนรับ / ฝากให้ รพ.สอง เรื่อง Iptables
« เมื่อ: สิงหาคม 20, 2006, 21:14:01 PM »
ตามที่ผมรับปากไว้ว่าจะส่งคู่มือให้ แต่เนื่องจากผมมีแต่ text book และเนื่อหาในเรื่อง iptables อ่านดูแล้วไม่ค่อยละเอียดเท่าไร จึงส่งเป็น link ไปยังเรื่องเกี่ยวกับ iptables ที่เป็นภาษาไทยมาให้แทนครับ ผมลองอ่านดูแล้วใช้ได้เลยครับ น่าจะตรงกับที่ต้องการ

http://www.thaicert.nectec.or.th/paper/firewall/iptables.php
http://www.itwizard.info/technology/linux/gateway_firewall_iptables.html
http://www.itwizard.info/technology/linux/short_iptables_nat.html

320
แบบฟอร์มใบสั่งยาห้องตรวจแพทย์ แยกหมวดค่าใช้จ่าย

นำไป import ทับได้เลยครับ

321
ฉลองขึ้นบ้านใหม่ที่ Chat room นะครับ (ปุ่ม chat มุมบนขวา)   8)

ผม Online ทั้งคืนครับ

322
การเขียน SQL Script / Pascal Script for Fun Part I
« เมื่อ: สิงหาคม 16, 2006, 01:33:26 AM »
ในการเขียน Script นอกจากจะเขียนเป็น Script ให้ทำงานตามที่สั่งได้แล้ว ยังสามารถออกแบบให้สามารถติดต่อกับผู้ใช้งานโดยใช้ Standard VCL Component ได้ด้วย แต่เนื่องจากระบบ Script ไม่มีระบบ IDE ที่จะออกแบบหน้าจอ ดังนั้นจึงต้องใช้วิธีนำ component มาใช้โดยการเขียน Code มาดูตัวอย่างครับ

โค๊ด: Pascal
  1. Unit Script;
  2.  
  3. var MyForm : TForm;
  4.     OKButton : TButton;
  5.  
  6.  
  7. Implementation
  8.  
  9.  
  10. Procedure OKButtonClick;
  11. begin
  12.   MyForm.close;
  13.  
  14. end;
  15.  
  16. Procedure InitilizeForm;
  17. begin
  18.  
  19.   MyFORM:=TForm.create(nil);
  20.   MyForm.top:=100;
  21.   MyForm.left:=100;
  22.  
  23.   OKButton:=TButton.Create(MyForm);
  24.   OKButton.parent:=MyForm;
  25.   OKButton.Caption:='OK';
  26.   OKButton.left:=10;
  27.   OKButton.top:=10;
  28.  
  29.   OKButton.OnClick:=OkButtonClick;
  30.  
  31. end;
  32.  
  33.  
  34. Procedure Main;
  35. var
  36.   i:integer;
  37. begin
  38.   InitilizeForm;
  39.   MyForm.showmodal;
  40.   MyForm.free;
  41. end;
  42.  
  43.  
  44.  
  45.  
  46.  
  47. end.
  48.  
  49.  
  50.  

หน้า: 1 ... 5 6 [7]