สัปดาห์ที่ผ่านมาผมได้มีโอกาสอธิบายกลไกการทำงานบางอย่างของโปรแกรม ให้กับทีมงานที่เป็นสายบัญชี
เนื่องจากเป็นกลุ่มเฉพาะนักบัญชี ทำให้ต้องเรียบเรียงในมุมมองที่ไม่ลงลึกทางเทคนิคเกินไป ระหว่างที่ตรวจสอบสไลด์ รู้สึกสะดุดกับข้อความที่บอกว่า
"ผังบัญชี ไม่ต้องมี"
ผมเดาว่าเรื่องนี้เป็นเรื่องใหญ่สำหรับนักบัญชี การไม่มีผังบัญชี นับเป็นบาปประการที่แปด อาจทำให้ข้อดีอื่นถูกปฏิเสธทั้งหมด การท้าทายว่า "พระเจ้าตายแล้ว" นิทเช่ น่าจะทำให้สูญเสียแนวร่วมมากกว่า
นั่นเป็นสาเหตุที่ตัดสินใจสลับแทรกสไลด์เพิ่มก่อนเข้าสู่เนื้อหา ให้นึกถึงตอนที่ Steve Jobs นำเสนอ iPhone
Pseudo Code
ข้อเสนอแรกที่ผมท้าทายนักบัญชี แทนที่จะใช้รหัสบัญชีที่เป็นตัวเลข เช่น "4001" เราเปลี่ยนไปใช้คำที่มีความหมายเช่น "INCOME"
ในโลกของโปรแกรมเมอร์ มีภาษาคอมพิวเตอร์ที่แตกต่างกัน ดังนั้นการอธิบายว่าต้องการให้โปรแกรมทำงานอย่างไร เราจะไม่อธิบายเป็นภาษาคอมพิวเตอร์ แต่ใช้ภาษามนุษย์ที่คนทั่วไปอ่านแล้วเข้าใจก่อน คำอธิบายนี้จึงเรียกว่า Pseudo Code
เมื่อโปรแกรมเมอร์อ่าน Pseudo Code นั้นแล้วก็เขียนโปรแกรมเป็นภาษาคอมพิวเตอร์ เช่น Python, Java ฯลฯ ซึ่งคนทั่วไปอ่านไม่รู้เรื่อง แม้แต่โปรแกรมเมอร์ที่ถนัดภาษาโปรแกรมต่างกัน ก็อ่านภาษาของอีกโปรแกรมไม่รู้เรื่องเช่นกัน
ผังบัญชีก็เปรียบเสมือนภาษาโปรแกรมที่แตกต่างกันของแต่ละองค์กร รหัสบัญชีสำหรับเงินสด ลูกหนี้ รายได้ ฯลฯ อาจไม่ตรงกัน ดังนั้นนักบัญชีจึงต้องรู้รหัสบัญชีก่อนจึงลงบัญชีได้ หากต้องทำงานหลายที่ ดูแลบริษัทในเครือ หรือเป็นสำนักบัญชี หรือเปลี่ยนงาน ก็ต้องระวังรหัสบัญชีที่แตกต่าง ถ้ามีอำนาจทำได้อาจแก้ปัญหาด้วยการรื้อเปลี่ยนผังบัญชีให้ตรงกันมากที่สุด
แล้วทำไมเราไม่ใช้ "INCOME" หมายถึง บัญชีรายได้ เหมือนกันทุกที่ล่ะ
Accounting Software
ในยุคแรก นิยามของโปรแกรมบัญชี เริ่มจากรวบรวมหลักฐานที่เป็นเอกสารจากงานฝ่ายต่างๆ ส่งมาที่ฝ่ายบัญชี แล้วคนในฝ่ายบัญชีมีหน้าที่ตรวจสอบ บันทีกข้อมูลเข้าระบบบัญชี คาดหวังผลลัพธ์เป็นรายงานสรุปการเงินหรือที่เรียกว่า "งบ"
ภาพจำนี้ยังเห็นได้ทั่วไป เป็นความสัมพันธ์แบบกิจการกับสำนักบัญชีนั่นเอง
เมื่อคอมพิวเตอร์ใช้ประโยชน์ได้มากกว่าปิดงบ ยังช่วยพิมพ์บิลได้รวดเร็วสวยงามกว่าการเขียนด้วยมือ โปรแกรมบัญชีจึงขยายขอบเขตมาที่ต้นน้ำ เป็นโปรแกรมจัดทำเอกสารด้วยและเริ่มแพร่หลายภายในกิจการ
แล้วทำไมไม่เอาข้อมูลเอกสารนั้นมาทำบัญชีเลย จึงเป็นที่มาของแนวคิดของการออกแบบโปรแกรมที่ช่วยบันทึกบัญชีอัตโนมัติ
การเปิดบิล เช่น ใบกำกับภาษี เป็นเรื่องที่ทำทันที ขณะที่การบันทึกบัญชีแยกประเภทสามารถทำภายหลัง บางกรณีการเปิดบิลอาจทำโดยพนักงานที่ไม่จำเป็นต้องรู้เรื่องการลงบัญชี แค่บันทึกรายการให้ถูกต้องแล้วพิมพ์ออกมาได้
แนวคิดเรื่องบันทึกบัญชีอัตโนมัติจึงเกิดขึ้น โปรแกรมส่วนมากใช้วิธี post หรือสั่งให้มาบันทึกเป็นข้อมูลแยกประเภท โดยไม่ต้องหยิบเอาเอกสารมาบันทึกใหม่แบบดั้งเดิม แต่ต้องเริ่มจากผูกรหัสบัญชีให้กับรายการที่ใช้เปิดบิลก่อน เช่น ผูกรหัสบัญชีลูกหนี้กับข้อมูลลูกค้า, ผูกรหัสบัญชีรายได้กับข้อมูลสินค้า รวมไปถึงรหัสบัญชีซื้อ จ่าย และบัญชีอื่นที่มีในผัง
ผังบัญชีเสมือนเป็นกรอบนโยบาย ถ้าผังบัญชีที่ใช้อยู่ไม่มีรหัสบัญชีรายได้ขายออนไลน์ ก็ต้องเลือกรหัสบัญชีเท่าที่มีในผัง หรือรอเพิ่มรหัสบัญชีใหม่
นักบัญชีจึงเป็นผู้ควบคุมนโยบายว่ามีรายการอะไรบ้างที่สามารถเอามาใช้เปิดบิลได้ หรือที่เรียกกันว่า ตั้งข้อมูลในมาสเตอร์ ทำให้การวางระบบทำงานให้กับกิจการใดๆ จึงมักเริ่มต้นจากศูนย์บัญชี
Anatomy of Transaction
อาจารย์ที่เป็นผู้สอบบัญชีเคยสอนผมว่า "โลกของบัญชีมันก็วนเวียนอยู่แค่ ซื้อ ขาย จ่าย รับ" ตอนนั้นก็ได้แต่รับคำจดจำไว้โดยไม่เข้าใจ เพราะผมเป็นแค่คนทำโปรแกรมให้นักบัญชีใช้
เพราะไม่มีพื้นฐาน จึงเห็นภาพบัญชีแบบคนที่ไม่รู้บัญชี หากยังไม่คิดถึงการจำแนกประเภทของธุรกรรมใดๆ ผมพบว่ารูปแบบของเอกสารชั้นต้นที่เราใช้กัน หรือ บิลต่างๆ จะประกอบด้วยโครงสร้างดังนี้
ยอดเงิน ในบรรทัดรายการแต่ละบรรทัด เป็นส่วน "ตั้งค่า" ส่วนใหญ่มักเกี่ยวข้องกับ รายได้หรือค่าใช้จ่าย
ยอดเงิน ในรายการชำระด้านล่าง (ถ้ามี) เป็นส่วน "ล้างค่า" ส่วนใหญ่มักเกี่ยวข้องกับสินทรัพย์
ส่วนต่างระหว่าง "ตั้งค่า" กับ "ล้างค่า" คือ "ค้างค่า" เป็นยอดที่จะถูกล้างค่าในอนาคต
เมื่อแทนค่าของส่วนต่างๆ ด้วย Psuedo Code โดยยังไม่สนใจว่าจะธุรกรรมนั้นจะเป็น ซื้อ/ขาย/จ่าย/รับ ก็จะใช้รหัสพื้นฐานเหมือนกันดังนี้
"ตั้งค่า" แบ่งคร่าวๆ ได้เป็น *GOODS สำหรับรายการที่เป็นสินค้า หรือ *DEFERRED สำหรับรายการที่ไม่ใช่สินค้า สามารถแยกแยะจากจากการสังเกต "จำนวน" หากรายการไหนมี "จำนวน" แสดงว่าเป็นสินค้า อาจทำให้ฉลาดขึ้นได้จากการวิเคราะห์ข้อความ เช่น คำที่ขึ้นต้นด้วย "ค่า.." มักไม่ใช่สินค้า
"ล้างค่า" คือ *PAID ยอดที่ชำระจบภายในบิล
"ค้างค่า" คือ *UNPAID ยอดที่ค้างชำระ รอให้มีธุรกรรมอื่นมาหักล้าง
นอกจากนี้ยังมี ยอดตั้งค่าพิเศษ ที่ใช้บ่อยคือ *VAT ในใบกำกับภาษี และ *DEFERRED-VAT หรือตั้งพักภาษี กรณีใบแจ้งหนี้ค่าบริการ ที่รอใบเสร็จที่เป็นใบกำกับภาษีมาล้างออกอีกทีหนึ่ง
ประเภทของธุรกรรมจะเป็นตัวบ่งบอกว่าเราควรลงบัญชีอย่างไร เช่น ธุรกรรมซื้อ "ตั้งค่า" จะมีธรรมชาติ "เดบิต" ขณะที่ขายจะกลับด้านเป็น "เครดิต"
(ซื้อ + *GOODS) จึงหมายถึง ลงบัญชีเดบิตซื้อสินค้า ขณะที่ (ขาย + *GOODS) คือ เครดิตรายได้ขายสินค้านั่นเอง
*DEFERRED จะเป็นบัญชีที่รวมความ "เยอะ" ที่หลากหลายไว้ด้วยกัน เป็นบัญชีรอสะสางไม่ง่ายที่จะตีความอัตโนมัติว่าเป็นค่าอะไรกันแน่ ผมจะอธิบายวิธีจัดการต่อไป
Compile GL
แนวคิดสำคัญของ compile GL ที่แตกต่างเทคนิค post GL ตรงที่ "บัญชีแยกประเภทอยู่ภายในเอกสารเดียวกัน"
ใบกำกับภาษีจึงเป็นใบสำคัญลงบัญชีด้วยในตัว เมื่อใดที่มีการแก้ไขรายการหรือยอดเงินในใบกำกับภาษี รายการแยกประเภทก็จะถูกซิงค์ตามอัตโนมัติ
การใช้หลักตีความตามส่วน "ตั้งค่า", "ล้างค่า" และ "ค้างค่า" แล้วอธิบายด้วย Pseudo Code ทำให้การพัฒนากลไกมาตรฐานในโปรแกรม ทำได้โดยไม่ผูกพันกับรหัสตามผังบัญชี
ซึ่งเป็นข้อดีสำหรับโปรแกรมเมอร์ในการพัฒนากลไก เพราะเป็นกฎที่ง่ายใช้ได้กับธุรกรรมทุกประเภทเหมือนกัน แต่ยังมีปัญหาไม่สามารถเอามาสรุปเป็นงบได้ เพราะรหัสทั้งหลายเช่น *GOODS หรือ *VAT ใช้เหมือนกันไม่ว่าจะเป็น ซื้อ/ขาย/จ่าย/รับ
Code Alias (Transcode)
ส่วนที่ยืดหยุ่นของ compile GL เปิดให้เรากำหนดเงื่อนไขแปลงรหัสพื้นฐาน โดยผูกกับประเภทธุรกรรม ให้เป็นรหัสขั้นสูง (high level Pseudo Code) เช่น
*GOODS@accno.inv = "*INCOME" //รายได้
*DEFERRED@accno.inv = "*INCOME" //รายได้
*VAT@accno.inv = "*OUTVAT" //ภาษีขาย
*UNPAID@accno.inv = "*AR" //ลูกหนี้
*GOODS@accno.po = "*PURCHASE" //ซื้อสินค้า
*DEFERRED@accno.po = "*EXPENSE" //ค่าใช้จ่าย
*VAT@accno.po = "*INVAT" //ภาษีซื้อ
*UNPAID@accno.po = "*AP" //เจ้าหนี้
ตัวอย่างข้างต้น เป็นตัวอย่างง่าย ๆ ยกมาให้พอเห็นภาพ ซึ่งสามารถกำหนดให้ละเอียดในระดับหมวดบิล เช่น เอกสารที่เป็นธุรกรรมขายบางหมวดอาจต้องการตั้งยอดค้างเป็น รายได้ค้างรับแทนลูกหนี้
หากไม่ต้องการแปลง Pseudo Code จาก basic เป็น high level ก็สามารถใช้เลขบัญชีจากผังบัญชีที่นักบัญชีรู้สึกสบายใจได้เช่นกัน
*GOODS@accno.inv = "40001" //รายได้
*DEFERRED@accno.inv = "40001" //รายได้
*VAT@accno.inv = "24003" //ภาษีขาย
*UNPAID@accno.inv = "12001" //ลูกหนี้
*GOODS@accno.po = "50001" //ซื้อ
*DEFERRED@accno.po = "51001" //ค่าใช้จ่าย
*VAT@accno.po = "14003" //ภาษีซื้อ
*UNPAID@accno.po = "22001" //เจ้าหนี้
อย่างไรก็ตามการแปลบัญชีเหล่านี้ไม่เพียงพอต่อการแยกประเภทที่ยิบย่อย เช่น ค่าใช้จ่ายต้องบอกละเอียดว่าเป็นค่าอะไร
Code Override
วิธีที่ง่ายที่สุดคือ ให้โปรแกรมอ่านค่ารหัสบัญชีแฝงอยู่ในรายการที่ต้องการลงบัญชีเป็นรหัสอื่น เช่น
ค่าวัสดุสำนักงาน {#*EXP-OFFICE}
ค่าใช้จ่ายเบ็ดเตล็ด {#*EXP-OTHER}
เมื่อเจอเช่นนี้ กลไก compile GL จะใช้รหัสที่ระบุในรายการแทน และอาจใช้ Code Alias แปลต่อก็ได้
หรืออาจใช้เลขบัญชีจากผังบัญชีทะลุมาตรงๆ เลยก็ได้เช่นกัน
ค่าวัสดุสำนักงาน {#52011}
ค่าใช้จ่ายเบ็ดเตล็ด {#59001}
Sub Account
ปัญหาของระบบผังบัญชีที่เป็นตัวเลข เมื่อใช้งานไปนาน ก็จะมีเลขบัญชีในตำนานที่เลิกใช้แล้วแต่ยังค้างเลขไว้ บางครั้งจำเป็นต้องคุมยอดของค่าใหม่ ต้องเพิ่มเลขรหัสเข้าไปในผัง และทำให้ผังบัญชีโตขึ้นเรื่อย ๆ
การทำผังบัญชีกลางที่ใช้ได้กับทุกกิจการจึงไม่มีจริง อย่างน้อยบัญชีธนาคารก็มีไม่เหมือนกันแล้ว
แนวคิดของ Sub Account คือ สามารถใช้ข้อความคุมยอดย่อยได้ รหัสบัญชีเปรียบเสมือนหัวบัญชีของกลุ่ม ดังนั้นเราอาจมีรหัส *BANK เป็นบัญชีคุมกลุ่มเงินฝากธนาคาร แล้วตามด้วยชื่อย่อยที่เป็นสมาชิกแตกต่างกันตามสะดวก เช่น SCB-saving , KBANK-saving
หากนำไปประยุกต์กับค่าใช้จ่าย เราก็จะมีหัวบัญชีรหัสเดียว *EXPENSE แล้วตามด้วยคำอธิบายที่ทำหน้าที่คุมค่าใช้จ่ายเหล่านั้นด้วย ค่าวัสดุสำนักงาน , ค่าใช้จ่ายเบ็ดเตล็ด เมื่อมีค่าใช้จ่ายใหม่ ก็สามารถระบุเพื่อลงบัญชีได้ทันที โดยไม่ต้องรอออกรหัสก่อน
แล้วเราจะจัดการกับปัญหาการใช้ข้อความในบัญชีย่อยไม่เหมือนกัน ทั้งที่เป็นค่าเดียวกันได้อย่างไร
COA Mapping
ถึงแม้ว่ากระบวนการบันทึกบัญชีแยกประเภททั้งหมด สามารถทำโดยไม่ใช้ผังบัญชี แต่การติดต่อกับโลกภายนอก เช่น ส่งงบให้ผู้สอบบัญชี หรือเอางบไปรวมกับบริษัทในเครือ ยังคงจำเป็นต้องใช้ภาษาทางการของนักบัญชีอยู่
อาจเรียกว่างานบัญชีภายใน ช่วยให้นักบัญชีทำงานน้อยลง ทำงานโดยไม่ขึ้นอยู่กับผังบัญชี ตัวเลขทั้งหมดที่ใช้ Pseudo Code + Sub Account สามารถสรุปยอดออกมาเป็นงบทดลองได้ แน่นอนว่าผลลัพธ์ที่ออกมาต้องเป็นอะไรที่แปลกแปร่งสำหรับนักบัญชีส่วนใหญ่ เพราะไม่ใช่งบตามผังบัญชีที่คุ้นเคย
ขั้นตอนสำคัญของนักบัญชี หรืออาจจะกล่าวให้เจาะจงคือ สมุหบัญชีเพียงคนเดียว ต้องมารีวิวตอนจบแปลจากบัญชีภายใน กลายเป็นบัญชีภายนอกตามผังที่ต้องการ บางครั้งยอดเล็กๆ น้อยๆ ที่แยกละเอียด จากบัญชีภายในอาจถูกโยนให้เข้าเป็นเลขบัญชีเดียวกันก็ได้ (เป็นอีกเรื่องที่ไม่ต้องปวดหัวตกลงกันก่อนว่า ค่าอะไรควรแยก ค่าอะไรรวมเป็นอื่นๆ)
งานของสมุหบัญชีคือ Chart of Accounts Mapping แปลงบของบัญชีภายใน กลายเป็นงบตามผังบัญชีภายนอก ซึ่งสามารถปรับเปลี่ยนขยับเขยื้อนได้ตามต้องการโดยไม่มีผลกระทบต่อกระบวนการบันทึกบัญชีภายใน
ขณะที่กระบวนการบันทึกบัญชีโดยพนักงานทั่วไป รวมถึงนักบัญชีอื่นด้วย สามารถใช้ Pseudo Code ในการบันทึก และตรวจสอบโดยไม่ต้องรับรู้ผังบัญชีภายนอก
การใช้บัญชีย่อยช่วยให้อิสระในการอธิบายรายการตามข้อเท็จจริง ไม่ต้องตีความตามผังบัญชี ซึ่งมักกลายเป็นภาระในการตรวจสอบภายหลังเมื่อตีความลงบัญชีของแต่ละคนอาจไม่เหมือนกัน
กระบวนการบันทึกบัญชีที่เป็นงานระหว่างทางก่อนที่จะสรุปเป็นงบการเงิน ไม่จำเป็นต้องลำเลียงมาด้วยเลขรหัสจากผังบัญชีอีกต่อไป กลายเป็นข้อสรุปแบบกระซิบเบาๆ ตอนจบของสไลด์ชุดนี้ว่า "ผังบัญชีภายใน ไม่ต้องมี" (ก็ได้)
Comments