Các câu đố, bài tập nhằm ôn tập & bổ sung kiến thức căn bản VBA

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,720
Giới tính
Nam
Với tinh thần chơi mà học, học mà chơi, nên tôi đã mở ra topic này, hy vọng các thành viên tham gia, nhất là các thành viên mới biết về VBA.

Sau đây là câu hỏi đầu tiên:

Câu hỏi 1: Bằng phương pháp nào nhanh nhất để tìm ra ô nào trong một cột chứa một điều kiện.

Tôi có 1 file Excel 2007, với cột A, từ A1 đến A1048576 đều có giá trị.

Bằng phương pháp nào nhanh nhất (dùng mảng, dùng For Each v.v...) để tìm ra ô nào trong cột A chứa chữ "Nghia", đồng thời với ô ở cột B tương ứng nhập giá trị "OK" vào đó?

Ví dụ tìm thấy trong ô A2 có giá trị là "Nghia" thì ô B2 nhập vào "OK".

Hiện tại, đáp án nhanh nhất mà tôi có được đã gửi mail riêng (nhằm ghi lại thời gian gửi, để tránh nói ăn gian).

Để tiện việc theo dõi các câu đố, các bài tập tôi đã tạo ra topic này các bạn click vào đây:

Các link của topic "Các câu đố, bài tập nhằm ôn tập & bổ sung kiến thức căn bản VBA"
 

File đính kèm

Lần chỉnh sửa cuối:
Câu hỏi 4: Sau khi chạy vòng lặp, i bằng bao nhiêu?

Đây là câu hỏi dành cho các thành viên mới học VBA.

Tôi có thủ tục sau:

