Có phải Do While...Loop chỉ là 1 dạng viết tắt của For.. Next?

Liên hệ QC

LinDan

Thành viên tiêu biểu
Tham gia
8/2/12
Bài viết
412
Được thích
111
Tôi chưa thạo lập trình lắm, phần vòng lặp sau khi đọc tôi có cảm giác Do While...Loop và For.. Next hình như bản chất chỉ là 1 (tức là Do While...Loop nó chỉ viết tắt cho gọn) phải không các bác.

Liệu có ví dụ nào thì dùng Do While...Loop nó sẽ ưu việt hơn hẳn dùng For.. Next không?
 
Tôi chưa thạo lập trình lắm, phần vòng lặp sau khi đọc tôi có cảm giác Do While...Loop và For.. Next hình như bản chất chỉ là 1 (tức là Do While...Loop nó chỉ viết tắt cho gọn) phải không các bác.

Liệu có ví dụ nào thì dùng Do While...Loop nó sẽ ưu việt hơn hẳn dùng For.. Next không?

Người ta không làm thừa cái gì đâu bạn à.

Hai dạng lặp:

For I = 1 To N
....
Next I

Do While I <= N
....
I = I +1
Loop

Nếu trong mỗi vòng lặp N có thể thay đổi thì phải dùng Do While.
Với For..Next thì dù thay đổi N thì nó vẫn lấy giá trị ban đầu để làm điều kiện lặp. Ví dụ ban đầu N= 10, trong quá trình lặp N = 100 thì For..Next vẫn đang hiểu N = 10.
Vậy nếu N là không đổi thì nên dùng For..Next tốc độ sẽ nhanh hơn vì VBA không tính lại biểu thức trong N ở mỗi vòng lặp.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi chưa thạo lập trình lắm, phần vòng lặp sau khi đọc tôi có cảm giác Do While...Loop và For.. Next hình như bản chất chỉ là 1 (tức là Do While...Loop nó chỉ viết tắt cho gọn) phải không các bác.

Liệu có ví dụ nào thì dùng Do While...Loop nó sẽ ưu việt hơn hẳn dùng For.. Next không?
Về bản chất, 2 vòng lặp For...Next và Do While...Loop (hay Do...Loop While, Do...Loop Until) là hoàn toàn khác nhau:
- Vòng lặp For...Next là vòng lặp có số lần biết trước. Chúng ta sử dụng vòng lặp này khi đã biết trước (hoặc có thể tính được) số lần lặp.
- Các vòng lặp Do... là các vòng lặp có số lần lặp chưa biết trước, nó chỉ dừng khi gặp một điều kiện phù hợp nào đó, quy định sau từ khóa While hoặc Until:
+ Vòng lặp Do While...Loop hoặc Do...Loop While sẽ chạy khi điều kiện sau While còn đúng, chỉ khác nhau là kiểm tra điều kiện rồi mới chạy lệnh hay ngược lại.
+ Vòng lặp Do...Loop Until sẽ chạy cho đến khi điều kiện sau Until đúng.
Như vậy, khi nào bạn biết được số lần lặp trước thì dùng For..., ngược lại thì dùng Do...
Tuy nhiên trong một số trường hợp, ta có thể "chế biến" qua lại giữa 2 vòng lặp này. Chẳng hạn:
1. Câu lệnh:
PHP:
For i=1 To N
     'Dãy lệnh'
Next
Có thể thay bởi dãy lệnh:
PHP:
i=1
Do While i<=N
     'Dãy lệnh'
    i=i+1
Loop
2. Câu lệnh:
PHP:
Do While Điều_kiện
     'Dãy lệnh'
Loop
Có thể thay bởi câu lệnh:
PHP:
For i=1 to N
    'Dãy lệnh'
    If Điều_kiện then Exit For
Next
 
Upvote 0
Sẵn đây, mình xin các bạn giải giúp bài tập sau

Viết dùm hàm tự tạo đễ cho biết số ngày chủ nhật trong tháng, một khi ta được cung cấp 1 ngày cụ thể nào đó của thế kỷ trước?

PHP:
 Function SoNgayCN( Dat As Date) As Byte
  '. . . . . . . . ' 
 End Function
 
Upvote 0
Viết dùm hàm tự tạo đễ cho biết số ngày chủ nhật trong tháng, một khi ta được cung cấp 1 ngày cụ thể nào đó của thế kỷ trước?
Chú SA coi có làm được gì không em viết đại

