get warnings message
กระทู้เก่าบอร์ด อ.Yeadram

 2,713   10
URL.หัวข้อ / URL
get warnings message

ผมตอบมาเยอะแล้ว ให้ผมถามบ้างนะครับ

ผมมีตารางสินค้า รหัสสินค้าเป็น primary
ผมมีตารางการเคลื่อนไหว สองตารางคือ tbtranmain เก็บหัวเอกสาร
กับตาราง tbtransub เก็บรายละเอียดของเอกสาร

ผมสร้างฟอร์มสำหรับจัดการ ข้อมูลสินค้า ซึ่งมีคำสั่งให้ลบสินค้าได้ด้วย (กรณีบันทึกเข้าไปแบบผิดๆ หรือแบบไม่ได้ตั้งใจ)

เมื่อผมสั่งลบด้วยคำสั่ง docmd.runcommand accmddeleterecord
มันลบได้บ้างไม่ได้บ้าง ตัวที่ลบไม่ได้ก็นิ่งไปซะอย่างนั้น ตามหาสาเหตุนานพอสมควร แล้วก็เลยลองปล่อย warnings (ปกติชอบปิดมันไว้)

ได้ความว่า สินค้ารหัสตัวที่ ไม่สามารถลบได้ คือสินค้าที่มีประวัติการเคลื่อนไหวแล้ว (รหัสสินค้านี้ได้เคยบันทึกเข้าตาราง tbtransub แล้ว) ดูๆ แล้วมันก็เป็นการดี ถึงดีมากๆ เลยล่ะ

แต่ทีนี้ ผมอยากจะเขียนคำอธิบาย ด้วยตัวผมเอง แล้วเอาไปแจ้ง user เอง ไม่อยากใช้ warnings message ของระบบ (เพราะบางเครื่องอาจลง office เมนูภาษาอังกฤษ ซึ่ง warnings มันก็จะเป็นภาษาอังกฤษ กลัวว่าผู้ใช้อ่านแล้วไม่เข้าใจ)

ถามว่า ผมจะดักจับ warnings เหล่านี้ได้อย่างไรครับ
ผมพยายามดักจับด้วย error debug แต่ไม่สำเร็จ ดูเหมือนมันไม่ใช่ error นะครับ

ปล. ปัญหาของผมจริงๆ แล้วผมเลี่ยงไปใช้ทางอื่นแล้วล่ะ แต่ติดตรงข้อสงสัยที่ว่า "ผมจะดักจับข้อความ warnings ได้อย่างไร เพื่อจะเอามาเขียนใหม่เอง"

เผื่อว่าสักวันอยากจะดักจับมันขึ้นมาจริงๆ อาจเป็น warnings ตัวอื่นก็ได้ครับ

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

1 @R04055
ลองคิดเล่น ๆ ดู   ไม่เคยใช้คำสั่งเหมือนกัน
โดยหลักการ
จำนวน record ลดลง ถือว่ามีการลบ
จำนวน record ไม่เปลี่ยนแปลง ถือว่ามีการใช้ มีประวัติการเคลื่อนไหว
จึงลองดักจับจำนวน record
เตือนด้วย message error
ไม่ทราบคุณ yeardram หรือท่านอื่น คิดอย่างไร


2 @R04057
อ๋อเรื่องลบ ไม่มีปัญหาแล้วครับ
ผมเลี่ยงไปใช้อย่างนี้
- ตรวจสอบข้อมูล ที่จะลบว่ามีการเคลื่อนไหวแล้วหรือยัง
- ถ้าเคยมีการเคลื่อนไหว แจ้งผู้ใช้ว่า ระบบไม่ให้ลบ
- หากยังจะฝืนลบ ต้อ??ให้ลบการเคลื่อนไหวนั้นก่อน
- หากยังไม่เคยมีการเคลื่อนไหว หรือ ลบการเคลื่อนไหวแล้ว
- ใช้การรัน sql ลบจาก ตารางได้โดยตรงเลย

ดูๆ ไปมันก็ไม่ได้ลำบากอะไรครับ ในการจะเขียน msgbox หลังเงื่อนไข หรือการเขียนคำชี้แจงต่างๆ แล้วตามด้วยการร้องขอ ข้อมูล อย่างการใช้ inputbox

