ถ้าข้อมูลอยู่ในชีตอย่างเดียว GOOGLEFINANCE เป็นทางเลือกที่สั้นที่สุด ส่วน Apps Script เหมาะเมื่อชีตต้องเรียก API เพิ่มเติม
- ใช้ GOOGLEFINANCE สำหรับค่าปัจจุบันและช่วงย้อนหลัง
- อ่านข้อมูลย้อนหลังของ GOOGLEFINANCE ผ่าน Sheets API หรือ Apps Script ไม่ได้
- ฟังก์ชัน FXRATE เรียก JSON และใช้แคชได้
- อย่าใส่ API key ใน Apps Script ของชีตที่แชร์
- เก็บ source และเวลาที่สังเกตค่าไว้เมื่อแสดงผล
เริ่มด้วย GOOGLEFINANCE
ใช้ =GOOGLEFINANCE("CURRENCY:USDEUR") สำหรับค่าปัจจุบัน หรือใส่วันเริ่ม วันสิ้นสุด และ DAILY สำหรับข้อมูลย้อนหลัง ราคาอาจมีความล่าช้า และข้อมูลย้อนหลังอ่านผ่าน Sheets API หรือ Apps Script ไม่ได้
เมื่อไรควรใช้ Apps Script
ใช้ Apps Script เมื่ออยากได้ JSON ชื่อฟังก์ชันเอง หรือแคช ตัวอย่างเริ่มจากการเรียกแบบไม่ใช้ key และแคชแต่ละคู่เป็นเวลาสิบนาที
วางฟังก์ชัน FXRATE
วางฟังก์ชันในส่วนขยาย → Apps Script ผู้แก้ไขชีตทุกคนมองเห็นโปรเจกต์ที่ผูกกับชีตได้ จึงไม่ใส่ key ในตัวอย่าง
ใช้ =FXRATE()
หลังบันทึกสคริปต์ ให้ใส่ =FXRATE("USD","EUR") ในเซลล์ เปลี่ยนรหัส ISO สองตัวเพื่อใช้คู่อื่น
การอัปเดตและความปลอดภัย
ฟังก์ชันกำหนดเองไม่ใช่สตรีมแบบเรียลไทม์ ถ้าชีตที่แชร์ต้องการโควตาที่แน่นอน ให้เรียก proxy ฝั่งเซิร์ฟเวอร์และเก็บ key ไว้ที่นั่น
คำถามที่พบบ่อย
=GOOGLEFINANCE("CURRENCY:USDEUR")=GOOGLEFINANCE("CURRENCY:USDEUR", "price", DATE(2026, 1, 1), DATE(2026, 1, 31), "DAILY")// google-sheets: Apps Script Code.gsconst CACHE_TTL = 600; // Cache successful responses for 10 minutes./** * Returns an indicative exchange rate for one currency pair. * @param {string} from Three-letter base currency code. * @param {string} to Three-letter quote currency code. * @return {number|string} The rate or a readable error marker. * @customfunction */function FXRATE(from, to) { from = (from || 'USD').toString().trim().toUpperCase(); to = (to || 'EUR').toString().trim().toUpperCase(); if (!/^[A-Z]{3}$/.test(from) || !/^[A-Z]{3}$/.test(to)) return '#NO_PAIR'; const cacheKey = `fx_${from}_${to}`; const cache = CacheService.getScriptCache(); const cached = cache.get(cacheKey); if (cached) return Number(cached); const url = `https://api.exchangerate.dev/v1/latest/${from}?symbols=${to}`; let resp; try { resp = UrlFetchApp.fetch(url, { muteHttpExceptions: true }); } catch { return '#FETCH_ERROR'; } const code = resp.getResponseCode(); if (code === 401 || code === 403) return '#ACCESS_ERROR'; if (code === 429) return '#RATE_LIMIT'; if (code !== 200) return '#ERROR'; let data; try { data = JSON.parse(resp.getContentText()); } catch { return '#INVALID_RESPONSE'; } const rate = data && data.rates && data.rates[to]; if (rate == null) return '#NO_PAIR'; if (typeof rate !== 'number' || !Number.isFinite(rate) || rate <= 0) return '#INVALID_RESPONSE'; cache.put(cacheKey, String(rate), CACHE_TTL); return Number(rate); // coerce so cells sum and sort}// Euro per US dollar=FXRATE("USD", "EUR") // 0.9245// Japanese yen per US dollar=FXRATE("USD", "JPY") // 157.32// British pound per euro=FXRATE("EUR", "GBP") // 0.8531// Indonesian rupiah per US dollar=FXRATE("USD", "IDR") // 16285.0{ "result": "success", "base": "USD", "source": "live", "market_session": "open", "timestamp": "2026-06-29T09:14:02Z", "data_updated_at": "2026-06-29T09:14:00Z", "rates": { "JPY": 157.32 }, "sources": { "JPY": "live" }, "notice": "Indicative rates, not for settlement."}=FXRATE("USD", "EUR")