Hàm này sai:
PHP:
Public Function SoNgayCNDoLoop(Dat As Date) As Byte
  Dim i As Byte, nsun As Byte
  Do
    i = i + 1
    If Weekday(DateSerial(Year(Dat), Month(Dat), i)) = 1 Then
      nsun = nsun + 1
    Else
      If Day(DateSerial(Year(Dat), Month(Dat) + 1, 0)) = i Then Exit Do
    End If
  Loop
  SoNgayCNDoLoop = nsun
End Function
Thử với ngày 1/9/2012 sẽ biết
Ngoài ra, mấy cái As Byte, As Integer nên dẹp đi cho rồi ---> Tất cả chuyển thành biến Long là ngon nhất (Dim i As Long, nsun As Long)... Kế cả biến Dat, nếu có thể cũng nên chuyển thành biến Long luôn
 
Lần chỉnh sửa cuối:
Upvote 0
Qui trình nên là vầy:

(1) Xác lập ngày đầu tháng từ tham số mà ta vừa nhận;

(Việc này nhờ hàm DateSerial(..., ... ,1) trong VBA)

(2) Tạo vòng lặp For . . . Next hay Do . . . . Loop để duyệt từ ngày đầu của tháng đến hết ngày 25 tháng đó xem có bao nhiêu ngày CN
 
Upvote 0
Về bản chất, 2 vòng lặp For...Next và Do While...Loop (hay Do...Loop While, Do...Loop Until) là hoàn toàn khác nhau:
- Vòng lặp For...Next là vòng lặp có số lần biết trước. Chúng ta sử dụng vòng lặp này khi đã biết trước (hoặc có thể tính được) số lần lặp.
- Các vòng lặp Do... là các vòng lặp có số lần lặp chưa biết trước, nó chỉ dừng khi gặp một điều kiện phù hợp nào đó, quy định sau từ khóa While hoặc Until:
+ Vòng lặp Do While...Loop hoặc Do...Loop While sẽ chạy khi điều kiện sau While còn đúng, chỉ khác nhau là kiểm tra điều kiện rồi mới chạy lệnh hay ngược lại.
+ Vòng lặp Do...Loop Until sẽ chạy cho đến khi điều kiện sau Until đúng.
Như vậy, khi nào bạn biết được số lần lặp trước thì dùng For..., ngược lại thì dùng Do...
Tuy nhiên trong một số trường hợp, ta có thể "chế biến" qua lại giữa 2 vòng lặp này. Chẳng hạn:
1. Câu lệnh:
PHP:
For i=1 To N
     'Dãy lệnh'
Next
Có thể thay bởi dãy lệnh:
PHP:
i=1
Do While i<=N
     'Dãy lệnh'
    i=i+1
Loop
2. Câu lệnh:
PHP:
Do While Điều_kiện
     'Dãy lệnh'
Loop
Có thể thay bởi câu lệnh:
PHP:
For i=1 to N
    'Dãy lệnh'
    If Điều_kiện then Exit For
Next
Em nghĩ mọi vòng lặp đều có bản chất giống nhau, đều lặp đi lặp lại số hành động cần làm
có khác chăng ở đây là cách thức lập
thử so sánh vòng lập mà ĐK không biết trước số vòng lặp thì có vòng do While, Do ... Loop While, do... Loop Until
do While, Do ... Loop While đều là số vòng lặp không biết trước số lần lặp

Nhưng với do While thì kiểm tra giá trị trước khi lặp có nghĩa là có thể không chạy vào vòng lặp nếu đk không thoả
còn với Do ... Loop While thì làm trước kiểm tra điều kiện sau nên ít nhất sẽ lặp được 1 lần nếu đk đầu tiên bị sai

còn với Do ... Loop Until tương tự như Do ... Loop While nhưng sẽ kết thúc khi điều kiện đúng

Còn vòng lặp For chẳng qua là trường hợp đặt biệt của vòng lặp While
với số lần lặp được biết trướctự động tăng hay giản biến điều kiện ngay trong vòng lặp(Nên hạn chế được việc treo máy vì đk)
 
Upvote 0
Ngoài ra, mấy cái As Byte, As Integer nên dẹp đi cho rồi ---> Tất cả chuyển thành biến Long là ngon nhất (Dim i As Long, nsun As Long)... Kế cả biến Dat, nếu có thể cũng nên chuyển thành biến Long luôn