แต่ว่ามันก็ยาวเหมือนกันนะ อิอิ
ที่ถาม ตรงนี้ก็คือ ก่อนนี้ผมใช้วิธีหักดิบ ลบได้ก็ลบ ลบไม่ได้ก็ไม่ให้ลบทุกกรณี ให้ผู้ใช้เข้าใจเลยว่า "ลบไม่ได้"

แต่เวลาระบบมันฟ้องออกมา มันฟ้องในรูปแบบ warnings "รายการนี้ลบไม่ได้เนื่องจากความสัมพันธ์กับตารางนั้นยังคงอยู่" อะไรประมาณนี้แหละครับ บางทีมันเขียนมาเป็น ภาษาอังกฤษไงครับ กลัวผู้ใช้อ่านไม่เข้าใจแล้วหงุดหงิด จึงอยากดักจับแค่ warnings นี้แหละครับ อยากรู้ว่า เมื่อไหร่มันจะเกิด เพราะอะไรมันถึงเกิด ที่มันเกิดน่ะข้อความว่าอย่างไร อยากดักมันครับ เผื่อว่าจะได้ใช้มันสักวัน
3 @R04058
อย่างแรกคือ หาว่ารหัสของ Error นี้คือรหัสอะไร ก็ทำได้โดยการสั่ง

On Error Resume Next
DoCmd.RunCommand acCmdDeleteRecord
Debug.Print Err.Number, Err.Description

ก็จะเห็นว่ามันคือรหัส 3200 จากนั้นเราก็ใช้ Error Handling Routine ของเราเองในการแสดงคำอธิบายของเราแทน โค้ดก็จะเป็นดังนี้ครับ

Private Sub btnDelete_Click()
    On Error GoTo btnDelete_Err
    DoCmd.RunCommand acCmdDeleteRecord
    
btnDelete_Exit:
    Exit Sub
    
btnDelete_Err:
    If Err.Number = 3200 Then
        MsgBox "ลบไม่ได้เพราะมีรายการเคลื่อนไหวของสินค้านี้แล้ว"
    End If
    Resume btnDelete_Exit
End Sub
4 @R04059
ขอบคุณครับ
เมื่อวาน ผมพยายามดักจับมัน ไม่เห็นมัน นึกว่ามันไม่ใช่ error

on error resume next
DoCmd.RunCommand acCmdDeleteRecord
if err<>0 then
msgbox err.number & vbcrlf & err.description
end if
on error goto 0

ผมดักจับแบบนี้แหละครับ แต่จับไม่เจอ สงสัยวิธีผมคงผิด
เดี๋ยว จะได้เอาวิธีของ อ.สันติสุขไปลองครับ
5 @R04060
ลอง if err.number <> 0 then สิครับ
6 @R04062
ขอถามต่อเลยนะครับว่าเราจะหาคำอธิบาย errornumber ได้จากที่ไหนครับ โดยไม่ต้องมาดักจับทีละตัว
7 @R04064
ตามเก็บครับ ความรู้ทั้งนั้น
8 @R04065
เรื่อง Error Handling Routine เป็นเรื่องที่ไม่ง่ายอย่างที่คิด เพราะ error มีมาได้จากหลายๆไลบรารี่ที่ผนวกเพิ่มเข้ามาในระบบ เช่น VBA เอง หรือ DAO ก็จะมี error number ของเขา (อย่างเช่นรหัส 3200 ตามกรณีข้างบน) ในขณะที่ ADO ก็มีของเขาอีกเช่นกัน ซึ่งไม่มีข้อกำหนดอะไรว่า เลขนี้ไลบรารี่นี้จองแล้ว ห้ามไม่ให้ไลบรารี่อื่นใช้ ดังนั้นการตรวจสอบ error จึงขึ้นกับว่าเราให้ความสนใจ error อะไรบ้างใน procedure นั้นๆ และสนใจไลบรารี่อะไร เพราะแต่ละไลบรารี่อาจมีวิธีการตรวจสอบ error ไม่เหมือนกันซะทีเดียว เช่น

- VBA ก็ให้ error เฉพาะของ VBA เองไม่เกี่ยวกับเรื่องปัญหาของข้อมูลและสามารถอ้างถึงด้วย Err object (ไม่ใช่ Error object)

