การถ่ายโอนข้อมูลขนาดใหญ่ระหว่างไฟล์ ODS โดยรักษา Macro ไว้: การสำรวจเครื่องมือและข้อจำกัด
Development Log · 2026-05-04
1. Title
การถ่ายโอนข้อมูลขนาดใหญ่ระหว่างไฟล์ ODS โดยรักษา Macro ไว้: การสำรวจเครื่องมือและข้อจำกัด
2. Date / Phase
วันที่เริ่มต้นสนทนา: 4 พฤษภาคม 2026 Phase: Data Migration & Tool Evaluation — Phase of Constraint Discovery
3. Background
ปัญหาที่จุดชนวนการสนทนาครั้งนี้คือความจำเป็นในการถ่ายโอนข้อมูลจำนวนมหาศาลจากเซลล์ช่วง
A6–P950000 ในไฟล์ M5_RawDataFilter_for_IS1.ods ไปยังเซลล์ช่วง
C17–R950000 ในไฟล์ M5_Exhaustive_HardFilter_for_IS1.ods
โดยไม่ให้ข้อมูลในเซลล์อื่นของไฟล์ปลายทางสูญหาย
โจทย์นี้ดูเรียบง่ายในเชิงเทคนิค แต่เมื่อพิจารณาถึงขนาดข้อมูล (ประมาณ 15.2 ล้านเซลล์) และลักษณะของไฟล์ ODS ที่มีโครงสร้างซับซ้อน (เป็น ZIP archive ที่บรรจุ XML หลายไฟล์) จึงกลายเป็นการสำรวจที่ลึกซึ้งถึงขีดจำกัดของเครื่องมือแต่ละชนิด และนำไปสู่คำถามสำคัญเกี่ยวกับการรักษา Macro ซึ่งเป็นส่วนประกอบที่เปราะบางที่สุดของเอกสาร
4. Key Insights
Insight ที่ 1: เครื่องมือแต่ละชนิดมีจุดแลกเปลี่ยน (Trade-off) ที่แตกต่างกัน
เครื่องมือสามกลุ่มถูกนำมาพิจารณา ได้แก่ ezodf (ควบคุมระดับเซลล์
รักษารูปแบบได้ดี แต่ช้า), pandas (ประมวลผลเป็นชุด เร็วกว่ามาก
แต่สูญเสียรูปแบบบางส่วน) และ LibreOffice UNO API (รักษาทุกอย่างได้
แต่ซับซ้อนและช้ากว่า)
เหตุผลที่ต้องเปรียบเทียบเช่นนี้ เพราะไม่มีเครื่องมือใดที่ "ดีที่สุด" ในทุกมิติ — การเลือกจึงขึ้นอยู่กับว่าอะไรคือสิ่งที่ยอมแลกได้ และอะไรคือสิ่งที่ห้ามสูญเสีย
Insight ที่ 2: ODS ไม่ใช่ "ไฟล์แผ่นงาน" แต่เป็น "คอนเทนเนอร์"
ความเข้าใจนี้เป็นจุดเปลี่ยนทางความคิด เพราะการมอง ODS เป็น ZIP ที่บรรจุ XML หลายไฟล์ทำให้เห็นว่า Macro ไม่ได้เป็นส่วนหนึ่งของ "ข้อมูล" ในเซลล์ แต่เป็นส่วนประกอบแยกที่ library ส่วนใหญ่ไม่รู้จักและไม่รักษาไว้ นี่คือรากของปัญหาทั้งหมด
Insight ที่ 3: UNO API คือทางเดียวที่รักษา Macro ได้อย่างสมบูรณ์
แต่มาพร้อมกับข้อกำหนดที่เข้มงวด คือ LibreOffice ต้องรันใน listening mode และเปิด
connection ผ่าน socket ทุกครั้งที่ทำงาน แม้จะดูเป็นภาระ
แต่ก็สามารถทำให้เป็นอัตโนมัติได้ด้วย subprocess และ
atexit ซึ่งเปลี่ยนภาระให้กลายเป็นส่วนหนึ่งของ lifecycle ของสคริปต์
Insight ที่ 4: ขนาดข้อมูลมีนัยต่อเวลาและหน่วยความจำ
เครื่อง Ryzen 5 5600G พร้อม RAM 32GB เพียงพอต่อการประมวลผล แต่เวลาจะขึ้นอยู่กับวิธี: pandas ใช้เวลาเพียง 8–15 วินาที, ezodf 45–75 วินาที, UNO API 5–20 นาที ความต่างนี้สะท้อนหลักการว่า "ความสมบูรณ์ของข้อมูลและ metadata มีต้นทุนเสมอ"
Insight ที่ 5: ไฟล์ต้องถูกปิดก่อนรันสคริปต์
ข้อนี้ดูเหมือนรายละเอียดเล็กน้อย แต่เป็นข้อผิดพลาดที่พบบ่อยที่สุด — การที่ไฟล์ถูกเปิดอยู่ในโปรแกรมตารางจะทำให้เกิด lock และสคริปต์ไม่สามารถเขียนทับได้
5. Decisions
Decision ที่ 1: เลือกใช้ LibreOffice UNO API สำหรับงานที่ต้องรักษา Macro
หลังจากการประเมิน trade-off ระหว่างความเร็วและความสมบูรณ์ของ metadata การตัดสินใจคือยอมแลกความเร็วกับความสมบูรณ์ของเอกสาร เพราะ Macro เป็นสินทรัพย์ทางตรรกะที่สร้างขึ้นด้วยความตั้งใจ ไม่ควรสูญเสียไปเพียงเพื่อประหยัดเวลาไม่กี่นาที
Decision ที่ 2: ทำสคริปต์ให้เปิดและปิด LibreOffice อัตโนมัติ
แทนที่จะให้ผู้ใช้จัดการ LibreOffice listening mode ด้วยตนเองทุกครั้ง
เราเลือกฝังการจัดการนี้เข้าไปในสคริปต์ผ่าน subprocess และ
atexit เพื่อให้ lifecycle ของ LibreOffice ผูกกับ lifecycle
ของสคริปต์
Decision ที่ 3: ทดสอบด้วยชุดข้อมูลขนาดเล็กก่อน
ก่อนรันกับข้อมูล 950,000 แถว ควรทดสอบกับ 100 แถวก่อน เพื่อยืนยันว่าเส้นทาง (path) ของไฟล์, การเชื่อมต่อ UNO และการแมปตำแหน่งเซลล์ถูกต้องทั้งหมด
Decision ที่ 4: แนะนำให้สำรองไฟล์ก่อนรันทุกครั้ง
เนื่องจากสคริปต์เขียนทับไฟล์ปลายทาง การสำรองจึงเป็นมาตรการป้องกันที่ไม่ควรละเลย โดยเฉพาะเมื่อไฟล์มี Macro ที่อาจสูญหายได้
6. Philosophy
บทสนทนานี้เผยให้เห็นหลักการเชิงปรัชญาที่สำคัญว่า "ข้อมูลไม่เท่ากับเอกสาร" — ข้อมูลคือเนื้อหา ส่วนเอกสารคือระบบนิเวศที่ประกอบด้วยเนื้อหา รูปแบบ และตรรกะ (Macro) การรักษาเฉพาะเนื้อหาแต่ทิ้งตรรกะ คือการรักษาร่างแต่ทิ้งวิญญาณ
อีกนัยหนึ่งคือ "ความเร็วไม่ใช่เป้าหมายสูงสุด แต่เป็นตัวแปรที่ต้องเจรจา" — เราไม่ควรเลือกวิธีที่เร็วที่สุดโดยอัตโนมัติ หากวิธีนั้นทำลายสิ่งที่เราให้คุณค่า การเลือกใช้ UNO API แม้จะช้ากว่า คือการยอมรับว่าคุณค่าบางอย่างมีราคาที่ต้องจ่าย
และสุดท้าย "ภาระที่ทำซ้ำได้ ควรถูกเปลี่ยนเป็นอัตโนมัติ" — การที่ต้องรัน LibreOffice ใน listening mode ทุกครั้งไม่ใช่ข้อจำกัดที่ต้องทน แต่เป็นโอกาสที่จะออกแบบ lifecycle ให้สคริปต์ดูแลตัวเอง
7. Future Work
สิ่งที่ควรทำต่อ:
- ทดสอบ UNO API กับข้อมูลจริงขนาด 950,000 แถว เพื่อวัดเวลาจริงและตรวจสอบว่าไม่มี memory leak
- ขยายสคริปต์ให้รองรับการเลือก sheet ปลายทาง (ปัจจุบัน hardcode เป็น sheet แรก)
- เพิ่ม logging แบบละเอียด เพื่อให้ตรวจสอบย้อนหลังได้หากเกิดข้อผิดพลาดกลางทาง
- พัฒนา rollback mechanism กรณีการถ่ายโอนล้มเหลวกลางทาง เพื่อไม่ให้ไฟล์ปลายทางอยู่ในสภาพครึ่ง ๆ กลาง ๆ
- สำรวจแนวทางใช้ XLSM แทน ODS หาก Macro เป็นปัจจัยสำคัญระยะยาว เพราะ ecosystem ของ Excel อาจมี library ที่รักษา Macro ได้ดีกว่า
8. Closing Note
การถ่ายโอนข้อมูลระหว่างไฟล์ ODS ที่ดูเหมือนเป็นเพียงงานเทคนิคเล็ก ๆ กลับกลายเป็นการเดินทางที่เผยให้เห็นชั้นของปัญหา และในแต่ละชั้นก็มีบทเรียนซ่อนอยู่ เราเริ่มต้นด้วยคำถามง่าย ๆ ว่า "จะย้ายข้อมูลอย่างไร" แต่เมื่อไล่ตามไป กลับพบว่าแท้จริงแล้วเรากำลังถามว่า "อะไรคือสิ่งที่เรายอมสูญเสีย" และ "อะไรคือสิ่งที่เราต้องรักษาไว้ไม่ว่าจะมีราคาเท่าใด"
การเลือกใช้ UNO API แม้จะช้ากว่า ไม่ได้เป็นเพียงเพราะความสมบูรณ์ของ Macro หากแต่เป็นการยอมรับว่าในงานข้อมูลบางประเภท ความเร็วไม่ใช่ตัวชี้วัดเดียวของความสำเร็จ และบางครั้ง การยอมช้าลงเพื่อรักษาสิ่งที่สำคัญกว่า คือการตัดสินใจที่ฉลาดที่สุด
การเดินทางครั้งนี้จึงไม่ใช่แค่การเขียนสคริปต์ แต่เป็นการเรียนรู้ที่จะคิดแบบวิศวกรที่ให้ความสำคัญกับ lifecycle ทั้งหมดของระบบ ไม่ใช่แค่ผลลัพธ์ปลายทาง
— บันทึกโดย KOOeda6, Phase of Constraint Discovery
