แสดงกระทู้

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Tatchawin

หน้า: 1 2 3 [4]
55
ขอแทรกหน่อยครับ ดูแล้วเหมือนว่า TerminatedDate จะขึ้นกับ Contractor เพียงอย่างเดียว ไม่ได้ขึ้นกับ WorkID เลย ดังนั้น TerminatedDate ควรไปอยู่ในเทเบิลของ Contractor มากกว่าหรือไม่
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

56
น่าจะได้นะครับ มันจะไปเช็คค่า ContractorID จากคิวรี่ นั้นและ อัพเดท Field TerminatedDate ตาม  ContractorID ครับ
แต่ TerminatedDate และ WorkID ต้องเชื่อมกับตารางไรตารางนึงด้วยนะครับ

โค๊ด: [Select]
Private Sub TerminatedDate_AfterUpdate()
Me.Dirty = False
DoCmd.SetWarnings False
DoCmd.RunSQL "UPDATE qryWork SET qryWork.TerminatedDate = [forms]![frmEditWork]![TerminatedDate] WHERE (((qryWork.ContractorID)=[forms]![frmEditWork]![ContractorID]));", dbFailOnError
DoCmd.SetWarnings True

End Sub
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

57
อ้างถึง
ความต้องการของผมคือ หากกรอก TerminatedDate ที่ Record ใด Record หนึ่ง ก็ให้ค่า TerminatedDate ที่กรอกนั้น ถูก Insert ลงไปยัง Record อื่นๆที่มี ContractorID เดียวกันให้หมด ผมควรจะเขียนโค้ดอย่างไรดีครับ

แก้ไขใหม่
น่าจะเป็น

โค๊ด: [Select]
Private Sub TerminatedDate_AfterUpdate()
Me.Dirty = False
DoCmd.SetWarnings False
DoCmd.RunSQL "UPDATE tblWork SET tblWork.TerminatedDate = [forms]![frmEditWork]![TerminatedDate] WHERE (((tblWork.ContractorID)=[forms]![frmEditWork]![ContractorID]));", dbFailOnError
DoCmd.SetWarnings True
End Sub

tblWork คือตารางที่เราจะอัพเดท By ContractorID ครับ
วิธีนี้ ถ้า ContractorID เดียวกัน ก็จะอัพเดทวันที่ให้ทั้งหมดทุกแถวครับ ไม่สนว่าจะมี WorkID กี่ตัวครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

58
เราก็สามารถสร้างเงื่อนไขต่อไปได้ครับว่า ถ้าฟิลด์ TerminateDate มีค่าก็ให้เทียบค่าวันที่ฟิลด์นี้ แต่ถ้าไม่มีค่าก็เทียบค่าวัน ที่วันที่ปัจจุบัน
คำนวณวัน
CompanyHiringDate_Day:
IIf(isnull([TerminateDate]),
IIf(DateDiff("d",DateAdd("m",DateDiff("m",[CompanyHiringDate],Date()),[CompanyHiringDate]),Date())<0,DateDiff("d",DateAdd("m",DateDiff("m",[CompanyHiringDate],Date())-1,[CompanyHiringDate]),Date()),DateDiff("d",DateAdd("m",DateDiff("m",[CompanyHiringDate],Date()),[CompanyHiringDate]),Date())),
IIf(DateDiff("d",DateAdd("m",DateDiff("m",[CompanyHiringDate],[TerminateDate]),[CompanyHiringDate]),[TerminateDate])<0,DateDiff("d",DateAdd("m",DateDiff("m",[CompanyHiringDate],[TerminateDate])-1,[CompanyHiringDate]),[TerminateDate]),DateDiff("d",DateAdd("m",DateDiff("m",[CompanyHiringDate],[TerminateDate]),[CompanyHiringDate]),[TerminateDate])))

ทำในส่วนของ เดือน และ ปี ด้วย ประมาณนี้ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

59
ตามหลักการแล้ว อะไรที่ขึ้นกับคนนั้นและไม่มีทางเปลี่ยน ก็ให้ผูกกับเทเบิลที่มี Primary Key เป็น NationalID เช่น วันเกิด  แต่อะไรที่เปลี่ยนแปลงไปได้ เช่น ชื่อ นามสกุล ที่อยู่ เบอร์โทร ก็ต้องผูกกับเทเบิลที่มี Primary Key เป็น NationalID + NumberOfEdited  แต่เท่าที่ดู มีแค่ฟิลด์วันเกิดเท่านั้นที่ไม่เปลี่ยนแปลง ดังนั้นการจะแยกเป็นอีกเทเบิลที่มีแต่ฟิลด์ NationalID กับ BirthDate อาจจะดูไม่คุ้มกับการทำ ผมคิดว่าให้เทเบิล tbl_Contracter และ tbl_Address มี Primary Key เป็น NationalID + NumberOfEdited ไปเลยจะดีกว่า และคิดว่าเพิ่มฟิลด์ประเภท Boolean อีกฟิลด์ทั้งใน 2 เทเบิล เพื่อบอกว่า Edition ไหน เป็น Edition ปัจจุบันไปด้วย จะทำให้ตอนค้นหาข้อมูลปัจจุบันเพื่อนำมาใช้ในส่วนต่างๆ ไม่ยุ่งยากเมื่อเทียบกับการต้องหาว่า Edition ไหนเป็น Edition ล่าสุดโดยไม่มีฟิลด์ที่ว่า แต่ก็ต้องจัดการให้ดีๆว่า ในขณะใดขณะหนึ่งต้องมีเพียงเรคอร์ดเดียวเท่านั้นที่ฟิลด์ที่ว่ามีค่าเป็น True    ส่วนเทเบิลอื่นๆที่ต้องโยงมายัง 2 เทเบิลนี้ ก็ต้องเก็บทั้ง NationalID และ NumberOfEdited ไปด้วย ดังนั้น transaction ต่างๆก็จะอิงกับข้อมูลที่เป็นปัจจุบัน ณ เวลานั้นครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

60
ใช่ครับอาจารย์ พอดีไปค้นเจอมาจากเว็บนอกครับเลยเอามาประยุกต์กับเคสนี้  :grin: :grin:
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

61

Public Function RowNum(frm As Form) As Variant
        ...
        ...
        ...

เพิ่งรู้ว่าการอ้าง Form property ผ่านฟังก์ชั่นบน Continuous Form จะทำให้อ้างถึงเรคอร์ดเฉพาะของบรรทัดนั้นๆบนฟอร์ม แทนที่จะเป็นเรคอร์ดปัจจุบันบนฟอร์มเพียงเรคอร์ดเดียว
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

62
อ้างถึง
1. ผมต้องการทำเลขบอกลำดับด้านหน้า Record บนคล้าย Continuous Form คล้ายๆกับ Running Sum บน Report จะมีวิธีการทำอย่างไร? (ตามภาพ)

ขั้นตอนที่ 1 สร้าง Module เอา โค้ดนี้ใส่เข้าไป
โค๊ด: [Select]
Public Function RowNum(frm As Form) As Variant
On Error GoTo Err_RowNum
   
    With frm.RecordsetClone
        .Bookmark = frm.Bookmark
        RowNum = .AbsolutePosition + 1
    End With
   
Exit_RowNum:
    Exit Function
   
Err_RowNum:
    If Err.Number <> 3021& Then
        Debug.Print "RowNum() error " & Err.Number & " - " & Err.Description
    End If
    RowNum = Null
    Resume Exit_RowNum
End Function
ขั้นตอนที่ 2 สร้าง textbox ชื่อ No ที่ ControlSource ใส่ ว่า =RowNum([Form])


ลำดับก็จะรันอัตโนมัติครับ


อ้างถึง
2. ผมทำช่องให้กรอกช่วงเวลาที่ต้องการค้นหา Record(Search by Date Rage) เอาไว้ครับ(ตามภาพ)
แก้โค้ดเป็นแบบนี้ดูครับ ใช้การกำหนด Sql แทน แก้ชื่อ Form1 เป็นชื่อฟอร์มของคุณด้วยนะครับ
โค๊ด: [Select]
Sub Search()
Dim Sql As String
 If IsNull(Me.txtDateFrom) Or IsNull(Me.txtDateTo) Then
    MsgBox "Please enter the date range", vbInformation, "Date Range Required"
    Me.txtDateFrom.SetFocus
    Sql = "SELECT * FROM qryTransactions ORDER BY qryTransactions.TransactionsDate;"
        Else
    Sql = "SELECT * FROM qryTransactions  WHERE (((qryTransactions.[TransactionsDate]) Between forms!Form1!txtDateFrom And forms!Form1!txtDateTo)) ORDER BY qryTransactions.TransactionsDate;"       
End If
        Me.Form.RecordSource = Sql       
End Sub

