Thursday, December 22, 2011

การแก้ปัญหา ทศนิยม ของ Crystal Report ไม่ต้องการให้มันปัด ทศนิยม

เช่น ค่า 1,161.998 ต้องการแสดง ให้เป็น 1,161.99 โดยไม่ต้องการปัด ขึ้น หรือ ปัดลง

--------------------------------------------------------------
คุณต้องเรียกใช้งานฟิลด์นี้ ในส่วนของ formula ค่ะ

ใช้ Truncate(1,161.998, 2)

ก็จะได้ผลลัพธ์ 1,161.99 ค่ะ
--------------------------------------------------------------

หรือ

คลิกขวาที่ฟิลด์=>Format Object=>กดปุ่ม Customize
เลือก
Decimals: = 1.000 ทศนิยม 3 ตำแหน่ง
Rounding = 0.001 ปัดเฉพาะตำแหน่งที่ 3 เป็นต้นไป


การส่งค่าตัวแปรจาก .NET application ไปยังรายงาน Crystal Report

การส่งค่าตัวแปรจาก .NET application ไปยังรายงาน Crystal Report
1. สร้าง Parameter ในรายงาน

คลิกขวาที่ Parameter Fields แล้วเลือก New
กำหนดชื่อของ Parameter ตามภาพ


ตั้งชื่อของ Parameter


ลากไปใส่ในรายงาน ฟิลด์ที่เป็น Parameter จะแสดงนำหน้าด้วยเครื่องคำถาม



2. ส่งค่าตัวแปรจากโปรแกรมไปให้รายงาน

ผมแสดงโค้ดในการติดต่อ Crystal Report มาให้ศึกษาทั้งหมดเลย
ประกอบไปด้วย 3-4 เรื่อง คือ
a. การส่ง DataSet ไปให้รายงาน (SetDataSource method)
b. การกำหนดเงื่อนไข (SelectionFormula property)
c. การส่งค่าตัวแปรไปให้ Parameter (SetParameterValue method)
d. การนำ report document ไปแสดงในตัว viewer (ReportSource property)



การสร้าง Parameter ของคุณ buggio ยังไม่ได้ Add ให้กับตัวรายงานครับ
เมื่อรายงานไม่ได้รับการกำหนดค่า Parameter ก็จะแสดง Dialog Box อย่างที่นำมาให้ดู

ดูตัวอย่างโค้ดตามตัวอย่างนี้ครับ.
ReportDocument เป็นคลาสที่อยู่ในเนมสเปซ CrystalDecisions.CrystalReports.Engine

ตัวอย่างเมื่อรันโปรแกรม ทำให้ดูทั้งการส่งค่า Parameter และการกำหนด RecordSelectionFormula



ref : http://greatfriends.biz/webboards/msg.asp?id=9076

แปลงค่าตัวเลข(เงิน)เป็นตัวหนังสือใน ที่ทำใน formula ของ Crystal Report

แปลงค่าตัวเลข(เงิน)เป็นตัวหนังสือใน ที่ทำใน formula ของ Crystal Report ด้วยครับ

