BMS-HOSxP Community

HOSxP => แจ้งปัญหา / ขอความช่วยเหลือ => ข้อความที่เริ่มโดย: ~ L~ อิสระเสรี ~ L~ ที่ กุมภาพันธ์ 24, 2010, 08:48:13 AM

หัวข้อ: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ กุมภาพันธ์ 24, 2010, 08:48:13 AM
ขอรับคำแนะนำการเขียนคำสั่ง วนลูป ใน Report Disiner ในช่วงที่ออกรายงานด้านในอ่าครับ เรื่องของเรื่องคือว่า ER ต้องการรายงาน สรุปสาเหตุการบาดเจ็บ 19 สาเหตุ แยกรายตำบล และแยกหมู่บ้าน อันที่มีในหน้ารายงานหลักมันไม่ตอบสนองความต้องการของแพทย์ผู้ขอรายงานได้ แต่เนื่องจากผมไม่เข้าใจ การเขียนสคลิป จึงคิดว่าจะเขียนใน Valiable หรือ Events แทน แต่ติดที่การวนลูป รับค่าตัวเลขหมู่บ้านครับ ที่สำคัญ แต่ละตำบล มีหมู่บ้านไม่เท่ากัน แต่ที่ต่อรองได้คือให้ 1 ตำบลต่อ 1 หน้ากระดาษ ตอนนี้ที่ทำไปแล้วคือ การเลือกตำบล แต่ยังเขียนคำสั่งรับค่าตัวเลขหมู่บ้านไม่ได้ครับ ไม่ทราบว่าพอจะแนะนำวิธีเขียนคำสั่ง วนลูปใน Report Disiner ว่าเขียนกันยังไงหน่อยนะครับผมมองไม่เห็นภาพเลยอ่าครับ คิดวิธีการได้แต่ทำไม่ได้ครับ รบกวนด้วยนะครับ ขอบคุณล่วงหน้าครับ ??? ??? ???

ปล.ขอคำสั่งแบบชัดเจนนะครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: udomchok ที่ กุมภาพันธ์ 24, 2010, 11:07:34 AM
มีของท่าน Neo ทำไว้แล้วครับ ลองค้นหาดูก่อนนะครับ

แต่ถ้าจะเอาแบบเลือกตำบลได้ (ไม่เลือกจะแสดงทั้งหมด) ...ค้นด้วยคำว่า Person-sreach ดูนะครับ ผมทำเอาไว้ลักษณะแบบนี้ อันนี้ต้องไปประยุกต์หน่อยครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ กุมภาพันธ์ 24, 2010, 11:53:01 AM
มีของท่าน Neo ทำไว้แล้วครับ ลองค้นหาดูก่อนนะครับ

แต่ถ้าจะเอาแบบเลือกตำบลได้ (ไม่เลือกจะแสดงทั้งหมด) ...ค้นด้วยคำว่า Person-sreach ดูนะครับ ผมทำเอาไว้ลักษณะแบบนี้ อันนี้ต้องไปประยุกต์หน่อยครับ

ขอบคุณมากนะครับ เดี๋ยวหาก่อนนะครับ

ปล.ขอชื่อรายงาน ได้ไหมครับ เพราะมันเยอะมาก ขอบคุณมากครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ กุมภาพันธ์ 25, 2010, 08:11:24 AM
ดันครับ ยังหาตัวช่วยไม่เจอครับ รบกวนด้วยนะครับท่าน อ.ทั้งหลายครับ ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: asawincyber ที่ กุมภาพันธ์ 25, 2010, 08:39:14 AM
http://hosxp.net/index.php?option=com_smf&topic=9163 (http://hosxp.net/index.php?option=com_smf&topic=9163)  ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ กุมภาพันธ์ 25, 2010, 11:48:15 AM
http://hosxp.net/index.php?option=com_smf&topic=9163 (http://hosxp.net/index.php?option=com_smf&topic=9163)  ;D ;D

ขอบคุณมากนะครับ อ.asawincyber แต่ที่ผมต้องการคือการให้มันวนมารับค่า เช่น ตำบล ก. มีหมู่บ้านอยู่ 12 หมู่บ้าน,ตำบล ข. มีหมู่บ้านอยู่ 19 หมู่บ้าน, ตำบล ค. มีหมู่บ้านอยู่ 6 หมู่บ้าน
วิธีคิด
-เลือกตำบล
-ให้รวม ข้อมูลแต่ละสาเหตุ ของแต่ละหมู่บ้าน โดยแยกหมู่
ขั้นตอน (สมมุติ)
- เลือกตำบล ก.
-ก็ให้ทำการ แสดงข้อมูล 19 สาเหตุ ของแต่ละหมู่บ้านออกมา ทั้ง 12 หมู่บ้าน
- เลือกตำบล ข.
-ก็ให้ทำการ แสดงข้อมูล 19 สาเหตุ ของแต่ละหมู่บ้านออกมา ทั้ง 19 หมู่บ้าน
- เลือกตำบล ค.
-ก็ให้ทำการ แสดงข้อมูล 19 สาเหตุ ของแต่ละหมู่บ้านออกมา ทั้ง 6 หมู่บ้าน

