Google Sheets Nâng Cao Bài 9: Bảo Mật, Phân Quyền và Chia Sẻ Chuyên Nghiệp

Google Sheets Nâng Cao Bài 9: Bảo Mật, Phân Quyền và Chia Sẻ Chuyên Nghiệp
Bài 9 trong series Google Sheets Nâng Cao. Sau khi thành thạo Pivot Table và SUMPRODUCT (Bài 8), bây giờ chúng ta học cách bảo vệ dữ liệu và quản lý quyền truy cập chuyên nghiệp.
Bạn có một file Google Sheets chứa dữ liệu kinh doanh nhạy cảm — bảng lương, margin sản phẩm, thông tin khách hàng. Bạn muốn chia sẻ cho nhóm nhưng không muốn mọi người đều thấy và sửa mọi thứ. Bài này sẽ hướng dẫn bạn thiết lập bảo mật và phân quyền chuẩn doanh nghiệp.
Tại Sao Bảo Mật Google Sheets Quan Trọng?
Rủi Ro Thực Tế
- Nhân viên nghỉ việc nhưng vẫn có link: Nếu file shared "Anyone with link", người đã nghỉ vẫn xem được mãi mãi
- Sửa nhầm công thức: Một click chuột nhầm có thể xóa công thức quan trọng
- Lộ thông tin lương: Nhân viên A thấy được lương của nhân viên B
- Dữ liệu khách hàng bị copy: CCCD, email, số điện thoại của 10,000 khách hàng
- Báo cáo bị chỉnh sửa ngược: Ai đó sửa số liệu để che giấu sai phạm
Case Study: Chi Phí Của Lỗi Bảo Mật
Tình huống thực tế:
- Công ty A có file doanh thu chia sẻ "Viewer"
- Nhân viên B screenshot toàn bộ số liệu
- B nghỉ việc và mang sang đối thủ
- Kết quả: Đối thủ biết margin, chiến lược giá của công ty A
Giải pháp: Protected ranges + Revoke access khi nhân viên nghỉ
Share Settings — Nền Tảng Bảo Mật
3 Cấp Độ Chia Sẻ
CẤP 1: Restricted (Giới hạn) — AN TOÀN NHẤT
→ Chỉ những người được mời mới truy cập được
→ Dùng cho: Dữ liệu nhạy cảm, bảng lương, báo cáo tài chính
CẤP 2: Anyone with link (Có link là vào được) — NGUY HIỂM
→ Bất kỳ ai có đường link đều truy cập được, kể cả người lạ
→ CHỈ dùng cho: Content public, template miễn phí, form công khai
CẤP 3: Public on the web (Công khai)
→ Google có thể index vào kết quả tìm kiếm
→ KHÔNG dùng cho dữ liệu kinh doanh
Cách Thiết Lập Share Settings
- Click nút "Share" (góc trên phải)
- Panel "Share with people and groups" xuất hiện
- Nhập email từng người → chọn quyền: Viewer / Commenter / Editor
- Phần "General access": đảm bảo là "Restricted"
- Click "Done"
Phân Biệt 3 Vai Trò
| Quyền Hạn | Viewer | Commenter | Editor |
|---|---|---|---|
| Xem nội dung | Có | Có | Có |
| Tải xuống | Có* | Có* | Có |
| Thêm comment | Không | Có | Có |
| Sửa nội dung | Không | Không | Có |
| Thêm/xóa sheet | Không | Không | Có** |
| Share thêm người | Không | Không | Có** |
*Có thể tắt bằng "Disable download" | **Có thể tắt bằng "Prevent editors from changing access"
Cài Đặt Nâng Cao Trong Share Dialog
Mở Share > Settings (icon bánh răng):
☑ Prevent editors from changing access and adding new people
→ Chỉ Owner mới có thể chia sẻ thêm
☑ Disable downloading, printing, and copying for commenters and viewers
→ Ngăn Viewer tải xuống/in (nhưng KHÔNG ngăn được screenshot)
⚠️ Lưu ý quan trọng:
"Disable download" không ngăn được người dùng kỹ thuật.
Đây là biện pháp ngăn chặn ngẫu nhiên, không phải bảo mật tuyệt đối.
Protected Ranges — Bảo Vệ Vùng Dữ Liệu Quan Trọng
Tại Sao Cần Protected Ranges?
Khi chia sẻ file với nhiều Editor, bạn muốn:
- Nhân viên nhập liệu vào vùng A, nhưng KHÔNG sửa được công thức ở vùng B
- Lễ tân cập nhật lịch hẹn nhưng KHÔNG xóa được dữ liệu lịch sử
- Kế toán xem doanh thu nhưng KHÔNG thay đổi được cấu trúc báo cáo
Cách Tạo Protected Range
Cách 1: Click chuột phải vào vùng cần bảo vệ > "Protect range"
Cách 2: Menu Data > "Protect sheets and ranges"
Bước thực hiện:
1. Chọn vùng ô cần bảo vệ (ví dụ: E2:H1000 - cột công thức)
2. Data > Protect sheets and ranges
3. Nhập mô tả: "Công thức doanh thu - chỉ Owner sửa"
4. Click "Set permissions"
5. Chọn: "Restrict who can edit this range"
6. Chọn "Only you" hoặc nhập email người được phép sửa
7. Click "Done"
Ví Dụ Thực Tế: Bảo Vệ File Bán Hàng
File quản lý bán hàng — phân quyền chi tiết:
Protected Range 1: Cột A-D (Mã SP, Tên SP, Danh Mục, Giá Nhập)
→ Chỉ Owner (Giám đốc) mới sửa được
→ Nhân viên không thay đổi được giá nhập
Protected Range 2: Cột G-I (Công thức tính lãi, margin, KPI)
→ Chỉ Owner sửa được
→ Đảm bảo công thức không bị xóa nhầm
Vùng nhập liệu tự do: Cột E-F (Số lượng bán, Ghi chú)
→ Tất cả Editor được sửa
→ Nhân viên nhập doanh số hàng ngày
Protected Sheet: "BAO_CAO_THANG"
→ Không ai được sửa (chỉ xem)
→ Tự động tính từ dữ liệu nguồn
Bảo Vệ Toàn Bộ Sheet
Cách bảo vệ sheet (không phải range):
1. Click chuột phải vào tab sheet phía dưới
2. "Protect sheet"
3. Tích "Except certain cells" nếu muốn cho phép sửa một số vùng nhất định
Ví dụ: Sheet DASHBOARD
- Protect toàn bộ sheet
- Except: B1:B3 (ô chọn filter/tháng/năm)
→ Người dùng chỉ có thể thay đổi dropdown filter, không sửa được dashboard
Named Ranges cho Bảo Mật và Dễ Quản Lý
Tại Sao Named Ranges Giúp Bảo Mật?
Thay vì công thức:
=SUMIF('Sheet1'!C:C,"Hà Nội",'Sheet1'!G:G)
Dùng Named Range:
=SUMIF(KhuVuc,"Hà Nội",DoanhThu)
Lợi ích bảo mật:
1. Ẩn tên sheet nguồn (người dùng không biết dữ liệu lấy từ sheet nào)
2. Dễ thay đổi source data mà không phá vỡ công thức
3. Công thức rõ ràng, khó sửa nhầm
Tạo Named Range
Data > Named ranges > + Add a range
Tên: DoanhThuThang1
Range: 'DON_HANG'!H2:H1000
(Giới hạn cụ thể, không dùng H:H)
Named Range hay dùng:
- DoanhThu → DON_HANG!H2:H10000
- KhuVuc → DON_HANG!D2:D10000
- NgayBan → DON_HANG!A2:A10000
- NhanVien → DON_HANG!E2:E10000
- SanPham → DON_HANG!B2:B10000
Ẩn Sheets và Công Thức
Ẩn Sheet Chứa Dữ Liệu Nhạy Cảm
Cách ẩn sheet:
Click chuột phải vào tab sheet > "Hide sheet"
Ví dụ ứng dụng:
- Ẩn sheet "BANG_LUONG" khỏi nhân viên thông thường
- Ẩn sheet "GIA_NHAP" khỏi nhân viên kinh doanh
- Ẩn sheet "AUDIT_LOG" khỏi tất cả trừ Owner
Lưu ý: Ẩn sheet KHÔNG ngăn Editor giỏi kỹ thuật xem.
Phải kết hợp với Protected Range để thực sự bảo mật.
Cách xem lại sheet ẩn:
View > Hidden sheets > [Tên sheet]
Ẩn Công Thức trong Formula Bar
Kỹ thuật 1: Protected Range + hide formula
1. Chọn vùng có công thức bí mật
2. Data > Protect sheets and ranges
3. Trong permissions, chỉ cho Owner edit
4. Tick "Hide this range from non-editors in formula bar"
→ Viewer/Commenter không thấy công thức trong formula bar
Kỹ thuật 2: Dùng Apps Script để tính toán phức tạp
function calculateMargin(productId) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('GIA_NHAP');
// Logic tính margin ẩn trong script, không lộ công thức
return margin;
}
// Custom function =calculateMargin(A2) trong sheet
// Người dùng chỉ thấy "=calculateMargin(A2)", không thấy logic thật
Revision History — "Cỗ Máy Thời Gian" của Google Sheets
Xem Lịch Sử Thay Đổi
Cách truy cập:
File > Version history > See version history
Hoặc: Ctrl+Alt+Shift+H (Windows) / Cmd+Option+Shift+H (Mac)
Thông tin hiển thị:
- Ai thay đổi (email)
- Thay đổi gì (tô màu vùng thay đổi)
- Thay đổi lúc nào
- Có thể khôi phục về version trước
Restore Version Cũ
Kịch bản: Nhân viên vô tình xóa 200 dòng dữ liệu tháng 3
Cách khôi phục:
1. File > Version history > See version history
2. Cuộn timeline tìm version trước khi xóa
3. Click "Restore this version"
4. Xác nhận → File quay về trạng thái trước khi xóa
Giữ version lịch sử bao lâu?
- Google Workspace Business: Không giới hạn
- Google Account thường: 100 versions hoặc 30 ngày (tùy cái nào đến trước)
Đặt tên version quan trọng:
File > Version history > Name current version
Ví dụ: "Báo Cáo Tháng 12 - Đã Duyệt CFO"
→ Dễ tìm lại sau này
Tạo "Read-Only Dashboard" cho Manager
Pattern: Tách Data và Dashboard
File 1: "DATA_MASTER.gsheet" (Restricted — chỉ team nhập liệu)
→ Chứa toàn bộ dữ liệu thô
→ Protected ranges cho công thức
File 2: "DASHBOARD_MANAGER.gsheet" (Shared với Manager — Viewer only)
→ IMPORTRANGE từ File 1
→ Chỉ chứa báo cáo tổng hợp
→ Manager xem nhưng không thể sửa dữ liệu gốc
// Trong DASHBOARD_MANAGER.gsheet:
=IMPORTRANGE("spreadsheet_url_of_DATA_MASTER", "BAO_CAO!A1:H50")
Lần đầu: GS sẽ hỏi "Allow access" → Click cho phép
Sau đó: Dữ liệu tự đồng bộ realtime
Dashboard Chỉ Cho Phép Xem Filter
// Kỹ thuật: Sheet DASHBOARD có protected range
// Chỉ cho phép thay đổi ô B1:B3 (dropdown filter)
Protected: Toàn bộ DASHBOARD sheet
Exception: B1 (chọn Khu Vực), B2 (chọn Tháng), B3 (chọn Năm)
// Công thức trong dashboard dùng B1:B3 làm filter động
=SUMPRODUCT(
(KhuVuc=B1)*
(MONTH(NgayBan)=MONTH(DATE(B3,B2,1)))*
DoanhThu
)
Manager thay đổi dropdown → Dashboard cập nhật
Manager không thể sửa công thức hay dữ liệu nguồn
Collaborative Editing An Toàn
Vấn Đề: Nhiều Người Sửa Cùng Lúc
Kịch bản: 5 nhân viên kinh doanh cùng nhập đơn hàng vào 1 sheet
Rủi ro:
- A nhập vào dòng 100, B cũng nhập vào dòng 100 → ghi đè lên nhau
- C xóa bộ lọc của D đang dùng
- Conflict khi 2 người sửa cùng 1 ô
Giải Pháp: Lock Khu Vực Theo Người Dùng
Cách 1: Mỗi nhân viên có sheet riêng
- Sheet "NV_A", "NV_B", "NV_C"
- Mỗi người nhập vào sheet của mình
- Sheet "TONG_HOP" dùng IMPORTRANGE để gộp
Cách 2: Dùng Google Forms thay vì nhập trực tiếp
- Tạo Google Form cho nhập liệu
- Responses tự đổ vào Sheets (mỗi form submit = 1 dòng mới)
- Không ai sửa dữ liệu của người khác
Cách 3: Named ranges + Protected ranges phân theo cột
- Nhân viên A chỉ sửa được cột F (Số lượng bán)
- Nhân viên B chỉ sửa được cột G (Ghi chú giao hàng)
- Cột công thức tự động không ai sửa được
Sử Dụng Filter Views (Bộ Lọc Cá Nhân)
Vấn đề: A đang lọc "Hà Nội", B đang lọc "HCM"
→ Khi A lọc, màn hình của B cũng bị thay đổi
Giải pháp: Filter Views (bộ lọc riêng tư)
Data > Filter views > Create new filter view
→ Mỗi người tạo filter view riêng
→ Filter của A không ảnh hưởng đến B
Tạo filter view cho cả team:
- "Filter_HaNoi" — cho nhân viên Hà Nội
- "Filter_HCM" — cho nhân viên TP.HCM
- "Filter_Q1_2027" — cho báo cáo Q1
→ Ai cũng dùng filter phù hợp mà không xung đột
Apps Script: Audit Log — Ai Sửa Gì Khi Nào
Triển Khai Audit Log Cơ Bản
// Extensions > Apps Script > Dán code sau:
function onEdit(e) {
// Chỉ log các sheets quan trọng
const sensitiveSheets = ['DON_HANG', 'BANG_LUONG', 'BENH_NHAN', 'TAI_CHINH'];
const sheetName = e.range.getSheet().getName();
if (!sensitiveSheets.includes(sheetName)) return;
const logSheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('AUDIT_LOG');
if (!logSheet) {
SpreadsheetApp.getActiveSpreadsheet().insertSheet('AUDIT_LOG');
}
const user = Session.getActiveUser().getEmail();
const timestamp = new Date();
const cell = e.range.getA1Notation();
const oldVal = e.oldValue !== undefined ? e.oldValue : '[empty]';
const newVal = e.value !== undefined ? e.value : '[deleted]';
logSheet.appendRow([
timestamp,
user,
sheetName,
cell,
oldVal,
newVal
]);
}
Audit Log Nâng Cao với Thống Kê
// Thêm vào script trên:
// Gửi email tóm tắt cuối ngày (trigger: time-driven, 6pm)
function dailyAuditSummary() {
const logSheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('AUDIT_LOG');
const today = new Date();
const data = logSheet.getDataRange().getValues();
const todayEdits = data.filter(row => {
const editDate = new Date(row[0]);
return editDate.toDateString() === today.toDateString();
});
if (todayEdits.length === 0) return;
const summary = todayEdits.map(row =>
row[1] + ' sửa ' + row[2] + '!' + row[3] +
': "' + row[4] + '" → "' + row[5] + '"'
).join('
');
GmailApp.sendEmail(
'owner@company.com',
'Audit Log hôm nay: ' + todayEdits.length + ' thay đổi',
'Chi tiết:
' + summary
);
}
// Phát hiện thay đổi bất thường (xóa nhiều dòng)
function onEdit(e) {
// ... (code cũ)
// Cảnh báo nếu xóa > 10 dòng cùng lúc
if (e.changeType === 'REMOVE_ROW' && e.range.getNumRows() > 10) {
GmailApp.sendEmail(
'owner@company.com',
'⚠️ CẢNH BÁO: Xóa nhiều dòng!',
user + ' vừa xóa ' + e.range.getNumRows() +
' dòng trong sheet ' + sheetName
);
}
}
IMPORTRANGE với Permission
Cách IMPORTRANGE Hoạt Động
=IMPORTRANGE("spreadsheet_url", "sheet_name!range")
Ví dụ:
=IMPORTRANGE("https://docs.google.com/spreadsheets/d/ABC123/edit", "DoanhThu!A1:H1000")
Lần đầu sử dụng:
→ Hiện thông báo "You need to connect these sheets"
→ Click "Allow access" — chỉ cần làm 1 lần
→ Sau đó tự động đồng bộ
Phân Quyền IMPORTRANGE
IMPORTRANGE yêu cầu người dùng có quyền trên FILE NGUỒN.
Tình huống:
- File A (nguồn): chỉ Owner và 3 Manager có quyền xem
- File B (dashboard): shared rộng hơn (20 nhân viên)
- File B dùng IMPORTRANGE từ File A
Kết quả:
- 3 Manager có quyền trên File A → thấy data từ IMPORTRANGE trong File B
- 17 nhân viên không có quyền File A → thấy lỗi "#REF!" trong File B
Giải pháp nếu muốn cả 20 nhân viên thấy data được chọn lọc:
→ Tạo File C trung gian (chỉ chứa data đã lọc, không nhạy cảm)
→ File B IMPORTRANGE từ File C
→ File C có quyền rộng hơn
Best Practices Bảo Mật Dữ Liệu Nhạy Cảm
Checklist Bảo Mật Google Sheets Doanh Nghiệp
THIẾT LẬP BAN ĐẦU:
□ Share settings: "Restricted" (không phải "Anyone with link")
□ Tắt "Download/print/copy for viewers and commenters"
□ Tắt "Editors can change access"
□ Chia sẻ theo email cụ thể, không theo domain (@company.com = tất cả nhân viên)
PROTECTED RANGES:
□ Khóa tất cả cột công thức
□ Khóa header row
□ Khóa dữ liệu tham chiếu (giá, danh mục)
□ Chỉ để trống vùng nhập liệu
AUDIT VÀ MONITORING:
□ Bật Apps Script Audit Log
□ Thiết lập trigger email cảnh báo thay đổi bất thường
□ Review audit log hàng tuần
□ Đặt tên version quan trọng
QUẢN LÝ QUYỀN TRUY CẬP:
□ Review danh sách người có quyền mỗi 3 tháng
□ Thu hồi quyền ngay khi nhân viên nghỉ việc
□ Không dùng chung tài khoản Google cho nhiều người
□ Log lại danh sách người có quyền và lý do
Xử Lý Khi Nhân Viên Nghỉ Việc
Checklist khi nhân viên nghỉ:
1. Mở tất cả Google Sheets quan trọng
2. Share > Tìm email của nhân viên đó
3. Click icon X bên cạnh tên → Remove
4. Lặp lại cho tất cả files
Tự động hóa với Apps Script:
function revokeAccessForUser(userEmail) {
// Lấy tất cả files trong Drive
const files = DriveApp.getFiles();
while (files.hasNext()) {
const file = files.next();
try {
file.revokePermissions(userEmail);
Logger.log('Revoked: ' + file.getName());
} catch(e) {
// File không có quyền của user này, bỏ qua
}
}
}
// Chạy: revokeAccessForUser("nhanvien.nghi@company.com")
Bảo Mật Nâng Cao: Apps Script Kiểm Soát Truy Cập
// Giới hạn truy cập theo giờ (không cho xem ngoài giờ làm việc)
function checkAccessTime() {
const hour = new Date().getHours();
const allowedHours = hour >= 8 && hour <= 18; // 8am - 6pm
if (!allowedHours) {
const ui = SpreadsheetApp.getUi();
ui.alert('Truy cập ngoài giờ làm việc bị hạn chế!');
// Không thể close sheet tự động, nhưng có thể ẩn sheets
const sensitiveSheets = ['BANG_LUONG', 'TAI_CHINH'];
const ss = SpreadsheetApp.getActiveSpreadsheet();
sensitiveSheets.forEach(name => {
try { ss.getSheetByName(name).hideSheet(); } catch(e) {}
});
}
}
// Chạy khi mở file
function onOpen() {
checkAccessTime();
// Tạo menu tùy chỉnh
SpreadsheetApp.getUi()
.createMenu('Bảo Mật')
.addItem('Xem Audit Log', 'viewAuditLog')
.addItem('Export Báo Cáo An Toàn', 'exportSafeReport')
.addToUi();
}
Tóm Tắt Bài 9 — Kiến Thức Cần Nắm
| Chủ Đề | Công Cụ / Tính Năng | Mức Độ Ưu Tiên |
|---|---|---|
| Share Settings | Restricted, Viewer/Commenter/Editor, Disable download | Bắt buộc |
| Protected Ranges | Data > Protect sheets and ranges | Bắt buộc |
| Ẩn Sheets | Right-click > Hide sheet | Khuyến nghị |
| Revision History | File > Version history | Bắt buộc |
| Filter Views | Data > Filter views | Khuyến nghị |
| Audit Log | Apps Script onEdit() | Nâng cao |
| IMPORTRANGE | Cross-file data sharing | Nâng cao |
| Revoke Access | Share > Remove user | Bắt buộc |
Bài tiếp theo: Bài 10 — Google Apps Script cho Tự Động Hóa Nâng Cao (coming soon)
Bài trước: Bài 8: Pivot Table và SUMPRODUCT
📚 Bài Viết Liên Quan
- Template Google Sheets Báo Cáo Bán Hàng Theo Vùng và Đại Lý 2027: Phân Tích Đa Chiều
- Google Sheets Nâng Cao Bài 4: Hàm QUERY - Lọc và Phân Tích Dữ Liệu Chuyên Nghiệp
- Template Google Sheets Quản Lý Phòng Khám và Bệnh Viện Nhỏ 2027
- Template Google Sheets Báo Cáo Tài Chính Tháng và Quý 2027: Tự Động Từ Sổ Sách
Chia sẻ bài viết:
Tuân Hoang
Đội ngũ SheetStore
Bạn thấy bài viết hữu ích?
Đăng ký nhận thông báo khi có bài viết mới.