ผมใช้ประมาณนี้ครับ ถ้าไงก็ลองไปปรับใช้นะครับ {@Currency } => เงินที่ต้องการแปลงครับ
//BahtString
//ประการตัวแปรต่างๆ ::..
Local stringVar array D:=["","สิบ","ร้อย","พัน","หมื่น","แสน","ล้าน"];
Local stringVar array E:=["หนึ่ง","สอง","สาม","สี่","ห้า","หก","เจ็ด","แปด","เก้า"];
Local stringVar array strArrNumSplit;
Local numberVar numLength=0;
Local stringVar strTmp;
Local stringVar strResualt;
Local stringVar strRevertNumber;
Local numberVar i=0;
Local numberVar j=0;
Local numberVar k=0;
Local numberVar numIndex=0;
//แยกจำนวนเต็มกับทศนิยม::.
strArrNumSplit:=Split(Cstr( {@Currency} ,2,""),".");
numLength := Length(strArrNumSplit[1]);
strRevertNumber:=StrReverse(strArrNumSplit[1]);
//วนตัวเลขจนครบจำนวนหลัก(ตัวเลขหน้าจุด)::.
for i :=1 to numLength do (
//แปลงตัวเลขเป็นตัวหนังสือ::.
for j :=1 to 9 do (
if (Mid(strRevertNumber,i,1)=CSTR(j,0)) then (
strTmp := E[j];
if ((i=1 and Mid(strRevertNumber,i,1)="1" and numLength>1 )) or
((i=7 and Mid(strRevertNumber,i,1)="1" and numLength>7 )) then
(strTmp := "เอ็ด";);
if ((i=2 or i=8) and Mid(strRevertNumber,i,1)="1") then
(strTmp :="";);
if ((i=2 or i=8) and Mid(strRevertNumber,i,1)="2") then
(strTmp := "ยี่";);
//ใส่ค่าประจำหลัก::.
if(i>1 and i<7) then
(strTmp :=strTmp+D[i];)
else if(i=7)then
(strTmp :=strTmp+D[i]; )
else if(i>7)then
( numIndex :=(i mod 7)+ 1;
strTmp := strTmp+D[numIndex];);
//::..
strResualt := strTmp + strResualt;
exit for;
);
);//End For j
);//End For i
//วนตัวเลขจนครบจำนวนหลัก(ตัวเลขหลังจุด)::.
Local stringVar strNum;
Local stringVar num1 := Mid(strArrNumSplit[2],1,1);
Local stringVar num2 := Mid(strArrNumSplit[2],2,1);
strResualt := strResualt+"บาท";
if(num1="0" and num2="0") then
(
strResualt := strResualt+"ถ้วน";
)
else
(
for i := 1 to 2 do
(
strNum :=Mid(strArrNumSplit[2],i,1);
//แปลงตัวเลขเป็นตัวหนังสือ::.
for j:=1 to 9 do
(
if(strNum =CSTR(j,0)) then
(
strTmp :=E[j];
if(i=1 and strNum="1") then (strTmp := "";);
if(i=1 and strNum="2") then (strTmp := "ยี่";);
if(i=1) then (
strTmp := strTmp+ "สิบ";
);
if(i=2 and num1<>"0" and num2="1" ) then strTmp :="เอ็ด";
strResualt := strResualt + strTmp;
exit for;
);
);
);
strResualt := strResualt+ "สตางค์";
);

การใช้งานนะครับ คือ ให้คุณ สร้าง Formula Fields

เช่น ชื่อ BahtString จากนั้นก็เอา code นี้ ไปใส่ครับ

แล้วก็ใช้ BahtString ใน Report


ส่วนตรง {@Currency } ก็คือ จำนวนเงินครับ

คุณอาจลองเทส ผล เช่น การใส่ตัวเลขไปแทน {@Currency }


แล้วพอใช้จริงค่อย ใส่ Field ที่ต้องการแปลง


ถ้าไม่อยากใส่ไปตรงๆ ก็อาจจะสร้าง Formula Fields

อีกตัว ชื่อ Currency แล้วก็นำ Field ที่ต้องการแปลงมาใส่ใน code

ของ Formula Fields Currency ก็ได้ครับ

ref : http://greatfriends.biz/webboards/msg.asp?id=33237

ทำรายงาน Crystal Report โดยใช้ Class

ทำรายงาน Crystal Report โดยใช้ Class
หัวข้อนี้ได้แรงบันดาลใจจากกระทู้นี้ http://www.greatfriends.biz/?130875
ขอแบ่งปันประสบการณ์ด้าน Crystal Report ไว้เป็นอีกหนึ่งทางเลือกครับ

เหมาะกับใคร? : เหมาะกับคนที่ชอบดึงข้อมูลจาก Database มาแล้วโยนเข้า Crystal Report เพื่อออกรายงาน

วัตถุประสงค์ : นำเสนอวิธีการทำ Crystal Report อีกแนวทางหนึ่งสำหรับคนที่ชอบ ดึงข้อมูลมาแล้วโยนเข้า Crystal Report
เครื่องมือที่ใช้

เริ่มกันเลย
หลักการทำรายงานด้วย Crystal Report มี 2 ข้อ
1. การเตรียมโครงข้อมูลและจัดรูปแบบรายงาน
2. การโยนข้อมูลใส่ Crystal Report

