Bài tập về vòng lặp

Liên hệ QC

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,930
Những ai đã từng xem qua bài viết này: Giới thiệu Cơ bản về vòng lặp For . . . next của sư phụ ptm0412 giờ hãy cùng làm 1 vài bài tập từ đơn giản đến nâng cao nhé
Xin mở màn bằng 1 bài tập sau:

Bài tập 01:

Hãy tính xem từ năm 1900 đến nay có bao nhiêu ngày thuộc dạng THỨ SÁU NGÀY 13
------------------------
Các bạn ai có bài tập gì hay xin post lên đây nhé! Cảm ơn
 
Chỉnh sửa lần cuối bởi điều hành viên:
Vậy cứ thống nhất vậy nhé.
Từ 19/08/2010 - 31/12/2010 mình sẽ làm việc bao nhiêu ngày. Ngày lễ gồm có: 2/9 và ngày nghỉ là CN. Và liệt kê những ngày thứ hai gán vào A1->An của 1 sheet. Dòng vòng lặp thông thường.
Các anh xem góp ý cho Em nhé!
Mã:
Sub lamviec()
Dim i As Integer, j As Integer, k As Integer, dk As Boolean
  Dim ngayle As Integer, ngaynghi As Integer, ngaylam As Long
  ngayle = 1: ngaynghi = 0
   For i = 8 To 12
       dk = i Mod 8
       k = IIf(dk, 1, 19)
       For j = k To 31
           With [COLOR=Red]ActiveCell[/COLOR]
               If Weekday(DateSerial(2010, i, j)) = 1 Then
                  ngaynghi = ngaynghi + 1
                  .Value = DateSerial(2010, i, j)
                  .Offset(1, 0).Select
               End If
           End With
       Next j
   Next i
       ngaylam = DateSerial(2010, 12, 31) - DateSerial(2010, 8, 19) - ngayle - ngaynghi
       MsgBox "Tong ngay lam viec la: " & ngaylam
End Sub
Điều kiện đưa vào bắt đầu cells(1,1) Em chưa biết, nên dùng Activecell thì nó mới chạy, mong các Anh giúp.
 

File đính kèm

  • Ngaylam.xls
    28 KB · Đọc: 22
Upvote 0
Bài 4 câu b có thể giải bằng 1 vòng lặp duy nhất:

Bằng cách dùng cells(i , j) với gia số dòng K và gia số cột L với điều kiện:

Nếu j = tổng số cột hoặc j=1, i tăng lên 1, ta cho gia số dòng k = 0 sau đó tăng k = k + 1

khi tô màu từ trái qua phải, j tăng 1 đến khi bằng tổng số cột thì ngưng, xuống dòng.
khi tô từ phải qua trái, j giảm 1 đến khi bằng 1 thì ngưng, xuống dòng.
Vậy ta cho gia số cột L = 1 và khi thoả điều kiện, L = - L (đổi dấu)

Vòng lặp chạy từ 1 đến tích số dòng và cột. Lưu ý rằng j có những mốc không tăng, không giảm, đó là khi vừa xuống dòng.

Để tô 2 màu xen kẽ, ta đặt điều kiện cho gia số k, nếu k Mod 2 = 0 thì tô màu này, ngược lại thì tô màu kia.

PHP:
Sub tomau2()
Dim i As Long, j As Long, k As Long, L As Long, t As Long
Dim CRows As Long, CCols As Long
    Cells.Clear
    k = 0: L = 1
    i = 1: j = 0: t = 0
    On Error GoTo exit1
    CRows = InputBox("So dong?")
    CCols = InputBox("So cot?")
    For t = 1 To CRows * CCols
        Cells(i + k, j + L).Interior.ColorIndex = IIf(k Mod 2 = 0, 28, 3)
        j = j + L
        If t Mod CCols = 0 And t < CRows * CCols Then
            k = k + 1
            Cells(i + k, j).Interior.ColorIndex = IIf(k Mod 2 = 0, 28, 3)
            t = t + 1
            L = -L
        End If

        Sleep 20
    Next
exit1:
    Exit Sub
End Sub

Hai vòng lặp không phải là dở, nhưng bằng biện pháp dùng gia số dòng cột này, hãy nghĩ đến câu c.
 

File đính kèm

  • Taptomau.xls
    32 KB · Đọc: 30
