การเริ่มต้นค่าตัวแปรใหม่อีกครั้งใน VBA (Reinitializes) ด้วย Nothing, Empty และ Erase

ในการกำหนดค่าเริ่มต้นตัวแปรใหม่สำหรับการเขียนโปรแกรม อาจทำไม่บ่อย แต่ถ้าจำเป็นต้องทำขึ้นมา เรามีวิธีล้างค่าเดิมที่เก็บอยู่ให้เป็นค่าเริ่มต้นได้อย่างไรบ้าง

ตัวแปรแบบ Object ใช้ Nothing

สำหรับตัวแปรแบบ Object หากไม่ต้องการใช้งาน Object ดังกล่าวต่อแล้ว และต้องการคืนหน่วยความจำที่ถูกใช้งาน ให้กำหนดค่าด้วย Nothing

Dim testObject As New Collection

testObject.Add "Data 1"
testObject.Add "Data 2"
'process object ...

Set testObject = Nothing 'Release object and free space	

ยกเว้นว่า หากมีตัวแปรที่อ้างถึง Object เดียวกันอยู่เกิน 1 ตัว ตัว VBA จะยังไม่คืนหน่วยความจำที่ถูกใช้งาน จนกว่าตัวแปรที่อ้างอิง Object นั้นถูกกำหนดเป็น Nothing ทั้งหมด

จากตัวอย่างด้านล่าง severalObject ได้อ้างอิงตำแหน่ง Object เดียวกับ testObject ดังนั้นแม้จะกำหนด Nothing ให้กับ testObject ไปแล้ว แต่ตัว VBA จะยังไม่คืนหน่วยความจำจนกว่าจะกำหนด Nothing ให้กับ severalObject ด้วย

Dim testObject As New Collection
Dim severalObject As Collection

testObject.Add "Data 1"
testObject.Add "Data 2"
'process object ...

Set severalObject = testObject
Set testObject = Nothing  	'ยังมี severalObject อีกตัวที่ยังอ้างถึง Collection อยู่
Set severalObject = Nothing 	'ลบ Collection ที่จองไว้ออกจากหน่วยความจำ

สำหรับ Object ที่เราใช้อ้างอิงถึงวัตถุใน Excel อื่น ๆ เช่น Workbook WorkSheet และอื่น ๆ การใช้ Nothing ไม่ได้เป็นการยกเลิกการใช้งาน เพื่อคืนหน่วยความจำ เนื่องจากวัตถุพวกนี้ถูกสร้างจากโปรแกรม Excel ดังนั้นหากต้องการจะยกเลิก ต้องใช้ Method โดยเฉพาะเท่านั้น เช่น

Dim wbReport As Workbook

Set wbReport = Workbooks.Open("C:\My Documents\Demo.xlsx") 'สร้าง Object จาก Excel

wbReport.Close 'เมื่อเลิกใช้แล้ว ให้ปิด Workbook 

Set wbReport = Nothing 'กำหนดให้เป็น Nothing เพื่อป้องกันการใช้งาน Workbook ที่ถูกปิดไปแล้ว	

การใช้ Empty เพื่อเริ่มต้นค่าในตัวแปรอีกครั้ง

หากอ่านคู่มือ VBA จะพบว่า Empty ใช้กำหนดกับตัวแปรชนิด Variant ที่ยังไม่ได้กำหนดค่าใด ๆ ซึ่งจะเป็นค่าเริ่มต้นของตัวแปร Variant แต่ในการใช้งานจริง การใช้ Empty กับตัวแปรอื่น ๆ ก็ได้ผลไม่ต่างจากตัวแปร Variant คือ เป็นการกำหนดค่าเริ่มต้นใหม่กับตัวแปรนั้น ๆ ปกติ หากเรามีตัวแปรแบบ ตัวเลข และ ข้อความ เราจะล้างค่าเป็นค่าเริ่มต้นดังนี้

Dim myNumber As Integer
Dim myText As String

'ใช้งานตัวแปรในโปรแกรม
'...
'...

'กำหนดค่าเริ่มต้นให้ตัวแปรแบบที่เรียนกันมา
myNumber = 0
myText = ""

หากเขียน VBA มาพอสมควรจะทราบว่า ตัว VBA นั้นมีกระบวนการช่วยแปลงชนิดข้อมูลให้อัตโนมัติ เช่น

Dim myNumber As Integer
Dim myText As String

myNumber = "100" 'แปลงข้อความ "100" เป็นตัวเลข 100
myText = 100 'แปลงตัวเลข 100 เป็นข้อความ "100"

