มีปัญหาในการสร้าง Query กับการสร้าง Form รบกวนหน่อยครับ


0 สมาชิก และ 2 บุคคลทั่วไป กำลังดูหัวข้อนี้

04 ก.ค. 62 , 11:30:46
ตอบกลับ #18

Tonwrp

อ้างถึง
คราวนี้เป็น Status เป็น No หมดทุกตัวเลยครับอาจารย์
หมายถึงคอมโบบ็อกส์แสดงพวกที่เป็น No หมด หรือว่ายังไง

เอาโค้ดที่เขียนมาให้ดูอีกทีครับ

และลองทดสอบโดยการก็อปปี้ข้อความในส่วนสีแดง (จากโค้ดคุณเองนะ ไม่ใช่ก็อปจากคำตอบนี้) แล้วไปเปิด Query ใหม่สักตัว เลือกแสดงเป็น SQL View  แปะข้อความที่ก็อปปี้ลงไป  แล้วเปิดเป็น Datasheet View ดูว่าผลเป็นอย่างไร
 
Me.Asset_ID.RowSource = "  SELECT Asset_ID FROM Tb_Assets WHERE ASSET_Status = YES  "

ขึ้นว่า Invalid SQL Statement ครับ ส่วนใน Tb_Assets นั้นตรงฟิลด์ที่เป็น Yes/No มันเอาติ๊กออกหมดเลยครับกลายเป็น No หมดเลย จึงไม่แสดงใน combobox เลยครับ
ส่วนพอเปิด Form ขึ้นมามันแจ้งว่าเกิด Debug ใน Code ตรงนี้ครับ
Me.cbo_Asset.RowSource = "SELECT Asset_ID FROM Tb_Assets WHERE Asset_ID = " & CStr(Me.Asset_ID) & " OR Asset_Status = YES"

 

04 ก.ค. 62 , 11:51:00
ตอบกลับ #19

สันติสุข

อ้างถึง
ขึ้นว่า Invalid SQL Statement ครับ
แปลว่า SELECT statement นั้นมีอะไรผิดแล้ว เช็คดีๆครับว่าชื่อฟิลด์ ชื่อเทเบิล ถูกต้องหรือไม่

อ้างถึง
ใน Tb_Assets นั้นตรงฟิลด์ที่เป็น Yes/No มันเอาติ๊กออกหมดเลยครับกลายเป็น No หมดเลย
ในคำสั่ง DoCmd.RunSQL "UPDATE ... เช็คชื่อฟิลด์ เทเบิล และคอมโบบ็อกส์ว่าถูกต้องหรือไม่

อ้างถึง
มันแจ้งว่าเกิด Debug ใน Code
มันบอกว่า error อะไรครับ เอาข้อความมาแสดงหน่อย หรือว่าคุณแบ่งโค้ดเป็น 2 บรรทัด  ถ้าใช่ ให้แก้ไขให้อยู่ในบรรทัดเดียวกันนะครับ

สุดท้าย ให้คลิกที่เมนู Debug และ Compile ดูว่ามีข้อผิดพลาดอะไรแสดงออกมาหรือไม่

ปล.คงอีกหลายชั่วโมงผมถึงเข้ามาตอบอีกทีครับ
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

04 ก.ค. 62 , 13:31:32
ตอบกลับ #20

Tonwrp

ตอนนี้ผมทำได้แล้วครับ
เพราะผมเข้าไปแก้ Code ในส่วนของ Form_Current()
จาก " SELECT Asset_ID FROM Tb_Assets WHERE Asset_Status = Yes "
ผมเปลี่ยนเป็น " SELECT * FROM Tb_Assetes WHERE Asset_Status = Yes " แทนครับ
เนื่องจากหน้าฟอร์มของผมต้องให้ค่าของ Column2 , Column3 ไปแสดงยัง Textbox ด้วยครับเป็น Serial No กับ Code No ของ Asset

ตอนนี้เกิด Compile Error ครับเป็นเรื่องของ
Argument not optional ครับมันไปเกิดตรงปุ่ม Save ได้ยังไงก็ไม่ทราบครับตอนนี้มึนมากๆ
ตัว Code ของปุ่ม save ยังเป็นตัวเดิมคือ
Private Sub bt_SaveLoan_Click()
Dim SavRec As Boolean
    If IsNull(Loan_No) Then
        MsgBox ("Please Put Loan No")
    ElseIf IsNull(Loan_Date) Then
        MsgBox ("Please Put Loan Date")
    ElseIf IsNull(Employee_ID) Then
        MsgBox ("Plse Put Employee Name")
    Else
        DoCmd.RunCommand (acCmdSaveRecord)
        DoCmd.RunSQL "UPDATE Tb_Assets SET Asset_Status = FALSE WHERE Asset_ID = " & CStr(Me.Asset_ID)
        SavRec = True
    End If
       