Lần chỉnh sửa cuối:
Upvote 0
Bài tập 04 này thực chất là loạt bài thao tác với ma trận tương tự như sau
a)Nhập vào dòng, cột in ra ma trận:
1|2|3|4
5|6|7|8
9|10|11|12
13|14|15|16
17|18|19|20
21|22|23|24
b)Nhập vào dòng, cột, in ra ma trận:
1|2|3|4
8|7|6|5
9|10|11|12
16|15|14|13
17|18|19|20
24|23|22|21
Nếu hiểu rõ về ma trận thì cả 2 câu này không khó, chỉ cần duy nhất 1 vòng lặp từ 1 đến Dòng*Cột là xong. Tôi gợi ý 1 chút như sau, với cả 2 câu đều thực hiện giống nhau, với mỗi bước của vòng lặp, xác định biến Dòng và Cột từ biến chạy, xử lý cho cell tương ứng với Dòng và Cột vừa tính được.
 
Upvote 0
Theo gợi ý của RollOver (chuyên gia mảng), câu a làm lại như sau: (thủ thuật tương tự bài ma phương)

PHP:
Sub tomau1()
Dim i As Long, j As Long
Dim CRows As Long, CCols As Long
    Cells.Clear

    CRows = InputBox("So dong?")
    CCols = InputBox("So cot?")
    For t = 1 To CRows * CCols
        i = Int((t - 1) / CCols) + 1
        j = IIf(t Mod CCols = 0, CCols, t Mod CCols)
        Cells(i, j).Interior.ColorIndex = IIf(i Mod 2 = 0, 3, 4)
        Sleep 50
   Next
End Sub

Đây là thủ thuật biến mảng 1 chiều thành mảng 2 chiều. Nếu là gán số xuống vùng vừa tô thì như sau:
Thêm câu lệnh gọi vào sub tomau1:
PHP:
Ganso CRows, CCols

PHP:
Sub Ganso(CRows As Long, CCols As Long)
Dim Arr()
ReDim Arr(1 To CRows, 1 To CCols)
    For t = 1 To CRows * CCols
        i = Int((t - 1) / CCols) + 1
        j = IIf(t Mod CCols = 0, CCols, t Mod CCols)
        Arr(i, j) = t
    Next
    Range(Cells(1, 1), Cells(CRows, CCols)) = Arr
End Sub
 
Upvote 0
Ghi chú:

câu c bài 04, để tránh trường hợp tô hoài không hết như huuthang_bd cảnh báo, xin giới hạn đề bài thành 1 hình chữ nhật cụ thể 15 dòng, 24 cột cho các bạn mới học dễ làm.
 
Upvote 0
Ghi chú:

câu c bài 04, để tránh trường hợp tô hoài không hết như huuthang_bd cảnh báo, xin giới hạn đề bài thành 1 hình chữ nhật cụ thể 15 dòng, 24 cột cho các bạn mới học dễ làm.
Không cần đâu sư phụ à! Chỉ cần trong quá trình tô màu mà có lập lại ít nhất 1 cell đã tô thì ... THOÁT ---> Đơn giản mà!
Tóm lại: Vùng cần tô màu = Selection (với Selection là 1 vùng liên tục)
 
Upvote 0
Không cần đâu sư phụ à! Chỉ cần trong quá trình tô màu mà có lập lại ít nhất 1 cell đã tô thì ... THOÁT ---> Đơn giản mà!

Không đâu ndu à, khi trái bi da lăn, ai cấm nó lăn cắt ngang đường cũ chứ? Mà không cho nó lăn cắt ngang (vừa đụng vào đướng cũ là thoát) làm sao nó chạy qua hết tất cả các ô cần thiết?
 
Upvote 0
Không đâu ndu à, khi trái bi da lăn, ai cấm nó lăn cắt ngang đường cũ chứ? Mà không cho nó lăn cắt ngang (vừa đụng vào đướng cũ là thoát) làm sao nó chạy qua hết tất cả các ô cần thiết?
Sư phụ chỉ cần xét 4 đường biên là được rồi ---> Bên trong không cần!
Nếu rơi vào vòng lập vô hạn thì chắc chắn nó phải "đạp" vào 1 cell nào đó (tại đường biên) mà nó đã từng đi qua
 
Lần chỉnh sửa cuối:
Upvote 0
Nói cũng phải, nhưng để anh em người ta làm dzới chứ. Từ dễ đến khó mà.
 
Upvote 0
Ghi chú:

câu c bài 04, để tránh trường hợp tô hoài không hết như huuthang_bd cảnh báo, xin giới hạn đề bài thành 1 hình chữ nhật cụ thể 15 dòng, 24 cột cho các bạn mới học dễ làm.
Nếu xuất phát từ 1 góc của hình chữ nhật thì khi lăn đến một trong 3 góc còn lại của hình chữ nhật thì coi như trái banh đã lăn qua tất cả các điểm có thể đi qua. Dù có tô hết hay chưa, nếu có lăn tiếp thì cũng lặp lại quỹ đạo cũ. Vì vậy có thể dựa vào đặc điểm này để làm điều kiện thoát vòng lặp.
 