Mã:
Sub ForNext()
[COLOR=#0000cd][B]    Dim i As Long[/B][/COLOR]
    For [COLOR=#ff0000][B]i = 1 To 1000[/B][/COLOR]
        ''Your code here
    Next
End Sub

Các bạn nhìn vào code, khoan thử vội, đố các bạn biết sau khi chạy code, i sẽ có giá trị là bao nhiêu?
 
Lần chỉnh sửa cuối:
Upvote 0
Đây là câu hỏi dành cho các thành viên mới học VBA.

Tôi có thủ tục sau:

Mã:
Sub ForNext()
[COLOR=#0000cd][B]    Dim i As Long[/B][/COLOR]
    For [COLOR=#ff0000][B]i = 1 To 1000[/B][/COLOR]
        ''Your code here
    Next
End Sub

Các bạn nhìn vào code, khoan thử vội, đố các bạn biết sau khi chạy code, i sẽ có giá trị là bao nhiêu?
Sau vòng lặp cuối cùng, i=1000, tuy nhiên sau khi chạy "Your code here" có lệnh next nên sau khi chạy thì i sẽ tăng lên 1 tức là i=1001.
 
Upvote 0
Đây là câu hỏi dành cho các thành viên mới học VBA.

Tôi có thủ tục sau:

Mã:
Sub ForNext()
[COLOR=#0000cd][B]    Dim i As Long[/B][/COLOR]
    For [COLOR=#ff0000][B]i = 1 To 1000[/B][/COLOR]
        ''Your code here
    Next
End Sub

Các bạn nhìn vào code, khoan thử vội, đố các bạn biết sau khi chạy code, i sẽ có giá trị là bao nhiêu?

Đây cũng chính là chỗ e khó hiểu nhất. Mặc dù mình cho nó chạy tới 1000 mà sau khi hết vòng lặp nó luôn luôn là 1000+1.
Mong a giải thích cho e hiểu chỗ này được không ah !
 
Upvote 0
Đây là câu hỏi dành cho các thành viên mới học VBA.

Tôi có thủ tục sau:

Mã:
Sub ForNext()
[COLOR=#0000cd][B]    Dim i As Long[/B][/COLOR]
    For [COLOR=#ff0000][B]i = 1 To 1000[/B][/COLOR]
        ''Your code here
    Next
End Sub

Các bạn nhìn vào code, khoan thử vội, đố các bạn biết sau khi chạy code, i sẽ có giá trị là bao nhiêu?
Mặc định i = 0 trước For được xem là 1 giá trị hay không?
Còn lại là như 2 bạn trên đã trả lời, nếu cộng luôn i = 0 thì tổng cộng có 1002 giá trị.
 
Upvote 0
Đây cũng chính là chỗ e khó hiểu nhất. Mặc dù mình cho nó chạy tới 1000 mà sau khi hết vòng lặp nó luôn luôn là 1000+1.
Mong a giải thích cho e hiểu chỗ này được không ah !

Thì "nó" gọi là "code" mà, đâu phải NGƯỜI
Nó phải cộng 1 vào và so sánh nó mới biết thằng mới cộng vào lớn hơn giới hạn chứ
Tóm lại: Giải thuật For... Next nó là như vậy. Nếu không thích có thể dùng Do... Loop
 
Upvote 0
Cám ơn các "tềnh iu" đã trả lời, thế thì với các bạn, trong code của tôi, các bạn bằng thủ tục nào để xác định được i vậy? Ý tôi nói các bạn đặt thủ tục nào, tại đâu trong code của tôi thủ tục của bạn để nhận biết được i?
 
Upvote 0
Cám ơn các "tềnh iu" đã trả lời, thế thì với các bạn, trong code của tôi, các bạn bằng thủ tục nào để xác định được i vậy? Ý tôi nói các bạn đặt thủ tục nào, tại đâu trong code của tôi thủ tục của bạn để nhận biết được i?
Em dùng Msgbox i sau next
 
Upvote 0
Không phải tôi bắt bẻ bạn. Cái khó là tuỳ theo cách học mà vấn đề X đối với A là cơ bản trong khi đối với B là sâu.
Tốt hơn hết là định nghĩa cái giới hạn của cơ bản trước đã.
Đối với tôi chẳng hạn, chỉ riêng việc cóp range ra array để xử lý đã thuộc về cao cấp rồi.
Anh Vetmini đã có những gợi ý (trong topic hỏi cơ bản về VBA của tungnguyen_tk và topic này) mình cảm thấy "rất cần" cho những người đang đi những bước cơ bản với VBA (như mình). Trong topic này, nên chăng có những giới hạn, những chỉ mục cơ bản, cái cơ bản có sự lựa chọn, có quản lý và có định hướng.
Ở một số diễn đàn có những Event để thành viên theo dõi, tham gia. Như những câu đố hàng năm của Thầy Mỹ vào mỗi dịp sinh nhật GPE, thành viên hào hứng tham gia và mỗi kết quả là những bài học bổ ích. Topic Đối vui căn bản về VBA này cũng vậy, mong là anh Nghĩa và các Thầy duy trì thường xuyên, cập nhật câu hỏi mỗi ngày.
Với tinh thần chơi mà học, học mà chơi, nên tôi đã mở ra topic này, hy vọng các thành viên tham gia, nhất là các thành viên mới biết về VBA.
....
Hiện tại, đáp án nhanh nhất mà tôi có được đã gửi mail riêng (nhằm ghi lại thời gian gửi, để tránh nói ăn gian).
Có thể mở Tag HIDE trên GPE được không, nếu được thì thuận tiện hơn khi gửi bài (chỉ có BQT mới xem được).
 
Lần chỉnh sửa cuối:
Upvote 0
Đây cũng chính là chỗ e khó hiểu nhất. Mặc dù mình cho nó chạy tới 1000 mà sau khi hết vòng lặp nó luôn luôn là 1000+1.
Mong a giải thích cho e hiểu chỗ này được không ah !
Xin giải thích một lần nữa về vòng lặp For: Xét vòng lặp For như sau:
[GPECODE=vb]For i = Dau To Cuoi
'Dãy lệnh
Next[/GPECODE]
Vòng lặp For này sẽ được thực hiện thông qua một số bước như sau:
[NOTE2=""]Bước 1: Gán i = Dau
Bước 2: Kiểm tra điều kiện i <= Cuoi
- Nếu thỏa mãn thì qua Bước 3;
- Nếu không thỏa mãn thì thoát khỏi vòng lặp.
Bước 3:
3.1. Thực hiện Dãy lệnh ở trong vòng For
3.2. Gán i = i + 1 và quay lại Bước 2.[/NOTE2]
Do đó:
- Nếu Dau > Cuoi thì Dãy lệnh trong vòng lặp không được thực hiện và kết quả là i = Dau (do đã được gán từ Bước 1)
- Nếu Dau <= Cuoi thì Dãy lệnh được thực hiện ít nhất 1 lần và kết quả là i = Cuoi + 1, vì ở lần cuối cùng Dãy lệnh được thực hiện thì i = Cuoi, sau đó tại bước 3.2, phép gán i = i + 1 sẽ cho i = Cuoi + 1 (đương nhiên sau phép gán này thì điều kiện ở Bước 2 bị vi phạm nên vòng lặp kết thúc).

Nhân đây, xin đố các bạn: Nếu thay vòng lặp trên bởi vòng lặp sau thì sau khi chạy, i sẽ bằng bao nhiêu:
[GPECODE=vb]For i = Dau To Cuoi Step n
'Dãy lệnh
Next[/GPECODE]
Cụ thể hơn là:
[GPECODE=vb]For i = 1 To 1000 Step 6
'Dãy lệnh
Next[/GPECODE]
(tất nhiên là theo đúng tinh thần của topic này đưa ra: Đố vui căn bản về VBA)
 
Upvote 0
Để cho có hệ thống, nghiaphuc vui lòng ngắt phần này ra thành bài mới và đánh số bài đố tiếp tục được không ạ? cám ơn!

====================

Đọc xong xin vui lòng xóa bài này!
Thực ra thì câu đố của em chỉ là phát triển, hay nói chính xác là tổng quát câu 5 của anh thôi mà, nó không phải là một câu hỏi mới, vì nguyên lý hoạt động của vòng For là chỉ có một, và câu 5 của anh chỉ là trường hợp riêng trong câu của em, ứng với n = 1 thôi mà.
 
Upvote 0
Xin giải thích một lần nữa về vòng lặp For: Xét vòng lặp For như sau:
[GPECODE=vb]For i = Dau To Cuoi
'Dãy lệnh
Next[/GPECODE]
Vòng lặp For này sẽ được thực hiện thông qua một số bước như sau:
[NOTE2=""]Bước 1: Gán i = Dau
Bước 2: Kiểm tra điều kiện i <= Cuoi
- Nếu thỏa mãn thì qua Bước 3;
- Nếu không thỏa mãn thì thoát khỏi vòng lặp.
Bước 3:
3.1. Thực hiện Dãy lệnh ở trong vòng For
3.2. Gán i = i + 1 và quay lại Bước 2.[/NOTE2]
Do đó:
- Nếu Dau > Cuoi thì Dãy lệnh trong vòng lặp không được thực hiện và kết quả là i = Dau (do đã được gán từ Bước 1)
- Nếu Dau <= Cuoi thì Dãy lệnh được thực hiện ít nhất 1 lần và kết quả là i = Cuoi + 1, vì ở lần cuối cùng Dãy lệnh được thực hiện thì i = Cuoi, sau đó tại bước 3.2, phép gán i = i + 1 sẽ cho i = Cuoi + 1 (đương nhiên sau phép gán này thì điều kiện ở Bước 2 bị vi phạm nên vòng lặp kết thúc).

Nhân đây, xin đố các bạn: Nếu thay vòng lặp trên bởi vòng lặp sau thì sau khi chạy, i sẽ bằng bao nhiêu:
[GPECODE=vb]For i = Dau To Cuoi Step n
'Dãy lệnh
Next[/GPECODE]
Cụ thể hơn là:
[GPECODE=vb]For i = 1 To 1000 Step 6
'Dãy lệnh
Next[/GPECODE]
(tất nhiên là theo đúng tinh thần của topic này đưa ra: Đố vui căn bản về VBA)

i=dau+INT((cuoi-dau+1)/n)*n+n
Trường hợp n=6, dau=1, cuoi=1000=>i=1002
 
Lần chỉnh sửa cuối:
Upvote 0
Mặc định i = 0 trước For được xem là 1 giá trị hay không?
Còn lại là như 2 bạn trên đã trả lời, nếu cộng luôn i = 0 thì tổng cộng có 1002 giá trị.
Đó là nhận xét của leonguyenz, tuy nhiên dù là trước nó có là 0 hay bất cứ số nào (0, 76, 100, 999, v.v...) nó luôn trả về giá trị i = giá trị cuối + 1.

Chẳng hạn:

Mã:
Sub test()
    For i = [COLOR=#ff0000]999 [/COLOR]To 1000
    Next
    Debug.Print i
End Sub

Các bạn có thể thay 999 bằng 1 số bất kỳ miễn đừng lớn hơn 1000 là được, riêng trường hợp lớn hơn 1000 thì i sẽ bằng chính số đó.
 
Upvote 0
Mình có một thắc mắc tại sao MsgBox i có kết quả là 1003?
Đúng vậy, khi Step là 6 thì bắt đầu nó lặp như sau

Với For i = 1 to 1000 Step 6

vòng lặp đầu tiên nó sẽ có giá trị i = 1
vòng thứ 2 nó có giá trị i = 7
vòng thứ 3 nó có giá trị i = 13
....

Nói chung là căn cứ vào giá trị đầu nó sẽ chạy ở vòng lặp đầu tiên, sau đó nó mới tính đến bước step.

Như thế khi nó chạy đến số 997 tức 1 + 6 * 166 lần lặp nó vẫn chưa đạt đến số 1000 vì thế nó phải lặp thêm 1 vòng nữa cho đủ. Vì bước step nó là 6 nên nó "rướn" lên đến 1003, như thế đã không thỏa điều kiện là 1000 nên nó thoát vòng lặp!
 
Upvote 0
Đó là nhận xét của leonguyenz, tuy nhiên dù là trước nó có là 0 hay bất cứ số nào (0, 76, 100, 999, v.v...) nó luôn trả về giá trị i = giá trị cuối + 1.

Chẳng hạn:

Mã:
Sub test()
    For i = [COLOR=#ff0000]999 [/COLOR]To 1000
    Next
    Debug.Print i
End Sub

Các bạn có thể thay 999 bằng 1 số bất kỳ miễn đừng lớn hơn 1000 là được, riêng trường hợp lớn hơn 1000 thì i sẽ bằng chính số đó.
theo mình thì i ko nhất thiết là giá trị cuối cộng 1
mà chính là giá trị i cuối + với giá trị step
nên cái 1002 của leonguyenz có được khi step là 2
quote_icon.png
Nguyên văn bởi leonguyenz
Mặc định i = 0 trước For được xem là 1 giá trị hay không?
Còn lại là như 2 bạn trên đã trả lời, nếu cộng luôn i = 0 thì tổng cộng có 1002 giá trị.


nếu i bằng 0 to 1000 (step là 1) thì nó có 1001 vòng lập chứ ko phải 1002 được
for i = 0 to 10 step 4
a=a+4 'vi du vay
next i
và cai i cuối cùng dùng so với 10 theo mình nó sẽ là 12
và các giá tri i của nó sẽ là 0, 4 , 8 và 12
nó chỉ cộng 1 khi ta ko có gia tri step hoặc đặt giá tri step là 1

để ko tạo bài rác mình trích dẫn trong bài
Ở bài đố 5, tôi có thêm bước step nào không vậy? Nếu không có bước step nào thì mặc định chúng là 1. Điều này không cần giải thích nhé!

Good-Luck coi lại bài #76 nhé! Tôi đã giải thích rất rõ rồi đấy!
Anh nghia quá nhảy cảm rồi, do thấy bài LeonguyeenZ nên mình giải thích thêm phần leonguyenz thắt mắt thôi
 
Lần chỉnh sửa cuối:
Upvote 0
theo mình thì i ko nhất thiết là giá trị cuối cộng 1
mà chính là giá trị i cuối + với giá trị step
nên cái 1002 của leonguyenz có được khi step là 2

for i = 0 to 10 step 4
a=a+4 'vi du vay
next i
và cai i cuối cùng dùng so với 10 theo mình nó sẽ là 12
và các giá tri i của nó sẽ là 0, 4 , 8 và 12
nó chỉ cộng 1 khi ta ko có gia tri step hoặc đặt giá tri step là 1

Ở bài đố 5, tôi có thêm bước step nào không vậy? Nếu không có bước step nào thì mặc định chúng là 1. Điều này không cần giải thích nhé!

Good-Luck coi lại bài #76 nhé! Tôi đã giải thích rất rõ rồi đấy!
 
Upvote 0
theo mình thì i ko nhất thiết là giá trị cuối cộng 1
mà chính là giá trị i cuối + với giá trị step
nên cái 1002 của leonguyenz có được khi step là 2

for i = 0 to 10 step 4
a=a+4 'vi du vay
next i
và cai i cuối cùng dùng so với 10 theo mình nó sẽ là 12
và các giá tri i của nó sẽ là 0, 4 , 8 và 12
nó chỉ cộng 1 khi ta ko có gia tri step hoặc đặt giá tri step là 1
Với Câu đố 5 (#61) thì đúng là Step bằng 1 đó bạn.
 
Upvote 0
Thật ra đăc tính của vòng lặp FOR tôi đã diễn giải một lần rồi. Ở thớt nào quên mất tiêu.
Trong đó tôi có nhấn mạnh:
Vòng lặp sẽ kết thúc khi trị số của biến đếm (i) vượt quá giới hạn cuối (trị ngay sau từ khoá "TO"). Vì vậy sau khi chạy hết vòng lặp, trị của biến này sẽ lớn hơn hoặc nhỏ hơn tuỳ theo bước dương hay âm, nhưng không bao giờ bằng.
Chỉ có một trường hợp ngoại lệ duy nhất là khi vòng lặp được thoát sớm, bằng lệnh Exit hay lệnh Goto, Resume,...

Để giải thích lý do tại sao từ "TO" lại có nghĩa như vậy phải trở về lịch sử ngôn ngữ lập trình từ thập niên 1950's

Công thức của honagminhtien không đúng:
1. Nó không tính đến trường hợp trị đầu lớn hơn giới hạn cuối. Trường hợp này, trị của biến đếm là trị đầu.
2. FOR i = 1 TO 1000 STEP 6 : Trị đầu là số lẻ, bước là số chẵn. Suy ra i luôn luôn là số lẻ, không thể = 1002.
 
Upvote 0
Web KT

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

Back
Top Bottom