> For the complete documentation index, see [llms.txt](https://javascriptuse.gitbook.io/javascript/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://javascriptuse.gitbook.io/javascript/advanced/bai-12-lien-ket-google-form-sheet-apps-script.md).

# Bài 12: Liên kết Google Form – Sheet – Apps Script

Google Form và Google Sheet là 2 dịch vụ quá đỗi thân thuộc với người dùng. Nhưng còn liên kết chúng với Apps Script và ứng dụng trong thực tiễn như thế nào thì hôm nay HocGgSheet.com sẽ giới thiệu đến với các bạn.

### File luyện tập

Tạo bản sao về Drive của bạn để xem và chỉnh sửa code nhé

<https://docs.google.com/spreadsheets/d/1oUruazoQd4l5dQBy97-HpNCsxV2Rminy25yjpu4mnJw/edit?usp=sharing>

Google Form:\
<https://goo.gl/forms/AV4rw3fhxqYjfWFF3>

### Mô tả ví dụ và Chuẩn bị

![](https://i2.wp.com/hocggsheet.com/wp-content/uploads/2019/01/1-4.jpg?resize=300%2C183\&ssl=1)

Cho 1 form đơn giản như hình trên và liên kết với sheet “answer” trong file Google Sheet như sau (có sẵn một vài mẫu):

![](https://i2.wp.com/hocggsheet.com/wp-content/uploads/2019/01/4-1.jpg?fit=696%2C319\&ssl=1)

Ở file Google Sheet, mình tạo thêm 1 sheet tên là “database”, 2 cột “Phê duyệt” và “Ngày chỉnh sửa”. Mục đích của chúng là:

* Phê duyệt: Mỗi khi chọn “Duyệt” hoặc “Không duyệt” thì dòng đó sẽ được chuyển sang “database”. Ví dụ, chọn C6 là “Duyệt”, thì ta sẽ di chuyển dòng 6 sang “database”
* Ngày chỉnh sửa: Mỗi khi chọn giá trị “Phê duyệt”, thời điểm bao gồm ngày và giờ hiện tại sẽ được cập nhật ghi ra vào ô cùng hàng trong cột D

#### Xác thực dữ liệu cho cột C “Phê duyệt”

Ta thấy “Phê duyệt” có 2 giá trị là “Duyệt” và “Không duyệt”. Vậy nên có thể xác thực dữ liệu cho nó

Xác thực dữ liệu cho “Phê duyệt”

![](https://i0.wp.com/hocggsheet.com/wp-content/uploads/2019/01/3-3.jpg?fit=696%2C259\&ssl=1)

Các bạn lưu ý, chúng ta không cần Xác thực cho cả cột C. Mà chỉ cần Xác thực cho *Những dòng hiện có* và *Dòng trắng tiếp theo*. Ví dụ, mình có 9 dòng đầu là Những dòng hiện có, vậy thì chỉ cần Xác thực cho 9 dòng đó và dòng thứ 10. Mục đích là để khi có người gửi form mới, bản ghi mới sẽ tự động lấy định dạng (xác thực) của dòng trước

### Code hoàn chỉnh

| 0123456789101112131415 | function onEdit() {   var ss = SpreadsheetApp.getActiveSpreadsheet();   var answer = ss.getSheetByName('answer');   var dbSheet = ss.getSheetByName('database');   var activeCell = ss.getActiveCell();     if (activeCell.getColumn() == 3 && (activeCell.getValue() == "Duyệt" \|\| activeCell.getValue() == "Không duyệt")) {     var currentTime = new Date();     activeCell.offset(0, 1).setValue(currentTime);           var luu = answer.getRange(activeCell.getRow(), 1, 1, 4).getValues();         dbSheet.getRange(dbSheet.getLastRow()+1, 1, 1, 4).setValues(luu);     answer.deleteRow(activeCell.getRow());   }} |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

### Giải thích

#### 1. Biến toàn cục

* answer là sheet “answer”
* dbsheet là sheet “database”
* activeCell là ô chúng ta đang bấm vào

#### 2. Chương trình chính

Sử dụng trigger onEdit() để khi thay đổi giá trị ở cột “Phê duyệt” thì sẽ tiến hành chạy chương trình

| 01 | if (activeCell.getColumn() == 3 && (activeCell.getValue() == "Duyệt" \|\| activeCell.getValue() == "Không duyệt")) { |
| -- | -------------------------------------------------------------------------------------------------------------------- |

“Phê duyệt” nằm ở cột C, tức cột 3, và nếu nó bằng “Duyệt” hoặc “Không duyệt” thì sẽ lưu bản ghi vào trong database

| 012 | var currentTime = new Date();activeCell.offset(0, 1).setValue(currentTime); |
| --- | --------------------------------------------------------------------------- |

Đây là cách để lấy thời điểm hiện tại ra và ghi vào ô bên cột D. Hàm offset có chức năng dóng hàng dóng cột. Ở đây, nó dóng sang ô cùng hàng với activeCell bên cột D

3 câu lệnh cuối là kỹ thuật [Di chuyển dòng từ sheet này sang sheet khác](https://hocggsheet.com/di-chuyen-dong-tu-sheet-nay-sang-sheet-khac-hoc-app-script-sheet/)

| 01 | var luu = answer.getRange(activeCell.getRow(), 1, 1, 4).getValues(); |
| -- | -------------------------------------------------------------------- |

Biến luu dùng để ghi giá trị của dải ô bao gồm các ô cùng hàng với activeCell

| 01 | dbSheet.getRange(dbSheet.getLastRow()+1, 1, 1, 4).setValues(luu); |
| -- | ----------------------------------------------------------------- |

Dòng này để ghi dải ô của biến luu vào Dòng cuối cùng tiếp theo trong sheet “database”

| 01 | answer.deleteRow(activeCell.getRow()); |
| -- | -------------------------------------- |

Sau cùng là xóa dòng đã duyệt bên sheet “answer”

### Ứng dụng Liên kết Form – Sheet – Apps Script

Các bạn có thể ứng dụng ví dụ trên vào các trường hợp sau:

* Xử lí dữ liệu văn phòng
* Tạo Cơ sở dữ liệu (Database)
* Xét duyệt nội dung


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://javascriptuse.gitbook.io/javascript/advanced/bai-12-lien-ket-google-form-sheet-apps-script.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
