thongkorn โพสต์ 2022-10-11 13:04:10

[VB6] การตรวจสอบข้อมูล (Validate Data) สำหรับ TextBox Control

การตรวจสอบข้อมูล หรือ Validate Data เป็นส่วนสำคัญอย่างมาก ในการดัก Error โดยเฉพาะค่าทางตัวเลข เพราะเราจะดักค่า หรือเช็คความถูกต้องก่อนที่จะนำค่าไปคำนวณผล โดยที่ไม่ต้องมาใช้คำสั่ง IF ซ้อนๆกัน และเหตุการณ์ที่ต้องทำซ้ำๆ ด้งนั้นเราควรจะนำโค้ดไปเก็บไว้ในลักษณะของ Public Function (รับค่าและคืนค่าได้) เพื่อให้ฟอร์มทุกฟอร์มมองเห็นได้ และลดจำนวนโค้ดลงไป ในโค้ดชุดนี้แอดมินได้เพิ่มเรื่องของการทำไฮไลท์เพื่อแสดงตำแหน่งโฟกัสการป้อนข้อมูล และที่สำคัญคือการแก้ปัญหาในเรื่องการกด Enter ในการเลื่อนตำแหน่งโฟกัส ซึ่งจะมีปัญหามาตั้งแต่ Windows 8+ ทำให้เกิด Error หรือที่เรียกว่า Permission Denied (Run Time Error 70)

http://www.g2gsoft.com/webboard/images/VB6/ValidateVB6.jpg
การทำไฮไลท์ให้กับตำแหน่งโฟกัส

http://www.g2gsoft.com/webboard/images/VB6/ValidateVB6-01.jpg
เทคนิคการเรียงลำดับ TabIndex

http://www.g2gsoft.com/webboard/images/VB6/ValidateVB6-02.jpg
ควรย้ายฟังค์ชั่นเหล่านี้ให้ไปอยู่ในโมดูล และประกาศเป็นแบบ Public

มาดูโค้ดฉบับเต็มกันเถอะ ... Option Explicit

' / ---------------------------------------------------------------------------
Private Sub Form_Load()
' / ---------------------------------------------------------------------------
    '/ เคลียร์ค่าใน TextBox ทั้งหมด
    txtAlphabet.Text = ""
    txtAlphabetUCase.Text = ""
    txtInteger.Text = "0"
    txtDouble.Text = "0.00"
    '/ จัดเรียงลำดับของการโฟกัส หรือ TabIndex (ไปทำในตอน Designer จะง่ายกว่า)
    txtAlphabet.TabIndex = 0
    txtAlphabetUCase.TabIndex = 1
    txtInteger.TabIndex = 2
    txtDouble.TabIndex = 3
End Sub

' / ---------------------------------------------------------------------------
' / เหตุการณ์ในการที่ TextBox ได้รับโฟกัส
Private Sub txtAlphabet_GotFocus()
' / ---------------------------------------------------------------------------
    '/ ทำไฮไลท์แถบแสง โดยเรียกไปยังฟังค์ชั่น HLText และส่งชื่อ Control ไปด้วย
    Call HLText(txtAlphabet)
End Sub

' / ---------------------------------------------------------------------------
Private Sub txtAlphabet_KeyPress(KeyAscii As Integer)
' / ---------------------------------------------------------------------------
    ' / หากเกิดการกด Enter ให้ส่งคีย์ TAB เพื่อเลื่อนตำแหน่งโฟกัสไปยัง Control ถัดไป
    ' / VB6 ไม่มีเหตุการณ์กด Enter แล้วเลื่อนโฟกัส ต้องใช้การส่งคีย์ (SendKeys) การกด TAB แทน
    If KeyAscii = 13 Then
      Sendkeys "{TAB}"
      KeyAscii = 0    '/ ปิดเสียง
    Else
      '/ ส่งค่า KeyAscii ที่กดลงไปบนคีย์แต่ละตัว ไปให้กับฟังค์ชั่น CheckAlphabet และส่งค่ากลับคืนมา
      '/ หากเป็นตัวอักษรภาษาอังกฤษก็จะคืนค่า Ascii Code A - Z (65 - 90), a - z (97 - 122)
      '/ หากไม่ใช่ ก็จะคืนค่า 0 กลับมา เสมือนว่าไม่มีการกดคีย์ใดๆเลย
      KeyAscii = CheckAlphabet(KeyAscii)
    End If
End Sub

' / ---------------------------------------------------------------------------
' / เหตุการณ์ในการที่ TextBox ได้รับโฟกัส
Private Sub txtAlphabetUCase_GotFocus()
' / ---------------------------------------------------------------------------
    '/ ทำไฮไลท์แถบแสง โดยเรียกไปยังฟังค์ชั่น HLText และส่งชื่อ Control ไปด้วย
    Call HLText(txtAlphabetUCase)