Sao lại dẹp đi ah, thấy các sách đều nói phải chọn đúng loại khai báo,
Chỗ này không hiểu , nhờ ndu... giải thích
 
Upvote 0
Em nghĩ mọi vòng lặp đều có bản chất giống nhau, đều lặp đi lặp lại số hành động cần làm
có khác chăng ở đây là cách thức lập
thử so sánh vòng lập mà ĐK không biết trước số vòng lặp thì có vòng do While, Do ... Loop While, do... Loop Until
do While, Do ... Loop While đều là số vòng lặp không biết trước số lần lặp

Nhưng với do While thì kiểm tra giá trị trước khi lặp có nghĩa là có thể không chạy vào vòng lặp nếu đk không thoả
còn với Do ... Loop While thì làm trước kiểm tra điều kiện sau nên ít nhất sẽ lặp được 1 lần nếu đk đầu tiên bị sai

còn với Do ... Loop Until tương tự như Do ... Loop While nhưng sẽ kết thúc khi điều kiện đúng

Còn vòng lặp For chẳng qua là trường hợp đặt biệt của vòng lặp While
với số lần lặp được biết trướctự động tăng hay giản biến điều kiện ngay trong vòng lặp(Nên hạn chế được việc treo máy vì đk)

Vậy thầy? thầy cho ví dụ cụ thể đi ạ,
Chứ các thành viên nói kiểu này rối như canh hẹ lun, Túm lại FOR làm gì khi nào dùng, Do While, Loop khi nào dùng, vì nếu bản chất giống nhau thì cứ dùng đại phải không?
Thầy nói treo máy vì đk là sao, nghĩa là cứ có đk là treo máy ah?
 
Upvote 0
Sao lại dẹp đi ah, thấy các sách đều nói phải chọn đúng loại khai báo,
Chỗ này không hiểu , nhờ ndu... giải thích
Tại sao phải dùng biến Long thay cho Integer và Byte, ở trên GPE đã nói nhiều lần rồi! Bạn tìm đi
Cứ hãy nhớ thuộc lòng rằng: ĐÓ LÀ CHÂN LÝ
 
Upvote 0
Tại sao phải dùng biến Long thay cho Integer và Byte, ở trên GPE đã nói nhiều lần rồi! Bạn tìm đi
Cứ hãy nhớ thuộc lòng rằng: ĐÓ LÀ CHÂN LÝ

hehe, sách mới là chân lý ah,
Vấn đề là khai báo ở đây Dim i As Byte, nsun As Byte dùng để chứa ngày (chắc chắn chỉ 1--31) và nsun chắc chắn là nhỏ hơn 10 vậy dùng Byte là chuẩn ah,
Vậy thì tác giả bài đó làm đúng khai đó ah (?)
Không rõ ý a sao?
Chập chững VBA , nên theo sách thôi,... , mong mọi người chỉ cho cách học chuẩn
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy thầy? thầy cho ví dụ cụ thể đi ạ,
Chứ các thành viên nói kiểu này rối như canh hẹ lun, Túm lại FOR làm gì khi nào dùng, Do While, Loop khi nào dùng, vì nếu bản chất giống nhau thì cứ dùng đại phải không?
Thầy nói treo máy vì đk là sao, nghĩa là cứ có đk là treo máy ah?
Ví dụ vòng lặp sẽ treo máy:
Dim i as Long
i=1
Do Until i=100

i= i + 2
' ....

Loop

 
Upvote 0
May quá, em cũng đang cần tìm hiểu về cái này thì tìm thấy bài http://www.giaiphapexcel.com/forum/showthread.php?13255-Biến-integer-biến-long-cái-nào-nhanh-hơn , bác Vodòix vào đây xem nhé

tôi đã đọc,

Vấn đề không phải thời gian (vì bài này tính có trong tháng), hay tài nguyên (vì bài này quá nhỏ, sử dụng không nhiều biến),
mà còn thể hiện sự chuẩn dữ liệu: Dữ liệu đến đâu khai báo đến đó như thế mới giúp kiểm soát lỗi tốt hơn cho biến,
Nói cách khác, cứ theo sách thì bạn sẽ hiểu đúng kiểu loại dữ liệu hơn, chứ không phải vô tiền khoáng hậu kiểu dùng số đại thế, cái gì sinh ra cũng có lý của nó
 