วัตถุประสงค์เพื่อ
-แจ้งให้หมู่บ้านที่เกิดอุบัติเหตุ มากที่สุด ทราบและหาวิธีป้องกัน จริงๆแล้ว แพทย์ต้องการข้อมูลว่าเกิดอุบัติเหตุจากหมู่บ้านไหนมากที่สุด มากกว่า แต่ โปรแกรมไม่สามารถระบุได้ว่าเกิดเหตุที่ ไหน (หมู่บ้านไหน?  ตำบลไหน?) ประมาณนี้ครับ

รบกวนด้วยนะครับ ที่สำคัญคือ ผมเขียน สลิปไม่เป็นครับ เข้าไปดูละไม่เข้าใจครับ ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: naj ที่ กุมภาพันธ์ 25, 2010, 11:51:42 AM
"รบกวนด้วยนะครับ ที่สำคัญคือ ผมเขียน สลิปไม่เป็นครับ เข้าไปดูละไม่เข้าใจครับ"
Slip นี้คงไม่ต้องเขียน แค่เอาบัตรไปรูดก็พอครับ ;D ;D ;D ;D ;D ;D
แต่จะช่วยลองเขียนดูครับ  :) :) :)
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: thannawe ที่ กุมภาพันธ์ 25, 2010, 11:56:12 AM
สคริป ครับ ไม่ใช่ สลิป  ;D :D ;D

script  <> slip  ;D :D ;)


ก่อนจะเขียน script ได้ ผมคง สลิฟ(sleep) ก่อน
รอ อ.นาจ ได้เลยครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ กุมภาพันธ์ 25, 2010, 13:28:17 PM
"รบกวนด้วยนะครับ ที่สำคัญคือ ผมเขียน สลิปไม่เป็นครับ เข้าไปดูละไม่เข้าใจครับ"
Slip นี้คงไม่ต้องเขียน แค่เอาบัตรไปรูดก็พอครับ ;D ;D ;D ;D ;D ;D
แต่จะช่วยลองเขียนดูครับ  :) :) :)

ขอบคุณมากครับ อ.naj รบกวนคร้าบ ผมจะเพิ่มความพยายาม และตั้งตารอคอยอ. ครับ ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 03, 2010, 10:03:30 AM
ดันครับ  ;D ;D ยังรอคอยอยู่ครับ อ.naj ตอนนี้ตันสุดๆละครับ มืด 8 ด้านเลย สถานะการณ์ สร้างวีระบุรุษ  ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: redfireball ที่ มีนาคม 03, 2010, 10:09:43 AM
ลองแนบ report ขึ้นมาครับ  ;D ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: champ_db ที่ มีนาคม 03, 2010, 10:42:44 AM
เขียนทั้ง script และ slip ไม่เป็นครับ  ;D
แต่ช่วยดันกระทู้ให้อีกคนครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: E-Hos ที่ มีนาคม 03, 2010, 11:02:28 AM
เขียนทั้ง script และ slip ไม่เป็นครับ  ;D
แต่ช่วยดันกระทู้ให้อีกคนครับ

เห็นด้วยอย่างยิ่ง.. ;D ;D ;D
ดันอีกที
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 03, 2010, 11:28:08 AM
อันนี้ที่ลองทำดูนะครับ มันมั่วได้ใจเลยครับ ตอนนี้เลยหยิบรายงานของฝ่ายอื่นมาปั่นก่อนเพราะทำมาเป็นอาทิตย์แล้วครับไม่เห็นผลอะไรเลย  :'( :'(  แต่จะกลับมาปั่นอีกทีอีก วัน สองวันนี้แหละครับ เคลียร์อันอื่นหมดละ ผมแนบมาให้แล้วนะครับ ที่ผมทำมันยังไม่ได้ระบุหมู่บ้านเลยครับ มั่ว จนจับจุดไม่ได้ละครับ รบกวนด้วยครับ และขอขอบคุณทุกท่านที่ช่วยดันครับ  ;D ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 05, 2010, 11:10:07 AM
ดันครับ  ;D ;D
::) ::)
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: howtodo ที่ มีนาคม 05, 2010, 13:40:34 PM
เลข 1-19 ด้านบนเป็นเลขหมู่ หรือ สาเหตุ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 05, 2010, 20:36:23 PM
เลข 1-19 ด้านบนเป็นเลขหมู่ หรือ สาเหตุ

หมู่บ้านครับ ตอนนี้กำลังพยายามปรับแก้ไขเนื้อหา ประมาณว่า
- เลือกตำบล
-เลือกเลือกวันที่
-เลือกประเภทอุบัติเหตุ
-คำนวณว่าอุบัติเหตุชนิดนี้ เกิดขึ้นที่หมู่บ้านไหนบ้าง จำนวนคนที่ประสบเหตุ ประมาณนี้ครับ
แต่จริง ๆ แล้วต้องการให้มันแสดงทั้ง 19 สาเหตุ และ ตำบลในเขตรับผิดชอบมี 7 ตำบล จำนวนหมู่บ้านที่สูงสุด คือ 19 หมู่บ้าน (นี้คือสาเหตุที่ใช้เลข 19 เป็นฐาน) ถ้าหมู่บ้านในตำบลไหนน้อยกว่า ส่วนที่เกินก็จะกลายเป็น 0 เอง ผมคิดว่างั้นนะครับ ต้องการข้อมูลอะไรเพิ่มก็ถามมาได้ครับ