End Sub

' / ---------------------------------------------------------------------------
Private Sub txtAlphabetUCase_KeyPress(KeyAscii As Integer)
' / ---------------------------------------------------------------------------
    ' / หากเกิดการกด Enter ให้ส่งคีย์ TAB เพื่อเลื่อนตำแหน่งโฟกัสไปยัง Control ถัดไป
    If KeyAscii = 13 Then
      Sendkeys "{TAB}"
      KeyAscii = 0    '/ ปิดเสียง
    Else
      '/ รับค่าตัวอักษรภาษาอังกฤษทั้งตัวใหญตัวเล็ก แต่กดตัวอักษรตัวเล็ก a - z จะแปลงเป็นตัวอักษรตัวใหญ่ A - Z ให้อัตโนมัติ
      KeyAscii = Asc(UCase(Chr(CheckAlphabet(KeyAscii))))
    End If
End Sub

' / ---------------------------------------------------------------------------
' / เหตุการณ์ในการที่ TextBox ได้รับโฟกัส
Private Sub txtDouble_GotFocus()
' / ---------------------------------------------------------------------------
    '/ ทำไฮไลท์แถบแสง โดยเรียกไปยังฟังค์ชั่น HLText และส่งชื่อ Control ไปด้วย
    Call HLText(txtDouble)
End Sub

' / ---------------------------------------------------------------------------
Private Sub txtDouble_KeyPress(KeyAscii As Integer)
' / ---------------------------------------------------------------------------
    ' / หากเกิดการกด Enter ให้ส่งคีย์ TAB เพื่อเลื่อนตำแหน่งโฟกัสไปยัง Control ถัดไป
    If KeyAscii = 13 Then
      Sendkeys "{TAB}"
      KeyAscii = 0    '/ ปิดเสียง
    Else
      '/ ส่งค่า KeyAscii ที่กดลงไปบนคีย์แต่ละตัว ไปให้กับฟังค์ชั่น CheckAlphabet และส่งค่ากลับคืนมา
      '/ หากเป็นตัวอักษรภาษาอังกฤษก็จะคืนค่า Ascii Code A - Z (65 - 90), a - z (97 - 122)
      '/ หากไม่ใช่ ก็จะคืนค่า 0 กลับมา เสมือนว่าไม่มีการกดคีย์ใดๆเลย
      KeyAscii = CheckCurrency(KeyAscii, txtDouble)
    End If
End Sub

' / ---------------------------------------------------------------------------
' / เหตุการณ์ที่ TextBox หลุดโฟกัสไป
Private Sub txtDouble_LostFocus()
' / ---------------------------------------------------------------------------
    '/ ป้องกันค่าว่าง ก่อนที่จะนำค่าไปเก็บหรือคำนวณ
    If Trim(txtDouble.Text) = "" Then
      txtDouble.Text = "0.00"
    Else
      '/ จัดรูปแบบให้กับค่าตัวเลขแบบทศนิยม
      txtDouble.Text = Format(CDbl(txtDouble.Text), "0.00")
    End If
End Sub

' / ---------------------------------------------------------------------------
' / เหตุการณ์ในการที่ TextBox ได้รับโฟกัส
Private Sub txtInteger_GotFocus()
' / ---------------------------------------------------------------------------
    '/ ทำไฮไลท์
    Call HLText(txtInteger)
End Sub

' / ---------------------------------------------------------------------------
' / เหตุการณ์ที่ TextBox หลุดโฟกัสไป
Private Sub txtInteger_LostFocus()
' / ---------------------------------------------------------------------------
    '/ ป้องกันค่าว่าง ก่อนที่จะนำค่าไปเก็บหรือคำนวณ
    If Trim(txtInteger.Text) = "" Then
      txtInteger.Text = "0"
    Else
      '/ จัดรูปแบบให้กับค่าตัวเลขแบบจำนวนเต็ม
      txtInteger.Text = Format(CInt(txtInteger.Text), "0")
    End If
End Sub

' / ---------------------------------------------------------------------------
' / โปรแกรมย่อยเหตุการณ์ (Event) ในการรับค่าการกดคีย์บนแป้นคีย์บอร์ดทีละตัว
Private Sub txtInteger_KeyPress(KeyAscii As Integer)
'/ ---------------------------------------------------------------------------
    ' / หากเกิดการกด Enter ให้ส่งคีย์ TAB เพื่อเลื่อนตำแหน่งโฟกัสไปยัง Control ถัดไป
    If KeyAscii = 13 Then
      Sendkeys "{TAB}"
      KeyAscii = 0    '/ ปิดเสียง
    Else
      '/ ส่งค่า KeyAscii ที่กดลงไปบนคีย์แต่ละตัว ไปให้กับฟังค์ชั่น CheckDigitOnly และส่งค่ากลับมา
      '/ หากเป็นตัวเลขก็จะคืนค่า Ascii Code 48 - 57 (หรือคีย์ 0 - 9) กลับคืนมา
      '/ หากไม่ใช่ ก็จะคืนค่า 0 กลับมา เสมือนว่าไม่มีการกดคีย์ใดๆเลย
      KeyAscii = CheckDigitOnly(KeyAscii)
    End If