1. การเตรียมโครงข้อมูลและจัดรูปแบบรายงาน
หลักการสำคัญข้อนี้คือ จัดทำโครงข้อมูลใน Crystal Report ขอยกตัวอย่างการออกรายงานข้อมูลพนักงาน ประกอบด้วย
- Id เป็น int
- Name เป็น string
- Position เป็น string
- Department เป็น string
- Salary เป็น decimal

โดยปกติเห็นหลายๆ คนจะทำเป็น DataSet แต่ผมชอบทำเป็น Class แล้วจับใส่ Crystal Report ผมจะเขียน Class Employee ขึ้นมาดังภาพต่อไปนี้


เสร็จแล้วต้อง Build Project ก่อนนะครับ ไม่งั้น Crystal Report จะมองไม่เห็นคลาส Employee


ต่อไปนำโครงเข้ามาใน Crystal Report และจัดรูปแบบกัน โดยสร้างรายงาน Crystal Report ก่อนตามภาพ


ตั้งชื่อเป็น rptEmployee.rpt ครับ หลังจากกด Add จะได้ก็เลือกประเภทรายงาน ตามภาพต่อไป

เลือกแบบ Standard แล้วกด OK
Crystal Report จะให้เลือกโครงข้อมูลให้คลิ๊กที่ Project Data -> .NET Objects หา Class Employee ที่ทำไว้ดังภาพ

สังเกตุว่า Class Employee จะ ขึ้นต้นด้วย Name Space ในโปรเจคนี้ผมตั้งชื่อ Name Space เป็น SampleCrystalReport
คลาสข้อมูลจึงเป็น SampleCrystalReport.Employee คลิ๊กที่คลาส SampleCrystalReport.Employee แล้วกดปุ่ม > ด้านขวา
เพื่อเลือกคลาส จากนั้นกดปุ่ม Next > ด้านล่าง ต่อไปก็ทำตามภาพจนกระทั่งกดปุ่ม Finish ครับ




ตอนนี้เราได้ก็ได้โครงสร้างและรูปแบบรายงานแล้ว ดังภาพด้านล่าง


ต่อมาทำฟอร์มแสดงข้อมูล ผมขอใช้ Windows Form นะครับ ง่ายดี
สร้าง Windows Form ฟอร์มมา 1 ตัวครับ แล้วเอา Crystal Report Viewer มาวางไว้ ดังภาพ


2. การนำข้อมูลใส่ให้ Crystal Report
ตอนนำข้อมูลโยนใส่ Crystal Report จะนำมาจากไหนก็ได้ มีข้อแม้ว่าต้องเตรียมข้อมูลให้อยู่ในรูปแบบ Collection หรือ DataTable
โดยถ้าเป็นรูปแบบ Collection เช่น
List<คลาสข้อมูล> Property ต้องเป็น Public และชื่อ Property ต้องตรงกับชื่อฟิล์ดใน Crystal Report
หรือถ้าเป็น DataTable ก็ต้องมีชื่อฟิล์ดตรงกับชื่อฟิล์ดใน Crystal Report ด้วยเช่นกัน
อาจใช้วิธีปรับแต่ง SQL Statement แบบนี้ก็ได้เช่น
Select EmpID AS Id, TName + FName + " " + LName AS Name, ..... พอจะนึกออกใช่มั้ยครับ

มาลุยต่อผมจะยกตัวอย่าง Code แบบใช้ Collection ในที่นี้ขอใช้ List<Employee> โดยเขียน Code ที่ Event Form_Load ดังนี้


เสร็จแล้ว Run Program จะได้ผลลัพธ์ตามนี้



ref : http://greatfriends.biz/webboards/msg.asp?id=130890
หวังว่าจะเป็นประโยชน์นะครับ

การออกรายงานโดยใช้ CrystalReport กับ DatagridView และ ADO.Net

1.Design หน้าตาแบบฟอร์ม(Form1) อย่าลืม DatagridView นะครับ

2. หลังจาก Design ฟอร์มเรียบร้อยให้ทำการ Add DataSet เข้ามาใน Project แล้วคลิกขวาเลือก
Add > DataTable
3. ที่หน้าต่าง DataTable คลิกขวา Add > Column และกำหนด DataType ตามที่ต้องการ

