Kết nối nhanh bằng Apps Script
Tạo hàm tùy chỉnh =VDV_GOLD("SJC","1m") trong Google Sheets — token nhập đúng 1 lần qua menu,
công thức cực gọn, không lặp lại token. Đánh đổi: phải chấp nhận một cảnh báo "ứng dụng chưa xác minh" của Google (1 lần).
Khi nào nên dùng cách này?
| IMPORTDATA + ô token | Apps Script (trang này) | |
|---|---|---|
| Công thức | URL dài (token tham chiếu 1 ô) | =VDV_GOLD("SJC","1m") |
| Cảnh báo Google | Không | Có (1 lần, tự bấm qua) |
| Tự refresh ~1h | Có | Không (cache theo tham số) |
| Hợp với | Phát cho người dùng cuối | Bạn tự dùng / team nội bộ |
Lưu ý về cảnh báo "ứng dụng chưa xác minh"
Khi cấp quyền lần đầu, Google hiện màn hình "Google hasn't verified this app". Đây là cảnh báo mặc định cho mọi Apps Script cá nhân chưa qua quy trình thẩm định của Google — không phải dấu hiệu script độc hại.
api.vietdataverse.online để lấy dữ liệu. Không đọc/ghi gì khác.
Bước 1 — Dán script vào Apps Script
/**
* Viet Dataverse — Google Sheets connector
* Dùng: =VDV_GOLD("SJC","1m") (token nhập 1 lần qua menu, không gõ lại)
*/
const VDV_BASE = 'https://api.vietdataverse.online/api/v1';
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Viet Dataverse')
.addItem('Nhập / cập nhật API key', 'VDV_promptKey_')
.addItem('Xoá API key', 'VDV_clearKey_')
.addToUi();
}
function VDV_promptKey_() {
const ui = SpreadsheetApp.getUi();
const res = ui.prompt('Viet Dataverse', 'Dán API key (lấy ở trang Developer):', ui.ButtonSet.OK_CANCEL);
if (res.getSelectedButton() !== ui.Button.OK) return;
const key = res.getResponseText().trim();
if (!key) { ui.alert('Key rỗng.'); return; }
PropertiesService.getScriptProperties().setProperty('VDV_API_KEY', key);
ui.alert('Đã lưu API key. Giờ gõ: =VDV_GOLD("SJC","1m")');
}
function VDV_clearKey_() {
PropertiesService.getScriptProperties().deleteProperty('VDV_API_KEY');
SpreadsheetApp.getUi().alert('Đã xoá API key.');
}
function VDV_key_() {
const k = PropertiesService.getScriptProperties().getProperty('VDV_API_KEY');
if (!k) throw new Error('Chưa có API key — menu "Viet Dataverse" -> "Nhập API key".');
return k;
}
function VDV_fetch_(path, params) {
params = params || {};
params.format = 'csv';
params.api_key = VDV_key_();
const qs = Object.keys(params)
.map(function (k) { return k + '=' + encodeURIComponent(params[k]); })
.join('&');
const resp = UrlFetchApp.fetch(VDV_BASE + path + '?' + qs, { muteHttpExceptions: true });
const code = resp.getResponseCode();
if (code !== 200) {
throw new Error('Viet Dataverse lỗi ' + code + ': ' + resp.getContentText().slice(0, 150));
}
// CSV -> mảng 2 chiều; đổi ô số sang kiểu number để vẽ chart được
return Utilities.parseCsv(resp.getContentText()).map(function (row) {
return row.map(function (cell) {
return (cell !== '' && !isNaN(cell)) ? Number(cell) : cell;
});
});
}
/**
* Giá vàng Việt Nam.
* @param {string} type Loại vàng: "SJC", "DOJI HN", "PNJ", "BTMC". Mặc định "SJC".
* @param {string} period "7d", "1m", "1y", "all". Mặc định "1m".
* @return Bảng: ngày | giá mua | giá bán
* @customfunction
*/
function VDV_GOLD(type, period) {
return VDV_fetch_('/gold', { type: type || 'SJC', period: period || '1m' });
}
addItem(...) thì menu sẽ sai và hàm báo "Chưa có API key".
Bước 3 — Dùng hàm
Gõ ở ô bất kỳ — hàm tự tràn ra bảng (ngày · giá mua · giá bán), số đã đúng kiểu để vẽ chart:
| Bạn gõ | Kết quả |
|---|---|
=VDV_GOLD() | SJC 1 tháng (mặc định) |
=VDV_GOLD("SJC","1y") | SJC 1 năm |
=VDV_GOLD("DOJI HN","7d") | DOJI Hà Nội 7 ngày |
Tham số: type = SJC · DOJI HN · PNJ · BTMC; period = 7d · 1m · 1y · all.
VDV_GOLD. Khi mở CSV cho bạc/tỷ giá/lãi suất, sẽ bổ sung VDV_SILVER, VDV_FX… vào cùng script.
Lỗi thường gặp
#ERROR! Chưa có API key
Bạn chưa nhập key qua menu (Bước 2), hoặc đã lỡ dán token vào code. Mở menu Viet Dataverse → Nhập API key để nhập đúng cách.
Viet Dataverse lỗi 401
Key sai hoặc đã bị thu hồi. Mỗi lần "Generate New Key" ở trang Developer sẽ thu hồi key cũ — lấy lại key mới nhất bằng nút "Sao chép" rồi cập nhật qua menu.
Ô vẫn #ERROR sau khi nhập key
Hàm có thể đang cache lỗi cũ. Sửa nhẹ công thức (vd thêm/bớt dấu cách) rồi Enter để buộc tính lại.
Dữ liệu không tự cập nhật
Custom function cache theo tham số, không tự refresh như IMPORTDATA. Sửa lại công thức rồi Enter để lấy dữ liệu mới.
Cần hỗ trợ? Email findatasolution@gmail.com · Quay lại hướng dẫn Google Sheets cơ bản.