End Sub

' / ---------------------------------------------------------------------------
' / ฟังค์ชั่นในการทำไฮไลท์เมื่อ TextBox ถูก Focus
' / ---------------------------------------------------------------------------
Public Sub HLText(ByRef sText)
    On Error Resume Next
    With sText
      .SelStart = 0
      .SelLength = Len(sText.Text)
    End With
End Sub

' / ---------------------------------------------------------------------------
' / แก้ปัญหาเรื่อง SendKeys ตั้งแต่ Windows 8+
Public Sub Sendkeys(Text As String, Optional Wait As Boolean = False)
' / ---------------------------------------------------------------------------
    Dim WshShell As Object
    Set WshShell = CreateObject("Wscript.shell")
    WshShell.Sendkeys Text, Wait
    Set WshShell = Nothing
End Sub

' / ---------------------------------------------------------------------------
' / ฟังค์ชั่นในการตรวจสอบว่าคีย์ที่กดลงไปนั้นมันเป็น 0 - 9 หรือไม่
' / รับค่า KeyAscii จาก TextBox เข้ามาทีละตัว และเช็คค่า ASCII Code
' / หากเป็นตัวเลขก็คืนค่าตัวมันเองกลับ ก็คือยอมรับการกดคีย์นั่นเอง
' / หากไม่ใช่ก็คืนค่ากลับเป็น 0 เสมือนไม่มีการกดคีย์ใดๆนั่นเอง
Public Function CheckDigitOnly(ByVal Index As Integer) As Integer
'/ ---------------------------------------------------------------------------
      Select Case Index
            '/ ASCII Code หากมีค่า 48 - 57 ก็คือเลข 0 - 9 ก็คืนค่าตัวมันเองกลับไป
            Case 48 To 57
            Case 8, 13 ' Backspace = 8, Enter = 13
            '/ หากไม่ใช่คีย์ที่กดใน 2 Case ด้านบน ก็คืนค่า 0 กลับไป เสมือนว่าไม่มีการกดคีย์ใดๆ
            Case Else
                Index = 0
      End Select
      CheckDigitOnly = Index
End Function

'/ ---------------------------------------------------------------------------
' / ฟังค์ชั่นในการตรวจสอบว่าคีย์ที่กดลงไปนั้นมันเป็น 0 - 9 และ . หรือไม่
' / และเครื่องหมายจุด (.) จะรับได้เพียงค่าเดียวเท่านั้น
Public Function CheckCurrency(Index As Integer, Ctrl As TextBox) As Integer
'/ ---------------------------------------------------------------------------
    Select Case Index
            ' 0 - 9 and Return index = KeyAscii
      Case 48 To 57
            ' Back Space and Return index = KeyAscii
      Case 8
            ' Enter and Return index = KeyAscii
      Case 13
      Case 46 ' รหัส Ascii Codeของเครื่องหมายจุด
            If InStr(Ctrl, ".") Then Index = 0 '/ ใช้ฟังค์ชั่น InStr (In String) เพื่อหาเครื่องหมายจุดใน TextBox
      Case Else
            Index = 0
    End Select
    CheckCurrency = Index ' Return ค่ากลับตามที่ได้ตรวจสอบ
End Function

'/ ---------------------------------------------------------------------------
' / ฟังค์ชั่นในการรับค่าตัวอักษรภาษาอังกฤษเท่านั้น
'/ ---------------------------------------------------------------------------
Public Function CheckAlphabet(Index As Integer) As Integer
    Select Case Index
      '/ ASCII Code A - Z (65 - 90), a - z (97 - 122)
      Case 65 To 90, 97 To 122 '/ หรือค่าอื่นๆที่เราต้องการ , Asc(" "), Asc("-"), Asc("&"), Asc("."), Asc("*"), Asc("[      DISCUZ_CODE_0      ]quot;), Asc("/"), Asc("+"), Asc("%")
            CheckAlphabet = Index
      '/ Back Space
      Case 8
      '/ Enter
      Case 13
      'Case 42 ' *
      'Case 43 ' +
      'Case 45 ' -
      'Case 46 ' .
      'Case 47 ' /
      Case Else
            Index = 0
    End Select
    '/ Return ค่ากลับ
    CheckAlphabet = Index
End Function
ดาวน์โหลดโค้ด VB6 (SP1) ฉบับเต็มได้จากที่นี่ ...
หน้า: [1]
ดูในรูปแบบกติ: [VB6] การตรวจสอบข้อมูล (Validate Data) สำหรับ TextBox Control