Upvote 0
Vậy cứ thống nhất vậy nhé.
Từ 19/08/2010 - 31/12/2010 mình sẽ làm việc bao nhiêu ngày. Ngày lễ gồm có: 2/9 và ngày nghỉ là CN. Và liệt kê những ngày thứ hai gán vào A1->An của 1 sheet. Dòng vòng lặp thông thường.
Với yêu cầu dạng này dùng vòng lặp là làm chơi thôi, có thể không cần dùng vòng lặp cũng ra được kết quả vì nó có quy luật rõ ràng. Ngày làm=Tổng số ngày-Ngày nghỉ. Tính ngày nghỉ thì xác định ngày nghỉ cuối cùng, ngày nghỉ đầu tiên kết hợp thêm con số 7 nữa là ra. Các ngày nghỉ đặc biệt thì chỉ cần kiểm tra có thuộc khoảng xét hay không nữa là xong.
 
Upvote 0
Với yêu cầu dạng này dùng vòng lặp là làm chơi thôi, có thể không cần dùng vòng lặp cũng ra được kết quả vì nó có quy luật rõ ràng. Ngày làm=Tổng số ngày-Ngày nghỉ. Tính ngày nghỉ thì xác định ngày nghỉ cuối cùng, ngày nghỉ đầu tiên kết hợp thêm con số 7 nữa là ra. Các ngày nghỉ đặc biệt thì chỉ cần kiểm tra có thuộc khoảng xét hay không nữa là xong.
Vâng! Nhưng cũng như tôi đã nói ở lần trước: Chúng ta đang tập tành với vòng lập ---> Vậy thì cứ quét từ ngày đầu đến ngày cuối và xét điều kiện đi ---> Đâu có vấn đề gì chứ
(Chứ để làm bài này thì công thức cũng xong)
 
Upvote 0
Mình xin xúi 1 cách làm tầm bậy, như sau

(*) Tính tổng số ngày;

(*) Tạo 1 vòng lặp từ ngày đầu tiên đến 7 ngày sau đó để tìm ra ngày CN đầu tiên

(*) Tạo vòng lặp từ ngày CN đầu tiên cho đến ngày cuối bước nhảy là 7 để đếm hết các ngày CN

(*) Kiểm thêm ngày Quốc khánh là thứ máy trong tuần

(*) Đáp án là tổng đại số các ngày trên;

Khà, khà,. . . .
 
Upvote 0
(*) Tính tổng số ngày;

(*) Tạo 1 vòng lặp từ ngày đầu tiên đến 7 ngày sau đó để tìm ra ngày CN đầu tiên

(*) Tạo vòng lặp từ ngày CN đầu tiên cho đến ngày cuối bước nhảy là 7 để đếm hết các ngày CN

(*) Kiểm thêm ngày Quốc khánh là thứ máy trong tuần

(*) Đáp án là tổng đại số các ngày trên;

Khà, khà,. . . .
Bác này chỉ xúi không à. Bài tập về vòng lặp thì cũng nên đi tư cơ bản đã, dạng như quy nạp, vậy cứ xét từ ngày đầu đền ngày cuối. Sau khi làm xong thấy cũng hay, ngồi nghĩ lại sao mà vòng này chạy nhiều quá tốn xăng, => mới nghiệm lại có thể nào bớt vòng đi. Chưa gì Bác đã gợi ý, có khi các bạn lại thích vòng lặp kiểu khác sao. Và nhất là phải liệt kê những ngày nghỉ nữa.
Em xin có ngu ý như vậy. Các bạn nếu muốn học VBA sao không xem đây là cơ hội. Thử viết xem 1 code như trên hoàn chỉnh, mình tin chắc sẽ có những cao nhân như Bac SA_DQ, Ndu, RollOver, HuuThang, PTM sẽ hướng dẫn và trau chuốt thêm. Chắc chắn sẽ có ích.
 
Upvote 0
Về bài 4 câu C, tôi xin đưa lên 1 file ví dụ tạo khí thế cho các bạn nghiên cứu, xin được đưa code lên sau, do đó tạm thời tôi protect code(dĩ nhiên là protect VBA không ý nghĩa gì với các cao thủ cả :)).
Chạy macro test trong file này sẽ cho phép nhập vào số Dòng, số Cột(kích thước nào cũng thực hiện tô hết), thực hiện bắt đầu tô từ 1 ô ngẫu nhiên trong vùng và tiến về hướng ngẫu nhiên trong 4 hướng. Nếu kích thước phù hợp sẽ thực hiện tô 1 lần đến hết, nếu kích thước thuộc trường hợp bị lặp lại thì khi nào phát hiện lặp lại thì sẽ thực hiện tô từ 1 ô ngẫu nhiên trong số ô chưa tô theo hướng ngẫu nhiên.
 

