บทความในตอนนี้จึงขอนำเสนอการดัก หรือ ตรวจสอบการกดคีย์บอร์ดเพื่อให้รับค่าเฉพาะตัวเลข และ จุดทศนิยม ซึ่งต้องนำไปใช้งานกับการกรอกค่าจำนวนเงิน หรืออื่นๆ ที่ต้องมีจุดทศนิยมมาผสมด้วย (ผมเป็นคนที่ไม่นิยม MaskEdit Component และ ใช้ไม่เป็นด้วยครับ แฮะๆ) โดยผมแบ่งเป็น 2 เวอร์ชั่น คือตัวแรกเนี่ยผมคิดได้ตอนเริ่มเขียนโปรแกรมใหม่ๆครับ และมันมีจุดสนใจให้ศึกษาไปด้วย (คือไม่อยากให้ Copy Code ไปอย่างเดียวล่ะน่ะ) ไม่ว่าจะเป็นคำสั่ง (หรือ ฟังค์ชั่น) แบบพื้นฐาน เช่น Mid$, Len, Left หรือ Right ประมาณนี้ มันมีอยู่แล้วแทบจะทุกๆภาษา และเราต้องใช้มันมาแก้ปัญหาต่างๆค่อนข้างจะเยอะมาก
ในตัวอย่างนี้ผมทำเป็นโปรแกรมย่อยที่มีการส่งค่าไป และ รับค่ากลับมาได้ ซึ่งเราเรียกมันว่า "ฟังค์ชั่น" ครับพี่น้อง การทำเป็นฟังค์ชั่นนี้ก็เพราะมันมีการทำงานเดิมซ้ำๆหลายหน เราจึงต้องจับแยกออกมา เช่น มีการป้อนค่าลงใน TextBox หลายๆตัวนั่นแหละครับ เพื่อให้สะดวกต่อการแก้ไข ปรับปรุง และลดจำนวนโค้ดลงไปได้อีกด้วย และ จากตัวอย่างนี้ผมได้เปรียบเทียบให้เห็นถึงการเลือกใช้งานคำสั่ง Select Case ซึ่งคำสั่งนี้มันทำงานเหมือนกับ IF ... Then ... Else ทุกประการ แต่การใช้ Select Case (ภาษา C จะใช้ Switch ส่วนภาษาอื่นอาจเป็น Case เฉยๆ) มันมีข้อสังเกตเรื่องนึงคือ เงื่อนไขที่ใช้ทดสอบนั้นมันจะเป็นค่าคงที่ (เสมอ) หรือ สามารถระบุค่าที่ใช้ในการตรวจสอบได้ ซึ่งมันก็ต้องขึ้นอยู่กับสถานะการณ์เมื่อต้องเลือกใช้งานแหละครับ แต่บางคนก็ถนัด IF ก็ใช้ได้น่ะครับ ไม่ผิดกฏ กติกา มารยาทแต่อย่างใด
ออกแบบฟอร์มให้มี TextBox กับ Label อย่างละตัว
Option Explicit
Private Sub Form_Load()
Text1.Text = ""
End Sub
' สังเกตว่าเป็นการรับค่าจาก TextBox เข้ามาโดยตรง หรือ Pass By Value
Function CheckCurrencyVol1(Index As Integer, tmpStr As String) As Integer
Dim i As Integer
Select Case Index
Case 48 To 57
' 0 - 9 and Return index = KeyAscii
Case 8
' Back Space and Return index = KeyAscii
Case 13
' Enter and Return index = KeyAscii
Case 46 ' KeyAscii Code ของเครื่องหมายจุดครับพี่น้อง
For i = 1 To Len(tmpStr) ' นับตามความยาวของค่าที่ป้อนเข้าไป
If Mid$(tmpStr, i, 1) = "." Then
Index = 0 ' พบเครื่องหมายจุดแล้ว ให้ยกเลิกคีย์ Ascii ที่กด และรีเทิร์นค่ากลับเป็น 0
Exit For ' ให้ออกจากลูปไปได้เลย
End If
Next i
Case Else
Index = 0
End Select
CheckCurrencyVol1 = Index ' Return ค่ากลับตามที่ได้ตรวจสอบ
End Function
Private Sub Text1_KeyPress(KeyAscii As Integer)
' ส่งค่าคีย์ที่กดไปตรวจสอบที่ฟังค์ชั่น และต้อง Return ค่ากลับมาด้วย
KeyAscii = CheckCurrencyVol1(KeyAscii, Text1.Text)
End Sub
|
ผลลัพธ์ที่ได้ก็คือผู้ใช้งานสามารถกดคีย์ตัวเลข (จะให้มีความยาวกี่ตัวก็ไปแก้ไขที่คุณสมบัติ MaxLength น่ะครับ) แต่ไคลแมกซ์ของเรื่องนี้ คือ จะกดปุ่มจุดทศนิยมได้เพียงครั้งเดียวเท่านั้น (นั่นคือลด Human Error ได้อีกเปลาะหนึ่งครับ) จากเวอร์ชั่นแรกนี้ เราสามารถใช้ฟังค์ชั่น Left, Right แทนได้ด้วยน่ะครับ แต่จะเห็นว่าการตรวจสอบค่าคีย์นั้น ค่อนข้างจะยุ่งยากเกินไป แต่ผมอยากจะเปรียบเทียบให้ได้เห็นภาพกันจะๆว่า เมื่อเริ่มต้นตั้งไข่เพื่อที่จะเขียนโปรแกรม (หรือแม้แต่ทุกวันนี้ก็ตามเหอะน่ะ) การแก้ไขปัญหาเฉพาะหน้าเป็นเรื่องที่ต้องให้ความสำคัญมากกว่า การประดิดประดอยเพื่อให้ได้โค้ดที่สวยงาม (ต้องทำตามเวลาให้ทันกำหนดส่งงาน ประมาณนั้น) หลังจากนั้นการเก็บประสบการณ์ที่เพิ่มมากขึ้นเรื่อยๆ มันก็จะเป็นสิ่งที่สอนตัวเราเองได้ดีที่สุด ก็ค่อยๆพัฒนาหาทางแก้ไขให้ดูดีขึ้นล่ะครับ
Option Explicit
Private Sub Form_Load()
Text1.Text = ""
End Sub
' ทีนี้เป็นการรับค่าแบบ Control หรือ Object แทน หรือ Pass By Reference
' ซึ่งวิธีการนี้เราสามารถนำไปดัดแปลงใช้งานได้หลากหลาย ทำให้โปรแกรมของเรามีความยืดหยุ่นสูง (จริงๆ)
Function CheckCurrencyVol2(Index As Integer, Ctrl As TextBox) As Integer
Select Case Index
Case 48 To 57
' 0 - 9 and Return index = KeyAscii
Case 8
' Back Space and Return index = KeyAscii
Case 13
' Enter and Return index = KeyAscii
Case 46 ' รหัส Ascii Code ของเครื่องหมายจุดครับพี่น้อง
If InStr(Ctrl, ".") Then Index = 0 ' ใช้ฟังค์ชั่น InStr (In String) เพื่อหาเครื่องหมายจุดใน TextBox
Case Else
Index = 0
End Select
CheckCurrencyVol2 = Index ' Return ค่ากลับตามที่ได้ตรวจสอบ
End Function
Private Sub Text1_KeyPress(KeyAscii As Integer)
' ส่งค่าคีย์ที่กดไปตรวจสอบที่ฟังค์ชั่น และต้อง Return ค่ากลับมาด้วย
KeyAscii = CheckCurrencyVol2(KeyAscii, Text1)
End Sub
|
ลองทดสอบด้วยการรันแบบ Step หรือ กด F8 ไปทีละขั้น ทีละตอนไปล่ะกันครับ เพื่อจะได้ศึกษาในรายละเอียดปลีกย่อยของการทำงาน แล้วก็ลองนำไปพัฒนา ปรับปรุงใช้งานกับโจทย์อื่นๆได้อีกต่อไป ..... นี่คือสิ่งที่ผมต้องการอยากให้ท่านเข้าใจครับ ... พี่น้อง
|