“ทำอะไรอยู่หรือ” ผมถามแฟนที่กำลังคร่ำเครียดอยู่หน้าจอคอมพิวเตอร์
“กำลังพิมพ์สลิปจ่ายเงินเดือนอยู่” เธอกำลังลอกข้อมูลจากตาราง Excel มาแปะลงไปในโปรแกรม Word แล้วพิมพ์ออกไปทีละใบ
ผมปล่อยให้แฟนทำเองอยู่สักพัก พอรู้ชัดแน่นอนว่าที่แฟนผมกำลังทำอยู่นั้นมีขั้นตอนเป็นยังไงก็บอกแฟนว่าเดี๋ยวผมจะทำให้ดีกว่า แค่คลิกเดียวคอมพิวเตอร์ก็จะพิมพ์สลิปเงินเดือนพนักงานแต่ละคนให้เอง เสร็จในไม่กี่อึดใจ รู้แบบนี้น่าจะปล่อยให้ผมทำให้ตั้งนานแล้ว
งานลักษณะเดียวกันนี้เป็นงานที่ต้องใช้เป็นประจำ นอกจากใช้พิมพ์สลิปเงินเดือนที่ต้องทำทุกเดือน ยังมีงานพิมพ์ใบ Invoice ใบสั่งซื้อ ใบเสร็จรับเงิน ใบหักภาษี ณ ที่จ่าย ซึ่งต้องทำเป็นประจำทุกวัน ถ้าแต่ละวันต้องพิมพ์นับร้อยนับพันรายการ คนที่รับผิดชอบงานแบบนี้รับรองว่าต้องเครียดจัด และรู้สึกว่าเป็นงานที่น่าเบื่อมาก
VBA ย่อมาจากคำว่า Visual Basic for Applications ซึ่งก่อนจะนำ VBA มาประยุกต์ใช้ ต้องแบ่งขั้นตอนการทำงานระหว่างคนกับ Excel กับ VBA ให้ได้ชัดเจนเสียก่อน ขั้นตอนใดบ้างที่ปล่อยให้เป็นหน้าที่ของคน ขั้นตอนใดบ้างที่เป็นหน้าที่ของ Excel และขั้นตอนใดที่จะปล่อยให้ใช้ VBA ช่วยเพื่อทำให้คอมพิวเตอร์ทำงานเองแบบอัตโนมัติ อย่าเหมารวมเอาทุกขั้นตอนมาเป็นหน้าที่ของ VBA โดยขอให้ยึดหลักต่อไปนี้
เรื่องอะไรที่ยากควรปล่อยไว้ในส่วนของ Excel แล้วปล่อยเรื่องง่ายไว้ในส่วนของ VBA
จริงหรือไม่ที่ผู้ใช้ Excel แทบทุกคนมีพื้นฐานและถนัดเรื่อง Excel มากกว่าเรื่อง VBA ดังนั้นจึงไม่ใช่เรื่องยากที่จะเปิดแฟ้มขึ้นมาแล้วแก้ไขสูตรหรือหน้าตาตาราง แต่ถ้ายกทั้งสูตรและขั้นตอนการสร้างตารางไปไว้ในส่วนของ VBA ลองนึกดูว่า ถ้าวันหนึ่งต้องปรับปรุงแก้ไขรหัส VBA ขึ้นมา จะพบแต่รหัสอะไรก็ไม่รู้ยาวเหยียดหลายสิบบรรทัด ซึ่งไม่ใช่เรื่องง่ายเลยที่จะแก้รหัส VBA โดยเฉพาะอย่างยิ่งเมื่อคนที่ทำหน้าที่แก้ไขหรือใช้งาน ไม่ได้เป็นคนสร้างรหัสเหล่านั้น
ถ้ามองแบบง่ายๆ แค่สร้างสูตรดึงข้อมูลเงินเดือนพนักงานแต่ละรายมาใส่ในหน้าแบบพิมพ์ให้ได้ก่อน จากนั้นก็ใช้ VBA ควบคุมการดึงข้อมูลทีละรายแล้วพิมพ์ออกไป ขั้นตอนมีแค่นี้เอง
แต่ถ้าคิดให้รอบคอบต้องตั้งหลักไว้ด้วยว่า พยายามสร้างรหัส VBA ให้สั้นที่สุด สามารถนำไปใช้กับการพิมพ์งานอื่นได้สารพัดโดยไม่ต้องแก้ไขรหัสแม้แต่น้อย หรือหากจะต้องแก้ไขบ้างก็แก้ไขเพียงเล็กน้อยและต้องทำได้ง่าย
ขั้นตอนส่วนที่ปล่อยให้เป็นหน้าที่ของคน
- สร้างตารางฐานข้อมูล B4:E9 และกรอกข้อมูลแต่ละรายการลงไปในตาราง
- สร้างแบบพิมพ์ M4:Q18 ตามแบบที่กำหนด
- กำหนดขอบเขต Print Area M4:Q18 และ Print Setup อื่น เช่น ข้อความบนหัวกระดาษและท้ายกระดาษ
- ลอกรหัส VBA Sub myPrintLoop ตามภาพไปใส่ไว้ใน Module ของแฟ้มงาน แล้วสร้างปุ่ม Print โดย Assign Macro ตามรหัส VBA Sub myPrintLoop
- เมื่อต้องการสั่งพิมพ์แบบ Manual ให้คลิกที่ช่องแสดงรหัสซึ่งอยู่เหนือปุ่ม Print เพื่อเลือกรหัสลูกค้าที่ต้องการพิมพ์ หรือจะใช้วิธีพิมพ์เลขที่รายการลงไปในเซลล์ G4 ซึ่งตั้งชื่อ Range Name ว่า Choice แทนก็ได้
- ถ้าต้องการสั่งพิมพ์อัตโนมัติให้คลิกที่ปุ่ม Print
ขั้นตอนส่วนที่เป็นหน้าที่ของ Excel ซึ่งใช้สูตรตามที่คนสร้างไว้
- ใช้สูตร Index ดึงข้อมูลตามเลขที่รายการในเซลล์ Choice มาแสดงไว้ในแบบฟอร์ม เช่น เซลล์ O7 มีสูตร =INDEX(C5:C9,Choice) เพื่อดึงชื่อลูกค้าจากพื้นที่ C5:C9 ในลำดับที่ตามเลขในเซลล์ Choice
- ใช้สูตร =COUNTA(B5:B9) เพื่อนับจำนวนรายการทั้งหมดมาแสดงไว้ในเซลล์ G7 ซึ่งตั้งชื่อ Range Name ว่า Total
ขั้นตอนส่วนที่เป็นหน้าที่ของ VBA
Sub myPrintLoop()
MyVar = [choice]
myStart = InputBox("From#", , 1)
myStop = InputBox("To#", , [Total])
For i = myStart To myStop
[choice] = i
ActiveWindow.SelectedSheets.PrintPreview
Next i
[choice] = MyVar
End Sub
- Sub myPrintLoop()
เป็นชื่อของชุดคำสั่ง - MyVar = [choice]
เพื่อเก็บเลขที่รายการเริ่มแรกตามที่เคยกรอกไว้ในเซลล์ชื่อ Choice ไปเก็บไว้ในตัวแปรชื่อ MyVar ช่วยทำให้หลังจากพิมพ์ครบทุกรายการแล้วจะนำตัวเลขรายการเดิมกลับไปแสดงไว้ตามเดิม - myStart = InputBox("From#", , 1)
เพื่อเปิดหน้าจอให้กรอกเลขที่รายการแรกสุดที่ต้องการพิมพ์ โดยระบบจะกรอกเลข 1 ให้เป็นค่าเริ่มแรกไว้ให้ก่อน แล้วจะนำตัวเลขรายการนี้ไปเก็บไว้ในตัวแปรชื่อ myStart - myStop = InputBox("To#", , [Total])
เพื่อเปิดหน้าจอให้กรอกเลขที่รายการสุดท้ายที่ต้องการพิมพ์ โดยระบบจะนำเลขตามจำนวนรายการที่นับได้ในเซลล์ Total ให้เป็นค่าเริ่มแรกไว้ให้ก่อน แล้วจะนำตัวเลขรายการนี้ไปเก็บไว้ในตัวแปรชื่อ myStop - For i = myStart To myStop
เริ่มต้นคำสั่งให้ทำงานซ้ำ โดยใช้ตัวเลขจากตัวแปรชื่อ myStart ไปวนซ้ำทีละครั้งแล้วเพิ่มเลขทีละ 1 ไปจนจบตามตัวเลขจากตัวแปรชื่อ myStop ซึ่งทุกรอบที่ทำงานจะส่งตัวเลขไปเก็บไว้ในตัวแปรชื่อ i - [choice] = i
เป็นขั้นตอนสำคัญที่สุดเพื่อส่งตัวเลข i แต่ละรอบไปที่เซลล์ที่ตั้งชื่อว่า choice ซึ่งสูตร Index ก็จะดึงข้อมูลตามเลขที่รายการในแต่ละรอบไปแสดงไว้ในแบบฟอร์ม - ActiveWindow.SelectedSheets.PrintPreview
ตัวอย่างนี้ใช้คำสั่ง PrintPreview เพื่อแสดงภาพบนหน้าจอให้เห็นตามหน้าแบบฟอร์มที่จะพิมพ์ออกไป ซึ่งในการใช้งานจริงให้เปลี่ยนเป็นคำสั่งนี้แทน ActiveWindow.SelectedSheets.PrintOut - Next i
เพื่อสั่งให้วนรอบต่อไป - [choice] = MyVar
เพื่อปรับข้อมูลให้กลับสู่เลขที่รายการเดิมก่อนที่จะสั่งพิมพ์ - End Sub
จบชุดคำสั่ง
Download ตัวอย่างได้จาก
https://drive.google.com/file/d/1vP1w-YI6C5QGI6Xd_LM8qfVHMFkbAOnC/view?usp=sharing