โปรแกรมข้างบนหาก Run แล้วจะไม่เกิด Runtime Error เพราะ VBA ช่วยแปลงค่าให้ แล้ว Empty ล่ะตัว VBA แปลงค่าให้เป็นอะไรได้บ้าง

Dim myNumber As Integer
Dim myText As String

myNumber = 100
myText = "my text"

myNumber = Empty 'ค่าใน myNumber = 0
myText = Empty		'ค่าใน myText = ""

โปรแกรมด้านบน เมื่อกำหนดค่า Empty ให้ตัวแปรประเภทตัวเลข (Interger) และตัวแปรข้อความ (String) แล้วจะกลายเป็นการเริ่มต้นค่าตัวแปรใหม่อีกครั้ง

ทำไมถึงเป็นอย่างนั้น หากเราใช้คำสั่งในการแปลงประเภทข้อความ เช่น CInt() และ CStr() กับ Empty แล้วจะพบว่ามันคืนค่าเป็นค่าเริ่มต้นของข้อความประเภทนั้น ๆ อัตโนมัติ

myNumber = CInt(Empty) 'CInt(Empty) คืนค่า 0
myText = CStr(Empty)		'CStr(Empty) คืนค่า ""

จะเห็นว่าคราวนี้เราจะกำหนดค่าเริ่มต้นของตัวแปรประเภทต่าง ๆ ไม่ว่าจะเป็น Variant Integer Long Single Double String Boolean สามารถใช้ Empty ได้ทันที ซึ่งสะดวกมากสำหรับการทำการตัวแปรครั้งละหลาย ๆ ตัว หลาย ๆ ประเภทปนกัน เช่น ผมมี Class ที่ใช้เก็บค่าที่ได้จากฐานข้อมูล ที่มีหลายสิบฟิวส์ (fields) ดังนี้

Public RecordNo As Long
Public cancel As String
Public PONo As Long
Public PODate As Date
Public DistributorTName As String
Public SellerCode As Long
Public SellerName As String
Public Region As String
Public CustomerName As String
Public PaymentMethod As String
Public ItemCode As Variant
Public Description As String
Public Brand As String
Public Cost_PC As Double
Public Qty As Long
Public Price_PC As Double
Public Discount1 As Double
Public Discount2 As Double

หากจำเป็นต้องล้างค่าใน Class ทุกฟิวส์ หากไม่ใช่ Empty เราจำเป็นต้องกำหนดค่าตามประเภทของมูลเอง ซึ่งทำให้เสียเวลาในการเขียนโปรแกรมมากและอาจกำหนดค่าผิดประเภทได้

RecordNo = 0
cancel = ""
PONo = 0
PODate = 0
DistributorTName = ""

ดังนั้นการใช้ Empty ไปเลยนอกจากจะทำให้ได้ค่าเริ่มต้นแล้ว ยังสะดวกมาก ๆ เพราะสามารถใช้กับ Primitive datatype หรือประเภทข้อมูลพื้นฐานได้ทั้งหมด

RecordNo = Empty
cancel = Empty
PONo = Empty
PODate = Empty
DistributorTName = Empty

การกำหนดค่าเริ่มต้น และคืนหน่วยความจำของ Array ด้วย Erase

ตัวแปรประเภท Array หากเราต้องการจะทำการล้างข้อมูลภายใน Array ให้เป็นค่าเริ่มต้น สามารถใช้คำสั่ง Erase ได้ทันที ตัวอย่างการใช้งานจาก Help ของ VBA

Dim NumArray(10) As Integer    ' Integer array.
Erase NumArray    ' NumArray(0) ถึง NumArray(9) ถูกกำหนดค่าเป็น 0

Dim StrVarArray(10) As String    ' Variable-string array.
Erase StrVarArray    ' StrVarArray(0) ถึง NumArray(9) ถูกกำหนดค่าเป็น ""

Dim StrFixArray(10) As String * 10    ' Fixed-string array.
Erase StrFixArray    ' StrFixArray(0) ถึง StrFixArray(9) ถูกกำหนดค่าเป็น Char(0) * 10 ตัว

Dim VarArray(10) As Variant    ' Variant array.
Erase VarArray    ' Each element set to Empty.

Dim DynamicArray() As Integer    ' Dynamic array.
ReDim DynamicArray(10)    ' จองพื้นที่เก็บข้อมูลตัวเลข จำนวน 10 ตัว
Erase DynamicArray    ' คืนพื้นที่เก็บตัวเลข จำนวน 10 ตัว หากจะใช้งาน ต้อง ReDim ใหม่อีกครั้ง