Upvote 0
Ví dụ vòng lặp sẽ treo máy:
Dim i as Long
i=1
Do Until i=100

i= i + 2
' ....

Loop


cám ơn bạn

Cái này thì rõ ai cũng biết ah, vì đk đặt sai - lỗi sai do người viết

theo thầy Phi... các vòng lặp đó giống nhau, còn vòng lặp DoWhile..Loop Until... cứ có đk là treo máy (nguyên văn: "Nên hạn chế được việc treo máy vì đk")

và muốn biết khi nào thì dùng cái nào ah (?)
 
Upvote 0
Như mình trước đây, khi mới có những hàm ngây ngô đầu tiên & chưa thể có GPE.COM, thì những SF của mình còn buồn cười hơn í chứ.

& đến giờ, khi về lại cơ quan cũ, dỡ những macro thời xưa của mình, mình mới thấy nhờ GPE.COM mà mình mở mang đầu óc ra nhiều. . . .

Mà mình cũng không ngờ bài tập nhỏ của mình làm sôi nổi lại sự tranh luận gây gắt khi xưa;

/-)úng là: " 3 thằng Do thái không bằng 1 thằng VN; Nhưng 3 thằng VN không bằng 1 thằng Nga!"


Để khỏi mang tội SPAM, mình xin gợi í thêm:

Trong vòng lặp ta nên có 2 điều kiện để thoát ngay vòng lặp:

(1) Thoát ngay khi đã sang tháng khác (Cái ni đương nhiên & dễ);
(2) Thoát khi tìm ra CN là ngày 25 trở đi;
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Ví dụ vòng lặp sẽ treo máy:
Dim i as Long
i=1
Do Until i=100

i= i + 2
' ....

Loop


Không phải treo mà nó vẫn làm việc đến khi mất điện :d.

Điều kiện của bạn không đúng. I = 1, sau đó tăng mỗi vòng lắm là I = I + 2 ==>

I =
1
3
5
Toàn số lẻ, nên Until I = 100 không bao giờ xảy ra.
 
Upvote 0
hehe, sách mới là chân lý ah,
Vấn đề là khai báo ở đây Dim i As Byte, nsun As Byte dùng để chứa ngày (chắc chắn chỉ 1--31) và nsun chắc chắn là nhỏ hơn 10 vậy dùng Byte là chuẩn ah,
Vậy thì tác giả bài đó làm đúng khai đó ah (?)
Không rõ ý a sao?
Chập chững VBA , nên theo sách thôi,... , mong mọi người chỉ cho cách học chuẩn
Tôi nói bạn không tin, bạn đọc trong quyển sách nào đó và bạn cho là chân lý thì bạn cứ việc tin... Tôi không ép!
Còn những ai muốn tiếp tục "cày" với VBA hay VB thì cứ việc thuộc lòng rằng: hãy thay kiểu biến Byte hoặc Integer bằng kiểu biến Long
Vậy đi nha!
 
Upvote 0
theo thầy Phi... các vòng lặp đó giống nhau, còn vòng lặp DoWhile..Loop Until... cứ có đk là treo máy (nguyên văn: "Nên hạn chế được việc treo máy vì đk")

Do Phi viết sai. Đúng ra theo ý đó, sẽ phải viết là "hạn chế được vòng lặp vô tận do không có điều kiện thoát hoặc điều kiện thoát sai". Vòng lặp vô tận khác với treo máy. Vòng lặp vô tận chỉ buộc Excel chạy mãi chạy hoài thôi.

Nhưng!
ý đó chưa đúng!

Không đặt điều kiện thoát, hoặc đặt điều kiện thoát không đúng để xảy ra lỗi vòng lặp vô tận, là lỗi người viết code học chưa tới, chứ không phải lỗi của Do mà chê Do không dùng.

Người ta chọn Do Loop hay chọn For - Next, là tuỳ từng bài toán cụ thể.

Đối với cá nhân tôi, chỉ dùng Do khi chưa biết trước số vòng lặp. Dùng For - Next, có những cái lợi:

- Có thể lồng nhiều vòng For vào nhau để đơn giản hoá code thực thi bên trong.
- Cũng có thể đặt điều kiện để thoát, không cần chạy đủ số vòng lặp quy định.
- Và như Tuân nói ở bài 2, For - Next nhanh hơn.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom