สมัครสมาชิก
 

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



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

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

สันติสุข

  • แฟนพันธุ์แท้ไท.Access
  • *
  • กระทู้: 358
  • พลังขอบคุณ: 314

  • แยกทิ้งขยะถูกประเภท เทศบาลนำไปกำจัดได้ง่าย

    • ดูรายละเอียด

ผมแนะนำว่าควรมีการบันทึกในใบคืนของ ว่าเป็นการคืนมาจากการยืมเลขที่อะไรด้วย (สมมุติชื่อฟิลด์คือ 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 ตามที่อาจารย์บอกครับ ขอบคุณมากๆเลยครับผม

 

08 ส.ค. 62 , 19:06:33
ตอบกลับ #36

สันติสุข

  • แฟนพันธุ์แท้ไท.Access
  • *
  • กระทู้: 358
  • พลังขอบคุณ: 314

  • แยกทิ้งขยะถูกประเภท เทศบาลนำไปกำจัดได้ง่าย

    • ดูรายละเอียด

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

21 ส.ค. 62 , 10:50:10
ตอบกลับ #37

Tonwrp

สอบถามอาจารย์ครับ ตอนนี้เกิดปัญหาเวลาที่มี User เข้าฟอร์ม Loan พร้อมกันแล้วกดปุ่มใส่ Loan_No แบบที่ผมเซ็นให้เป็น auto run เพิ่มไปเรื่อยๆ ปัญหาที่พบคือถ้าหากเข้าฟอร์มการ Loan พร้อมกันแล้วกดปุ่มนี้มันจะขึ้นเป็น Loan_No เดียวกันเลยครับไม่ทราบว่าสามารถทำให้มันไม่ซ้ำกันได้มั้ยครับ

 

21 ส.ค. 62 , 15:28:27
ตอบกลับ #38

สันติสุข

  • แฟนพันธุ์แท้ไท.Access
  • *
  • กระทู้: 358
  • พลังขอบคุณ: 314

  • แยกทิ้งขยะถูกประเภท เทศบาลนำไปกำจัดได้ง่าย

    • ดูรายละเอียด

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

22 ส.ค. 62 , 09:51:27
ตอบกลับ #39

Tonwrp

เขียนโค้ดเอาเองครับ พอจะมีทางแก้จุดบอดตรงนี้มั้ยครับ

 

22 ส.ค. 62 , 16:20:17
ตอบกลับ #40

สันติสุข

  • แฟนพันธุ์แท้ไท.Access
  • *
  • กระทู้: 358
  • พลังขอบคุณ: 314

  • แยกทิ้งขยะถูกประเภท เทศบาลนำไปกำจัดได้ง่าย

    • ดูรายละเอียด

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

26 ส.ค. 62 , 12:06:11
ตอบกลับ #41

Tonwrp

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

ผมเขียนไว้ที่ After Update ครับผมสงสัยคงต้องไปเขียนใน before update แทนแต่ตอนนี้เกิดปัญหาครับเนื่องจาก code autorun หมายเลขมันไม่ยอมบวกให้ครับแต่จะเริ่มนับ 1 ใหม่เมื่อขึ้นเดือนใหม่ครับอยากรบกวนอาจารย์ช่วยติโค้ดหน่อยได้มั้ยครับ

โค๊ด: [Select]
txt_LoanNo = "TSD" & Format([txt_LoanDate], "yymm") & Right("000" & DCount("[Loan_No]", "[Tb_Loan]", "Left([Loan_No],4) = Format([txt_LoanDate],'yymm')") + 1, 3)ตอนแรกยังบวกอยู่เลยครับแต่อยู่ดีๆก็ไม่บวกเพิ่มไปเฉยๆซะอย่างนั้นเลย

 

26 ส.ค. 62 , 16:26:27
ตอบกลับ #42

สันติสุข

  • แฟนพันธุ์แท้ไท.Access
  • *
  • กระทู้: 358
  • พลังขอบคุณ: 314

  • แยกทิ้งขยะถูกประเภท เทศบาลนำไปกำจัดได้ง่าย

    • ดูรายละเอียด

อ้างถึง
txt_LoanNo = "TSD" & Format([txt_LoanDate], "yymm") & Right("000" & DCount("[Loan_No]", "[Tb_Loan]", "Left([Loan_No],4) = Format([txt_LoanDate],'yymm')") + 1, 3)

ใช่ครับ โค้ดข้างบนนี้จะเริ่มให้ค่า 1 เมื่อเป็นเดือนใหม่ ถ้าต้องการให้ +1 ในปีนั้นไปเรื่อยๆจนกว่าจะเป็นปีใหม่ ก็ต้องเป็น
อ้างถึง
txt_LoanNo = "TSD" & Format([txt_LoanDate], "yymm") & Right("000" & DCount("[Loan_No]", "[Tb_Loan]", "Left([Loan_No],2) = Format([txt_LoanDate],'yy')") + 1, 3)
แต่ผมว่าดูแปลกๆไม่สัมพันธ์กับเลขหลัง TSD หรือเปล่า เพราะพอเดือนใหม่ เลขหลัง TSD ก็เป็น ปีและเดือน ถัดไป แต่เลขรันนิ่งยังเป็นเลขต่อจากเดือนที่แล้ว เช่น ในเดือน 8 มีเลขรันจาก TSD1908001 ถึง TSD1908123 แต่เลขแรกของเดือน 9 เป็นเลข TSD1909124  แต่ไม่ว่ายังไงก็ตาม การใช้ DCount ค่อนข้างไม่ถูกต้อง เพราะมันเป็นการนับจำนวน อย่างเดือน 8 มีเลขที่สมมุติข้างบน  ถ้าเรายังอยู่ในเดือน 8 และมี 1 เรคอร์ดที่ถูกลบไป   พอสร้างเลขต่อไป  Dcount ก็จะนับได้ทั้งหมดเหลือ 122 เลข พอบวก 1 ก็จะได้เลขถัดไปเป็น TSD1908123 ซึ่งซ้ำกับเลขเดิมแน่ๆ

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

26 ส.ค. 62 , 17:32:17
ตอบกลับ #43

Tonwrp

ผมอยากได้แค่ให้มันเป็น TSD-1908001 พอเปลี่ยนเดือนใหม่ก็รันเป็น 001 ใหม่พอเปลี่ยนปีก็เป็น TSD-2001001 อะไรทำนองนี้เองครับแต่ผมไม่ค่อยเข้าใจฟังก์ชั่น Dcount เท่าไหร่เลยงงๆครับแหะๆ

 

26 ส.ค. 62 , 19:01:03
ตอบกลับ #44

สันติสุข

  • แฟนพันธุ์แท้ไท.Access
  • *
  • กระทู้: 358
  • พลังขอบคุณ: 314

  • แยกทิ้งขยะถูกประเภท เทศบาลนำไปกำจัดได้ง่าย

    • ดูรายละเอียด

Dim TSDYYMM As String
Dim MaxRunNo As Integer

TSDYYMM = "TSD-" & Format([txt_LoanDate], "yymm")
MaxRunNo = Val( Right( Nz(DMax("[Loan_No]", "[Tb_Loan]", "[Loan_No] Like '" & TSDYYMM & "*'"),"0"),3 )  )
txt_LoanNo = TSDYYMM  & Format(MaxRunNo + 1, "000")
ช่วยพกถุงผ้า/ถุงพลาสติกไปซื้อของเพื่อลดการใช้พลาสติก ขยะ รักษาสิ่งแวดล้อม และไม่ให้ภาวะโลกร้อนวิกฤติเร็วขึ้นกว่านี้
ช่วยคลิกโฆษณาข้างล่างนี้ เพื่อสนับสนุนเวปบอร์ดด้วยครับ
:nice day:
 
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

27 ส.ค. 62 , 08:51:00
ตอบกลับ #45

Tonwrp

ขอบคุณอาจารย์สันติสุขมากๆครับผม

 


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