ต้องการเติมวันที่ไม่มีข้อมูล REPORT
กระทู้เก่าบอร์ด อ.Yeadram

 2,796   14
URL.หัวข้อ / URL
ต้องการเติมวันที่ไม่มีข้อมูล REPORT

ผมมีข้อมูลการเบิกสินค้าดังนี้
                           เบิก
1/1/52                  10 ชิ้น
15/1/52                 20 ชิ้น
23/1/52                 10 ชิ้น

แต่ REPORT ต้องการ แสดงทุกวันที่ เช่น
1/1/52                  10 ชิ้น
2/1/52                    0 ชิ้น
3/1/52                    0 ชิ้น
........
15/1/52                 20 ชิ้น
.........
23/1/52                 10 ชิ้น

(แบบฟอร์มเขากำหนดแบบนี้ครับ-และไม่ต้องการเก็บ หรือ KEY RECORD ที่ไม่ได้เบิก(0 ชิ้น))
จะต้องทำอย่างไรครับ ขอบคุณครับ

14 Reply in this Topic. Dispaly 1 pages and you are on page number 1

1 @R01337
วิธีที่ 1 การสร้างตารางหลอก แล้วเอามาเชื่อมกัน (Left Join)

ตารางหลอกที่ว่านี้ เราจะสร้างให้มีฟิลด์เดียว เป็นชนิด Date/Time
............
    On Error Resume Next
     currentproject.connection.excute "create table tb1 (rpDate Date)"
     If Err = 3010 Then currentproject.connection.excute "Delete From tb1"
.....................

สมมติว่า source ของคุณ (query หรือ table ) ชื่อว่า src1 มีฟิลด์วันที่ ชื่อ docDate
- ให้หาวันที่แรกสุดของ source เข้าตัวแปร bgDate
- ให้หาวันที่สุดท้ายของ source เข้าตัวแปร fnDate
- ให้หาผลต่างเพื่อวนลูป j= datediff("d",fnDate,bgDate)
ทำการวนลูป ป้อนข้อมูลเข้าตาราง
for i = 0 to j
currentproject.connection.excute "INSERT INTO tb1 (" & dateadd("d",i,bgDate) & ")"
next

ทีนี้คุณก็จะได้ตารางหลอกเรียบร้อย ให้เอาตารางหลอก มาเชื่อมกับ src1 ของคุณแล้วเอาไปเป็น source ของรายงานได้เลยครับ

me.recordsource = "SELECT rpDate, src1.*
FROM tb1 LEFT JOIN src1 ON rpDate = docDate;"


ลองดูครับ
2 @R01338
ผมขอเสนออีกวิธีให้ทดลองกัน

Report มี property เฉพาะอยู่ตัวนึงที่ชื่อ NextRecord ซึ่งจะมีค่าเป็น True/False ระบบจะกำหนดให้มีค่าเป็น True ก่อน Format event ทุกครั้งเสมอ เมื่อเป็น True เรคอร์ดที่จะนำไปพิมพ์จะเป็นเรคอร์ดต่อไป ซึ่งก็จะเป็นไปตามปกติที่เราเห็นๆกันอยู่   แต่ถ้าเป็น False เรคอร์ดจะยังคงเป็นเรคอร์ดเดิม เราสามารถใช้คุณสมบัตินี้มาตรวจและกำหนดได้ว่าจะพิมพ์อะไรออกมา

สมมุติว่าบน Report มีเท็กซ์บอกส์สำหรับแสดงวันที่ (fDate), จำนวน (fQty), วันที่จากเทเบิล (DT) และจำนวนจากเทเบิล (Qty) สองอันหลังให้ Invisible ไว้ แล้วคุณก็ใส่โค้ดข้างล่างนี้ลงไป

Dim mLastDT     As Variant ' เก็บวันที่ล่าสุดที่พิมพ์ไปแล้ว
Dim mCurrDT     As Variant ' วันที่ปัจจุบันที่ควรจะพิมพ์

Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
    If IsEmpty(mLastDT) Then    ' ถ้าก่อนหน้ายังไม่ได้กำหนดอะไรมาเลย
        mCurrDT = Me.DT        ' ก็ให้เป็นวันแรกที่อ่านข้อมูลได้
    Else
        mCurrDT = DateAdd("d", 1, mLastDT) ' ไม่เช่นนั้น ก็ให้เป็นวันถัดจากวันล่าสุดที่ได้พิมพ์ไปแล้ว
    End If
    
    Me.fDate = mCurrDT          ' พิมพ์วันที่
    If mCurrDT <> Me.DT Then    ' ถ้าวันที่ควรจะพิมพ์ไม่เป็นวันเดียวกับวันที่อ่านได้
        Me.NextRecord = False   ' กำหนดให้ไม่ต้องเลื่อนเรคอร์ด
        Me.fQty = 0             ' พิมพ์จำนวนเป็นศูนย์
    Else
        Me.fQty = Me.Qty        ' ไม่เช่นนั้น ก็พิมพ์จำนวนจากข้อมูลที่อ่านได้
    End If
    