End Sub


เหมือนเดิมตามที่อาจารย์บอกเลยครับหรือว่าผมต้องเพิ่มเงื่อนไขไปอีกครับขอบคุณอาจารย์สันติสุขมากๆครับ
« แก้ไขครั้งสุดท้าย: 04 ก.ค. 62 , 14:38:22 โดย Tonwrp »

 

04 ก.ค. 62 , 18:46:07
ตอบกลับ #21

สันติสุข

ให้ลองเปลี่ยนชื่อ Loan_No, Loan_Date, Employee_ID, Asset_ID ไปเป็น  Me.ชื่อเท็กซ์บ็อกซ์หรือคอมโบบ็อกส์  ที่ตรงกันบนฟอร์มดูครับ  ถ้ายังไม่ได้อีก ก็ให้ลอง Compact and Repair Database ครับ
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

05 ก.ค. 62 , 08:47:53
ตอบกลับ #22

Tonwrp

ให้ลองเปลี่ยนชื่อ Loan_No, Loan_Date, Employee_ID, Asset_ID ไปเป็น  Me.ชื่อเท็กซ์บ็อกซ์หรือคอมโบบ็อกส์  ที่ตรงกันบนฟอร์มดูครับ  ถ้ายังไม่ได้อีก ก็ให้ลอง Compact and Repair Database ครับ

ยังไม่ได้เช่นเดิมครับอาจารย์สันติสุขใน Form การคืนของก็เป็นที่จุดเดียวกันครับ ทั้งเปลี่ยนเป็น Me.txt_.....และ Compact and Repair Database ก็แล้วยังขึ้นเหมือนเดิมเลยครับ
ไม่ทราบว่าผมเขียนอะไรผิดรึเปล่าครับ แบบคำสั่งมันขัดแย้งกันภายในตัวเองรึเปล่า
« แก้ไขครั้งสุดท้าย: 05 ก.ค. 62 , 08:53:19 โดย Tonwrp »

 

05 ก.ค. 62 , 09:10:06
ตอบกลับ #23

สันติสุข

ถ้าได้ก็อัพโหลดโปรแกรมมาครับ หรือไม่ก็ค่อยๆ comment หรือตัดไปทีละบรรทัด ดูว่าเมื่อไหร่ไม่มี error ก็แปลว่าบรรทัดนั้นเป็นปัญหาครับ
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

05 ก.ค. 62 , 09:44:10
ตอบกลับ #24

Tonwrp

รบกวนอาจารย์ช่วยเช็คให้ผมทีครับ

 

05 ก.ค. 62 , 10:06:17
ตอบกลับ #25

สันติสุข

แย่แล้วผม ทำไมผิดอย่างนี้    DoCmd.SetWarnings False หรือ True ไม่ต้องมีเครื่องหมาย = ครับ
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

05 ก.ค. 62 , 10:14:56
ตอบกลับ #26

Tonwrp

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

 

05 ก.ค. 62 , 10:19:48
ตอบกลับ #27

สันติสุข

เลือก Data Entry property ของฟอร์มเป็น Yes เท่านี้เองครับ
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

05 ก.ค. 62 , 11:14:22
ตอบกลับ #28

Tonwrp

ขอบคุณอาจารย์สันติสุขมากๆครับที่คอยชี้แนะคนที่ไม่เคยทำอย่างผมมาก่อนขอบคุณจริงๆครับ

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

05 ก.ค. 62 , 15:51:53
ตอบกลับ #29

Tonwrp



รบกวนอาจารย์สันติสุขอีกหนึ่งรอบครับ
เนื่องจากผมต้องการที่จะให้มันโชว์ รูปของ Asset ด้วย
จึงได้เขียน Code ลงไปใน  Event Procedure Afterupdate ของ combobox ที่เลือก Asset
แต่หลังจากที่กดบันทึกมันกลับขึ้นว่า Object doesn't support this property or method

และรูปไม่ขึ้นด้วยมันเกิดจากอะไรอ่ะครับ

 

06 ก.ค. 62 , 01:35:16
ตอบกลับ #30

