photo.MgHla.net - ေ မာ င္ လွ ရဲ ႕ ဓာ တ္ ပုံ ျပ ခ န္ း

ကၽြန္ေတာ္ ဖန္တီးခဲ့ေသာ / ဖန္တီးလွ်က္႐ွိေသာ / ဆက္လက္ ဖန္တီးမည့္ ဓာတ္ပုံ၊ ႐ုပ္ပုံ၊ လႈပ္႐ွားမႈ ပုံမ်ား၊ စာသား စသည့္ ဖန္တီးမႈမ်ား အားလုံးအား a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. လုိင္စင္ ရယူထားပါေၾကာင္း အသိေပးအပ္ပါသည္။
http://creativecommons.org/licenses/by-nc-nd/3.0/


Friday, September 21, 2007

Dynamic Report in Microsoft Access

ေမာင္လွေရ... မွတ္ထားဦးကြယ့္...

Microsoft Access မွာ Crosstab Query ကို Report ထုတ္မယ္ဆုိရင္ ဒီလုိေလး ထုတ္ရတယ္...

Table ေတြ ရွိၿပီးသား ဆုိရင္ေတာ့ ပထမဆုံးလုပ္ရမယ့္ အလုပ္က Crosstab Query တစ္ခု တည္ေဆာက္ရမယ္... ေဟာ့ဒီမွာ crosstab query design ကို နမူနာၾကည့္ပါဦး...

အဲဒီမွာ OutletID, OutletName, VrNo, NetAmt ေတြက Row Heading လုိ႔ေရြးထားတယ္... Stock ဆုိတဲ့ field ကိုေတာ့ Column Heading ဆုိၿပီး ေရြးထားလုိက္တယ္... NetQty ကိုေတာ့ Value လုိ႔ေရြးလုိက္တယ္... ရက္အလိုက္ေရြးၾကည့္လုိ႔ ရေအာင္ Date ကို Where ဆုိၿပီး ေရြးထားတယ္...

အဲဒီ query ကို run ၾကည့္မယ္ဆုိရင္ ေအာက္က ပုံစံမ်ဳိးေပၚလိမ့္မယ္... အဲဒီမွာ Date တစ္ခု လာေတာင္းလိမ့္မယ္... 6/27/2007 ဆုိၿပီး ႐ိုက္ထည့္လုိက္တယ္... အဲဒီေန႔ဟာေတြပဲ ေဖာ္ျပေပးပါတယ္...

query ကို ပိတ္ၿပီး ေနာက္တစ္ေခါက္ ျပန္ run ၾကည့္ပါဦး... ဒီတစ္ခါ 6/28/2007 လုိ႔႐ုိက္ထည့္ၾကည့္ပါ... ဘာေတြ႕ရမလဲဆုိေတာ့ Row Heading လုိ႔ေျပာထားတဲ့ OutletID, OutletName, VrNo, NetAmt ေတြက data ေတြ မတူႏုိင္ေပမယ့္ ပုံေသ column ေတြ အေနနဲ႔ ေဖာ္ျပေပးၿပီး Column Heading လုိ႔ ေရြးထားတဲ့ Stock ကေတာ့ အဲဒီေန႔မွာ ၁၀-မ်ဳိးေရာင္းရရင္ ေကာ္လံ ၁၀-ခု ေဖာ္ျပေပးမွာ ျဖစ္ၿပီး ၅-မ်ဳိးေရာင္းရင္ ေကာ္လံ ၅-ခု ေဖာ္ျပေပးတာကို ေတြ႕ရပါလိမ့္မယ္... value လုိ႔ ေရြးထားတဲ့ NetQty က ဘယ္နား ေရာက္သြားလဲ ဆုိေတာ့ သက္ဆုိင္ရာ Stock ေကာ္လံထဲမွာ ေဖာ္ျပေပးတာကို ေတြ႕ရပါလိမ့္မယ္...

Report အပုိင္းကို သြားရေအာင္...
Report အသစ္ တည္ေဆာက္ဖုိ႔ Create Report in Design နဲ႔ ဝင္စရာလုိပါတယ္... ေအာက္က ပုံမွာ ျပထားတဲ့ အတုိင္း ဒါမွမဟုတ္ ကိုယ္လုိခ်င္တဲ့ ပုံအတုိင္း Report Design လုပ္ပါ... က်ေတာ္ အခုသုံးထားတဲ့ coding ေတြအတုိင္း သုံးမယ္ဆုိရင္ေတာ့ Label နဲ႔ Text box ေတြ name ေပးတဲ့ ေနရာမွာ Page Header မွာရွိတဲ့ဟာေတြဆုိရင္ lblstk1, lblstk2, lblstk3 ပုံစံနဲ႔ ေပးရပါမယ္... က်ေတာ့္ report မွာ column ၃၀-အထိ ေဖာ္ျပႏုိင္လုိ႔ lblstk30 အထိ ေပးထားတယ္... Detail ထဲမွာ ရွိတဲ့ Text box ေတြကိုေတာ့ က်ေတာ္က stk1, stk2, stk3, ..., stk30 အထိ name ေတြ ေပးထားပါတယ္... Report footer ထဲမွာရွိတဲ့ text box ေတြကိုေတာ့ tot1 ကေန tot30 ဆုိၿပီး name ေတြ သတ္မွတ္ေပးလုိက္ပါတယ္...

ၿပီးရင္ Report design tool bar မွာ code ဆုိတဲ့ button ကိုရွာၿပီး ႏွိပ္ပါ... Option Compare Database ဆုိတဲ့ စာေၾကာင္းနဲ႔ windows ေပၚလာရင္ ေအာက္က ကုဒ္ေတြ ေကာ္ပီကူးၿပီး ထည့္လုိက္ပါ... ေဘးက က်ေတာ္ သိသေလာက္ ရွင္းျပထားတဲ့ ရွင္းလင္း ခ်က္ေတြကိုေတာ့ ဖ်က္ၿပီးထည့္ပါ...
Const conTotalColumns = 30 ' အခု က်ေတာ့္ report မွာ column ၃၀ အထိ အမ်ားဆုံး ရလုိ႔ ၃၀ ဆုိၿပီး ထည့္ထားတာပါ... ေကာ္လံ ၁၅-ခု အမ်ားဆုံးရရင္ 15 လုိ႔ျပင္ေပးပါ...

Dim dbsReport As Database
Dim rstReport As Recordset

Dim intColumnCount As Integer
Dim lngRgColumnTotal(1 To conTotalColumns) As Long
Dim lngReportTotal As Long

Private Sub InitVars()
Dim intX As Integer

lngReportTotal = 0
For intX = 1 To conTotalColumns
lngRgColumnTotal(intX) = 0
Next intX
End Sub

Private Function xtabCnulls(varX As Variant)
If IsNull(varX) Then
xtabCnulls = 0
Else
xtabCnulls = varX
End If
End Function

Private Sub Detail_format(Cancel As Integer, FormatCount As Integer)
Dim intX As Integer

If Not rstReport.EOF Then
If Me.FormatCount = 1 Then
For intX = 6 To intColumnCount ' intX = 6 ဆုိၿပီး 6 ကေန ဘာျဖစ္လုိ႔ စထားလဲဆုိေတာ့ ပထမဆုံး ေကာ္လံ ၅-ခုက အၿမဲတမ္း ေပၚေနမွာ ျဖစ္လုိ႔ပါ... နမူနာမွာေတာ့ ေကာ္လံ တစ္ခုကို က်ေတာ္ blank ဆုိၿပီးေပးထားပါတယ္...
Me("stk" + Format(intX)) = xtabCnulls(rstReport(intX - 1))
Next intX

For intX = intColumnCount + 2 To conTotalColumns
Me("stk" + Format(intX)).Visible = False
Next intX

rstReport.MoveNext
End If
End If
End Sub

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
Dim intX As Integer
Dim lngRowTotal As Integer

If Me.PrintCount = 1 Then
lngRowTotal = 0

For intX = 6 To intColumnCount ' intX = 6 မွာ လုိအပ္ရင္ ဂဏန္းျပင္ေပးရပါမယ္...
lngRowTotal = lngRowTotal + Me("stk" + Format(intX))

lngRgColumnTotal(intX) = lngRgColumnTotal(intX) + Me("stk" + Format(intX))
Next intX

'Me("stk" + Format(intColumnCount + 1)) = lngRowTotal
Me("stk" + Format(intColumnCount + 1)) = Null
'lngReportTotal = lngReportTotal + lngRowTotal
End If
End Sub

Private Sub Detail_Retreat()

' Always back up to previous record when "Detail" section retreats.
rstReport.MovePrevious

End Sub

Private Sub PageHeaderSection_Format(Cancel As Integer, FormatCount As Integer)
Dim intX As Integer
For intX = 6 To intColumnCount ' intX = 6 မွာ လုိအပ္ရင္ ဂဏန္းျပင္ေပးရပါမယ္...
Me("lblstk" + Format(intX)).Caption = rstReport(intX - 1).Name
Next intX