End Sub

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
    mLastDT = mCurrDT           ' กำหนดวันที่ล่าสุดที่ได้พิมพ์ไป
End Sub
3 @R01339
แจ่มครับ เพิ่งรู้ว่ามีวิธีนี้ ขอบคุณ อาจารย์มากครับ จะเก็บไว้ลองครับ
4 @R01340
ดีมากเลย
ความรู้ใหม่
5 @R01341
ได้แล้วครับ แบบ อาจารย์ว่า ผมงงอยู่นาน ครง
(fDate), (fQty), ก็คือสร้าง TEXTBOX เป่ล่า ไม่ ผูก กับใคร
OK ครับ
ส่วน(DT) (Qty) ผูกกับ TABLE
ขอบคุณครับ
6 @R01348
Dim mLastDT     As Variant ' เก็บวันที่ล่าสุดที่พิมพ์ไปแล้ว
Dim mCurrDT     As Variant ' วันที่ปัจจุบันที่ควรจะพิมพ์
Dim i 'คงเหลือสะสม
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If IsEmpty(mLastDT) Then
        mCurrDT = Forms("50stock_card").Text8
        i = Me.Text17
    Else
        mCurrDT = DATEADD("d", 1, mLastDT) '
    End If
    
    Me.fDate = mCurrDT
    If mCurrDT <> Me.date2 Then
        Me.NextRecord = False
        Me.fQty = 0
        Me.satana1 = ""
        Me.com1 = "ไม่มีรับ/จ่าย"
        Me.ROY = i
    Else
        Me.fQty = Me.Res
        Me.satana1 = Me.satana
        Me.com1 = Me.Com
        Me.ROY = Me.Text17
        i = Me.Text17
    End If
End Sub
ติดปัญหาอีกนิดครับ คือผมต้องการให้ออกทั้งหมดตาม FORM ระบุ เช่น
mCurrDT = Forms("50stock_card").Text8 อันนี้ได้แล้ว เป็นขอบล่าง

แต่ขอบบน จะอ้างให้เท่ากับ FORM อีกเช่นกัน
แต่มีข้อมูลไม่ถึงขอบบน   เช่นผมระบุใน FORM ถึงวันที่ 31/11/51
แต่ข้อมูลมันมีถึงวันที่ 14/11/51 พอมัน RUN มาถึง 14/11/51
มันก็ไม่บวกเพิ่มวันแล้ว ผมต้องการให้มัน RUN ต่อ ถึง 31/11/51
ตามที่เราใส่ตัวแปรใน FORM
เช่น
1/11/51
2/11/51
.....

14/11/51   'ข้อมูลสุดท้ายถึงตรงนี้ครับ
-----
----
31/11/51   แม้ว่าจะไม่มีข้อมูลก็ตาม
ผมต้องแก้ตรงไหนครับ
7 @R01353
ผมได้แก้ไข แต่ยังอิงจากโค้ดเดิมของผมเองนะครับ ก็เอาไปปรับปรุงแล้วกัน   ส่วนที่แก้ไขเพิ่มเติม ผมจะ comment ด้วยเครื่องหมาย <=== เอาไว้   ส่วนตัวแปร mBeginDT, mEOFDT และ mStopDT ผมกำหนดให้เป็นค่าคงที่ แต่เวลาใช้จริง จะไปหาค่ามาจากไหน ก็แล้วแต่จะเอาไปประยุกต์ใช้นะครับ


Dim mLastDT     As Variant ' เก็บวันที่ล่าสุดที่พิมพ์ไปแล้ว
Dim mCurrDT     As Variant ' วันที่ปัจจุบันที่ควรจะพิมพ์

Dim mEOFDT      As Variant ' <=== วันที่สุดท้ายที่มีข้อมูลอยู่จริง
Dim mBeginDT    As Variant ' <=== วันแรกที่ต้องการพิมพ์ ** ห้ามมากกว่าวันแรกที่มีข้อมูลอยู่จริง **
Dim mStopDT     As Variant ' <=== วันสุดท้ายที่ต้องการพิมพ์ ** ห้ามน้อยกว่า mEOFDT **

Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
    If IsEmpty(mLastDT) Then
        mCurrDT = mBeginDT ' <===
    Else
        mCurrDT = DateAdd("d", 1, mLastDT)
    End If
    
    Me.fDate = mCurrDT
    
    ' <=== ตั้งแต่ส่วนนี้ลงไป
    ' แยกพิจารณาระหว่าง
    ' 1) เมื่อไหร่จะพิมพ์ข้อมูลจากเทเบิล
    ' 2) เมื่อไหร่จะเลื่อนเรคอร์ด
    
    ' พิจารณาส่วนที่ (1)
    If (mCurrDT = Me.DT) And (mCurrDT <= mEOFDT) Then
        Me.fQty = Me.Qty
    Else
        Me.fQty = 0
    End If
    
    ' พิจารณาส่วนที่ (2) แม้ว่าการสั่ง Me.NextRecord = True
    ' จะไม่ต้องเขียนก็ได้เพราะเป็นค่า Default อบู่แล้ว
    ' แต่เพื่อให้ง่ายต่อความเข้าใจในการเปรียบเทียบ
    ' ระหว่างช่วงเวลาว่าช่วงไหนจะเลื่อน/ไม่เลื่อนเรคอร์ด
    ' ผมก็เลยระบุเอาไว้
    If mCurrDT = mStopDT Then
        Me.NextRecord = True
    ElseIf (mCurrDT >= mEOFDT) And (mCurrDT < mStopDT) Then
        Me.NextRecord = False
    ElseIf (mCurrDT = Me.DT) Then
        Me.NextRecord = True
    Else
        Me.NextRecord = False
    End If