สันติสุข

คุณจะดึงฟิลด์ Attachment มาจากคิวรี่แล้วมากำหนดให้ Attachment Control โดยตรงอย่างนี้ไม่ได้  แต่เราสามารถเอามาเป็น Control Source ของ  Attachment Control ได้ ดังนั้นเราจะสร้าง Attachment Control ตัวนึง (ชื่อว่า A) ใส่ลงฟอร์มเปล่า (ชื่อว่าฟอร์ม F) แล้วเอา F มาใส่เป็น Sub Form control (ชื่อ SF) ใน ฟอร์มการยืมอีกที ทีนี้เมื่อใดที่มีการเลือก Asset เราก็จะสร้าง Record Source ของ SF เป็น SQL SELECT statement ที่ดึงเอาเฉพาะฟิลด์ Attachment ที่เก็บรูปภาพตาม Asset_ID ที่เลือก  ดังนั้นภาพก็จะแสดงออกมา เท่านี้เองครับ

โค้ดให้ใส่ไว้ใน Private Sub cbo_Loanasset_AfterUpdate() , ใน Private Sub Form_Current() และใน Private Sub Form_Undo(Cancel As Integer) ด้วย
โค๊ด: [Select]
    If IsNull(Me.cbo_Loanasset) Then
        Me.SF.Form.RecordSource = ""
    Else
        Me.SF.Form.RecordSource = "select Asset_Photo from tb_Asset where Asset_ID = " & Cstr(Me.cbo_Loanasset)
    End If

นอกจากนี้ให้กำหนด property เหล่านี้เอาไว้ด้วย

สำหรับ A
Control Source เป็น Asset_Photo
Enabled   No

สำหรับ F
Record Selectors   No
Naviagtion Buttons   No
Dividing Lines      No
Scroll Bars         Neither
Recordset Type      Snapshot

ที่เหลือก็ปรับขนาดกรอบรูปเท่านั้นครับ
« แก้ไขครั้งสุดท้าย: 06 ก.ค. 62 , 09:49:07 โดย สันติสุข »
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

08 ก.ค. 62 , 09:39:00
ตอบกลับ #31

Tonwrp

ได้แล้วครับขอบคุณอาจารย์สันติสุขมากๆเลยครับ

 

05 ส.ค. 62 , 16:12:29
ตอบกลับ #32

Tonwrp

รบกวนอาจารย์สันติสุขอีกรอบครับ คือผมได้ทำการสร้างคิวรี่ เพื่อ tracking Loaned Asset Status ครับ โดยเขียน sql ประมาณนี้ครับ
โค๊ด: [Select]
SELECT Tb_Assets.[Serial No], Tb_Loan.Loan_No, Tb_Employees.Employee_Name, Tb_Loan.Machine_Description, Tb_Loan.Machine_Serial_No, Tb_Loan.[Expired Date], IIf([Expired Date]<Date(),"EXPIRED",IIf([Expired Date]>Date(),"PENDING")) AS Status, Tb_Loan.Loan_Date
FROM Tb_Employees INNER JOIN (Tb_Assets INNER JOIN Tb_Loan ON Tb_Assets.Asset_ID = Tb_Loan.Asset_ID) ON Tb_Employees.Employee_ID = Tb_Loan.Employee_ID
WHERE (((Tb_Assets.Asset_Status)=False));

แต่ปัญหาคือหลังจากที่ผม return asset ตัวนั้นไปแล้วและมีคนมายืมไปอีกรอบ มันจะขึ้นใน query tracking ด้วยครับ เช่น Asset_A ถูกยืมใน loan_No ที่ ABC00001 และได้ทำการคืนแล้วทำให้ status มันเป็น True แต่ Asset_A ถูกยืมอีกรอบนึงใน loan_No ที่ ABC00005 ทีนี้มันขึ้นทั้งสองอันเลยครับคือทั้ง ABC00001 กับ ABC00005 คือผมอยากให้มันขึ้นเฉพาะ หมายเลขล่าสุดที่ยืมไปอ่ะครับไม่ทราบว่าจะต้องเขียนอย่างไรดีครับผมนึกไม่ออกจริงๆ

 

05 ส.ค. 62 , 16:53:00
ตอบกลับ #33

สันติสุข

