Hướng dẫn

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

Tuân HoangTuân Hoang
14 phút đọc
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

  1. Click nút "Share" (góc trên phải)
  2. Panel "Share with people and groups" xuất hiện
  3. Nhập email từng người → chọn quyền: Viewer / Commenter / Editor
  4. Phần "General access": đảm bảo là "Restricted"
  5. Click "Done"

Phân Biệt 3 Vai Trò

Quyền HạnViewerCommenterEditor
Xem nội dung
Tải xuốngCó*Có*
Thêm commentKhông
Sửa nội dungKhôngKhông
Thêm/xóa sheetKhôngKhôngCó**
Share thêm ngườiKhôngKhôngCó**

*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ăngMức Độ Ưu Tiên
Share SettingsRestricted, Viewer/Commenter/Editor, Disable downloadBắt buộc
Protected RangesData > Protect sheets and rangesBắt buộc
Ẩn SheetsRight-click > Hide sheetKhuyến nghị
Revision HistoryFile > Version historyBắt buộc
Filter ViewsData > Filter viewsKhuyến nghị
Audit LogApps Script onEdit()Nâng cao
IMPORTRANGECross-file data sharingNâng cao
Revoke AccessShare > Remove userBắ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

Chia sẻ bài viết:

Tuân Hoang

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.

Nhận thông báo khi có bài viết mới. Không spam, hứa luôn! 😊

Bình luận (0)

Vui lòng đăng nhập để tham gia thảo luận