GAS : โหลดข้อมูลแบบ Batch คืออะไร และทำไมต้องใช้

 


ปัญหาคลาสสิกของ GAS

เมื่อข้อมูลใน Google Sheet มีจำนวนมาก (หลักหมื่น–แสนแถว)

  • ⏱ Script timeout (6 นาที)
  • 🐌 หน้าเว็บค้าง
  • ❌ โหลดไม่ครบ
  • ❌ quota เต็มเร็ว

สาเหตุหลัก

GAS + Sheet ไม่เหมาะกับการ “อ่านทีละแถว / ทีละเซลล์”
แต่เหมาะกับการ “อ่านเป็นก้อน (Array)”


แนวคิดของ Batch Loading

Batch = แบ่งข้อมูลก้อนใหญ่ → เป็นก้อนเล็กหลายรอบ

แทนที่จะโหลด 100,000 แถวครั้งเดียว
👉 แบ่งเป็น 1,000 แถว × 100 รอบ

[ 1000 ][ 1000 ][ 1000 ] → ... → [ 1000 ]

หลักการสำคัญของ Batch ใน GAS

1️⃣ อ่าน Sheet ครั้งเดียวต่อรอบ
2️⃣ ส่งข้อมูลไป Client ทีละชุด
3️⃣ Client เรียกซ้ำอัตโนมัติ
4️⃣ แสดง Progress ให้ผู้ใช้เห็น


🧩 โครงสร้างระบบ (ภาพรวม)

Google Sheet ↓ GAS (loadBatch) ↓ Web App (JS) ↓ Render + Progress

ตัวอย่างพื้นฐาน : โหลดข้อมูลแบบ Batch

🧱 Google Sheet

ชื่อชีต : data

| id | name | class | score |

1️⃣ GAS : ฟังก์ชัน Batch

function loadBatch(offset, limit) { const sh = SpreadsheetApp.getActive() .getSheetByName("data"); const lastRow = sh.getLastRow(); if (offset >= lastRow) { return { rows: [], done: true }; } const numRows = Math.min(limit, lastRow - offset); const rows = sh .getRange(offset + 1, 1, numRows, sh.getLastColumn()) .getDisplayValues(); return { rows, loaded: offset + numRows, total: lastRow - 1, done: offset + numRows >= lastRow }; }


อธิบาย

ตัวแปรความหมาย
offsetแถวที่โหลดไปแล้ว
limitจำนวนต่อรอบ
rowsข้อมูลที่โหลด
doneโหลดครบหรือยัง

2️⃣ Client (HTML + JS)

<div class="progress"> <div id="bar" class="progress-bar" style="width:0%">0%</div> </div> <table> <tbody id="tbody"></tbody> </table> <script> let offset = 1; const limit = 1000; let total = 0; function loadNext() { google.script.run.withSuccessHandler(res => { if (!total) total = res.total; render(res.rows); updateBar(res.loaded, total); if (!res.done) { offset += res.rows.length; setTimeout(loadNext, 50); } }).loadBatch(offset, limit); } function render(rows) { const tbody = document.getElementById("tbody"); rows.forEach(r => { const tr = document.createElement("tr"); tr.innerHTML = `<td>${r[0]}</td><td>${r[1]}</td>`; tbody.appendChild(tr); }); } function updateBar(loaded, total) { const p = Math.round((loaded / total) * 100); const bar = document.getElementById("bar"); bar.style.width = p + "%"; bar.textContent = p + "%"; } loadNext(); </script>

ตัวอย่างประยุกต์ใช้จริง

1) ระบบ LMS

  • โหลดรายชื่อนักเรียน
  • โหลดคะแนน
  • โหลดประวัติการส่งงาน

ประโยชน์

  • หน้าเว็บไม่ค้าง
  • ครูเปิดดูหลายครั้งได้เร็ว


2) Dashboard ผู้บริหาร

  • โหลดข้อมูลย้อนหลังหลายปี
  • แสดงกราฟแบบเรียลไทม์

เทคนิคเสริม

limit = 2000; CacheService.getScriptCache();

 3) ระบบไฟล์ Drive

  • แสดงไฟล์หลายหมื่นไฟล์
  • โหลดทีละโฟลเดอร์


4) ระบบทะเบียน / ประวัติ

  • ค้นหาจากข้อมูลจำนวนมาก
  • โหลดเฉพาะหน้าที่ต้องใช้


Best Practices (มืออาชีพใช้)

✅ ใช้

  • getDisplayValues()
  • setTimeout() ฝั่ง JS
  • CacheService
  • limit 500–2000

❌ หลีกเลี่ยง

  • อ่านทีละแถว
  • appendRow() ใน loop
  • ส่ง Object ซ้อนลึกไป Client


สรุป

หัวข้อBatch
รองรับข้อมูลใหญ่
ป้องกัน timeout
UX ดี
Production Ready



แสดงความคิดเห็น (0)
ใหม่กว่า เก่ากว่า