พบปัญหา Invalid procedure call or argument ใน VBA หลังจาก Update Windows 10 Version 1903

เมื่อเดือนสิงหาที่ผ่านมา ทาง Microsoft ได้ปล่อย Update Windows 10 Version 1903 ออกมาสด ๆ ร้อน ๆ สำหรับคนที่ใช้งาน Windows ทั่วไปหลังจาก Updated แล้วก็คงใช้งานตามปกติ แต่สำหรับคนที่ใช้โปรแกรม VBA บางส่วน ไม่ว่าจะใน Excel หรือ Access ต่างได้รับผลกระทบจากการ Update ครั้งนี้

Windows 10 Version 1903 ที่ลงเมื่อเดือนสิงหาคม พ.ศ.2562 ที่ผ่านมา

ปัญหาที่เกิดขึ้นคือ โปรแกรมที่ใช้ VBA เดิมที่เคยใช้งานได้ตามปกติ กลับขึ้น Error ว่า Invalid procedure call or argument ทั้งที่ไม่เคยเกิดขึ้นมาก่อน โปรแกรมก็ไม่ได้ไปแก้ไขอะไร

VBA ขึ้น Error หลังจากเปิดใช้งานตามปกติ

เลยลองวิธีเดิมที่เคยเจอปัญหาแบบเวลา VBA มันเอ๋อก็คือ Repair โปรแกรม Microsoft Office อีกรอบครับ

ทำการ Repair Microsoft Office

ผลปรากฎว่าไม่หายครับ ยังขึ้นเหมือนเดิม เลยลองเข้าไปดูว่ามัน Error ตรงไหน เมื่อ Debug แล้วพบว่ามัน Error ตอนกำหนดค่าตัวแปรแบบ ParamArray

เกิด Error เมื่อพยายาม copy ตัวแปรจาก ParamArray

และเมื่อตรวจสอบเพิ่มเติมจึงพบว่ามัน Error เฉพาะเวลาที่ไม่มีค่าตัวแปรส่งมาให้ ParamArray เท่านั้น หากมีการส่งค่ามามันจะไม่ Error ลองดูตัวอย่าง Code

Public Sub Test()
	Call ShowQuestion("message", "title", "option1", "option2")	'แบบนี้ OK ไม่เกิด Error ส่ง "option1" และ "option2" ให้ตัวแปร templates
	
	Call ShowQuestion("message", "title")	'<-- แบบนี้จะเกิด Error ไม่มีการส่งค่าให้ตัวแปร templates()
	
End Sub

Public Sub ShowQuestion(ByVal sMessage As String, ByVal sTitle As String, ParamArray templates() As Variant)
	Me.iconShow.Picture = Me.iconQuestion.Picture
	m_bYesNo = True
	nClickButton = vbNo
	m_sMessage = sMessage
	m_sTitle = sTitle
	m_templates = templates	'<-- จะ Error ที่บรรทัดนี้
	Call MakeMessage
End Sub

เมื่อลองไปดูว่าตัวแปร m_templates ประกาศประเภทข้อมูลเอาไว้อย่างไร ก็พบว่ามันประกาศไว้แบบเดียวกันกับ template คือเป็น Array ของข้อมูลประเภท Variant

ส่วนประกาศตัวแปร m_templates

วิธีแก้ไขปัญหาของผมที่ใช้คือ ลองตัดการประกาศแบบ Array เป็น Variant ธรรมดาแทน ซึ่งผลปรากฎว่าผ่านครับ ไม่เกิด Error

แก้ไข Code โดยเปลี่ยนจาก Array เป็น Variant ธรรมดา

อาจมีคนสงสัยว่าตอนแรกจะประกาศตัวแปรเป็น Array ทำไม ที่ทำแบบนั้นเพื่อให้เวลาเขียนโปรแกรม มันจะได้แสดง infomation ของตัวแปรนั้นถูกต้องครับ และสะดวกในการเขียนโปรแกรมเพราะตัว IDE จะแสดงว่าเป็น Array

แล้วคนอื่น ๆ มีใครที่มีปัญหาแบบนี้ไหม ที่ลองค้นหา Google ก็มี แต่อาจจะกระทบไม่มาก เพราะการเขียนโปรแกรม VBA โดยออกแบบฟังก์ชั่นให้รองรับการส่ง Parameters หลาย ๆ ตัวแบบยืดหยุ่น (dynamic number of arguments) ปกติก็ไม่ได้ใช้กันบ่อย ๆ แต่ถ้าใช้ก็มีปวดหัวกันงานนี้เพราะต้องตามไปแก้ไข Code กัน ตัวอย่างผู้ที่ได้รับผลกระทบ Microsoft Community ข้างล่างคือ Code ที่ยกตัวอย่างการเกิด Error ครับ

Sub Test()

	Test1 "A", "B"		'Works OK with and without Windows Update

	Test1			'Fails after Windows Update

End Sub

Sub Test1(ParamArray P() As Variant)

	Test2 P

End Sub

Sub Test2(ByVal P As Variant)    'Error occurs on this line

End Sub

ก็ถือว่าเป็นเคสที่แปลกประหลาดมากที่ Update Windows แล้ว VBA ใช้งานไม่ได้ เกิดปัญหา ส่วนตัวผู้เขียนเองเคยเจอปัญหาคล้าย ๆ แบบนี้กับ Action Script ที่ใช้งานบน Flash Player ที่พอเปลี่ยน Version แล้ว Code ที่เขียนบางแบบจะใช้งานไม่ได้ ซึ่งก็เซ็งพอสมควร แต่กับ VBA ก็ไม่เคยคิดว่าจะเกิดปัญหาแบบเดียวกัน ซึ่งก็หวังว่าจะมีปัญหาแค่จุดนี้จุดเดียว เพราะถ้ามีจุดอื่นแบบที่ทำงานไม่ถูกต้องและไม่แสดง Error เนี่ย จะเลวร้ายสุด ๆ เลย สาธุ...