chwpart='56'  amppart='06'    ;D ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 16, 2010, 08:31:59 AM
ดันครับ  ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 16, 2010, 15:41:07 PM
อันนี้ผมทำเสร็จแล้วแต่ว่า เนื้อหารายงานมันออกมาเยอะเกินไปครับ คือผมนำตัวสาเหตุมาเรียงใน valiable  ครบ 19 สาเหตุ จากนั้นให้เลือก ตำบล->หมู่บ้าน->เลือกวันที่ (หมู่บ้านเลือกได้ครั้งละ 1 หมู่บ้าน) แต่พอออกหน้ารายงาน มันเกิดการซ้ำของสาเหตุใน valiable ไม่ทราบว่าผมต้องแก้ไขยังไงดีครับ ผมส่งตัว รายงาน + รูปที่เกิดการซ้ำของ valiable มาให้ด้วยนะครับ รบกวนด้วยนะครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: Svl2Nuk3 ที่ มีนาคม 17, 2010, 01:53:42 AM
ดูกระทู้นี้แล้วเห็นความตั้งใจของพี่จริงๆ ครับ  (เรียกพี่ละกันนะครับผมเกิด 29 อ่ะ)

รายงานบางตัวที่มีเงื่อนไขซับซ้อนมาก ๆ อย่างเช่นตัวนี้แหละครับ  จะแยกรายตำบล  แยกรายหมู่อีก  แล้วก็มาแยกตาม  diag   เงื่อนไขค่อนข้างจะเยอะเอาการ   

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

ส่วน  report ที่โพสขึ้นมาให้ดูนั้น   มี  subquery  เยอะมากครับ  แล้วก็มีการ  join table  โดยไม่จำเป็น   มันจะทำให้ report  ของเราช้าครับ

ลองดู  Code นี้เป็นแนวทางนะครับ  พึ่งเขียนเสร็จเมื่อกี้เลยครับ  อิอิ
Concept หลัก ๆ ของการเขียนโดยใช้สคริปจะเป็นประมาณนี้ครับ

1.  ดึงข้อมูลเท่าที่จำเป็นเข้า  tempreport  โดยมี  id หรือ reportname  เป็นตัวบอกว่าเป็นข้อมูลของ report ตัวไหน
     Code จะอยู่ใน Tab Script 
2.  ดึงข้อมูลจาก tempreport   (เขียน  sql  ดึงข้อมูลธรรมดา)  เช่น select * from tempreport where id ="xx"  ก็จะได้ข้อมูลจากข้อ 1
3.  จัด Layout  ของ  report

เท่านี้ก็สามารถทำรายงานที่เงื่อนไขซับซ้อนได้แล้วครับ



ตัวอย่าง 
รายงาน  19  สาเหตุของ  ตำบลต่าง ๆ 

ข้อมูลที่่จะใช้ก็จะมีประมาณนี้ครับ

select name as "accident_type" ,
name1 as chwpart,
name2 as amppart,
name3 as tmbpart,
name4 as aid,
name5 as tmbname,
mon1 as acident_id,
name6 as count

from tempreport  t1
where id="Imnuke"
order by aid,acident_id




ส่วนนี้เป็น  code  ดึงข้อมูลใส่ tempreport  อันนี้ต้องลองแกะ  code  ดูครับ
ผมก็  แกะ  code มาจาก  report ใน hosxp เหมือนกัน  แต่ที่สำคัญคือ  อัลกอรึทึมที่จะดึงข้อมูลให้ได้ตามเงื่อนไข  อันนี้ต้องฝึกบ่อย ๆ ครับ

การทำงานของ code คร่าว ๆ
1.  ดึง  chwpart  กับ  amppart  มาเก็บไว้ก่อน
1.  ตำบลทั้งหมดในเขตอำเภอของ  รพ. จาก chwpart และ amppart จากข้อ 1 (ในแต่ละตำบลจะไปวนลูปเอาข้อมูล  19 สาเหตุ)
2.  ดึงข้อมูล  19 สาเหตุตามตำบล  (วนลูปดึงทั้ง 19 สาเหตุ)

จะสังเกตว่า  2 ลูปนี้มันซ้อนกันอยู่   เพื่อที่จะให้ได้ข้อมูล  19  สาเหตุทุกตำบล
แล้วนำไป Group  ใน Report

ปล.  เทคนิคในการทำ code ให้สั้นของ Script  นี้คือ    การ  Look Up Table 
       โดยการสร้าง  array  ที่เป็นสตริงมาเก็บเงื่อนไข   แล้วตอน Query  ก็ดึงเงื่อนไขจาก Array


//===========================================================
// Report ER , 19 accident type
// @Author   Nattapong  Roadmuang
// @Since    2010 March 16
// @HOSxP    3.53.3.9
// @DBMS     MySQL 5.1.3
// @OS       Microsoft Windows Se7en
// @Hospital   Phomphiram Hospital , Phitsanulok
//===========================================================