ผมแนะนำว่าควรมีการบันทึกในใบคืนของ ว่าเป็นการคืนมาจากการยืมเลขที่อะไรด้วย (สมมุติชื่อฟิลด์คือ Loan_no) ถ้าเพิ่มได้ คิวรี่นี้ก็เปลี่ยนเงื่อนไขที่ WHERE เป็น (Asset ถูกยืมไปแล้ว) และ (ไม่พบใบคืนที่มีเลขที่ยืมอันเดียวกันนี้ปรากฏอยู่)

WHERE ((Tb_Assets.Asset_Status=False)
     AND NOT EXISTS (SELECT Tb_Return.Loan_No FROM Tb_Return WHERE Tb_Return.Loan_No = Tb_Loan.Loan_No);



หรือไม่ต้องเช็คสถานะของ Asset เลยก็ได้ เป็น

WHERE NOT EXISTS (SELECT Tb_Return.Loan_No FROM Tb_Return WHERE Tb_Return.Loan_No = Tb_Loan.Loan_No);

เพราะตามตรรกะของระบบแล้ว แน่นอนว่าของที่มีใบยืม แต่ไม่มีเลขที่ใบยืมอยู่ในใบคืนใดๆเลย ก็คือของที่ Asset_Status เป็น False นั่นเอง แต่มัน **อาจจะ** ทำให้การค้นหาช้าลงเมื่อมีข้อมูลการยืม/คืนอยู่เป็นจำนวนมาก (ที่บอกว่า อาจจะ เพราะถ้าอยากทราบจริงๆ ต้องขุดลึกลงไปว่าตัวจัดการคิวรี่ (Query Optimizer) มันฉลาดหรือทื่อๆแค่ไหนกับคำสั่งคิวรี่นั้นๆ)
« แก้ไขครั้งสุดท้าย: 05 ส.ค. 62 , 17:24:07 โดย สันติสุข »
ช่วยพกถุงผ้า/ถุงพลาสติกใช้แล้วไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

08 ส.ค. 62 , 08:57:23
ตอบกลับ #34

Tonwrp

ผมแนะนำว่าควรมีการบันทึกในใบคืนของ ว่าเป็นการคืนมาจากการยืมเลขที่อะไรด้วย (สมมุติชื่อฟิลด์คือ Loan_no) ถ้าเพิ่มได้ คิวรี่นี้ก็เปลี่ยนเงื่อนไขที่ WHERE เป็น (Asset ถูกยืมไปแล้ว) และ (ไม่พบใบคืนที่มีเลขที่ยืมอันเดียวกันนี้ปรากฏอยู่)

WHERE ((Tb_Assets.Asset_Status=False)
     AND NOT EXISTS (SELECT Tb_Return.Loan_No FROM Tb_Return WHERE Tb_Return.Loan_No = Tb_Loan.Loan_No);



หรือไม่ต้องเช็คสถานะของ Asset เลยก็ได้ เป็น

WHERE NOT EXISTS (SELECT Tb_Return.Loan_No FROM Tb_Return WHERE Tb_Return.Loan_No = Tb_Loan.Loan_No);

เพราะตามตรรกะของระบบแล้ว แน่นอนว่าของที่มีใบยืม แต่ไม่มีเลขที่ใบยืมอยู่ในใบคืนใดๆเลย ก็คือของที่ Asset_Status เป็น False นั่นเอง แต่มัน **อาจจะ** ทำให้การค้นหาช้าลงเมื่อมีข้อมูลการยืม/คืนอยู่เป็นจำนวนมาก (ที่บอกว่า อาจจะ เพราะถ้าอยากทราบจริงๆ ต้องขุดลึกลงไปว่าตัวจัดการคิวรี่ (Query Optimizer) มันฉลาดหรือทื่อๆแค่ไหนกับคำสั่งคิวรี่นั้นๆ)

แล้วเราจะต้องสร้าง Relationship  loan_No ของทั้งสองตารางมั้ยครับหรือว่าผมทำ lookup wizard ไปเลยในฟอร์มของการคืน

 

08 ส.ค. 62 , 09:53:41
ตอบกลับ #35

Tonwrp

ได้แล้วครับอาจารย์ ผมทำการเพิ่ม Field Loan_No เข้าไปในตารางการคืนแล้วก็ดึงลงมาเป็น textbox ใน ฟอร์มการคืน หลังจากนั้นก็ลองไปเขียน query ตามที่อาจารย์บอกครับ ขอบคุณมากๆเลยครับผม

 


บอร์ดเรียนรู้ Access สำหรับคนไทย


 

Sitemap 1 2 3 4 5