การใส่วันที่ในหลายๆฟีวด์โดยตรวจสอบค่าว่างก่อน
กระทู้เก่าบอร์ด อ.Yeadram

 1,278   10
URL.หัวข้อ / URL
การใส่วันที่ในหลายๆฟีวด์โดยตรวจสอบค่าว่างก่อน

หลักการ คือ มีเครื่องมือหนึ่งชนิดอยู่ในโกดัง มีการนำไปใช้ได้หลายครั้งในเวลาต่างๆกัน ในแต่ละครั้งที่นำไปใช้จะมีการบันทึกวันที่นำไปใช้ แต่ไม่ได้ใส่วันที่ไปตรงๆมันมีขั้นตอนการนำไปใช้หลายขั้น และขั้นสุดท้ายต้องบันทึกวันที่ใช้ ดังนั้นอยากให้คลิ๊กปุ่มเดียวแล้วรวมให้ใส่วันที่ในตารางด้วย
วิธีการ คือ มีตาราง tbl_A มีฟีวด์ ID (primary key, autonumber), tool_name, Date01, Date02, Date03, Date04, Date05 รวม 7 ฟีวด์
สร้างฟอร์มหนึ่งฟอร์ม ชื่อ frm_tool โดยใช้ข้อมูลมาจากตาราง tbl_A ดังกล่าว
ในฟอร์มนี้มี textbox ชื่อ dateuse เพื่อใส่วันที่ และ check box เพื่อเลือกเรคอร์ดที่ต้องการ เช่น เรคอร์ดที่ tool_name เป็น "A" สิ่งที่ต้องการ คือ ถ้าใส่วันที่ใน textbox นี้แล้วเลือกใน check box ว่าเลือก tool_name "A" กดปุ่มตกลง ให้ตรวจสอบว่าค่าวันที่ในฟีวด์ Date01, Date02, Date03, Date04, Date05 ว่างหรือไม่ โดยไล่ตั้งแต่ Date01 ถ้า Date01 ว่างให้ใส่ค่าวันที่จาก textbox ที่มาจากในฟอร์มนั้น ในฟีวด์ Date01 นี้ โดยไม่ต้องใส่ในฟีวด์ที่เหลือ (Date02, Date03, ...)
ถ้าในฟีวด์ Date01 มีค่าวันที่อยู่แล้วให้ตรวจ Date02 ว่าว่างหรือไม่ (ไม่ต้องทำอะไรกับฟีวด์ Date01) ถ้าว่างก็ให้ใส่ค่าวันที่จาก textbox ที่มาจากในฟอร์มนั้น ในฟีวด์ Date02 โดยไม่ต้องใส่ในฟีวด์ที่เหลือ (Date03, Date04, ...) อย่างนี้ไปเรื่อยๆจนได้วันที่ครบทั้ง 5 ฟีวด์
ไม่รู้ทำอย่างไร
รบกวนด้วยครับ

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

1 @R19242
ใช้การลูปครับ สมมุตชื่อ txtbox ชื่อเดียวกับชื่อฟิลด์ตารางคือ Date1..2..3..4..5ประมาณนี้

Dim i As Integer
For i = 1 To 5
    If IsNull(Me("Date0" & i)) Then
        Me("Date0" & i) = Me.dateuse
        Exit For
    End If
Next i

ปล. จริงๆการเก็บค่ารูปแบบเดียวกันหลายฟิลด์แบบนี้ไม่ยืดหยุ่นเท่าไหร่นะครับ หากมีการเบิกครั้งที่ 6,7,8 จะเก็บยังไง ลักษณะนี้ตามหลักผมว่าเก็บเป็นฟิลด์เดียวแหละครับคือ Date0 โดยเก็บในลักษณะของ Text แทน และแบ่งข้อมูลโดยใช้ , ก็ได้ เวลาดูข้อมูลก็ใช้การ Split() ดูเอาอย่างในกระทู้นี้ก็ได้ครับ
http://www.thai-access.com/yeadram_view.php?topic_id=4239

If Me.Date0 & "" = "" then
    me.date0 = me.dateuse
Else
    me.date0 = me.date0 & "," me.dateuse
End if

แต่ลักษณะนี้อาจต้องเขียนโค๊ดเยอะหน่อย แต่ผมว่ายืดหยุ่นกว่าเพราะจะบันทึกกี่ครั้งก็ได้
2 @R19259
คำสั่งนี้ใช้ได้ครับ แต่ได้แค่เรคอร์ดเดียว ผมต้องการให้ใส่ค่าใน textbox แล้วไปลงในฟีวด์ date ของทุกเรคอร์ดที่เลือกครับ รบกวนด้วยครับ
Dim i As Integer
For i = 1 To 5
    If IsNull(Me("Date0" & i)) Then
        Me("Date0" & i) = Me.dateuse
        Exit For
    End If