unit ImnukeReport;

procedure main;
var d1,d2:tdatetime;
    ds1,ds2:string;
    hosp_chwpart,hosp_amppart,hospcode:String;
    sql_condition:array[1..19] of String;
begin

   // SQL Condition of accident type
   sql_condition[1] := ' ov.icd10 between "V01" and "V899"';
   sql_condition[2] := ' ov.icd10 between "W00" and "W199"';
   sql_condition[3] := ' ov.icd10 between "W20" and "W499"';
   sql_condition[4] := ' ov.icd10 between "W50" and "W649"';
   sql_condition[5] := ' ov.icd10 between "W65" and "W749"';
   sql_condition[6] := ' ov.icd10 between "W75" and "W849"';
   sql_condition[7] := ' ov.icd10 between "W85" and "W999"';
   sql_condition[8] := ' ov.icd10 between "X00" and "X099"';
   sql_condition[9] := ' ov.icd10 between "X10" and "X199"';
   sql_condition[10] := ' ov.icd10 between "X20" and "X299"';
   sql_condition[11] := ' ov.icd10 between "X30" and "X399"';
   sql_condition[12] := ' ov.icd10 between "X40" and "X499"';
   sql_condition[13] := ' ov.icd10 between "X50" and "X579"';
   sql_condition[14] := ' ov.icd10 between "X58" and "X599"';
   sql_condition[15] := ' ov.icd10 between "X60" and "X849"';
   sql_condition[16] := ' ov.icd10 between "X85" and "Y099"';
   sql_condition[17] := ' ov.icd10 between "Y10" and "Y339"';
   sql_condition[18] := ' ov.icd10 between "Y35" and "Y369"';
   sql_condition[19] := ' ov.icd10 = "Y34"';


   // Get date
   if not getdaterange() then exit;
       d1:=date_result1();
       d2:=date_result2();
       ds1:=formatdatetime('yyyy-mm-dd',d1);
       ds2:=formatdatetime('yyyy-mm-dd',d2);

   // Initial tempreport
   zquery.sql.text:='delete from tempreport where id = "Imnuke" ';
   zquery.execsql;

   


   // Initial hospital data
   hospcode := getsqldata('select hospitalcode from opdconfig');
   hosp_chwpart := getsqldata('select chwpart from hospcode where hospcode="' + hospcode + '"');
   hosp_amppart := getsqldata('select amppart from hospcode where hospcode="' + hospcode + '"');

   // Get All tmbpart in amp
   fcds2.close;
   fcds2.datarequest('select chwpart,amppart,tmbpart,addressid,name as tmbname from thaiaddress '+
   'where chwpart="'+hosp_chwpart+'" and amppart="'+hosp_amppart+'" and codetype="3"');
   fcds2.open;
   fcds2.first;


   // Initial accident type
   fcds3.close;
   fcds3.datarequest('select er_accident_type_id,er_accident_type_name from er_accident_type');
   fcds3.open;

   // Initial dataset
   fcds.close;
   fcds.datarequest('select * from tempreport where id = "Imnuke" ');
   fcds.open;
   fcds.first;
   
  while not fcds2.eof do         // chwpart & amppart
  begin
       fcds3.first;
       while not fcds3.eof do    // Accident type
       begin
            fcds.insert;
            fcds['id']:='Imnuke';
            fcds['name'] := fcds3['er_accident_type_name'];
            fcds['mon1'] := fcds3['er_accident_type_id'];
            fcds['name1'] := fcds2['chwpart'];
            fcds['name2'] := fcds2['amppart'];
            fcds['name3'] := fcds2['tmbpart'];
            fcds['name4'] := fcds2['addressid'];
            fcds['name5'] := fcds2['tmbname'];
            fcds['name6'] := getsqldata('select count(*) from ovstdiag ov,vn_stat v '+
                             ' where ov.vn=v.vn and v.vstdate between "'+ds1+'" and "'+ds2+'"'+
                             ' and v.aid="'+fcds2['addressid']+'" and '+sql_condition[fcds3['er_accident_type_id']]);
            fcds.post;
            fcds3.next;
       end;
  fcds2.next;
  end;


  // Finally
  fcds.datarequest('select * from tempreport where id = "Imnuke" ');
  applyupdate_fcds();

end;

end.




ปล.   ลองแก้  Code   นี้ให้มีเงื่อนไขเป็นรายหมู่บ้านดูนะครับ   ถ้าทำได้แสดงว่าเข้าใจ   ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 17, 2010, 08:57:18 AM
ขอบคุณมากนะครับ คุณนุ๊ก  ได้แนวทางแบบนี้ก็น่าจะไปได้สวยเลยครับ  ;D ;D ;D

ดูกระทู้นี้แล้วเห็นความตั้งใจของพี่จริงๆ ครับ  (เรียกพี่ละกันนะครับผมเกิด 29 อ่ะ)

รายงานบางตัวที่มีเงื่อนไขซับซ้อนมาก ๆ อย่างเช่นตัวนี้แหละครับ  จะแยกรายตำบล  แยกรายหมู่อีก  แล้วก็มาแยกตาม  diag   เงื่อนไขค่อนข้างจะเยอะเอาการ   

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

