# Bài 4: Vòng Lặp For

Ở [bài lần trước](https://hocggsheet.com/copy-di-chuyen-dai-o-sang-sheet-khac/) mình đã giới thiệu đến các bạn cách để copy và di chuyển dữ liệu giữa 2 sheet khác nhau. Còn lần này chúng ta sẽ học cách sử dụng vòng lặp, với mục đích hiện tại là: copy dải ô từ một sheet sang nhiều sheet khác cùng lúc. Đây chỉ là ví dụ do mình đặt ra, còn trong thực tế các bạn có thể vận dụng vòng lặp For để giải quyết nhiều nhu cầu khác.

Clip hướng dẫn

#### Nội dung

* Vòng lặp trong App Script
* Cấu trúc vòng lặp For
* Ví dụ
* Code
* Giải thích
* \[QUAN TRỌNG] Khi nào nên dùng và không nên dùng vòng lặp For?

#### Tóm tắt

* Vòng lặp For dùng để…
* Yếu điểm: …

#### Vòng lặp trong App Script

Ngắn gọn mà nói, vòng lặp For giúp chúng ta thực hiện những hành động có tính chật **lặp đi lặp lại nhiều lần**.

Khi ứng dụng App Script vào Google Sheet để xử lí các ô hay dải ô, chắc chắn sẽ có những công việc giống nhau, lặp lại nhiều lần. Thế nên ta có thể dùng vòng lặp For để tiết kiệm thời gian lập trình, cùng như chạy chương trình.

#### Cấu trúc vòng lặp For

| 0123 | for (giá trị đầu; điều kiện cho giá trị cuối; i tăng / i giảm) {câu lệnh;}  |
| ---- | --------------------------------------------------------------------------- |

* Giá trị đầu: thường thì ta dùng biến i là biến chạy trong vòng lặp, và khai báo biến i ở ngay trong vòng lặp (xem ví dụ)
* Điều kiện cho giá trị cuối: trong vòng lặp, ta cho i chạy từ giá trị đầu đến giá trị cuối và sử dụng điều kiện để giới hạn i (xem ví dụ). Tuy nhiên điều kiện không nhất thiết phải liên quan đến i
* i tăng / i giảm: nếu đây là vòng lặp tăng dần, ta dùng i++, tức là sau khi kết thúc 1 lần chạy, thì i sẽ tăng lên 1 đơn vị. Còn nếu đây là vòng lặp giảm dần thì dùng i–, ngược lại với i++ ([xem clip để rõ về i–](https://www.youtube.com/watch?v=IQQgTn5Fvl4))

#### Ví dụ

![Dùng vòng lặp for để copy dải ô A1:D6 đến vị trí F8:I14 trong các sheet: sheet1, sheet2, sheet3, sheet4 cùng lúc](https://i2.wp.com/hocggsheet.com/wp-content/uploads/2018/12/1-1.png?resize=608%2C495\&ssl=1)

Đầu tiên, mình có dải ô A1:D6, và mình muốn copy dải ô này đến vị trí F8:I14 trong các sheet: sheet1, sheet2, sheet3, và sheet4 cùng lúc.

Theo cách làm mà không dùng vòng lặp For thì bạn phải làm như sau:

* Sử dụng 4 biến để khai báo cả 4 sheet từ sheet1 -> sheet4
* Sử dụng hàm copyTo 4 lần để copy từ sheet0 đến các sheet trên

Nếu làm vậy thì chắc chắn là sẽ mất nhiều thời gian. Chúng ta dễ dàng thấy rằng việc khai báo cũng như sử dụng 4 lần hàm copyTo là công việc được lặp đi lặp lại nhiều lần. Thế nên ta hoàn toàn có thể áp dụng vòng lặp ở đây.

#### Code

| 01234567891011 | function myFunction() {  var ss = SpreadsheetApp.getActiveSpreadsheet();  var sheet0 = ss.getSheetByName("sheet0");  var range = sheet0.getRange("A1:D6");    for (var i = 1; i <= 4; i++) {    var sheetI = ss.getSheets()\[i];    var dichI  = sheetI.getRange("F8:I14");    range.copyTo(dichI);  \}}  |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Giải thích

Biến range dùng để lấy vị trí dải ô A1:D6

Trong vòng lặp, mình cho i chạy từ 1 đến khi i <= 4 vì ở đây chúng ta cần copy đến các sheet từ sheet1 -> sheet4

Khi chạy vòng lặp, biến sheetI cập nhật giá trị của i, nghĩa là:

* Khi i = 1, sheetI sẽ thành ss.getSheets()\[1]
* Khi i = 2, sheetI sẽ thành ss.getSheets()\[2]
* Khi i = 3, sheetI sẽ thành ss.getSheets()\[3]
* Khi i = 4, sheetI sẽ thành ss.getSheets()\[4]

Còn biến dichI thì sẽ lấy dải ô F8:I14 trong các sheet từ sheet1 -> sheet4 mỗi khi i tăng lên 1 đơn vị

#### \[QUAN TRỌNG] Khi nào nên dùng và không nên dùng vòng lặp For?

Thật ra, sau khi các bạn đã biết được cách sử dụng vòng lặp For, thì mình hi vọng các bạn có thể đọc được những dòng này, tại vì nó thực sự quan trọng.

Theo mình biết, vòng lặp For có mặt trong hầu hết tất cả ngôn ngữ lập trình (nếu không muốn nói là tất cả). Java Script cũng không ngoại lệ. Nó giúp tiết kiệm thời gian và nhiều thứ khác. Tuy nhiên, vòng lặp có 1 nhược điểm sau đây, ảnh hưởng trực tiếp khi chúng ta ứng dụng vào Google Sheet.

Đó là nó mất nhiều thời gian để chạy chương trình. Lỗi không phải là do bản thân vòng lặp For, mà vì khi kết hợp với các câu lệnh Spreadsheet App Script, nó vô tình tăng thời gian xử lí ô và dải ô. Nói đơn giản như ở ví dụ trên. Khi chúng ta cho i chạy từ 1 đến 4, tức là 4 lần, cộng thêm việc sử dụng hàm getSheets và getRange, thì nó cứ phải lấy vị trí của các sheet và dải ô đến 8 lần (2×4=8).

Đối với đoạn code chỉ có 8 lần lấy sheet hay dải ô, thì không có gì đáng nói. Nhưng khi áp dụng vào khoảng 100 dải ô hay 100 ô, tức là getRange 100 lần, thì sẽ bắt đầu nảy sinh vấn đề về thời gian. Chương trình của các bạn lúc đó sẽ chạy rất chậm. Còn với dữ liệu lớn hơn, vài trăm đến vài ngàn hay vài chục ngàn thì thôi khỏi nói rồi, App Script sẽ tự động dừng sau 6 phút.