'Me("lblstk" + Format(intColumnCount + 1)).Caption = "Totals"

For intX = (intColumnCount + 2) To conTotalColumns
Me("lblstk" + Format(intX)).Visible = False
Next intX
End Sub

Private Sub Report_Close()

On Error Resume Next

' Close recordset.
rstReport.Close
DoCmd.Close acForm, "dailyRpt43"
End Sub

Private Sub Report_NoData(Cancel As Integer)

MsgBox "No records match the criteria you entered.", vbExclamation, "No Records Found"
rstReport.Close
Cancel = True

End Sub

Private Sub Report_Open(Cancel As Integer)
Dim intX As Integer
Dim qdf As QueryDef
Dim frm As Form

DoCmd.OpenForm "DailyRpt43", , , , , acDialog ' ဒါ ကေတာ့ criteria ေမးမယ့္ form ကို ဖြင့္ခုိင္းတာပါ...

If Not IsLoaded("DailyRpt43") Then
Cancel = True
Report_Close
Else
Set dbsReport = CurrentDb
Set frm = [Forms]![dailyRpt43]
Set qdf = dbsReport.QueryDefs("rpt_43DSR")

qdf.Parameters("[Forms]![dailyRpt43]![Date]") = frm!Date ' query မွာ ေတာင္းထားတဲ့ criteria ဆုိတာ form ထဲက သက္ဆုိင္ရာ field ျဖစ္ေၾကာင္း သတ္မွတ္ေပးလုိက္တာပါ...

Set rstReport = qdf.OpenRecordset()

intColumnCount = rstReport.Fields.Count

End If

DoCmd.Maximize

End Sub

Private Sub ReportFooter_Print(Cancel As Integer, PrintCount As Integer)
Dim intX As Integer
For intX = 6 To intColumnCount
Me("Tot" + Format(intX)).Value = lngRgColumnTotal(intX)
Next intX

'Me("Tot" + Format(intColumnCount + 1)) = lngReportTotal
Me("Tot" + Format(intColumnCount + 1)) = Null

For intX = intColumnCount + 2 To conTotalColumns
Me("Tot" + Format(intX)).Visible = False
Next intX
End Sub

Private Sub ReportHeader_Format(Cancel As Integer, FormatCount As Integer)

rstReport.MoveFirst
InitVars

End Sub


က်န္တာတြေတာ့ မရွင္းတတ္ေတာ့ဘူးဗ်ာ... လုိအပ္ရင္ ကုိယ့္အားကုိယ္ကုိးၿပီး ေရးသားၾကည့္ၾကပါ... ဒီဟာေလးက microsoft.com ကေနရွာေတြ႕ထားတာပါ... ဒီလုိမ်ဳိး ေရးလုိ႔ရတယ္ဆုိတာကို ေျပာျပေပးတဲ့ နားခုိရာ ဘေလာ့ ပုိင္ရွင္ႀကီး ကို Little Moon နဲ႔ မွ NativeMyanmar မွေဘာ္ဒါမ်ားကို အထူး ေက်းဇူးတင္ရွိပါတယ္...

နမူနာ ဖုိင္ေလးပါ ...
http://maunghla.googlepages.com/DynamicReport.mdb

My Label: Access, how to, Crosstab query Report, Dynamic Report

2 comments:

KhunMoung said...

ေမာင္လွေရ...မွတ္ထားဦးကြယ္႔ အစျပဳတဲ႔ ပို႔စ္ေတြကို ကၽြန္ေတာ္သေဘာက်ပါတယ္။ ကိုေမာင္လွရဲ႔ကိုယ္႔ကိုယ္ကို ႏွိမ္႔ခ်သလိုနဲ႔ တျခားသူေတြကိုလည္း ပညာရေစတဲ႔ အေတြ႔အၾကံဳအေျခခံတဲ႔ပို႔စ္ေတြ ျဖစ္ပါတယ္။ ကၽြန္ေတာ္လည္း မွတ္ထားလိုက္ပါျပီ။ :) Cheers ကိုေမာင္လွ။

ေမာင္လွ said...

ေက်းဇူးပါ ကိုခြန္ေမာင္ေရ...
ဒါမ်ဳိးေလးေတြကို စာအုပ္ထဲမွာ ေရးထားရင္ စာအုပ္ေပ်ာက္သြားရင္ က်န္ခဲ့ရင္ က်ေတာ္ မလုပ္တတ္ေတာ့လုိ႔ အင္တာနက္ေပၚမွာ မွတ္တမ္းေလးက်န္ ျဖစ္ေအာင္ ေရးတာပါ...