ส่วน  report ที่โพสขึ้นมาให้ดูนั้น   มี  subquery  เยอะมากครับ  แล้วก็มีการ  join table  โดยไม่จำเป็น   มันจะทำให้ report  ของเราช้าครับ

ลองดู  Code นี้เป็นแนวทางนะครับ  พึ่งเขียนเสร็จเมื่อกี้เลยครับ  อิอิ
Concept หลัก ๆ ของการเขียนโดยใช้สคริปจะเป็นประมาณนี้ครับ

1.  ดึงข้อมูลเท่าที่จำเป็นเข้า  tempreport  โดยมี  id หรือ reportname  เป็นตัวบอกว่าเป็นข้อมูลของ report ตัวไหน
     Code จะอยู่ใน Tab Script 
2.  ดึงข้อมูลจาก tempreport   (เขียน  sql  ดึงข้อมูลธรรมดา)  เช่น select * from tempreport where id ="xx"  ก็จะได้ข้อมูลจากข้อ 1
3.  จัด Layout  ของ  report

เท่านี้ก็สามารถทำรายงานที่เงื่อนไขซับซ้อนได้แล้วครับ



ตัวอย่าง 
รายงาน  19  สาเหตุของ  ตำบลต่าง ๆ 

ข้อมูลที่่จะใช้ก็จะมีประมาณนี้ครับ

select name as "accident_type" ,
name1 as chwpart,
name2 as amppart,
name3 as tmbpart,
name4 as aid,
name5 as tmbname,
mon1 as acident_id,
name6 as count

from tempreport  t1
where id="Imnuke"
order by aid,acident_id




ส่วนนี้เป็น  code  ดึงข้อมูลใส่ tempreport  อันนี้ต้องลองแกะ  code  ดูครับ
ผมก็  แกะ  code มาจาก  report ใน hosxp เหมือนกัน  แต่ที่สำคัญคือ  อัลกอรึทึมที่จะดึงข้อมูลให้ได้ตามเงื่อนไข  อันนี้ต้องฝึกบ่อย ๆ ครับ

การทำงานของ code คร่าว ๆ
1.  ดึง  chwpart  กับ  amppart  มาเก็บไว้ก่อน
1.  ตำบลทั้งหมดในเขตอำเภอของ  รพ. จาก chwpart และ amppart จากข้อ 1 (ในแต่ละตำบลจะไปวนลูปเอาข้อมูล  19 สาเหตุ)
2.  ดึงข้อมูล  19 สาเหตุตามตำบล  (วนลูปดึงทั้ง 19 สาเหตุ)

จะสังเกตว่า  2 ลูปนี้มันซ้อนกันอยู่   เพื่อที่จะให้ได้ข้อมูล  19  สาเหตุทุกตำบล
แล้วนำไป Group  ใน Report

ปล.  เทคนิคในการทำ code ให้สั้นของ Script  นี้คือ    การ  Look Up Table 
       โดยการสร้าง  array  ที่เป็นสตริงมาเก็บเงื่อนไข   แล้วตอน Query  ก็ดึงเงื่อนไขจาก Array


//===========================================================
// Report ER , 19 accident type
// @Author   Nattapong  Roadmuang
// @Since    2010 March 16
// @HOSxP    3.53.3.9
// @DBMS     MySQL 5.1.3
// @OS       Microsoft Windows Se7en
// @Hospital   Phomphiram Hospital , Phitsanulok
//===========================================================

unit ImnukeReport;

procedure main;
var d1,d2:tdatetime;
    ds1,ds2:string;
    hosp_chwpart,hosp_amppart,hospcode:String;
    sql_condition:array[1..19] of String;
