กระทู้เก่าบอร์ด อ.Yeadram
3,024 15
URL.หัวข้อ /
URL
Textbox ไม่หยุดรอให้ key ข้อมูล
ขอความกรุณาช่วยดูให้หน่อยครับ
Private Sub Text29_LostFocus()
before_ent:
Me.Text29.SetFocus
If Len(Text29) <> 4 Then GoTo incorrect
For i = 1 To 4
If IsNumeric(Mid(Text29, i, 1)) = False Then GoTo incorrect
Next
-
-
-
ในกรณีที่ตรวจสอบการ key ข้อมูลแล้วไม่ถูกต้อง ต้องการให้เคอร์เซอร์ไปรอการ key ใน Textbox (Text29) ที่ผมใช้ GoTo before_ent แต่มันไม่เป็นอย่างนั้น มันไม่หยุดรอการ key จึงกลายเป็นการไปติด loop ออกไม่ได้ครับ ผมอาจเขียน code ผิดก็ได้หรืออาจเข้าใจคุณสมบัติของ Textbox ผิดก็ได้ ช่วยแนะนำหน่อยครับ
-
-
incorrect:
-
-
End Sub
Private Sub Text29_LostFocus()
before_ent:
Me.Text29.SetFocus
If Len(Text29) <> 4 Then GoTo incorrect
For i = 1 To 4
If IsNumeric(Mid(Text29, i, 1)) = False Then GoTo incorrect
Next
-
-
-
ในกรณีที่ตรวจสอบการ key ข้อมูลแล้วไม่ถูกต้อง ต้องการให้เคอร์เซอร์ไปรอการ key ใน Textbox (Text29) ที่ผมใช้ GoTo before_ent แต่มันไม่เป็นอย่างนั้น มันไม่หยุดรอการ key จึงกลายเป็นการไปติด loop ออกไม่ได้ครับ ผมอาจเขียน code ผิดก็ได้หรืออาจเข้าใจคุณสมบัติของ Textbox ผิดก็ได้ ช่วยแนะนำหน่อยครับ
-
-
incorrect:
-
-
End Sub
15 Reply in this Topic. Dispaly 1 pages and you are on page number 1
2 @R14406
ผมคงจะตั้งคำถามไม่กระจ่างครับ คืออย่างนี้ครับ
ผมมี Form อยู่ 1 Form บน Form มี Textbox หลาย Textbox ตัวอย่างที่ผมยกมาคือ Textbox ชื่อ Text29 รับข้อมูลเป็นตัวเลข 4 ตัว ปัญหามีอยู่ว่า(ในกรณีที่ยกตัวอย่างมาถาม) เมื่อมีการ key ตัวหนังสือ หรือ ตัวเลขที่ไม่ตรงกับ ที่มีในตาราง จะมี MsgBox เตือนผู้ key ข้อมูล
**** ความต้องการคือ
เมื่อเกิดการเตือนจาก MsgBox ขึ้น ผู้ key คลิก OK แล้ว ต้องการให้ เคอร์เซอร์ ไปรอรับการ key ครั้งใหม่ที่ Textbox ชื่อ Text29 (ตัวเดิม) บน Form แต่ปัญหาที่ผมพบคือ เคอร์เซอร์ มันไม่หยุดรอรับการ key มันจะไปปรากฎที่ Textbox ตัวต่อไป ลองใช้ Me.Text29.SetFocus ก็ไม่หยุด ...ผมลองใช้ GoTo before_ent กลายเป็นการติด loop ออกไม่ได้ เพราะเคอร์เซอร์ มันไม่หยุดรอรับการ key (ผมเข้าใจเอง) มันจึงเอาค่าที่ key ที่ผิดในครั้งแรกส่งไปตรวจสอบ วนเป็น loop ออกไม่ได้ ขึ้น MsgBox ตลอด ทำได้แค่ คลิก OK ยังไม่รู้จะแก้ยังไงครับ
ผมมี Form อยู่ 1 Form บน Form มี Textbox หลาย Textbox ตัวอย่างที่ผมยกมาคือ Textbox ชื่อ Text29 รับข้อมูลเป็นตัวเลข 4 ตัว ปัญหามีอยู่ว่า(ในกรณีที่ยกตัวอย่างมาถาม) เมื่อมีการ key ตัวหนังสือ หรือ ตัวเลขที่ไม่ตรงกับ ที่มีในตาราง จะมี MsgBox เตือนผู้ key ข้อมูล
**** ความต้องการคือ
เมื่อเกิดการเตือนจาก MsgBox ขึ้น ผู้ key คลิก OK แล้ว ต้องการให้ เคอร์เซอร์ ไปรอรับการ key ครั้งใหม่ที่ Textbox ชื่อ Text29 (ตัวเดิม) บน Form แต่ปัญหาที่ผมพบคือ เคอร์เซอร์ มันไม่หยุดรอรับการ key มันจะไปปรากฎที่ Textbox ตัวต่อไป ลองใช้ Me.Text29.SetFocus ก็ไม่หยุด ...ผมลองใช้ GoTo before_ent กลายเป็นการติด loop ออกไม่ได้ เพราะเคอร์เซอร์ มันไม่หยุดรอรับการ key (ผมเข้าใจเอง) มันจึงเอาค่าที่ key ที่ผิดในครั้งแรกส่งไปตรวจสอบ วนเป็น loop ออกไม่ได้ ขึ้น MsgBox ตลอด ทำได้แค่ คลิก OK ยังไม่รู้จะแก้ยังไงครับ
3 @R14408
? ใช่หรือเปล่า ?
Private Sub Text29_LostFocus()
If Len(Text29) <> 4 Then GoTo incorrect
If Not IsNumeric(Text29) Then GoTo incorrect
-
-
End If
incorrect:
Me.Text29.SetFocus
End Sub
Private Sub Text29_LostFocus()
If Len(Text29) <> 4 Then GoTo incorrect
If Not IsNumeric(Text29) Then GoTo incorrect
-
-
End If
incorrect:
Me.Text29.SetFocus
End Sub
4 @R14409
ทำไมไม่เขียนโค้ดใน Text29_BeforeUpdate event เพราะสามารถกำหนดค่า Cancel อากิวเมนท์ ให้เป็น True ซึ่งจะทำให้ไม่หลุดออกจากเท็กซ์บ็อกซ์นั้น ??? ลองค้นหาเวปนี้ด้วยคำว่า BeforeUpdate ดูครับ
5 @R14410
งั้นปัญหาของคุณไม่ใช่การ Setfocus หรอกครับ ต่อให้คุณ Setfocus ได้ แต่ข้อมูลก็ถูกบันทึกไปแล้วอยู่ดี อยู่ที่การ Cancel อย่างที่ อ.สันติสุข บอกแหละครับ
และหากข้อมูลทั้ง 4 ตัวเป็นตัวเลขทั้งหมด คุณก็ไม่ต้อง Loop ที่ละตัวหรอกครับใช้ IsNumeric อย่าง อ.PichaiTC เขียนได้เลย เช่น
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text1) <> 4 Or Not IsNumeric(Me.Text1) Then
MsgBox "...."
Cancel = True
End If
End Sub
ลองปรับดูนะครับ
และหากข้อมูลทั้ง 4 ตัวเป็นตัวเลขทั้งหมด คุณก็ไม่ต้อง Loop ที่ละตัวหรอกครับใช้ IsNumeric อย่าง อ.PichaiTC เขียนได้เลย เช่น
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text1) <> 4 Or Not IsNumeric(Me.Text1) Then
MsgBox "...."
Cancel = True
End If
End Sub
ลองปรับดูนะครับ
6 @R14411
แก้ไข
Text1 เป็น Text29
Text1 เป็น Text29
7 @R14413
ขอบคุณมากๆ นะครับ ท่าน อ.ทุกท่าน ที่กรุณาให้คำแนะนำ ผมเอาไปประยุกต์ใช้งานได้ตามความต้องการแล้วครับ
8 @R14415
จากตัวอย่างของคุณ TTT
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
MsgBox "...."
Cancel = True
End If
---> พอได้ข้อมูลจาก Text29 นำไปตรวจสอบกับข้อมูลในตาราง แล้วข้อมูลที่ได้มาไม่มีในตาราง ต้องการให้ เคอร์เซอร์กลับไปที่ Textbox "Text29" เพื่อให้ป้อนข้อมูลใหม่ ผมลองใช้ Me.Text29.SetFocus มันไม่ได้ครับ มันเตือนว่าต้องบันทึกข้อมูลก่อน มีวิธีไหนบ้างครับที่จะทำให้ขบวนการที่เราต้องการ..เสร็จก่อนจึงจะ End Sub
End Sub
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
MsgBox "...."
Cancel = True
End If
---> พอได้ข้อมูลจาก Text29 นำไปตรวจสอบกับข้อมูลในตาราง แล้วข้อมูลที่ได้มาไม่มีในตาราง ต้องการให้ เคอร์เซอร์กลับไปที่ Textbox "Text29" เพื่อให้ป้อนข้อมูลใหม่ ผมลองใช้ Me.Text29.SetFocus มันไม่ได้ครับ มันเตือนว่าต้องบันทึกข้อมูลก่อน มีวิธีไหนบ้างครับที่จะทำให้ขบวนการที่เราต้องการ..เสร็จก่อนจึงจะ End Sub
End Sub
9 @R14418
คำถามคือ ทำไม่คุณไม่ตรวจสอบให้เสร็จใน Event ของ Before Update เลยหละครับ เช่น
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
MsgBox "...."
Cancel = True
ElseIf isnull(Dlookup("ชื่อฟิลด์...", "ชื่อตารางที่ตรวจสอบ", "[ชื่อฟิลด์] = '" & Text29 & "'")) Then
Cancel = True
end if
End If
End Sub
อะไรประมาณนี้ครับ คือตรวจสอบให้จบที่เหตุการณ์เดียวไปเลยครับ ง่ายกว่า
แต่หากคุณสงสัยเรื่อง SetFocus ว่านั้นเป็นปัญหา อธิบายดังนี้นะครับว่า หากผมเข้าใจไม่ผิด มันเป็นการกดเปลี่ยนฟิลด์ เช่นการกดปุ่ม Tab Enter หรือการคลิ๊กเมาส์ ไปยังอีกฟิลด์เพื่อให้เหตุการณ์ในฟิลด์ Text29 ทำงาน เสร็จแล้วเมื่อมันไม่ตรงตามเงื่อนไขคุณก็สั่งให้มัน SetFocus กลับไปที่ฟิลด์ Text29 ถามว่าคำสั่งทำตามนั้นหรือไม่ ตอบว่าทำครับ หากคุณสั่งเกตุดีๆ แต่มันยังมีเหตุการณ์หลังจากคำสั่ง SetFocus ของคุณอยู่ คือการกดปุ่ม ไม่ว่าจะเป็น Tab Enter หรือคลิ๊กเมาส์ ของคุณนั้นเอง ซึ่งโปรแกรมจะถือว่านั้นเป็นเหตุการณ์ต่อจากคำสั่งคุณ ดังนั้นหลังการ SetFocus ที่ Text29 แล้ว มันจึงต่อด้วยการย้ายไปยัง Textbox ตัวอื่นที่คุณคลิ๊ก หรือกด Tab หรือ Enter อะไรก็ไม่ทราบได้ (งงเหมือนกัน) นั่นเอง แต่หากอยากแก้แค่นี้จริงๆ แบบกำปั้นทุบดิน ที่ผมคิดได้ตอนนี้คือประมาณนี้ครับ
Dim TT As String
TT = Me.CurrentRecord
MsgBox "................."
SendKeys "{F5}", True
DoCmd.GoToRecord , , acGoTo, dd
Me.Text29.SetFocus
ประมาณว่า Reset ฟอร์มใหม่แล้วค่อยกลับไป SetFocus ที่เรคคอร์ดเดิม ลองดูแล้วกันครับ
ปล. คิดว่าคุณต้องลองเรียบเรียงโค๊ดดูใหม่ให้ดี ไม่งั้นคุณอาจต้องมาเขียนแก้นั่นดักตรงนี้ เกินความจำเป็นนะครับ
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
MsgBox "...."
Cancel = True
ElseIf isnull(Dlookup("ชื่อฟิลด์...", "ชื่อตารางที่ตรวจสอบ", "[ชื่อฟิลด์] = '" & Text29 & "'")) Then
Cancel = True
end if
End If
End Sub
อะไรประมาณนี้ครับ คือตรวจสอบให้จบที่เหตุการณ์เดียวไปเลยครับ ง่ายกว่า
แต่หากคุณสงสัยเรื่อง SetFocus ว่านั้นเป็นปัญหา อธิบายดังนี้นะครับว่า หากผมเข้าใจไม่ผิด มันเป็นการกดเปลี่ยนฟิลด์ เช่นการกดปุ่ม Tab Enter หรือการคลิ๊กเมาส์ ไปยังอีกฟิลด์เพื่อให้เหตุการณ์ในฟิลด์ Text29 ทำงาน เสร็จแล้วเมื่อมันไม่ตรงตามเงื่อนไขคุณก็สั่งให้มัน SetFocus กลับไปที่ฟิลด์ Text29 ถามว่าคำสั่งทำตามนั้นหรือไม่ ตอบว่าทำครับ หากคุณสั่งเกตุดีๆ แต่มันยังมีเหตุการณ์หลังจากคำสั่ง SetFocus ของคุณอยู่ คือการกดปุ่ม ไม่ว่าจะเป็น Tab Enter หรือคลิ๊กเมาส์ ของคุณนั้นเอง ซึ่งโปรแกรมจะถือว่านั้นเป็นเหตุการณ์ต่อจากคำสั่งคุณ ดังนั้นหลังการ SetFocus ที่ Text29 แล้ว มันจึงต่อด้วยการย้ายไปยัง Textbox ตัวอื่นที่คุณคลิ๊ก หรือกด Tab หรือ Enter อะไรก็ไม่ทราบได้ (งงเหมือนกัน) นั่นเอง แต่หากอยากแก้แค่นี้จริงๆ แบบกำปั้นทุบดิน ที่ผมคิดได้ตอนนี้คือประมาณนี้ครับ
Dim TT As String
TT = Me.CurrentRecord
MsgBox "................."
SendKeys "{F5}", True
DoCmd.GoToRecord , , acGoTo, dd
Me.Text29.SetFocus
ประมาณว่า Reset ฟอร์มใหม่แล้วค่อยกลับไป SetFocus ที่เรคคอร์ดเดิม ลองดูแล้วกันครับ
ปล. คิดว่าคุณต้องลองเรียบเรียงโค๊ดดูใหม่ให้ดี ไม่งั้นคุณอาจต้องมาเขียนแก้นั่นดักตรงนี้ เกินความจำเป็นนะครับ
10 @R14419
แก้ไข (อีกแล้ว พิมพ์เองจากจินตนาการ เลย งง เอง)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
Dim TT As String
TT = Me.CurrentRecord
MsgBox "................."
SendKeys "{F5}", True
DoCmd.GoToRecord , , acGoTo, TT
Me.Text29.SetFocus
end sub
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
Dim TT As String
TT = Me.CurrentRecord
MsgBox "................."
SendKeys "{F5}", True
DoCmd.GoToRecord , , acGoTo, TT
Me.Text29.SetFocus
end sub
11 @R14427
ขอบคุณมากครับ คุณ TTT ผมใช้แนวการตรวจสอบ(ตามที่คุณบอก)ให้เสร็จก่อน ถ้าข้อมูลไม่ถูกต้อง ก็ไม่สามารถออกจาก Textbox บน Form นี้ได้ ถ้าข้อมูล(รหัสลูกค้าถูกต้อง) จะแสดงชื่อลูกค้าบน Textbox (Text37) บน Form ด้วยครับ ใช้งานได้ดีเลยครับ...แต่มีปัญหาอยู่ว่า สมมุติว่า เมื่อผู้ใช้งาน..เปิด Form นี้เพื่อป้อนข้อมูล แล้วเกิดเปลี่ยนใจ ต้องการยกเลิกการทำงาน จะออกจาก Textbox นี้ได้อย่างไรครับ ผมลองแล้ว มันไม่ยอมให้ออกเลยครับ
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
MsgBox "ป้อนเฉพาะตัวเลข 4 ตัว"
Cancel = True
ElseIf Me.Text29 = IsNull(DLookup("Customer_ID", "Table4", "Customer_ID = Forms!frmTable1_InsertData!Text29")) Then
MsgBox "รหัสผิด.. โปรดตรวจสอบใหม่"
Cancel = True
End If
Text37 = DLookup("Customer_Name", "Table4", "Customer_ID=FORMS!frmTable1_InsertData!Text29")
End Sub
Private Sub Text29_BeforeUpdate(Cancel As Integer)
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) Then
MsgBox "ป้อนเฉพาะตัวเลข 4 ตัว"
Cancel = True
ElseIf Me.Text29 = IsNull(DLookup("Customer_ID", "Table4", "Customer_ID = Forms!frmTable1_InsertData!Text29")) Then
MsgBox "รหัสผิด.. โปรดตรวจสอบใหม่"
Cancel = True
End If
Text37 = DLookup("Customer_Name", "Table4", "Customer_ID=FORMS!frmTable1_InsertData!Text29")
End Sub
12 @R14430
เพิ่ม เงื่อนไขนี้เข้าไปครับ And Not IsNull(Me.Text29) เป็นเงื่อนไขหากเปลี่ยนใจก็ลบค่าใน Text29 ออกให้หมด ก็สามารถย้าย Focus ได้ครับ
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) And Not IsNull(Me.Text29) Then
...
ElseIf Me.Text29 = IsNull(DLookup("Customer_ID", "Table4", "Customer_ID = Forms!frmTable1_InsertData!Text29")) And Not IsNull(Me.Text29) Then
จริงๆหากเป็นการเพิ่มเรคคอร์ดใหม่ ไม่ใช่การแก้ไขเรคคอร์ด ผู้ใช้ใส่ข้อมูลไปแล้ว ตามปกติ ผมเข้าใจว่าโปรแกรมจะบันทึกเป็นเรคคอร์ดใหม่เลยนะครับ ฉนั้นหากต้องการยกเลิกเรคคอร์ดใหม่อาจต้องใช้คำสั่ง
Me.Undo หรือ กดปุ่ม Esc หรือ sendkeys "{esc}" อะไรประมาณนี้ด้วยนะครับ ลองปรับใช้ดู พอดีวันนี้ผมอยู่ข้างนอกไม่มี MS Access ให้ลอง
If Len(Me.Text29) <> 4 Or Not IsNumeric(Me.Text29) And Not IsNull(Me.Text29) Then
...
ElseIf Me.Text29 = IsNull(DLookup("Customer_ID", "Table4", "Customer_ID = Forms!frmTable1_InsertData!Text29")) And Not IsNull(Me.Text29) Then
จริงๆหากเป็นการเพิ่มเรคคอร์ดใหม่ ไม่ใช่การแก้ไขเรคคอร์ด ผู้ใช้ใส่ข้อมูลไปแล้ว ตามปกติ ผมเข้าใจว่าโปรแกรมจะบันทึกเป็นเรคคอร์ดใหม่เลยนะครับ ฉนั้นหากต้องการยกเลิกเรคคอร์ดใหม่อาจต้องใช้คำสั่ง
Me.Undo หรือ กดปุ่ม Esc หรือ sendkeys "{esc}" อะไรประมาณนี้ด้วยนะครับ ลองปรับใช้ดู พอดีวันนี้ผมอยู่ข้างนอกไม่มี MS Access ให้ลอง
13 @R14432
ในกรณีที่ผมเขียนนี้นะครับก่อนการบันทึก record ต้องตรวจสอบข้อมูลใน Textbox บน Form ทั้งหมดก่อนว่ามีการใส่ข้อมูล ห้ามว่าง จึงจะบันทึกได้ครับ
14 @R14433
- แล้วประเด็นคืออะไร
"แต่มีปัญหาอยู่ว่า สมมุติว่า เมื่อผู้ใช้งาน..เปิด Form นี้เพื่อป้อนข้อมูล แล้วเกิดเปลี่ยนใจ ต้องการยกเลิกการทำงาน จะออกจาก Textbox นี้ได้อย่างไรครับ ผมลองแล้ว มันไม่ยอมให้ออกเลยครับ"
- ตามเงื่อนไขที่เพิ่มไป ก็ไม่บันทึกก็ถูกแล้ว ก็ให้เป็นค่าว่างก่อน แล้วยกเลิก กด Esc ก็ได้
"ในกรณีที่ผมเขียนนี้นะครับก่อนการบันทึก record ต้องตรวจสอบข้อมูลใน Textbox บน Form ทั้งหมดก่อนว่ามีการใส่ข้อมูล ห้ามว่าง จึงจะบันทึกได้ครับ"
- ก็ในเมื่อคุณต้องการยกเลิก แล้วคุณจะตรวจสอบห้ามว่าง จึงจะบันทึก อะไร จะสื่ออะไรครับ ขออีกที ผมงงเลย ตกลงต้องการบันทึก หรือ ยกเลิกได้
"แต่มีปัญหาอยู่ว่า สมมุติว่า เมื่อผู้ใช้งาน..เปิด Form นี้เพื่อป้อนข้อมูล แล้วเกิดเปลี่ยนใจ ต้องการยกเลิกการทำงาน จะออกจาก Textbox นี้ได้อย่างไรครับ ผมลองแล้ว มันไม่ยอมให้ออกเลยครับ"
- ตามเงื่อนไขที่เพิ่มไป ก็ไม่บันทึกก็ถูกแล้ว ก็ให้เป็นค่าว่างก่อน แล้วยกเลิก กด Esc ก็ได้
"ในกรณีที่ผมเขียนนี้นะครับก่อนการบันทึก record ต้องตรวจสอบข้อมูลใน Textbox บน Form ทั้งหมดก่อนว่ามีการใส่ข้อมูล ห้ามว่าง จึงจะบันทึกได้ครับ"
- ก็ในเมื่อคุณต้องการยกเลิก แล้วคุณจะตรวจสอบห้ามว่าง จึงจะบันทึก อะไร จะสื่ออะไรครับ ขออีกที ผมงงเลย ตกลงต้องการบันทึก หรือ ยกเลิกได้
15 @R14448
OK แล้วครับ ทำงานได้ตามความต้องการแล้วครับ ต้องขอขอบคุณ คุณ TTT มากเลยนะครับที่กรุณาสละเวลาชี้แนะ ให้ความรู้แก่ผู้ที่เพิ่งเริ่มต้นอย่างผม และอีกหลายท่านที่เข้ามาค้นคว้าหาความรู้ที่ Web นี้ และขอขอบคุณทุกท่านที่สละเวลาเข้ามาให้ความรู้ด้วยครับ
Time: 0.3547s
ลองดูครับ ใส่หลังคำสั่งที่เราอยากให้ทำก่อน เช่น
Me.Text29.SetFocus
DoEvents
If Len(Text29) <> 4 Then GoTo incorrect
For i = 1 To 4
If IsNumeric(Mid(Text29, i, 1)) = False Then GoTo incorrect
Next
หรืออาจใส่ใน Loop ในกรณีที่มีการ Loop นานๆ แต่อย่างให้ฟอร์มยังตอบสนองอยู่ ลองปรับใช้ดูครับ