File đính kèm

  • test.xls
    24 KB · Đọc: 44
Upvote 0
Về bài 4 câu C, tôi xin đưa lên 1 file ví dụ tạo khí thế cho các bạn nghiên cứu, xin được đưa code lên sau, do đó tạm thời tôi protect code(dĩ nhiên là protect VBA không ý nghĩa gì với các cao thủ cả :)).
Chạy macro test trong file này sẽ cho phép nhập vào số Dòng, số Cột(kích thước nào cũng thực hiện tô hết), thực hiện bắt đầu tô từ 1 ô ngẫu nhiên trong vùng và tiến về hướng ngẫu nhiên trong 4 hướng. Nếu kích thước phù hợp sẽ thực hiện tô 1 lần đến hết, nếu kích thước thuộc trường hợp bị lặp lại thì khi nào phát hiện lặp lại thì sẽ thực hiện tô từ 1 ô ngẫu nhiên trong số ô chưa tô theo hướng ngẫu nhiên.
Thêm 1 tí khí thế nữa --> Tuy không hay bằng của rollover79 nhưng nhìn cũng.. sướng mắt lắm nha!
Cách dùng: Chọn vùng tùy ý rồi nhấn nút
 

File đính kèm

  • Bi-a_03.xls
    29.5 KB · Đọc: 53
Upvote 0
Về bài 4 câu C, tôi xin đưa lên 1 file ví dụ tạo khí thế cho các bạn nghiên cứu, xin được đưa code lên sau, do đó tạm thời tôi protect code(dĩ nhiên là protect VBA không ý nghĩa gì với các cao thủ cả :)).
Chạy macro test trong file này sẽ cho phép nhập vào số Dòng, số Cột(kích thước nào cũng thực hiện tô hết), thực hiện bắt đầu tô từ 1 ô ngẫu nhiên trong vùng và tiến về hướng ngẫu nhiên trong 4 hướng. Nếu kích thước phù hợp sẽ thực hiện tô 1 lần đến hết, nếu kích thước thuộc trường hợp bị lặp lại thì khi nào phát hiện lặp lại thì sẽ thực hiện tô từ 1 ô ngẫu nhiên trong số ô chưa tô theo hướng ngẫu nhiên.
Xem kỹ lại code của rollover79 mới thấy để giải quyết bài này cho chuẩn thật chẳng đơn giản tí nào
- Chuẩn có nghĩa là tô ca rô toàn bộ vùng chọn, bất kể vùng ấy thế nào
- Dùng phép di chuyển như trái bi-a thì đương nhiên sẽ có trường hợp nào đó rơi vào vòng lập vô hạn dù ca rô chưa được tô hết
- Vậy, đối với trường hợp này ta phải thay đổi vị trí của ActiveCell thế nào đó sao cho bảo đảm tô màu ca rô toàn bộ
--------------------
Hay! nhưng mà với các bạn mới học vòng lập e rằng hơi quá sức chăng?
 
Upvote 0
Xem kỹ lại code của rollover79
Hay! nhưng mà với các bạn mới học vòng lập e rằng hơi quá sức chăng?

Vậy mới phải đề nghị 1 trường hợp cố định 15 dòng x 24 cột trước, cho người ta làm với. Mấy cao thủ cứ ngứa ngáy chân tay hoài.

http://s248.photobucket.com/albums/gg173/ptm0412/GPE/?action=view&current=to2mau.mp4



Code có tí tẹo à, chỉ vài dòng chính thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
Xem kỹ lại code của rollover79 mới thấy để giải quyết bài này cho chuẩn thật chẳng đơn giản tí nào
- Chuẩn có nghĩa là tô ca rô toàn bộ vùng chọn, bất kể vùng ấy thế nào
- Dùng phép di chuyển như trái bi-a thì đương nhiên sẽ có trường hợp nào đó rơi vào vòng lập vô hạn dù ca rô chưa được tô hết
- Vậy, đối với trường hợp này ta phải thay đổi vị trí của ActiveCell thế nào đó sao cho bảo đảm tô màu ca rô toàn bộ
--------------------
Hay! nhưng mà với các bạn mới học vòng lập e rằng hơi quá sức chăng?
Vậy tôi mới phải protect code lại, chỉ là tạo thêm hứng thú cho các bạn khác nghiên cứu thêm thôi mà. Còn bình thường thì đúng như bác ptm nói, không hề phức tạp, thậm chí rất đơn giản chỉ vài dòng code là xong. Còn code của tôi thì nó không đơn giản chỉ là về vấn đề vòng lặp, còn có khá nhiều vấn đề trong đó nữa mà có thể ta sẽ gặp trong các bài toán khác.
 
Upvote 0
Web KT
Back
Top Bottom