Tracks
หากเคยเขียนมาโคร VBA มาบ้าง น่าจะเคยมีจังหวะที่ต้องตรวจสอบว่ามีข้อความบางอย่างอยู่ในเซลล์หรือไม่ ใน VBA InStr เป็นหนึ่งในฟังก์ชันที่ได้ใช้บ่อยมาก ฟังก์ชันนี้บอกตำแหน่งที่ข้อความหนึ่งปรากฏอยู่ภายในอีกข้อความหนึ่ง ใช้ตรวจสอบว่ามีข้อความอยู่ในเซลล์ แยกค่าจากข้อความ หรือขับเคลื่อนเงื่อนไขในมาโครที่ขึ้นกับรูปแบบข้อความได้
ในคู่มือนี้ จะพาไปรู้จักไวยากรณ์ของ InStr ตัวอย่างการใช้งาน วิธีทำงานของโหมดการเปรียบเทียบ (ส่วนนี้มักทำให้สับสนเกินความจำเป็น) และแพตเทิร์นการใช้งานที่นำไปใช้ซ้ำได้จริง
แนะนำให้เริ่มจาก เส้นทางทักษะ Excel พื้นฐาน เพื่อปูพื้นฐานให้มั่นคงก่อนต่อยอดสู่ VBA หรือหากมีประสบการณ์อยู่แล้ว ลองคอร์ส ฟังก์ชัน Excel ขั้นสูง เพื่อเรียนรู้เพิ่มเติมว่าฟังก์ชันช่วยเพิ่มประสิทธิภาพในการวิเคราะห์ข้อมูลอย่างไร
VBA InStr คืออะไร?
InStr เป็นฟังก์ชัน VBA ที่ส่งกลับตำแหน่งของการพบสตริงหนึ่งภายในอีกสตริงหนึ่งเป็นครั้งแรก
ผลลัพธ์ทำงานดังนี้:
- ถ้าพบ จะคืนค่าเป็นตัวเลข (ตำแหน่งที่การจับคู่เริ่มต้น)
- ถ้าไม่พบอะไรเลย จะคืนค่าเป็น 0
เช่น หากคำว่า “cat” ปรากฏที่ตำแหน่งที่ 5 ในสตริง จะได้ 5 ถ้าไม่มี จะได้ 0
ไวยากรณ์ VBA InStr
นี่คือไวยากรณ์เต็มของ InStr:
InStr([start], string1, string2, [compare])
โดยที่:
-
start(ไม่บังคับ): ระบุตำแหน่งเริ่มต้นการค้นหา หากละไว้ VBA จะเริ่มจากตำแหน่งที่ 1 -
string1(บังคับ): ข้อความเต็มที่ต้องการค้นหาภายใน -
string2(บังคับ): ข้อความที่ต้องการค้นหา -
compare(ไม่บังคับ): กำหนดวิธีการเปรียบเทียบ (แยกตัวพิมพ์ใหญ่เล็กหรือไม่) หากละไว้ VBA จะใช้โหมดค่าเริ่มต้น ซึ่งมักจะแยกตัวพิมพ์ใหญ่เล็ก
สังเกตว่าสามารถละอาร์กิวเมนต์ start และ compare (InStr(string1, string2)) เพื่อให้รูปแบบเรียบง่ายขึ้นได้ แต่ถ้าจะใช้อาร์กิวเมนต์ compare ต้องระบุอาร์กิวเมนต์ start ด้วย
หลักการทำงานของ VBA InStr
นึกถึง InStr เหมือนการอ่านประโยคจากซ้ายไปขวาทีละอักขระ
ฟังก์ชันจะเริ่มจาก string1 ไล่สแกนและมองหาจุดแรกที่ string2 ตรงกัน ทันทีที่พบก็จะหยุดและคืนค่าตำแหน่งที่เริ่มตรงกันนั้น
ตำแหน่ง “ที่ตรงกัน” สำคัญเพราะ VBA นับจาก 1 ไม่ใช่ 0 ดังนั้นอักขระตัวแรกในสตริงคือตำแหน่งที่ 1 ตัวที่สองคือตำแหน่งที่ 2 และต่อไป
การตีความค่าที่คืนจาก VBA InStr
การตีความผลลัพธ์จากฟังก์ชัน InStr ตรงไปตรงมา จะได้อย่างใดอย่างหนึ่งต่อไปนี้:
-
ตัวเลขบวก: ถ้าพบการจับคู่ ตัวเลขจะบอกตำแหน่งที่เริ่มต้น
-
0: หากไม่พบการจับคู่ใด ๆ ในสตริง
อย่างไรก็ตาม หากสตริงอินพุตเป็น Null ฟังก์ชันจะคืนค่าเป็น Null แม้สำหรับมาโครพื้นฐานอาจละได้ แต่ความต่างนี้อาจทำให้เงื่อนไขผิดพลาดแบบเงียบ ๆ ได้
ตัวอย่างพื้นฐานของ VBA InStr
ต่อไปเป็นตัวอย่างการใช้ฟังก์ชัน InStr ใน VBA
ค้นหาคำในประโยค
เพื่อตรวจสอบว่าคำว่า “before” อยู่ในบันทึก “Deliver before noon” หรือไม่
Sub Before()
Dim result As Integer
result = InStr("Deliver before noon", "before")
MsgBox result
End Sub
ผลลัพธ์ของ VBA ข้างต้นคือ 9 เนื่องจาก “before” เริ่มที่อักขระตัวที่ 9
ตรวจสอบว่ามีอักขระอยู่หรือไม่
เพื่อตรวจสอบว่ามีอักขระ “0” อยู่ในสตริงที่กำหนดหรือไม่ ใช้ VBA ดังนี้:
Sub ChExist()
Dim result As Integer
result = InStr(“A1023”, “0”)
MsgBox result
End Sub
ในกรณีนี้ ผลลัพธ์ที่มากกว่า 0 หมายถึงพบอักขระดังกล่าว
ค้นหาตั้งแต่ต้นสตริง
หากต้องการค้นหาตั้งแต่ต้นสตริง ไม่ต้องระบุตำแหน่งเริ่มต้น การค้นหาจะเริ่มที่ 1 ตามค่าเริ่มต้นทุกครั้ง เว้นแต่จะระบุไว้เป็นอย่างอื่น
Sub ChExist()
Dim result As Integer
result = InStr("Report_2026_Final", "2026")
MsgBox result
End Sub
การใช้ VBA InStr ในคำสั่ง If
เมื่อทำงานกับสเปรดชีตจริง เป้าหมายไม่ใช่แค่ตัวเลข แต่คือการตัดสินใจ วิธีที่พบบ่อยที่สุดในการใช้ InStr คือภายในคำสั่ง If เพื่อกรองข้อมูล
ในบทเรียนนี้จะใช้ชุดข้อมูลตัวอย่าง Orders ที่มีคอลัมน์: ID, CustomerName, Email, City และ OrderNotes
If InStr(...) > 0 Then
เนื่องจาก InStr จะคืนค่า 0 หากไม่พบอะไร ดังนั้นจึงตรวจสอบว่าพบผลลัพธ์หรือไม่โดยดูว่าค่ามากกว่า 0 หรือไม่
ในตัวอย่างด้านล่าง โค้ดจะดูที่คอลัมน์ OrderNotes (คอลัมน์ที่ 5) หากพบคำว่า “Fragile” จะเขียน “Handle Carefully” ในคอลัมน์ที่ 6
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
' Check if the order notes mention "Fragile"
If InStr(Cells(i, 5).Value, "Fragile") > 0 Then
Cells(i, 6).Value = "Handle Carefully"
End If
Next i
End Sub
การตรวจคีย์เวิร์ดและการกรองข้อความแบบมีเงื่อนไข
สามารถใช้ฟังก์ชัน InStr เพื่อตรวจคีย์เวิร์ดในสตริง โดยเฉพาะเมื่อวลีอาจเปลี่ยนเล็กน้อย ตัวอย่างด้านล่างจะตรวจว่าบันทึกมีคำว่า “Call” อยู่หรือไม่ (เช่น “Call on arrival” หรือ “Call before delivery”) จากนั้นจะตั้งธงและเพิ่มแท็ก “Call Customer” ในคอลัมน์ที่ 6
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
' Check if the order notes mention “Call”
If InStr(Cells(i, 5).Value, “Call”) > 0 Then
Cells(i, 6).Value = “Call Customer”
End If
Next i
End Sub
ความไวต่ออักษรตัวพิมพ์และโหมดเปรียบเทียบของ VBA InStr
ตามค่าเริ่มต้น InStr จะแยกตัวพิมพ์ใหญ่เล็ก (เรียกว่า vbBinaryCompare) สมมติค้นหา “chicago” แต่ข้อมูลเป็น “Chicago” InStr จะคืนค่า 0
เพื่อแก้ปัญหานี้ ให้ใช้ อาร์กิวเมนต์ compare โดยที่:
-
vbBinaryCompare(ค่าเริ่มต้น): แยกตัวพิมพ์ใหญ่เล็ก (“A” ไม่เหมือนกับ “a”) -
vbTextCompare: ไม่แยกตัวพิมพ์ใหญ่เล็ก “A” เหมือนกับ “a”
ในตัวอย่างด้านล่าง InStr จะคืนค่า 0 เพราะค้นหา “fragile” (ตัวพิมพ์เล็ก) ภายใน “Fragile items”
Sub CheckFragile()
Dim result As Integer
result = InStr(1, "Fragile items", "fragile", vbBinaryCompare)
MsgBox result
End Sub
อย่างไรก็ตาม หากใช้ vbTextCompare จะได้ค่า 1 จากการค้นหาเดียวกันเพราะไม่สนใจตัวพิมพ์
Sub CheckFragile()
Dim result As Integer
result = InStr(1, "Fragile items", "fragile", vbTextCompare)
MsgBox result
End Sub
VBA InStr พร้อมตำแหน่งเริ่มต้น
บางครั้งไม่ต้องการเริ่มค้นหาตั้งแต่ต้นสตริง อาร์กิวเมนต์ start จะบอก VBA ว่าจะเริ่มค้นหาจากตรงไหน
ในตัวอย่างด้านล่าง อาร์กิวเมนต์ start ถูกตั้งเป็น 10 จึงเริ่มค้นหาจากอักขระตัวที่ 10 ไม่ใช่ตัวแรก และพบ "delivery" ในช่วงถัดไปของสตริง
Sub CheckUrgent()
Dim result As Integer
result = InStr(10, “Deliver before noon - urgent delivery”, “delivery”)
MsgBox result
End Sub
ผลลัพธ์ของตัวอย่างข้างต้นคือ 31 คือตำแหน่งที่ "delivery" เริ่มต้น
วิธีนี้มีประโยชน์เมื่ออยากหาครั้งที่สองของสิ่งใดสิ่งหนึ่ง หรือมองข้ามคำนำหน้าที่รู้ล่วงหน้าเมื่อทำงานกับแพตเทิร์นที่ซ้ำ ๆ
VBA InStr เทียบกับ InStrRev
อย่างที่ทราบ InStr ค้นหาจากซ้ายไปขวา ส่วน InStrRev ค้นหาจากขวาไปซ้าย
เช่น ใช้ InStrRev เพื่อหาจุดสุดท้ายในอีเมล ผลลัพธ์คือ 18 ซึ่งคือตำแหน่งของจุดก่อน “com”
Sub CheckChr()
Dim result As Integer
result = InStrRev("john.jacobs@email.com", ".")
MsgBox result
End Sub
จะพบว่า InStrRev มีประโยชน์มากเมื่อจำเป็นต้องหา “ครั้งสุดท้าย” ของบางอย่าง หรือเมื่อทำงานกับชื่อไฟล์ อีเมล หรือพาธ
กรณีการใช้ VBA InStr ที่พบบ่อย
เมื่อเห็นตัวอย่างการทำงานของฟังก์ชัน InStr แล้ว มาดูกรณีการใช้งานที่พบบ่อยกัน
ตรวจว่าเซลล์มีคีย์เวิร์ดหรือไม่
สมมติว่ามีชุดคำสั่งซื้อของลูกค้า และต้องการตั้งธงสำหรับการจัดการเฉพาะ โค้ดจะดูที่คอลัมน์ OrderNotes และตั้งธงทุกกรณีที่มีคำว่า “noon”
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
If InStr(1, "Deliver before noon", "noon", vbTextCompare) > 0 Then
' Logic to mark as "Morning Delivery"
End If
Next i
End Sub
ตรวจรูปแบบอีเมลเบื้องต้น
ยังสามารถใช้ฟังก์ชัน InStr เพื่อตรวจรูปแบบอีเมลอย่างรวดเร็วได้ ตัวอย่างด้านล่างตรวจว่าอีเมลมี @ หรือไม่ และเขียน “Valid Email Format” ในคอลัมน์ที่ 6
Sub ValidateEmail()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
If InStr(Cells(i, 3).Value, "@") > 0 Then
Cells(i, 6).Value = "Valid Email Format"
End If
Next i
End Sub
ตรวจตัวคั่น เช่น จุลภาคหรือขีดกลาง
สามารถใช้ฟังก์ชัน InStr เพื่อตรวจว่ามีขีดกลาง จุลภาค หรือทับอยู่ในข้อความหรือไม่ ในตัวอย่างด้านล่าง โค้ดวนลูปที่ OrderNotes (คอลัมน์ E) ตรวจว่ามีจุลภาคในข้อความ แล้วเขียนผลลัพธ์ลงในคอลัมน์ F
Sub ValidateEmail()
Dim i As Integer
Dim commaPos As Integer
Dim OrderNotes As String
For i = 2 To 51
OrderNotes = Cells(i, 5).Value
commaPos = InStr(1, OrderNotes, ",")
' If a comma exists, mark it
If commaPos > 0 Then
Cells(i, 6).Value = "Has comma"
Else
Cells(i, 6).Value = "No comma"
End If
Next i
End Sub
ข้อผิดพลาดที่พบบ่อยกับ VBA InStr
ถึงแม้จะมีประสบการณ์พัฒนา ก็อาจพบปัญหากับฟังก์ชัน InStr ที่ทำให้โค้ดทำงานผิดคาด ต่อไปนี้คือปัญหาที่พบได้บ่อยและแนวทางแก้ไข:
-
ลืมว่า InStr เริ่มนับที่ 1: จำไว้เสมอว่าตำแหน่งเริ่มที่ 1 ไม่ใช่ 0 ถ้ามาจาก Python หรือ JavaScript ตอนแรกอาจรู้สึกแปลก
-
คิดว่า InStr คืนค่า True/False: จำไว้ว่า
InStrไม่ได้คืนค่าTrueหรือFalseถ้าต้องการตรวจว่าพบหรือไม่ ต้องเช็คว่าผลลัพธ์> 0 -
ไม่สนใจความต่างตัวพิมพ์: อย่างที่ทราบ
InStrจะแยกตัวพิมพ์ใหญ่เล็กโดยค่าเริ่มต้น หากไม่ต้องการให้สนใจขนาดตัวอักษร ให้ระบุvbTextCompareในอาร์กิวเมนต์compare -
สลับตำแหน่ง string1 และ string2: จำไว้ว่าพารามิเตอร์แรกคือ “ที่ที่ค้นหา” พารามิเตอร์ที่สองคือ “สิ่งที่ค้นหา” ถ้าเขียนแบบนี้
InStr(SearchTerm, FullText)จะได้0ตลอด
VBA InStr เทียบกับฟังก์ชันสตริงอื่น ๆ ใน VBA
เพราะ InStr มักใช้เพื่อบอกตำแหน่งของสตริงในข้อความ มาดูการเปรียบเทียบกับฟังก์ชันสตริงอื่น ๆ
InStr เทียบกับ Like
ตัวดำเนินการ Like ใช้จับคู่แพตเทิร์น เช่น โค้ดด้านล่างตรวจคำว่า “Fragile” โดยใช้แพตเทิร์น * ซึ่งหมายถึง “อะไรก็ได้ก่อนหรือหลัง”
Sub ChExist()
Dim i As Integer
' Loop through rows 2 to 51
For i = 2 To 51
If Cells(i, 5).Value Like "*Fragile*" Then
Cells(i, 6).Value = "Handle Carefully"
End If
Next i
End Sub
ใช้ InStr เมื่อแค่อยากรู้ว่าข้อความมีอยู่หรือไม่ และใช้ Like เมื่อต้องตรวจข้อความตามแพตเทิร์นที่ซับซ้อน
InStr เทียบกับ Replace
แม้ใช้ InStr เพื่อเปลี่ยนค่าทั้งเซลล์ได้ แต่ฟังก์ชัน Replace จะเปลี่ยนเฉพาะข้อความบางส่วนในเซลล์
ในตัวอย่างด้านล่าง ฟังก์ชัน Replace จะสลับ “Fragile” เป็น “Handle Carefully” โดยตรงภายในข้อความ
Sub ReplaceOrder()
Dim i As Integer
For i = 2 To 51
Cells(i, 5).Value = Replace(Cells(i, 5).Value, "Fragile", "Handle Carefully")
Next i
End Sub
InStr เทียบกับ Mid
ฟังก์ชัน Mid ใช้ดึงข้อความจากสตริง ดังนั้นจึงมักใช้ Mid ร่วมกับ InStr เพื่อดึงข้อความหลังจากทราบตำแหน่งแล้ว
โค้ดด้านล่างดึงโดเมนจากอีเมลในชุดข้อมูล ฟังก์ชัน InStr หา位置ของ "@" ในอีเมล แล้ว Mid จึงเริ่มดึงหลังสัญลักษณ์นั้น จากนั้นเขียนโดเมนลงคอลัมน์ H
Sub ExtractDomain()
Dim i As Integer
Dim pos As Integer
Dim domain As String
For i = 2 To 51
pos = InStr(1, Cells(i, 3).Value, "@")
If pos > 0 Then
domain = Mid(Cells(i, 3).Value, pos + 1)
Cells(i, 8).Value = domain
End If
Next i
End Sub
InStr เทียบกับ Split
ฟังก์ชัน Split ใช้แยกข้อความออกเป็นส่วน ๆ โดยระบุตัวคั่น
ในตัวอย่างด้านล่าง โค้ดจะอ่านแต่ละแถวจากคอลัมน์ A ตรวจว่ามีจุลภาคหรือไม่ แล้วแยกข้อความออกเป็นสองส่วน จากนั้นเขียน Name → คอลัมน์ B และ City → คอลัมน์ C
Sub SplitTextColumn()
Dim i As Integer
Dim lastRow As Integer
Dim parts As Variant
Dim text As String
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
text = Cells(i, 1).Value
' Only split if a comma exists
If InStr(1, text, ",") > 0 Then
parts = Split(text, ",")
Cells(i, 2).Value = parts(0) ' Name
Cells(i, 3).Value = parts(1) ' City
End If
Next i
End Sub
แนวทางปฏิบัติที่ดีในการใช้ VBA InStr
เพื่อหลีกเลี่ยงข้อผิดพลาดใน VBA ขอแนะนำแนวทางต่อไปนี้ ซึ่งช่วยประหยัดเวลาได้มาก:
-
ใช้ vbTextCompare เมื่อไม่สนใจตัวพิมพ์: เนื่องจากข้อมูลจริงมักไม่สม่ำเสมอเรื่องตัวพิมพ์ อาจพลาดการจับคู่ได้ถ้าใช้โหมดเปรียบเทียบเริ่มต้น
-
ผสานกับ “If” เพื่อให้ตรรกะชัดเจน: พยายามใส่ตรรกะให้คืนค่าเสมอ เพราะ
InStrเพียงอย่างเดียวให้แค่ตัวเลข -
ตรวจ > 0 ไม่ใช่ตำแหน่งที่แน่นอน เว้นแต่ต้องการตำแหน่งจริง ๆ
-
ทำให้การแยกข้อความอ่านง่าย หลีกเลี่ยงการซ้อนฟังก์ชันหลายตัวในบรรทัดเดียว
สรุป
InStr ใช้ง่าย แต่จะได้ใช้ไปทั่ว มันให้ตำแหน่งของสตริงหนึ่งภายในอีกสตริงหนึ่ง และตัวเลขเดียวนี้ช่วยตัดสินใจหลายอย่างใน VBA ไม่ว่าจะมีอยู่หรือไม่ จะดึงจากตรงไหน และมาโครควรทำอะไรถัดไป ตัวมันเองคือการค้นหา แต่เมื่อผสานกับฟังก์ชันอย่าง Mid, Replace หรือแม้แต่ Split ก็กลายเป็นส่วนหนึ่งของเวิร์กโฟลว์ที่ทำงานได้จริง
ลงทะเบียนคอร์ส Data Analysis in Excel เพื่อเชี่ยวชาญการวิเคราะห์ขั้นสูง และคอร์ส Intermediate Power Query in Excel เพื่อเรียนรู้การแปลงข้อมูลและการใช้ภาษา M
FAQs
InStr คืนค่าอะไรจริง ๆ ?
คืนค่าตำแหน่งที่การจับคู่เริ่มต้น หากไม่พบอะไรเลย จะคืนค่า 0
InStr ไวต่ออักษรตัวพิมพ์หรือไม่?
ใช่ InStr แยกตัวพิมพ์ใหญ่เล็กโดยค่าเริ่มต้น ”Fragile” และ ”fragile” ถือว่าเป็นคนละคำ ใช้ vbTextCompare หากไม่ต้องการเปรียบเทียบแบบแยกตัวพิมพ์
หมายความว่า InStr นับจาก 1 คืออะไร?
อักขระตัวแรกในสตริงคือตำแหน่ง 1 ไม่ใช่ 0 ข้อนี้สำคัญเมื่อจะใช้ผลลัพธ์กับฟังก์ชันอื่น
ถ้าค่าหนึ่งเป็น Null จะเกิดอะไรขึ้น?
ผลลัพธ์จะเป็น Null เช่นกัน ไม่ใช่ 0
ความแตกต่างระหว่าง InStr และ InStrRev คืออะไร?
InStr ค้นหาจากซ้ายไปขวา ในขณะที่ InStrRev เริ่มจากขวาไปซ้าย ใช้อย่างหลังเมื่อสนใจตำแหน่งครั้งสุดท้าย