4.สร้างฟอร์มเพื่อเอาไว้ใช้แสดงรายงานโดยใช้ CrystalReportViewer(Form2)
5.Add crystal report เข้ามาใน Project
6.คลิกขวาที่ Database Field เลือก Database Expert… เลือก Project Data > ADO.Net DataSets
ทำการเพิ่ม DataTable ของเราที่อยู่ใน DataSet เข้าไป

7. ออกแบบรายงานตามรูปแบบต้องการ


มาถึงตัวอย่างการใช้งานครับ จากรูปแบบฟอร์มข้างต้น(Form1)
โดยเราจะทำการคำนวณราคารวม (จำนวน x ราคา)
Private Sub dgv_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgv.CellEndEdit
'แสดงค่าผลรวม และ ทศนิยม
For i As Integer = 1 To 2
If e.ColumnIndex = i Then
dgv.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = CDbl(dgv.Rows(e.RowIndex).Cells(e.ColumnIndex).Value).ToString("#,##0.00")
dgv.Rows(e.RowIndex).Cells(3).Value = CDbl(CDbl(dgv.Rows(e.RowIndex).Cells(1).Value) * CDbl(dgv.Rows(e.RowIndex).Cells(2).Value)).ToString("#,##0.00")
Exit Sub
End If
Next
End Sub

ในการคำนวณนั้นต้องเป็นตัวเลขกับตัวเลขเท่านั้นเราจึงต้องทำการตรวจสอบค่าที่ป้อนเข้าไป 'การตรวจสอบการกรอกข้อมูลว่าเป็นตัวเลขหรือไม่
Private Sub dgv_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgv.EditingControlShowing

If dgv.CurrentCell.ColumnIndex = 1 Or dgv.CurrentCell.ColumnIndex = 2 Then
Dim txtNumeric As TextBox = e.Control
AddHandler txtNumeric.KeyPress, AddressOf txtNumeric_KeyPress
End If

End Sub

Private Sub txtNumeric_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)

If dgv.CurrentCell.ColumnIndex = 1 Or dgv.CurrentCell.ColumnIndex = 2 Then
'ตรวจสอบการกด ตัวเลข "." backspace
Dim txtNumeric As TextBox = sender
If Asc(e.KeyChar) = Keys.Enter OrElse e.KeyChar Like "[.]" OrElse Asc(e.KeyChar) = Keys.Back Then
ElseIf Not (IsNumeric(e.KeyChar)) Then
MsgBox("กรุณาใส่ตัวเลขเท่านั้น")
e.Handled = True
End If

'ป้องกันการกด "." 2 ครั้ง
For i As Integer = 1 To txtNumeric.TextLength
If (Mid(txtNumeric.Text, i, 1)) = "." Then
If e.KeyChar Like "[.]" Then
e.Handled = True
Exit Sub
End If
End If
Next
End If

End Sub

ทดลองรันแล้วทำการป้อนข้อมูลเข้าไปใน DatagridView
คลิกที่ปุ่มพิมพ์เพื่อแสดงรายงาน
จบแล้วครับ
อาจจะเป็นเรื่องที่ พี่ ๆ น้อง ๆ หลายคนคงรู้แล้วแต่ก็หวังว่าพอจะมีประโยชน์สำหรับมือใหม่ไม่มากก็น้อยนะครับ(แล้วแต่การนำไปประยุกต์ใช้) ผมไม่เก่งทฤษฏี อาศัยครูพักลักจำเอาครับ อาจจะอธิบายน้อย เน้นรูปเยอะ code ก็เป็น code ง่าย ๆ ครับเอาแค่พอทำได้(เต็มที่แล้วครับ อิอิ)
แต่ก็อยากมีส่วนร่วมครับ
ขอบคุณครับ

ปล.ไม่กล้าใช้คำว่า บทความ ครับ เพราะดูมันเป็นเรื่องไม่พิเศษอะไรมากมายครับ คิดว่าเล่าสู่กันฟังแล้วกันนะครับ (ก่อน Post นี่ผมตีลังกาคิดประมาณ 37 รอบ ว่าจะ Post ดีมั้ยอ่ะครับ เหอ ๆ)

Wednesday, December 21, 2011

Crystal Report: Formatting the Decimal Field Custom Styling