- ในขณะที่ error ของ DAO แน่นอนว่าย่อมเกี่ยวกับเรื่องของข้อมูลอย่างเดียว เมื่อเกิด error อาจเกิดได้หลายๆ error ในครั้งเดียวกัน   แต่ละ error จะถูกบรรจุลงในแต่ละ Error object (ไม่ใช่ Err object) ภายใน Errors collection โดยที่ DBEngine.Errors(0) หรือ Error object ตัวแรกใน Errors collection นั้นจะเกิดจาก layer ที่ตำ่ที่สุดที่ DAO เรียกใช้ จนถึง layer สุดท้ายคือ error ที่มาจาก layer ของตัว DAO เอง ซึ่งก็คือ DBEngine.Errors( DBEngine.Errors.Count - 1 ) และเป็น Error object ตัวที่ให้ความหมายในระดับ end user ได้เข้าใจที่สุด และในขณะเดียวกัน error ที่มาจาก layer สุดท้ายนี้ก็สามารถอ้างอิงได้จาก Err object ของ VBA ด้วยเช่นกัน

- ในส่วนของ ADO เอง ก็คล้ายๆกับ DAO แต่ไม่สามารถอ้างจาก Err object ได้ ต้องตรวจสอบจาก Error object ของ ADO เองเท่านั้น และมี property SQLState กับ NativeError ที่เพิ่มมาจาก DAO เพื่อบอกรายละเีอียดเพิ่มเติมจาก SQL Data Source

จากที่เล่ามาจะเห็นว่า การเขียน Error Handling ก็แตกต่างกันไป ขึ้นกับเราสนใจไลบรารี่อะไร

ทีนี้มาถึงว่า เราจะรู้ได้งอย่างไรว่ามี error code อะไรบ้าง
- สำหรับตัว VBA เอง ดูได้จาก http://support.microsoft.com/kb/146864

- สำหรับ DAO หาได้จาก Application.AccessError( รหัส ) ซึ่งเลข (เท่าที่พบ) สูงสุดคือเลข 4 หลัก ค่าที่ให้ออกมาจาก method นี้คือ คำพูดที่แสดงเมื่อเกิด error นั้นๆขึ้น หรืออาจเป็น null string หรืออาจเป็นคำว่า Application-defined or object-defined error ดังนั้นเราก็สามารถเขียนโปรแกรมเล็กๆเพื่อวนลูปเช่น

Dim C as Integer
Dim S as Variant

For C = 1 to 9999
   S = Application.AccessError(C)
   Select Case S
      Case vbNullString
      Case "Application-defined or object-defined error"
      Case Else
          Debug.Print C, S
   End Select
Next C

แต่ข้อความที่ขึ้นมันอาจเยอะเกินกว่าที่หน้าจอ debug windows จะรองรับได้ คุณก็อาจรันทีละ 1000 หมายเลขก็ได้ ลองปรับดู   เมื่อได้ข้อความแล้ว คุณก็ต้องมานั่งอ่านทีละข้อความแล้วว่า อะไรที่คุณสนใจ คุณก็จดเลขและข้อความเอาไว้ แล้วก็ทำ Error Handling Routine ดักเลขรหัสเหล่านั้นแล้วแสดงเป็นข้อความของคุณเอง    error ประเภทหนึ่งๆ อาจมีข้อความมากว่า 1 แบบก็ได้ เช่น error ที่เกิดจากเรคอร์ดถูกล็อค อาจบอกว่า ถูกล็อคโดย session อื่นในเครื่องเดียวกันกับเรา และอาจมีบอกว่า ถูกล็อคแบบ exclusive จากไหน ก็เป็นไปได้ ซึ่งเราอาจใช้ข้อความอธิบายของเราเป็นข้อความเดียวกันเลยก็ได้ ตรงนี้ก็แล้วแต่ว่าใครอยากออกแบบ Error Handling Routine ของตัวเองเป็นอย่างไร ก็เชิญตามสบายเลยครับ

- สำหรับ ADO หล่ะ อันนี้ผมไม่มีข้อมูลจริงๆครับ คงต้องเทสโปรแกรมให้มันเกิด error แล้วเราค่อยเก็บ error นั้นไว้มั้ง
9 @R04066
โอ๊ะ โอว!!!
ตามมาเก็บข้อมูลด้วยครับ
ระดับเทพ คุยกันนี่น่าสนใจมากเลย ^_/|\_^
10 @R04069
ขอบคุณครับอย่างน้อยผมก็ได้ errorcode-message ไว้ละ เจ้าตัว DAO นี่ผมไม่เคยเขียนเลยครับใช้แต่ ADOX เท่านั้น
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.3814s