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ขับเคลื่อนโดย
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ขับเคลื่อนโดย
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ขับเคลื่อนโดย
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ขับเคลื่อนโดย
ตัวดำเนินการ 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 เมื่อต้องตรวจข้อความตามแพตเทิร์นที่ซับซ้อน
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ขับเคลื่อนโดย
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ขับเคลื่อนโดย
ในตัวอย่างด้านล่าง โค้ดจะอ่านแต่ละแถวจากคอลัมน์ 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 มาบ้าง น่าจะเคยมีจังหวะที่ต้องตรวจสอบว่ามีข้อความบางอย่างอยู่ในเซลล์หรือไม่ ใน VBA
InStrเป็นหนึ่งในฟังก์ชันที่ได้ใช้บ่อยมาก ฟังก์ชันนี้บอกตำแหน่งที่ข้อความหนึ่งปรากฏอยู่ภายในอีกข้อความหนึ่ง ใช้ตรวจสอบว่ามีข้อความอยู่ในเซลล์ แยกค่าจากข้อความ หรือขับเคลื่อนเงื่อนไขในมาโครที่ขึ้นกับรูปแบบข้อความได้ในคู่มือนี้ จะพาไปรู้จักไวยากรณ์ของ
InStrตัวอย่างการใช้งาน วิธีทำงานของโหมดการเปรียบเทียบ (ส่วนนี้มักทำให้สับสนเกินความจำเป็น) และแพตเทิร์นการใช้งานที่นำไปใช้ซ้ำได้จริงแนะนำให้เริ่มจาก เส้นทางทักษะ Excel พื้นฐาน เพื่อปูพื้นฐานให้มั่นคงก่อนต่อยอดสู่ VBA หรือหากมีประสบการณ์อยู่แล้ว ลองคอร์ส ฟังก์ชัน Excel ขั้นสูง เพื่อเรียนรู้เพิ่มเติมว่าฟังก์ชันช่วยเพิ่มประสิทธิภาพในการวิเคราะห์ข้อมูลอย่างไร
VBA InStr คืออะไร?
InStrเป็นฟังก์ชัน VBA ที่ส่งกลับตำแหน่งของการพบสตริงหนึ่งภายในอีกสตริงหนึ่งเป็นครั้งแรกผลลัพธ์ทำงานดังนี้:
เช่น หากคำว่า “cat” ปรากฏที่ตำแหน่งที่ 5 ในสตริง จะได้
5ถ้าไม่มี จะได้0ไวยากรณ์ VBA InStr
นี่คือไวยากรณ์เต็มของ
InStr:โดยที่:
start(ไม่บังคับ): ระบุตำแหน่งเริ่มต้นการค้นหา หากละไว้ VBA จะเริ่มจากตำแหน่งที่ 1string1(บังคับ): ข้อความเต็มที่ต้องการค้นหาภายใน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” หรือไม่
ผลลัพธ์ของ VBA ข้างต้นคือ
9เนื่องจาก “before” เริ่มที่อักขระตัวที่ 9ตรวจสอบว่ามีอักขระอยู่หรือไม่
เพื่อตรวจสอบว่ามีอักขระ “0” อยู่ในสตริงที่กำหนดหรือไม่ ใช้ VBA ดังนี้:
ในกรณีนี้ ผลลัพธ์ที่มากกว่า
0หมายถึงพบอักขระดังกล่าวค้นหาตั้งแต่ต้นสตริง
หากต้องการค้นหาตั้งแต่ต้นสตริง ไม่ต้องระบุตำแหน่งเริ่มต้น การค้นหาจะเริ่มที่ 1 ตามค่าเริ่มต้นทุกครั้ง เว้นแต่จะระบุไว้เป็นอย่างอื่น
การใช้ VBA InStr ในคำสั่ง If
เมื่อทำงานกับสเปรดชีตจริง เป้าหมายไม่ใช่แค่ตัวเลข แต่คือการตัดสินใจ วิธีที่พบบ่อยที่สุดในการใช้
InStrคือภายในคำสั่งIfเพื่อกรองข้อมูลในบทเรียนนี้จะใช้ชุดข้อมูลตัวอย่าง
Ordersที่มีคอลัมน์:ID,CustomerName,Email,CityและOrderNotesIf InStr(...) > 0 Then
เนื่องจาก
InStrจะคืนค่า0หากไม่พบอะไร ดังนั้นจึงตรวจสอบว่าพบผลลัพธ์หรือไม่โดยดูว่าค่ามากกว่า0หรือไม่ในตัวอย่างด้านล่าง โค้ดจะดูที่คอลัมน์
OrderNotes(คอลัมน์ที่ 5) หากพบคำว่า “Fragile” จะเขียน “Handle Carefully” ในคอลัมน์ที่ 6การตรวจคีย์เวิร์ดและการกรองข้อความแบบมีเงื่อนไข
สามารถใช้ฟังก์ชัน
InStrเพื่อตรวจคีย์เวิร์ดในสตริง โดยเฉพาะเมื่อวลีอาจเปลี่ยนเล็กน้อย ตัวอย่างด้านล่างจะตรวจว่าบันทึกมีคำว่า “Call” อยู่หรือไม่ (เช่น “Call on arrival” หรือ “Call before delivery”) จากนั้นจะตั้งธงและเพิ่มแท็ก “Call Customer” ในคอลัมน์ที่ 6ความไวต่ออักษรตัวพิมพ์และโหมดเปรียบเทียบของ VBA InStr
ตามค่าเริ่มต้น
InStrจะแยกตัวพิมพ์ใหญ่เล็ก (เรียกว่าvbBinaryCompare) สมมติค้นหา “chicago” แต่ข้อมูลเป็น “Chicago”InStrจะคืนค่า0เพื่อแก้ปัญหานี้ ให้ใช้ อาร์กิวเมนต์
compareโดยที่:vbBinaryCompare(ค่าเริ่มต้น): แยกตัวพิมพ์ใหญ่เล็ก (“A” ไม่เหมือนกับ “a”)vbTextCompare: ไม่แยกตัวพิมพ์ใหญ่เล็ก “A” เหมือนกับ “a”ในตัวอย่างด้านล่าง
InStrจะคืนค่า0เพราะค้นหา “fragile” (ตัวพิมพ์เล็ก) ภายใน “Fragile items”อย่างไรก็ตาม หากใช้
vbTextCompareจะได้ค่า1จากการค้นหาเดียวกันเพราะไม่สนใจตัวพิมพ์VBA InStr พร้อมตำแหน่งเริ่มต้น
บางครั้งไม่ต้องการเริ่มค้นหาตั้งแต่ต้นสตริง อาร์กิวเมนต์
startจะบอก VBA ว่าจะเริ่มค้นหาจากตรงไหนในตัวอย่างด้านล่าง อาร์กิวเมนต์
startถูกตั้งเป็น10จึงเริ่มค้นหาจากอักขระตัวที่ 10 ไม่ใช่ตัวแรก และพบ"delivery"ในช่วงถัดไปของสตริงผลลัพธ์ของตัวอย่างข้างต้นคือ
31คือตำแหน่งที่"delivery"เริ่มต้นวิธีนี้มีประโยชน์เมื่ออยากหาครั้งที่สองของสิ่งใดสิ่งหนึ่ง หรือมองข้ามคำนำหน้าที่รู้ล่วงหน้าเมื่อทำงานกับแพตเทิร์นที่ซ้ำ ๆ
VBA InStr เทียบกับ InStrRev
อย่างที่ทราบ
InStrค้นหาจากซ้ายไปขวา ส่วนInStrRevค้นหาจากขวาไปซ้ายเช่น ใช้
InStrRevเพื่อหาจุดสุดท้ายในอีเมล ผลลัพธ์คือ18ซึ่งคือตำแหน่งของจุดก่อน “com”จะพบว่า
InStrRevมีประโยชน์มากเมื่อจำเป็นต้องหา “ครั้งสุดท้าย” ของบางอย่าง หรือเมื่อทำงานกับชื่อไฟล์ อีเมล หรือพาธกรณีการใช้ VBA InStr ที่พบบ่อย
เมื่อเห็นตัวอย่างการทำงานของฟังก์ชัน
InStrแล้ว มาดูกรณีการใช้งานที่พบบ่อยกันตรวจว่าเซลล์มีคีย์เวิร์ดหรือไม่
สมมติว่ามีชุดคำสั่งซื้อของลูกค้า และต้องการตั้งธงสำหรับการจัดการเฉพาะ โค้ดจะดูที่คอลัมน์
OrderNotesและตั้งธงทุกกรณีที่มีคำว่า “noon”ตรวจรูปแบบอีเมลเบื้องต้น
ยังสามารถใช้ฟังก์ชัน
InStrเพื่อตรวจรูปแบบอีเมลอย่างรวดเร็วได้ ตัวอย่างด้านล่างตรวจว่าอีเมลมี@หรือไม่ และเขียน “Valid Email Format” ในคอลัมน์ที่ 6ตรวจตัวคั่น เช่น จุลภาคหรือขีดกลาง
สามารถใช้ฟังก์ชัน
InStrเพื่อตรวจว่ามีขีดกลาง จุลภาค หรือทับอยู่ในข้อความหรือไม่ ในตัวอย่างด้านล่าง โค้ดวนลูปที่OrderNotes(คอลัมน์ E) ตรวจว่ามีจุลภาคในข้อความ แล้วเขียนผลลัพธ์ลงในคอลัมน์ Fข้อผิดพลาดที่พบบ่อยกับ 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” โดยใช้แพตเทิร์น*ซึ่งหมายถึง “อะไรก็ได้ก่อนหรือหลัง”ใช้
InStrเมื่อแค่อยากรู้ว่าข้อความมีอยู่หรือไม่ และใช้Likeเมื่อต้องตรวจข้อความตามแพตเทิร์นที่ซับซ้อนInStr เทียบกับ Replace
แม้ใช้
InStrเพื่อเปลี่ยนค่าทั้งเซลล์ได้ แต่ฟังก์ชันReplaceจะเปลี่ยนเฉพาะข้อความบางส่วนในเซลล์ในตัวอย่างด้านล่าง ฟังก์ชัน
Replaceจะสลับ “Fragile” เป็น “Handle Carefully” โดยตรงภายในข้อความInStr เทียบกับ Mid
ฟังก์ชัน Mid ใช้ดึงข้อความจากสตริง ดังนั้นจึงมักใช้
Midร่วมกับInStrเพื่อดึงข้อความหลังจากทราบตำแหน่งแล้วโค้ดด้านล่างดึงโดเมนจากอีเมลในชุดข้อมูล ฟังก์ชัน
InStrหา位置ของ "@" ในอีเมล แล้วMidจึงเริ่มดึงหลังสัญลักษณ์นั้น จากนั้นเขียนโดเมนลงคอลัมน์ HInStr เทียบกับ Split
ฟังก์ชัน
Splitใช้แยกข้อความออกเป็นส่วน ๆ โดยระบุตัวคั่นในตัวอย่างด้านล่าง โค้ดจะอ่านแต่ละแถวจากคอลัมน์ A ตรวจว่ามีจุลภาคหรือไม่ แล้วแยกข้อความออกเป็นสองส่วน จากนั้นเขียน
Name→ คอลัมน์ B และCity→ คอลัมน์ Cแนวทางปฏิบัติที่ดีในการใช้ VBA InStr
เพื่อหลีกเลี่ยงข้อผิดพลาดใน VBA ขอแนะนำแนวทางต่อไปนี้ ซึ่งช่วยประหยัดเวลาได้มาก:
ใช้ vbTextCompare เมื่อไม่สนใจตัวพิมพ์: เนื่องจากข้อมูลจริงมักไม่สม่ำเสมอเรื่องตัวพิมพ์ อาจพลาดการจับคู่ได้ถ้าใช้โหมดเปรียบเทียบเริ่มต้น
ผสานกับ “If” เพื่อให้ตรรกะชัดเจน: พยายามใส่ตรรกะให้คืนค่าเสมอ เพราะ
InStrเพียงอย่างเดียวให้แค่ตัวเลขตรวจ > 0 ไม่ใช่ตำแหน่งที่แน่นอน เว้นแต่ต้องการตำแหน่งจริง ๆ
ทำให้การแยกข้อความอ่านง่าย หลีกเลี่ยงการซ้อนฟังก์ชันหลายตัวในบรรทัดเดียว
สรุป
InStrใช้ง่าย แต่จะได้ใช้ไปทั่ว มันให้ตำแหน่งของสตริงหนึ่งภายในอีกสตริงหนึ่ง และตัวเลขเดียวนี้ช่วยตัดสินใจหลายอย่างใน VBA ไม่ว่าจะมีอยู่หรือไม่ จะดึงจากตรงไหน และมาโครควรทำอะไรถัดไป ตัวมันเองคือการค้นหา แต่เมื่อผสานกับฟังก์ชันอย่างMid,Replaceหรือแม้แต่Splitก็กลายเป็นส่วนหนึ่งของเวิร์กโฟลว์ที่ทำงานได้จริงลงทะเบียนคอร์ส Data Analysis in Excel เพื่อเชี่ยวชาญการวิเคราะห์ขั้นสูง และคอร์ส Intermediate Power Query in Excel เพื่อเรียนรู้การแปลงข้อมูลและการใช้ภาษา M