Next i
3 @R19266
คำว่าทุกเรคคอร์ดที่เลือก คุณออกแบบการเลือกยังไงครับ
4 @R19267
เลือกโดยใช้ check box ครับ คือ เมื่อ check แล้วจะต้องใส่ค่าวันที่จาก textbox ในเรคอร์ดนั้นๆตามเงื่อนไขดังกล่าวตามคำถามครับ
5 @R19277
ไม่ค่อยเข้าใจการออกแบบของคุณนะครับ ตามที่เข้าใจคือว่าคุณสร้างฟิลด์ checkbox อีกฟิลด์ในตารางไว้สำหรับเลือกด้วยใช่ป่าวครับ ถ้างั้นก็เขียนประมาณแบบนี้เพิ่มเข้าไปครับ (สมมุติฟิลด์ Checkbox ขื่อ chk)

    Me.Recalc
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("tbl_A", dbOpenDynaset)
    rs.MoveFirst
    Do Until rs.EOF
        If rs("chk") Then
            Dim i As Integer
            For i = 1 To 5
            If IsNull(rs("Date0" & i)) Then
               rs.Edit
               rs("Date0" & i) = Me.dateuse
               rs.Update
               Exit For
            End If
            Next i
        End If
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    Me.Recalc

ประมาณนี้ครับ ต้องปรับใช้ดูจริงเพราะผมเขียนจากการเดาซึ่งยอมรับว่าผมยังไม่เข้าใจการออกแบบของคุณเท่าไหร่ ยังไงทำความเข้าใจปรับแก้เอาครับ
6 @R19286
ได้แล้วครับ เยื่ยมมากเลย ผมงมอยู่หลายวัย ขอบคุณอาจารย์ TTT มากๆครับ และผมอยากทราบความหมายของแต่ละคำสั่งทีละบรรทัดได้ไหมครับ เช่น   Me.Recalc หมายถึงอะไร อย่างนี้เป็นต้นนะครับ
ขอบคุณอีกครั้งครับ
7 @R19359
จากคำถามข้างบนทำได้แล้ว แต่มีคำปรึกษาเพิ่มเติมครับ คือว่าถ้าต้องการลบวันที่ครั้งล่าสุดที่พึ่งใส่ไปทุกเรคอร์ดที่เลือกต้องเขียนโค้ดอย่างไรครับ
8 @R19360
Me.Recalc คือ Recalculates สำหรับการสั่งให้ฟอร์ม คำนวณค่าใหม่อีกครั้ง แต่ในที่นี่เราใช้เป็นคำสั่งให้เซฟข้อมูลกรณีที่สถานะของเรคคอร์ดนั้นยังเป็นการแก้ไข
โดยจะแต่ต่างกับการใช้คำสั่ง Requery คือจะไม่ใช่การอ่านเรคคอร์ดใหม่ทั้งหมด ทำให้แก้ปัญหาในการสั่ง Requery บนฟอร์มที่เป็น Continuous แล้วเรคคอร์ดจะกลับไปที่เรคคอร์ดแรกเสมอ

หรือกรณีแบบนี้จะใช้ Me.Refresh ก็ได้เหมือนกันแล้วแต่ชอบครับ

- F9 คือ Recalculates เหมือน Me.Recalc
- F5 คือ Refreshes เหมือน Me.Refresh
- Shift + F9 คือ Requeries เหมือน DoCmd.Requery
9 @R19361
การสร้างปุ่ม ลบครั้งสุดท้ายที่เคยทำ

1. ประกาศตัวแปรในส่วนของ Declarations Section

Private iUndo As String ' สำหรับเก็บค่า ลำดับเรคคอร์ดที่เคยใส่ครั้งล่าสุด และชือฟิลด์ที่ใส่ว่าใส่ลงในฟิดล์ชื่ออะไร

2. แก้ไขโค๊ดเดิมสำหรับการใส่วันที่ดังนี้:

'-------เคลียร์ค่าตัวแปร iUndo ทุกครั้ง
    iUndo = ""
'--------------------------------------------
    Me.Recalc
    Dim iCount As Long
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("tbl_A", dbOpenDynaset)
    rs.MoveFirst
    Do Until rs.EOF
'-----------------เพิ่มตัวแปรสำหรับนับลำดับเรคคอร์ด จะได้รู้ตำแหน่งเรคคอร์ดที่เพิ่มข้อมูลล่าสุด
        iCount = iCount + 1
'------------------------------------------------------------------------------------------
        If rs("chk") Then
            Dim i As Integer
            For i = 1 To 5
            If IsNull(rs("Date0" & i)) Then
               rs.Edit
               rs("Date0" & i) = Me.dateuse
'---------------เพิ่มในส่วนนี้เพื่อเก็บข้อมูลการบันทึกในตัวแปร iUndo
               If iUndo & "" = "" Then
                    iUndo = iCount & "-" & "Date0" & i
               Else
                    iUndo = iUndo & "," & iCount & "-" & "Date0" & i
               End If
'--------------------------------------------------------------------------------
               rs.Update
               Exit For
            End If
            Next i
        End If
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    Me.Recalc

3. สร้างปุ่มสำหรับการ UnDo ใส่โค๊ดที่ Event > On Click ดังนี้:

    If iUndo & "" <> "" Then
        Me.Recalc
        Dim rs As DAO.Recordset
        Set rs = CurrentDb.OpenRecordset("tbl_A", dbOpenDynaset)
        Dim x() As String
        Dim i As Integer
        If Not IsNull(iUndo) Then
            x = Split(iUndo, ",")
            For i = 0 To UBound(x)
               rs.MoveFirst
               rs.Move (Mid(x(i), 1, InStr(1, x(i), "-") - 1) - 1)
               rs.Edit
               rs(Mid(x(i), InStr(1, x(i), "-") + 1)) = Null
               rs.Update
            Next i
        End If
        rs.Close: Set rs = Nothing
        Me.Recalc
        iUndo = ""
    End If

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