อ้างถึง
3. ผมต้องการให้แสดงผลลัพธ์ทั้งหมดที่ค้นหาได้ ตามภาพด้านบน จะมีแนวทางเขียนโค้ดอย่างไร
ผมสมมัติสร้าง textbox ไว้เก็บจำนวน Record ชื่อ txt_TotalRecordSearch
เวลาเราจะเรียกใช้ก็นำไปรวมกับ คำสั้งค้นหาวันที่ แบบนี้คับ

โค๊ด: [Select]
Sub Search()
Dim Sql As String
Dim FormRecCount  As Long
 If IsNull(Me.txtDateFrom) Or IsNull(Me.txtDateTo) Then
    MsgBox "Please enter the date range", vbInformation, "Date Range Required"
    Me.txtDateFrom.SetFocus
    Sql = "SELECT * FROM qryTransactions ORDER BY qryTransactions.TransactionsDate;"
        Else
    Sql = "SELECT * FROM qryTransactions  WHERE (((qryTransactions.[TransactionsDate]) Between forms!Form1!txtDateFrom And forms!Form1!txtDateTo)) ORDER BY qryTransactions.TransactionsDate;"       
End If
        Me.Form.RecordSource = Sql
        Me.txt_TotalRecordSearch.ControlSource = "=Count(No)"
End Sub

ตัวอย่างด้านล่างนะครับ

โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

63
เนื่องจากฐานข้อมูลมีการเปิดใช้ BigInt ไปแล้ว ซึ่งจะทำให้ฐานข้อมูลถูกอัพเกรดเป็น database รุ่น 16.7 อย่างถาวร ซึ่งจะเปิดใช้ได้เฉพาะ Access 2016 รุ่น 16.0.7xxx เป็นต้นไปเท่านั้น

วิธีแก้ไขคือให้เปลี่ยน data type จาก BigInt (Large Number) เป็น Number ธรรมดา

หลังจากนั้นให้สร้างไฟล์ Database ใหม่โดยที่ตรง Database Option ต้องไม่เปิดการใช้งาน BigInt (Support Bigint Data Type for Linked/Imported Tables ปกติมันจะไม่เปิดอยู่แล้ว) แล้วให้ Import ตารางจากไฟล์เก่าเข้ามาในไฟล์ Database ที่สร้างใหม่นี้แทน

https://support.office.com/en-gb/article/using-the-large-number-data-type-5b623f6e-641d-4e97-8bdf-b77bae076f70
https://support.office.com/en-gb/article/set-user-options-for-the-current-database-29b6b7be-4c3b-43a7-b8f0-5e1c68f5adce#largenumber
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

64
ขออนุญาตเรียนถามท่านครับ ว่าของท่านเคยเจอเคสแบบผมไหม แล้วถ้าแก้ไขตามที่ท่านว่า สามารถเปิดดูได้รึเปล่าครับ ขอบคุณครับ

ไม่เคยครับ แต่ Microsoft มาตอบเองคุณก็ลองเช็คดูครับว่ามี field ที่เป็น BigInt หรือไม่ ถ้าใช่มันก็คือสาเหตุแหละครับ หรือไม่อย่างนั้นก็อัพเกรดตัว MS Access 2016 เป็น version 16.0.7xxx.xxxx or later. แต่ผมไม่แนะนำวิธีหลังเพราะเดี๋ยวมีลูกค้าไปเปิดใน 2013 หรือ 2010 ก็เจอปัญหาอีก
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

65
https://support.microsoft.com/en-us/help/3208802/database-you-are-trying-to-open-requires-a-newer-version-of-microsoft

มีการใช้ BigInt Data type เช็คตารางที่มีการใช้ BigInt ให้เปลี่ยนจาก large Number เป็น Number เฉยๆ
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

66
...
...
...
        Me.RecordSource = strsearch
        If Me.Recordset.RecordCount <= 0 Then
            Msgbox .....
        End If
...
...
...
โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

67
เนื่องจากการสร้าง MainForm/Subform จำเป็นต้องมีการเชื่อมโยงกันระหว่างฟิลด์ Primary Key กับ Foreign Key

ในภาวะปกติจึงเป็นไปไม่ได้ที่จะบันทึกข้อมูลพร้อมกัน

สิ่งที่คุณต้องการนั้น จำเป็นต้องใช้ Unbound Form ซึ่งมีปุ่มใส่ข้อมูลเข้าไปในตารางครับ
โดย VBA ในปุ่มนี้สามารถทำได้หลายวิธีเช่น
1. ใช้ ADO Datasource
2. ใช้ DAO Datasource
3. ใช้ Docmd.RunSQL

โพสต์นี้ได้รับคำขอบคุณจาก: Tatchawin

หน้า: 1 2 3 [4]