begin

   // SQL Condition of accident type
   sql_condition[1] := ' ov.icd10 between "V01" and "V899"';
   sql_condition[2] := ' ov.icd10 between "W00" and "W199"';
   sql_condition[3] := ' ov.icd10 between "W20" and "W499"';
   sql_condition[4] := ' ov.icd10 between "W50" and "W649"';
   sql_condition[5] := ' ov.icd10 between "W65" and "W749"';
   sql_condition[6] := ' ov.icd10 between "W75" and "W849"';
   sql_condition[7] := ' ov.icd10 between "W85" and "W999"';
   sql_condition[8] := ' ov.icd10 between "X00" and "X099"';
   sql_condition[9] := ' ov.icd10 between "X10" and "X199"';
   sql_condition[10] := ' ov.icd10 between "X20" and "X299"';
   sql_condition[11] := ' ov.icd10 between "X30" and "X399"';
   sql_condition[12] := ' ov.icd10 between "X40" and "X499"';
   sql_condition[13] := ' ov.icd10 between "X50" and "X579"';
   sql_condition[14] := ' ov.icd10 between "X58" and "X599"';
   sql_condition[15] := ' ov.icd10 between "X60" and "X849"';
   sql_condition[16] := ' ov.icd10 between "X85" and "Y099"';
   sql_condition[17] := ' ov.icd10 between "Y10" and "Y339"';
   sql_condition[18] := ' ov.icd10 between "Y35" and "Y369"';
   sql_condition[19] := ' ov.icd10 = "Y34"';


   // Get date
   if not getdaterange() then exit;
       d1:=date_result1();
       d2:=date_result2();
       ds1:=formatdatetime('yyyy-mm-dd',d1);
       ds2:=formatdatetime('yyyy-mm-dd',d2);

   // Initial tempreport
   zquery.sql.text:='delete from tempreport where id = "Imnuke" ';
   zquery.execsql;

   


   // Initial hospital data
   hospcode := getsqldata('select hospitalcode from opdconfig');
   hosp_chwpart := getsqldata('select chwpart from hospcode where hospcode="' + hospcode + '"');
   hosp_amppart := getsqldata('select amppart from hospcode where hospcode="' + hospcode + '"');

   // Get All tmbpart in amp
   fcds2.close;
   fcds2.datarequest('select chwpart,amppart,tmbpart,addressid,name as tmbname from thaiaddress '+
   'where chwpart="'+hosp_chwpart+'" and amppart="'+hosp_amppart+'" and codetype="3"');
   fcds2.open;
   fcds2.first;


   // Initial accident type
   fcds3.close;
   fcds3.datarequest('select er_accident_type_id,er_accident_type_name from er_accident_type');
   fcds3.open;

   // Initial dataset
   fcds.close;
   fcds.datarequest('select * from tempreport where id = "Imnuke" ');
   fcds.open;
   fcds.first;
   
  while not fcds2.eof do         // chwpart & amppart
  begin
       fcds3.first;
       while not fcds3.eof do    // Accident type
       begin
            fcds.insert;
            fcds['id']:='Imnuke';
            fcds['name'] := fcds3['er_accident_type_name'];
            fcds['mon1'] := fcds3['er_accident_type_id'];
            fcds['name1'] := fcds2['chwpart'];
            fcds['name2'] := fcds2['amppart'];
            fcds['name3'] := fcds2['tmbpart'];
            fcds['name4'] := fcds2['addressid'];
            fcds['name5'] := fcds2['tmbname'];
            fcds['name6'] := getsqldata('select count(*) from ovstdiag ov,vn_stat v '+
                             ' where ov.vn=v.vn and v.vstdate between "'+ds1+'" and "'+ds2+'"'+
                             ' and v.aid="'+fcds2['addressid']+'" and '+sql_condition[fcds3['er_accident_type_id']]);
            fcds.post;
            fcds3.next;
       end;
  fcds2.next;
  end;


  // Finally
  fcds.datarequest('select * from tempreport where id = "Imnuke" ');
  applyupdate_fcds();

end;

end.