Crystal Report: Formatting the Decimal Field
Even though I am currently working in SharePoint I still have a fond of working in crystal reports. Recently in the MSDN forums I saw a requirement in Crystal Report forums section. The requirement is that there is a decimal type column in the SQL Server Database as Shown below.
When we connect the DB in the crystal report, we got the output like this.
But the output should show something like; if the Decimal Field value has no decimal value then it should show as integer without decimal places. If the Decimal Field value contains some decimal value data then it should be left as it is.
Solution:
In the Crystal Report, Right Click the Decimal Field we have placed in the Detail section and select Format Object.
In the Format Editor window select Custom Style under Style and click Customize button.
In the opening popup window select Number tab and click the Formula Editor Button next to Decimals:
Enter the formula as shown.
Click Save and Close in the Formula editor and click Ok in Custom Style window
Now the Output in the Crystal Report is come as Expected.

Tuesday, December 20, 2011

CR Report : Formula Function สำหรับ แสดงวันที่ภาษาไทย

ปกติแล้ว Crystral Report ในการ set format date นั้น สามารถเลือก format ปี เป็น ค.ศ. หรือพ.ศ. ได้ และ เดือนนั้น จะขึ้นกะ Regional ของเครื่ือง (หรือเปล่า ^^'')

ทีนี้สำหรับเครื่องที่แสดงผล date เป็น ปี ค.ศ. และ เดือนเป็นอังกฤษ (เซิร์ฟเวอร์ database T-T) หรืออะไรก็ตาม

พล่ามมาทำไมเนี่ย ว่าง่ายๆ ก็คือ เปนการเขียนฟังก์ชั่นใช้เอง ไม่ต้องแคร์เครื่อง
เปิด Crystral Report มาเลยครับ

1. เปิด Formula Editor สร้าง Function ขึ้นมาในส่วน Report Custom Fucntion ในรูปสร้าง toThaiDate



2. รายละเอียดใน Function


'เริ่มฟังก์ชั่น
Function (datetimeVar d)

'เช็คเงื่อนไข ถ้าปี เป็น ค.ศ. เปลี่ยนเป็น พ.ศ. (+543)
if(Year (d) <2500) then
d := DateTime (Year (d)+543,Month (d) ,Day (d) )
else
d;

'แปลง date to string ให้อยู่ใน format (อันนี้แล้วแต่ถนัด)
Local StringVar y;
y:= Totext(d,"dd MM yyyy");

' ทำการ replace เดือนที่เป็นหมายเลข 01-12 ด้วย คำที่ต้องการ
'(ในที่นี้จะใช้ การค้นหา " 01 " ด้วย " มกราคม " แทนการใช้ "01"
' เนื่องจาก จะไปเจอวันที่ "01" เข้า >< หากใช้ format เป็น dd/MM/yyyy
' ก็จะเป็น Replace (y,"/01/","/มกราคม/") แทนครับ
if(mid(y,4,2)="01") then
Replace (y," 01 "," มกราคม ")
else if(mid(y,4,2)="02") then
Replace (y," 02 "," กุมภาพันธ์ ")
else if(mid(y,4,2)="03") then
Replace (y," 03 "," มีนาคม ")
else if(mid(y,4,2)="04") then
Replace (y," 04 "," เมษายน ")
else if(mid(y,4,2)="05") then
Replace (y," 05 "," พฤษภาคม ")
else if(mid(y,4,2)="06") then
Replace (y," 06 "," มิถุนายน ")
else if(mid(y,4,2)="07") then
Replace (y," 07 "," กรกฎาคม ")
else if(mid(y,4,2)="08") then
Replace (y," 08 "," สิงหาคม ")
else if(mid(y,4,2)="09") then
Replace (y," 09 "," กันยายน ")
else if(mid(y,4,2)="10") then
Replace (y," 10 "," ตุลาคม ")
else if(mid(y,4,2)="11") then
Replace (y," 11 "," พฤศจิกายน ")
else if(mid(y,4,2)="12") then
Replace (y," 12 "," ธันวาคม ")
else
y

'ค่าที่ return ออกมาจะเป็นค่า y ที่ถูก replace


3.วิธีเรียกใน formula ก็ใส่ชื่อ function & parameter เลยครับ



จบแล้วครับ


หวังว่าคงจะได้นำไปใช้กัน หรือเป็นตัวอย่างในการเขียน custom function ใช้เองกันนะครับ