[VB.NET] การแยกตัวเลขออกมาจากชุดข้อความ
http://www.g2gnet.com/webboard/images/vbnet/SeparateFull.pngบังเอิญไปเจอหัวข้อของ Excel ในเรื่อง TextJoin ฟังค์ชั่นที่คุณต้องรู้ เป็นเรื่องที่กล่าวถึงคำสั่งภายใน หรือฟังค์ชั่นของ Excel ในการเชื่อมต่อ (Join) ข้อความ แต่ในตัวอย่างเขาทำการแยกชุดตัวเลข (Number) ออกมาจากชุดข้อข้อความ (String) พอเห็นแล้วก็คิดว่าเป็นเรื่องที่น่าสนใจ ก็เลยนำมาเผยแพร่เป็นความรู้ให้กับคนที่พึ่งเริ่มหัดเขียนโปรแกรมใหม่ๆ ซึ่งมันมีหลากหลายวิธีมากในการแก้ปัญหาโจทย์เรื่องนี้ เอาเป็นว่าแอดมินจะตัดมาเป็นบางส่วนเพื่อเป็นตัวอย่างให้ได้รับชมกัน โดยเริ่มจากวิธีการคิดแบบพื้นฐานในแบบที่ทุกๆภาษาก็ใช้หลักการเดียวกันนี่แหละ ไปจนถึงการใช้ความสามารถในตัวของ Visual Basic .NET ก็ลองศึกษาและนำไปปรับใช้งานกันเองล่ะครับ ...
วิธีคิดแบบพื้นฐาน ...
1. อ่านค่าชุดข้อความ (String) อินพุทเข้ามาสัก 1 ชุด
2. แยกตัวอักขระ (Character) ทีละตัวออกมา แล้วเช็คว่ามันเป็นตัวเลข 0 - 9 หรือไม่ หากใช่ก็นำไปเก็บในตัวแปร แล้วก็วนรอบตามความยาวของชุดตัวอักษร
3. นำมาแสดงผล ... จบ
จากวิธีการคิดดังกล่าว เราสามารถนำมาเขียนเป็นโปรแกรมเพื่อทำการทดสอบได้ดังนี้คือ ... ' / ----------------------------------------------------------------
' / ทดสอบวิธีการคิดแบบพื้นฐาน
Private Sub BasicThinking()
Dim myString As String = "a25B1"
Dim myChar As String = ""
Dim myNum As String = ""
'/ วนรอบตามความยาวของชุดข้อความ
For i = 1 To Len(myString)
'/ แยกตัวอักขระออกมาเช็คทีละตัว เรียงจากซ้ายไปขวา
myChar = Mid(myString, i, 1)
Select Case myChar
'/ มีค่าระหว่าง 0 - 9 หรือไม่
Case "0" To "9"
myNum = myNum + myChar
End Select
Next
MsgBox(myNum)
End Subเป็นการคิดแก้ไขปัญหาจากโจทย์ในแบบฉบับขั้นพื้นฐาน
เพิ่มระดับการฝึกฝนด้วยกระบวนการคิด ในการเขียนเป็นฟังค์ชั่นทั้งการส่งค่าและรับค่าคืนกลับ ...
' / ----------------------------------------------------------------
' / เขียนแบบฟังค์ชั่นโดยการรับค่าชุดข้อความและคืนกลับชุดตัวเลข
Private Function SeparateNumber(ByVal myString As String) As String
SeparateNumber = ""
Dim myChar As String = ""
'/ วนรอบตามความยาวของชุดข้อความ
For i = 1 To Len(myString)
'/ แยกตัวอักขระออกมาเช็คทีละตัว เรียงจากซ้ายไปขวา
myChar = Mid(myString, i, 1)
Select Case myChar
'/ มีค่าระหว่าง 0 - 9 หรือไม่
Case "0" To "9"
SeparateNumber = SeparateNumber + myChar
End Select
Next
Return SeparateNumber
End Function
การใช้ String Builder ' / ----------------------------------------------------------------
' / การใช้ String Builder
Function GetNumberFromStringBuilder(ByVal theString As String) As Long
Dim sb As New System.Text.StringBuilder(theString.Length)
For Each ch As Char In theString
'/ หากเป็นตัวเลขให้นำไปต่อท้าย (Append)
If Char.IsDigit(ch) Then sb.Append(ch)
Next
Return Long.Parse(sb.ToString)
End Function
การใช้ LINQ Statement
' / ----------------------------------------------------------------
' / การใช้ LINQ Statement
Private Function GetNumberFromStringLINQ(ByVal myString As String) As String
Dim numbers = (From s In myString
Where (Char.IsDigit(s))
Select Int32.Parse(s)).ToArray()
Dim myNums As String = ""
For Each n As String In numbers
myNums = myNums + n
Next
Return myNums
End Function
การใช้ Regular Expressions ... ' / ----------------------------------------------------------------
' / การใช้ Regular Expressions การกำหนดรูปแบบหรือกลุ่มคำ เพื่อเอาไว้ใช้ค้นหาข้อความต่างๆตามที่เราต้องการ
' / ต้อง Imports System.Text.RegularExpressions ด้วยล่ะ
Private Function RegExpress(ByVal value As String) As Integer
Dim returnVal As String = String.Empty
' / การสร้าง MatchCollection เพื่อเก็บค่าที่ตรงกับความต้องการ
Dim collection As MatchCollection = Regex.Matches(value, "\d+")
For Each m As Match In collection
returnVal += m.ToString()
Next
Return Convert.ToInt32(returnVal)
End Functionสำหรับ Regular Expressions หรือที่เรียกสั้นๆว่า Regex ค่อนข้างจะน่าสนใจเลยทีเดียว ก็ลองศึกษาค้นคว้ากันเพิ่มเติมนะครับ ส่วนเจ้า Pattern ที่เราต้องการค้นหา หรือที่เรียกมันว่า Cheat Sheet เราสามารถดูรูปแบบได้จากที่ Quick-Start: Regex Cheat Sheet
ตัวอย่างวิธีการที่ 1 นำมาใช้ในงานจริงกับการกระทำภายในตารางกริด ... (สำหรับ VB.Net)
' / ----------------------------------------------------------------
' / V.I เขียนฟังค์ชั่นขึ้นใช้งานเอง
Private Sub btnVersion1_Click(sender As System.Object, e As System.EventArgs) Handles btnVersion1.Click
'/ วนรอบตามจำนวนแถว
For i = 0 To DataGridView1.RowCount - 1
'/ อ่านค่าหลัก 0 (Index) ในแต่ละแถวเข้ามาเพื่อทำการแยกทีละ Character
Dim myString As String = DataGridView1.Rows(i).Cells(0).Value
Dim myNums As String = ""
Dim myChar As String
'/ อ่าน Character แต่ละตัวที่อยู่ในชุดข้อความ (ใช้ความยาวของชุดข้อความเป็นเงื่อนไข)
For x = 1 To Len(myString)
'/ แยก Character มาทีละหลัก ไล่จากซ้ายไปขวา
myChar = Mid(myString, x, 1)
'/ ส่งค่า Character แต่ละตัวไปยังฟังค์ชั่น
If CheckDigit(myChar) Then
'/ หากมีค่า 0 - 9
myNums = myNums + myChar
End If
Next
DataGridView1.Rows(i).Cells(1).Value = Format(CLng(myNums), "#,##")
Next
End Sub
การเขียนฟังค์ชั่นเพื่อใช้ตรวจสอบค่า 0 - 9 ขึ้นมาเอง ...
' / ----------------------------------------------------------------
' / เขียนฟังค์ชั่นขึ้นเอง เพื่อตรวจสอบว่าเป็นตัวเลข 0 - 9 หรือไม่
Function CheckDigit(ByVal ch As Char) As Boolean
Select Case ch
'/ หากมีค่าตั้งแต่ 0 - 9 ให้คืนค่า True
Case "0" To "9"
CheckDigit = True
Case Else
CheckDigit = False
End Select
End Functionค่าที่ส่งมา (ch) ยังฟังค์ชั่นก็จะเป็น Character หรือตัวอักขระ 1 ตัว โดยใช้เงื่อนไข "0" To "9" หากมีค่าตามนี้ก็จะคืนค่า True กลับไปบอก แต่ถ้าหากไม่ใช่มันก็คือ เท็จ หรือ False ... นี่คือวิธีที่เราๆท่านๆน่าจะคิดกันแบบโดยทั่วๆไป และทุกตัวแปรภาษาก็สามารถใช้ได้เลย
ตัวอย่างวิธีการที่ 2
' / ----------------------------------------------------------------
' / V.II ใช้ความสามารถของตัวแปลภาษา
Private Sub btnVersion2_Click(sender As System.Object, e As System.EventArgs) Handles btnVersion2.Click
'/ วนรอบตามจำนวนแถว
For i = 0 To DataGridView1.RowCount - 1
'/ อ่านค่าหลัก 0 (Index) ในแต่ละแถวเข้ามาเพื่อทำการแยกทีละ Character
Dim myChars() As Char = DataGridView1.Rows(i).Cells(0).Value.ToCharArray()
Dim myNums As String = ""
'/ อ่าน Character แต่ละตัวที่อยู่ในชุดข้อความ
For Each ch As Char In myChars
'/ เป็นตัวเลขหรือไม่
If Char.IsDigit(ch) Then
'/ หากใช่ให้แยกมาเก็บ โดยการจัดเรียงต่อกันด้วยเครื่องหมาย +
myNums = myNums + ch
End If
Next
'/ CLng = Convert To Long มีมาตั้งแต่ VB6 ครับ
DataGridView1.Rows(i).Cells(1).Value = Format(CLng(myNums), "#,##")
Next
End Sub
ตัวอย่างวิธีการที่ 3
' / ----------------------------------------------------------------
' / V.III
Private Sub btnVersion3_Click(sender As System.Object, e As System.EventArgs) Handles btnVersion3.Click
'/ วนรอบตามจำนวนแถว
For i = 0 To DataGridView1.RowCount - 1
Dim theString As String = DataGridView1.Rows(i).Cells(0).Value
Dim sb As New System.Text.StringBuilder(theString.Length)
For Each ch As Char In theString
If Char.IsDigit(ch) Then sb.Append(ch)
Next
DataGridView1.Rows(i).Cells(1).Value = Format(CLng(Long.Parse(sb.ToString)), "#,##")
Next
End Subดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่
ขอบพระคุณมากครับอาจารย์ ขอบคุณครับ
หน้า:
[1]