End Sub

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
    mLastDT = mCurrDT
End Sub

Private Sub Report_Open(Cancel As Integer)
    mBeginDT = #11/1/2008#       ' <===
    mEOFDT = #11/14/2008#        ' <===
    mStopDT = #11/30/2008#       ' <===
End Sub

8 @R01356
preview ในREPORT ถูกทุกอย่าง แต่เวลา PRINT ไม่เหมือน PREVIEW

ผมงง มากๆ ใน PREVIEW เหมือนมีหน้าเดียว เมื่อเลือกออกเดือนเดียวทุกอย่างถูกหมด(เลื่อน RECORD หน้าถัดไปไม่ได้) แต่เวลา PRINT มันเหมือนมีเป็น ร้อยๆ หน้า ออก RECORD ถัดไปเรื่อยๆ เมื่อลองสั่ง EXPORT ทาง EXCEL มันก็ RUN เป็นร้อยหน้า เหมือนวนลูป แล้ว ไม่สามารถพบเงื่อนไขที่ออกมาได้

แต่ที่งงคือ PREVIEW มันถูกทุกอย่างครับ เดียวลองไปตรวจสอบเงื่อนไขดูอีกทีครับ
9 @R01357
ใน PREVIEW REPORT มันแสดงตรงเงื่อนไข ที่กำหนดจาก FORM เช่น
1/1/51
-----
-----
31/1/51


เวลา print มันออกมาเป็น
1/2/51
------
-----
ไอ้ตรง เดือน 2 นี่ ไม่รู้มางัยครับ
ทั้งที่สั่ง PRINT ทีล่ะหน้า ครับ
10 @R01358
คิดว่าเป็น BUG แน่ preview กับ print ไม่เหมือนกัน
แก้ไม่ตก ตอนนี้ใช้วิธีคุณ YEADRAM แล้ว
เสร็จงานแล้ว เย้ เที่ยงพอดี
11 @R01359
ที่เป็นเช่นนี้เพราะการ preview ทำให้ค่าในตัวแปร mXXXXX มีค่าเรียบร้อยแล้ว     ส่วนการสั่ง pint จากหน้า preview นี้ ค่าตัวแปรต่างๆจะไม่ได้ถูก initialize    สถานะของมันจะไม่เป็นเหมือนตอนเริ่มเปิดตัว report    ดังนั้นลอจิคที่ทำงานจึงไม่เป็นไปตามที่เราคิด   ลอจิคของเราขึ้นกับค่าตัวแปรเหล่านั้นด้วย

วิธีแก้คือให้เพิ่ม PageHeader section ในตัว Report ด้วย แล้วเราจะย้ายการ initialize ค่าตัวแปรจาก Report_Open event ไปเป็น PageHeaderSection_Format event แทน

Private Sub PageHeaderSection_Format(Cancel As Integer, FormatCount As Integer)
    If Me.Page = 1 Then
        mLastDT = Null               ' <===
        mBeginDT = #11/1/2008#       ' <===
        mEOFDT = #11/14/2008#        ' <===
        mStopDT = #11/30/2008#       ' <===
    End If
End Sub

และเปลี่ยนคำสั่งการตรวจสอบ mLastDT จาก IsEmpty( ) เป็น IsNull( ) แทนดังนี้

Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
    If IsNull(mLastDT) Then    ' <===
    ...
    ...
    ...
12 @R01363
ลึกซึ้งมากครับ อาจารย์ เดี๋ยวจะลองเล่นดู
13 @R01366
ได้แล้วครับ   อาจารย์รู้ได้งัย
14 @R01367
มีหลายกรณีที่ทำให้ preview กับ print ต่างกัน   เรื่องของ initialize ตัวแปรนี่ก็เป็นเรื่องนึง   อันนี้ผมไม่รอบคอบเองครับที่ทำ initialize ไว้ที่ _Open event   

เรื่องของ Report มีความเป็นไปได้สูงที่จะทำงานแล้วประหลาดๆ เมื่อเมื่อใดก็ตามที่มีการบังคับการทำงานหรือใส่ลูกเล่นของตัว Report    ข้อนี้ขอให้จำไว้เป็นข้อสังเกตหลักเลยครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.3382s