ปล.   ลองแก้  Code   นี้ให้มีเงื่อนไขเป็นรายหมู่บ้านดูนะครับ   ถ้าทำได้แสดงว่าเข้าใจ   ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 17, 2010, 11:38:22 AM
เรียนท่าน Imnuke ครับ มึนสุดๆ ??? ??? :'( เอาอะไรใส่เข้าไปก็ไม่ได้ ไม่เข้าใจคำสั่ง ... หัวหน้าก็บอกให้เร่งทำ  :'( :'( ถ้าไงผมอยากเพิ่มให้จำนวนหมู่บ้านเป็ฯ บรรทักฐาน คือ ให้ทุกตำบล มี 19 หมู่บ้านหมดเลยครับเพราะจำนวนตำบลเยอะสุดอยู่ที่ 19 หมู่บ้านครับ  ผมพยายามทำแล้วหล่ะครับ แต่ยังไม่เข้าใจเลย จึง อยากรบกวนให้เพิ่ม หมู่บ้านให้จะได้ไหมครับ :-[ :-[ ไม่ทราบว่าจะสะดวกหรือเปล่านะครับ จะได้เอาเป็นแนวทางปฏิบัติ ต่อไปข้างหน้าครับ รบกวนด้วยนะครับ  ;D ;D ขอบคุณมากมาย  ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: Svl2Nuk3 ที่ มีนาคม 17, 2010, 15:30:54 PM
เรียนท่าน Imnuke ครับ มึนสุดๆ ??? ??? :'( เอาอะไรใส่เข้าไปก็ไม่ได้ ไม่เข้าใจคำสั่ง ... หัวหน้าก็บอกให้เร่งทำ  :'( :'( ถ้าไงผมอยากเพิ่มให้จำนวนหมู่บ้านเป็ฯ บรรทักฐาน คือ ให้ทุกตำบล มี 19 หมู่บ้านหมดเลยครับเพราะจำนวนตำบลเยอะสุดอยู่ที่ 19 หมู่บ้านครับ  ผมพยายามทำแล้วหล่ะครับ แต่ยังไม่เข้าใจเลย จึง อยากรบกวนให้เพิ่ม หมู่บ้านให้จะได้ไหมครับ :-[ :-[ ไม่ทราบว่าจะสะดวกหรือเปล่านะครับ จะได้เอาเป็นแนวทางปฏิบัติ ต่อไปข้างหน้าครับ รบกวนด้วยนะครับ  ;D ;D ขอบคุณมากมาย  ;D

ซ้อนลูปหมู่บ้านเข้าไปอีก  1  ลูปครับ   ว่าแต่ตอนนี้ไม่มีฐานข้อมูลให้ลองอ่ะครับ
ก็เลยไม่รู้ว่าจะไปดึง  หมู่บ้าน  จากตารางไหน
หลัก ๆ ก็คือ  Query  ข้อมูลหมู่บ้านมาใส่อีก 1 ฟิล ครับ   
แล้วใน Report group  2 ครั้ง   
ครั้งแรก  group ตำบล
อีกครั้งเป็น  group หมู่


ลองดูนะครับ  ไม่ยากเกินความพยายามหรอกครับ   ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 17, 2010, 16:04:22 PM
เรียนท่าน Imnuke ครับ มึนสุดๆ ??? ??? :'( เอาอะไรใส่เข้าไปก็ไม่ได้ ไม่เข้าใจคำสั่ง ... หัวหน้าก็บอกให้เร่งทำ  :'( :'( ถ้าไงผมอยากเพิ่มให้จำนวนหมู่บ้านเป็ฯ บรรทักฐาน คือ ให้ทุกตำบล มี 19 หมู่บ้านหมดเลยครับเพราะจำนวนตำบลเยอะสุดอยู่ที่ 19 หมู่บ้านครับ  ผมพยายามทำแล้วหล่ะครับ แต่ยังไม่เข้าใจเลย จึง อยากรบกวนให้เพิ่ม หมู่บ้านให้จะได้ไหมครับ :-[ :-[ ไม่ทราบว่าจะสะดวกหรือเปล่านะครับ จะได้เอาเป็นแนวทางปฏิบัติ ต่อไปข้างหน้าครับ รบกวนด้วยนะครับ  ;D ;D ขอบคุณมากมาย  ;D

ซ้อนลูปหมู่บ้านเข้าไปอีก  1  ลูปครับ   ว่าแต่ตอนนี้ไม่มีฐานข้อมูลให้ลองอ่ะครับ
ก็เลยไม่รู้ว่าจะไปดึง  หมู่บ้าน  จากตารางไหน
หลัก ๆ ก็คือ  Query  ข้อมูลหมู่บ้านมาใส่อีก 1 ฟิล ครับ   
แล้วใน Report group  2 ครั้ง   
ครั้งแรก  group ตำบล
อีกครั้งเป็น  group หมู่


ลองดูนะครับ  ไม่ยากเกินความพยายามหรอกครับ   ;D

ไม่ทราบว่าใช้คำสั่งอะไร Group ครับ ผมลองใช้ fcds4 มันก็ไม่ได้ครับ พอดีไม่มีพื้นฐานในการเขียนโปรแกรมลักษณะนี้ครับ เลยไม่ทราบว่าต้องทำยังไงต่อ ครับ แต่จะลองพยายามครับ  แต่อยากได้คำอธิบายที่เป็นภาษาไทยด้วยสักหน่อยหน่ะครับเผื่อจะเข้าใจกับตัวคำสั่งบ้าง ในบางจุดครับ แต่ก็ขอขอบคุณมากมายครับสำหรับคำตอบดีๆแล้วจะแวะมารบกวนใหม่นะครับ  ;D ;D
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 18, 2010, 08:40:21 AM
แย่แล้ว เดทไลด์ เที่ยงนี้ หัวหน้าฟันธงแว้ว ทำไงดี ๆ รบกวนผู้รู้คนไหนก็ได้ครับช่วยกรุณาหน่อยครับ  :'( :'( งานเข้าแล้ว ช่วยด้วยนะครับ เหลือแค่แยกลงรายหมู่บ้านครับ ที่คุณ Imnuke ให้มาเกื่อบครบแล้ว นั่งทำเมื่อวานจนดึกเลยยังไม่สำเร็จครับ รบกวนด้วยครับ
หัวข้อ: Re: การเขียนคำสั่ง วนลูป ใน Report Disiner ครับ
เริ่มหัวข้อโดย: ~ L~ อิสระเสรี ~ L~ ที่ มีนาคม 18, 2010, 10:23:43 AM
ที่ผมเพิ่มคำสั่งมา ที่เป็นสีแดงครับ มันขึ้น Error ตามที่ส่งมานี้ครับ ซึ่งไม่เข้าใจเลยครับ ใครเข้าใจกรุณา อธิบายให้ด้วยครับ หรือว่าต้องแก้ตรงไหนบ้างครับ ใกล้เส้นตายเข้าไปทุกทีแล้วครับ :'( :'( รบกวนด้วยครับ

//==============================================================================
// Report ER , 19 accident type
// @Author   Nattapong  Roadmuang
// @Since    2010 March 16
// @HOSxP    3.53.3.9
// @DBMS     MySQL 5.1.3
// @OS       Microsoft Windows Se7en
//==============================================================================

unit ImnukeReport;

procedure main;
var d1,d2:tdatetime;
    ds1,ds2:string;
    hosp_chwpart,hosp_amppart,hospcode:String;
    sql_condition:array[1..19] of String;
    moo_condition:array[1..19] of string;
    i:integer;begin

   // SQL Condition of accident type
   sql_condition[1] := ' ov.icd10 between "V01" and "V899"';
   sql_condition[2] := ' ov.icd10 between "W00" and "W199"';
   sql_condition[3] := ' ov.icd10 between "W20" and "W499"';
   sql_condition[4] := ' ov.icd10 between "W50" and "W649"';
   sql_condition[5] := ' ov.icd10 between "W65" and "W749"';
   sql_condition[6] := ' ov.icd10 between "W75" and "W849"';
   sql_condition[7] := ' ov.icd10 between "W85" and "W999"';
   sql_condition[8] := ' ov.icd10 between "X00" and "X099"';
   sql_condition[9] := ' ov.icd10 between "X10" and "X199"';
   sql_condition[10] := ' ov.icd10 between "X20" and "X299"';
   sql_condition[11] := ' ov.icd10 between "X30" and "X399"';
   sql_condition[12] := ' ov.icd10 between "X40" and "X499"';
   sql_condition[13] := ' ov.icd10 between "X50" and "X579"';
   sql_condition[14] := ' ov.icd10 between "X58" and "X599"';
   sql_condition[15] := ' ov.icd10 between "X60" and "X849"';
   sql_condition[16] := ' ov.icd10 between "X85" and "Y099"';
   sql_condition[17] := ' ov.icd10 between "Y10" and "Y339"';
   sql_condition[18] := ' ov.icd10 between "Y35" and "Y369"';
   sql_condition[19] := ' ov.icd10 = "Y34"';

   moo_condition[1] := '"01","1"';
   moo_condition[2] := '"02","2"';
   moo_condition[3] := '"03","3"';
   moo_condition[4] := '"04","4"';
   moo_condition[5] := '"05","5"';
   moo_condition[6] := '"06","6"';
   moo_condition[7] := '"07","7"';
   moo_condition[8] := '"08","8"';
   moo_condition[9] := '"09","9"';
   moo_condition[10] := '"10"';
   moo_condition[11] := '"11"';
   moo_condition[12] := '"12"';
   moo_condition[13] := '"13"';
   moo_condition[14] := '"14"';
   moo_condition[15] := '"15"';
   moo_condition[16] := '"16"';
   moo_condition[17] := '"17"';
   moo_condition[18] := '"18"';
   moo_condition[19] := '"19"';
   // Get date
   if not getdaterange() then exit;
       d1:=date_result1();
       d2:=date_result2();
       ds1:=formatdatetime('yyyy-mm-dd',d1);
       ds2:=formatdatetime('yyyy-mm-dd',d2);

   // Initial tempreport
   zquery.sql.text:='delete from tempreport where id = "Imnuke" ';
   zquery.execsql;

   // Initial hospital data
   hospcode := getsqldata('select hospitalcode from opdconfig');
   hosp_chwpart := getsqldata('select chwpart from hospcode where hospcode="' + hospcode + '"');
   hosp_amppart := getsqldata('select amppart from hospcode where hospcode="' + hospcode + '"');

   // Get All tmbpart in amp
   fcds2.close;
   fcds2.datarequest('select chwpart,amppart,tmbpart,addressid,name as tmbname from thaiaddress '+
   'where chwpart="'+hosp_chwpart+'" and amppart="'+hosp_amppart+'" and codetype="3"');
   fcds2.open;
   fcds2.first;


   // Initial accident type
   fcds3.close;
   fcds3.datarequest('select er_accident_type_id,er_accident_type_name from er_accident_type');
   fcds3.open;
   
   
   //village moo
   fcds4.close;
   fcds4.datarequest('select v.village_id,v.address_id,v.village_moo from village v '+
   'left outer join vn_stat vn v.address_id=vn.aid '+
   'left outer join patient p on p.hn=vn.hn '+
   'where p.chwpart="'+hosp_chwpart+'" and p.amppart="'+hosp_amppart+'"');
   fcds4.open;   

   // Initial dataset
   fcds.close;
   fcds.datarequest('select * from tempreport where id = "Imnuke" ');
   fcds.open;
   fcds.first;
   
  while not fcds2.eof do         // chwpart & amppart
  begin
     fcds4.first;
     while not fcds4.eof do
     begin       while not fcds3.eof do    // Accident type
       begin
            fcds.insert;
            fcds['id']:='Imnuke';
            fcds['name'] := fcds3['er_accident_type_name'];
            fcds['mon1'] := fcds3['er_accident_type_id'];
            fcds['name1'] := fcds2['chwpart'];
            fcds['name2'] := fcds2['amppart'];
            fcds['name3'] := fcds2['tmbpart'];
            fcds['name4'] := fcds2['addressid'];
            fcds['name5'] := fcds2['tmbname'];
            fcds['name7'] := fcds4['village_name'];
            fcds['name6'] := getsqldata('select count(*) from ovstdiag ov,vn_stat v '+
                             ' where ov.vn=v.vn and v.vstdate between "'+ds1+'" and "'+ds2+'"'+
                             ' and v.moopart="'+moo_condition[fcds4['village_moo']]+'" and v.aid="'+fcds2['addressid']+'" and '+sql_condition[fcds3['er_accident_type_id']]);
            fcds.post;
            fcds3.next;
       end;
      end;
  fcds2.next;
  end;


  // Finally
  fcds.datarequest('select * from tempreport where id = "Imnuke" ');
  applyupdate_fcds();

end;

end.