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,946
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:
(*) 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à,. . . .
Em sửa lại đoạn code theo hướng dẫn của Bác HYen17 như sau:
Mã:
Sub Tinhngay()
Dim tongngay As Long, nghi As Integer, le As Integer
Dim i As Long, j As Date
Cells.Clear
tongngay = DateSerial(2010, 12, 31) - DateSerial(2010, 8, 19)
le = 1: nghi = 0
For i = 19 To 26
    If Weekday(DateSerial(2010, 8, i)) = 1 Then
       For j = DateSerial(2010, 8, i) To DateSerial(2010, 12, 31) Step 7
        With ActiveCell
             .Value = j
             nghi = nghi + ActiveCell.Count
             .Offset(1, 0).Select
        End With
        Next
    End If
Next
If Weekday(DateSerial(2010, 9, 2)) <> 1 Then ActiveCell = DateSerial(2010, 9, 2)
MsgBox "Tong ngay lam viec la: " & tongngay - le - nghi
End Sub
Các Anh xem và góp ý cho Em nhé!
 

File đính kèm

  • Ngaylam.xls
    24.5 KB · Đọc: 18
Lần chỉnh sửa cuối:
Upvote 0
Muốn nhận được góp í thì đây, xin mời

đoạn code theo hướng dẫn của Bác HYen17 như sau: . . .
Các Anh xem và góp ý cho Em nhé!

(*) Sau lại nhốt chung vòng lặp sau vô trong vòng lặp trước vậy?

Nếu gặp ngay ngày CN từ đầu, có fải bạn fí fạm 6 lần lặp không cần thiết không nào?
Nên thoát khỏi nó ngay khi gặp ngày CN chứ; Tuy thêm 1 dòng lệnh, nhưng thưởng giảm đi được khoảng gần nữa đọan đường trong vòng lặp thứ nhật đó bạn.
 
Upvote 0
Em sửa lại đoạn code theo hướng dẫn của Bác HYen17 như sau:
Mã:
Sub Tinhngay()
Dim tongngay As Long, nghi As Integer, le As Integer
Dim i As Long, j As Date
Cells.Clear
tongngay = DateSerial(2010, 12, 31) - DateSerial(2010, 8, 19)
le = 1: nghi = 0
For i = 19 To 26
    If Weekday(DateSerial(2010, 8, i)) = 1 Then
       For j = DateSerial(2010, 8, i) To DateSerial(2010, 12, 31) Step 7
        With ActiveCell
             .Value = j
             nghi = nghi + ActiveCell.Count
             .Offset(1, 0).Select
        End With
        Next
    End If
Next
If Weekday(DateSerial(2010, 9, 2)) <> 1 Then ActiveCell = DateSerial(2010, 9, 2)
MsgBox "Tong ngay lam viec la: " & tongngay - le - nghi
End Sub
Các Anh xem và góp ý cho Em nhé!
Đây là code liệt kê tất cả những ngày đi làm ra cột A, từ đầu năm 2010 đến cuối năm 2010 (không tính chủ nhât)
PHP:
Sub Tinhngay()
  Dim i As Long, j As Long
  With Range("A:A")
    .ClearContents
    .NumberFormat = "dd/mm/yyyy"
    For i = DateSerial(2010, 1, 1) To DateSerial(2010, 12, 31)
      If Weekday(i, 1) > 1 Then
        j = j + 1
        .Cells(j, 1) = i
      End If
    Next
  End With
End Sub
Code này chưa tính đến nghỉ lễ ---> Bạn cứ cải tiến nhé
(Nhìn qua nhìn lại chỉ thấy có mỗi bạn MinhCong ---> cái vụ VBA này xem ra ít người khoái nhỉ?)
 
Lần chỉnh sửa cuối:
Upvote 0
Buồn quá, và ngứa ngáy nữa, nên đành post câu c bài 04 lên để tham khảo.

Như đã gợi ý ở câu b, ta dùng 1 gia số dòng và 1 gia số cột.

Xin giải thích 1 tẹo về chạy ca rô: Chạy ca rô là chạy ô vừa lên hoặc xuống, vừa chạy qua phải (hoặc trái), mỗi lần dịch chuyển 1 vị trí dòng và 1 vị trí cột. Xuống thì chỉ số dòng tăng và ngược lại. Qua phải thì chỉ số cột tăng và ngược lại.

Vậy gia số thêm vào cho dòng và cột là các số 1 và -1.

Trước tiên tô màu ô trên cùng bên trái vị trí là dòng i = 1 cột j = 1, hướng đi xuống về bên phải, gia số dòng K = 1 và gia số cột L = 1:

PHP:
i = 1: j = 1
K = 1, L = 1
Cells (i, j).Interior.ColorIndex = 15

Ô kế tiếp có vị trí dòng và cột là i = i + K, j = j + L

Nếu sau khi tô, vị trí ô vừa tô là cạnh rìa của hình chữ nhật, thì đổi chiều:

- Đụng cạnh rìa bên phải: L đổi từ 1 thành -1 để chạy qua trái
- Đụng cạnh rìa bên trái: L đổi từ -1 thành 1 để chạy qua phải
- Đụng cạnh dưới: K đổi từ 1 thành -1 để chạy lên
- Đụng cạnh trên: K đổi từ -1 thành 1 để chạy xuống.

Chưa cần tính tối ưu code làm gì, và cũng chưa cần bẫy lỗi làm gì, bạn đã có 1 đoạn code hoàn chỉnh và ngắn gọn. Với hình chữ nhật không đặc biệt (nghĩa là không bị trả về quỹ đạo cũ), bảo đảm sẽ tô toàn bộ khung chữ nhật thành carô.

Vậy tô bao nhiêu ô? Theo lý thuyết thì tô 1/2 tổng số ô, nhưng do chạy kiểu này, mỗi ô là 1 giao điểm của 2 đường chéo nên sẽ bị chạy qua 2 lần. Vậy Chọn số vòng lặp là tổng số ô và = dòng x cột. Có thể dư, có thể thiếu, nhưng tạm xài.

Code sau đây tô hình chữ nhật không đặc biệt 15 x 24:

PHP:
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
______________________________________

Sub colorRun()
i = 1: j = 1
K = 1: L = 1
For d = 1 To 15 * 24
Sleep (15)
Cells(i, j).Interior.ColorIndex = 15
i = i + K
j = j + L
If i = 15 Or i = 1 Then K = -K
If j = 24 Or j = 1 Then L = -L
Next
End Sub

Code chính có 1 tí tẹo, đúng không?
 
Lần chỉnh sửa cuối:
Upvote 0
Buồn quá, và ngứa ngáy nữa, nên đành post câu c bài 04 lên để tham khảo.
Code chính có 1 tí tẹo, đúng không?
1. Xin hỏi trường hợp code của anh số hàng bằng số cột thì tô màu chỉ có 1 đường chéo
2. Xin anh giải thích giúp đoạn code: Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Camr ơn anh
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
(Nhìn qua nhìn lại chỉ thấy có mỗi bạn MinhCong ---> cái vụ VBA này xem ra ít người khoái nhỉ?)

Không phải đâu anh, chẳng qua chưa làm được thì chưa post lên thôi, nhưng theo dõi và học tập thường xuyên, kính mong mấy anh giúp đỡ, đây là lớp học thuận tiên nhất
Cảm ơn các anh rất nhiều, chúc các anh luôn khỏe.
 
Upvote 0
2. Mở rộng tô hình chữ nhật lấy kích thước từ bàn phím: (Hình đặc biệt vẫn chưa bẫy lỗi, lỗi gì thì thử nhiều kích thước khác nhau sẽ thấy)

PHP:
Sub colorRun1()
CRows = InputBox("So dong?")
CCols = InputBox("So cot?")
If CRows = 1 Or CCols = 1 Then Exit Sub
i = 1: j = 1
K = 1: L = 1
For d = 1 To CRows * CCols
    Sleep (15)
    Cells(i, j).Interior.ColorIndex = 15
    i = i + K
    j = j + L
    If i = CRows Or i = 1 Then K = -K
    If j = CCols Or j = 1 Then L = -L
Next
End Sub

3. Mở rộng tô vùng chọn bất kỳ không phải bắt đầu từ A1: (vẫn chưa sửa gì cho hình chữ nhật đặc biệt)

PHP:
 Sub colorRun2()
CRows = Selection.Rows.Count
CCols = Selection.Columns.Count
If CRows = 1 Or CCols = 1 Then Exit Sub
i = 1: j = 1
K = 1: L = 1
For d = 1 To CRows * CCols
    Sleep (15)
    With Selection
        .Cells(i, j).Interior.ColorIndex = 15
        i = i + K
        j = j + L
        If i = CRows Or i = 1 Then K = -K
        If j = CCols Or j = 1 Then L = -L
    End With
Next
End Sub

Mọi người thử so sánh với code của mình làm xem? (Code của ndu và huuthang cũng chưa tô hết cho hình đặc biệt)
 

File đính kèm

  • TocaroDongian.xls
    40.5 KB · Đọc: 30
Lần chỉnh sửa cuối:
Upvote 0
1. Xin hỏi trường hợp code của anh số hàng bằng số cột thì tô màu chỉ có 1 đường chéo
2. Em chạy thấy báo lỗi dòng Sleep(15): Xin anh giải thích giúp
Camr ơn anh

Như đã nói từ đầu topic, làm từ dễ đến khó, bẫy lỗi cho mọi hình chữ nhật không phải đơn giản, mới chỉ có mình RollOver đưa file lên tô hình chữ nhật bất kỳ, ndu và Huuthang cũng chưa. Trước mắt suy luận chuyện dễ trước.
Lỗi dòng Sleep do có lẽ viehoai không copy dòng khai báo trên cùng. Tải file bài trên nhé.
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
CRows * CCols
hay 24*15
Con số này bạn lây ở đâu ra vậy, hình như vừa thừa vừa thiếu? đây là số hay, tôi mới tiếp xúc VBA , không biết nên hỏi, nếu không đúng, thì bỏ qua
tôi cũng bị lỗi giống thế, vậy hàm Sleep này mình nghĩ ra, hãy viết ở đâu?

Bạn đọc kỹ bài của tôi sẽ thấy câu này:

Chưa cần tính tối ưu code làm gì, và cũng chưa cần bẫy lỗi làm gì, bạn đã có 1 đoạn code hoàn chỉnh và ngắn gọn. Với hình chữ nhật không đặc biệt (nghĩa là không bị trả về quỹ đạo cũ), bảo đảm sẽ tô toàn bộ khung chữ nhật thành carô.

Vậy tô bao nhiêu ô? Theo lý thuyết thì tô 1/2 tổng số ô, nhưng do chạy kiểu này, mỗi ô là 1 giao điểm của 2 đường chéo nên sẽ bị chạy qua 2 lần. Vậy Chọn số vòng lặp là tổng số ô và = dòng x cột. Có thể dư, có thể thiếu, nhưng tạm xài.

Vậy nên tôi lấy tổng số ô = dài x rộng dùng làm số lần lặp.
Vì vẫn có 1 số ô nằm trên rìa hình chữ nhật không được tô 2 lần, nên hơi dư. Nếu không tô hết thì dư khá nhiều. Tuy vậy, không đến nỗi phải ngồi chờ suông lâu quá.

Hàm sleep là lấy trong thư viện Office ra, nó không có sẵn trong VBA nên phải khai báo đến thư viện (Lib) Kernel32.dll
mục đích dùng hàm này là để Pause code 1 khoảng thời gian tính bằng milisecond.
 
Lần chỉnh sửa cuối:
Upvote 0
Em xin mạnh dạng đưa code, xin các anh chị giúp đỡ:
1. Chọn cell để xác định hàng và cột cuối cùng của vùng cần tô màu nền caro --> chạy code
2. (phần hỏi) Để tô nền caro cho một range bất kỳ (không xuất phát A1) bằng cách quét chọn range bất kỳ nào đó. Muốn vậy cần xác định hàng và cột đầu tiên của Range đó bằng cách nào? (cell đầu tiên của Range đang chọn). Xin các anh chị giúp đỡ
Cảm ơn các anh chị.
 

File đính kèm

  • Caro.xls
    22 KB · Đọc: 51
Upvote 0
Em xin mạnh dạng đưa code, xin các anh chị giúp đỡ:
1. Chọn cell để xác định hàng và cột cuối cùng của vùng cần tô màu nền caro --> chạy code
2. (phần hỏi) Để tô nền caro cho một range bất kỳ (không xuất phát A1) bằng cách quét chọn range bất kỳ nào đó. Muốn vậy cần xác định hàng và cột đầu tiên của Range đó bằng cách nào? (cell đầu tiên của Range đang chọn). Xin các anh chị giúp đỡ
Cảm ơn các anh chị.

1. Để xác định dòng cột đầu của vùng chọn:

dongdau = Selection.Resize(1, 1).Row
cotdau = Selection.Resize(1, 1).Column

hoặc

dongdau = Selection.Row
cotdau = Selection.Column

2. Để xác định dòng cuối và cột cuối:

dongcuoi = dongdau + Selection.Rows.Count - 1
cotcuoi = cotdau + Selection.Columns.Count - 1

Viehoai có thể thử sửa code cho vùng chọn bất kỳ. Dù không phải tô kiểu bida, nhưng kết quả cũng là tô carô. Coi như bài tập phụ vậy.

Tuy nhiên, không cần thiết phải làm như vậy cho cực.

Đối với 1 vùng chọn hình chữ nhật đơn (nghĩa là không tô chọn nhiều vùng 1 lúc), VBA có thể dùng câu lệnh như sau để đối xử như cả sheet:

Selection.Cells(1, 1) tương đương với ô đầu tiên của vùng chọn. Viết đầy đủ là Sheet1.Selection.Cells(1, 1). Có thể dùng biến i, j bắt đầu từ 1 như cũ.

Đối với sheet thì là Sheet1.Cells(1, 1) nghĩa là ô A1, viết tắt là Cells(1, 1) vì mặc định selection đang là cả sheet.

Trong bài trên tôi đã áp dụng thủ pháp này.
 
Upvote 0
1. Để xác định dòng cột đầu của vùng chọn:

dongdau = Selection.Resize(1, 1).Row
cotdau = Selection.Resize(1, 1).Column

hoặc

dongdau = Selection.Row
cotdau = Selection.Column

2. Để xác định dòng cuối và cột cuối:

dongcuoi = dongdau + Selection.Rows.Count - 1
cotcuoi = cotdau + Selection.Columns.Count - 1

Viehoai có thể thử sửa code cho vùng chọn bất kỳ. Dù không phải tô kiểu bida, nhưng kết quả cũng là tô carô. Coi như bài tập phụ vậy.

Tuy nhiên, không cần thiết phải làm như vậy cho cực.

Đối với 1 vùng chọn hình chữ nhật đơn (nghĩa là không tô chọn nhiều vùng 1 lúc), VBA có thể dùng câu lệnh như sau để đối xử như cả sheet:

Selection.Cells(1, 1) tương đương với ô đầu tiên của vùng chọn. Viết đầy đủ là Sheet1.Selection.Cells(1, 1). Có thể dùng biến i, j bắt đầu từ 1 như cũ.

Đối với sheet thì là Sheet1.Cells(1, 1) nghĩa là ô A1, viết tắt là Cells(1, 1) vì mặc định selection đang là cả sheet.

Trong bài trên tôi đã áp dụng thủ pháp này.

Cảm ơn anh rất nhiều em hiểu sâu hơn về vấn đề này. Tuy nhiên Anh Mỹ giải thích giúp em cách 1 sao có thêm Resize(1,1)?
Em xin sửa lại code theo cách quét vùng chọn bất kỳ ---> chạy code
 

File đính kèm

  • Caro.xls
    22.5 KB · Đọc: 21
Lần chỉnh sửa cuối:
Upvote 0
Resize(1, 1) nhằm giảm kích thước vùng chọn xuống còn 1 dòng và 1 cột, tương đương 1 ô.
 
Upvote 0
(*) Sau lại nhốt chung vòng lặp sau vô trong vòng lặp trước vậy?

Nếu gặp ngay ngày CN từ đầu, có fải bạn fí fạm 6 lần lặp không cần thiết không nào?
Nên thoát khỏi nó ngay khi gặp ngày CN chứ; Tuy thêm 1 dòng lệnh, nhưng thưởng giảm đi được khoảng gần nữa đọan đường trong vòng lặp thứ nhật đó bạn.
Em sửa lại đoạn code theo góp ý của Bác ChanhTQ@ như sau:
Mã:
Sub Tinhngay()
Dim tongngay As Long, nghi As Integer, le As Integer
Dim i As Long, j As Date
Cells.ClearContents
tongngay = DateSerial(2010, 12, 31) - DateSerial(2010, 8, 19): le = 1
  For i = 19 To 25
    If Weekday(DateSerial(2010, 8, i)) = 1 Then Exit For
  Next
  For j = DateSerial(2010, 8, i) To DateSerial(2010, 12, 31) Step 7
    With [COLOR=Red]ActiveCell[/COLOR]
        .NumberFormat = "dd/mm/yyyy"
        .Value = j
        nghi = nghi + ActiveCell.Count
        .Offset(1, 0).Select
    End With
  Next
If Weekday(DateSerial(2010, 9, 2)) <> 1 Then ActiveCell = DateSerial(2010, 9, 2)
MsgBox "Tong ngay lam viec la: " & tongngay - le - nghi
End Sub
Tuy nhiên chỗ ActiveCell muốn nó nằm ở cột A thì làm sao nhỉ? Không lẽ phải thêm 1 vòng lặp nữa?
 
Lần chỉnh sửa cuối:
Upvote 0
VBA có thể tác động đến ô, dòng, cột bất kỳ, không cần select, chỉ cần dùng lệnh gán.
Thí dụ: 3 câu lệnh sau có kết quả như nhau:
PHP:
Sheet1.Range("A1") = i
Cells(1, 1) = i
[A1] = i

Nếu muốn gán kết quả xuống các ô kế tiếp nhau trên cùng cột, cũng có nhiều cách:

PHP:
[A1000]. End(xlUp).Offset(1,0) = i
[A1].End(xlDown).Offset(1,0) = i

Nếu có 1 biến khác chạy step 1, (thí dụ biến j), có thể dùng:

PHP:
Cells(j, 1) = i

Nếu j chạy step 2, thì j chia 2. Nếu không có biến nào phù hợp, tạo 1 biến đếm tăng 1 khi thoả điều kiện.

Cụ thể trong code trên, có thể dùng End cách 1 hoặc 2.

MinhCong xem thêm code tô màu, đâu có phải select từng cell để gán màu nữa đâu?
 
Lần chỉnh sửa cuối:
Upvote 0
Em sửa lại đoạn code theo góp ý của Bác ChanhTQ@ như sau:
Mã:
Sub Tinhngay()
Dim tongngay As Long, nghi As Integer, le As Integer
Dim i As Long, j As Date
Cells.ClearContents
tongngay = DateSerial(2010, 12, 31) - DateSerial(2010, 8, 19): le = 1
For i = 19 To 25
If Weekday(DateSerial(2010, 8, i)) = 1 Then Exit For
Next
For j = DateSerial(2010, 8, i) To DateSerial(2010, 12, 31) Step 7
With [COLOR=red]ActiveCell[/COLOR]
.NumberFormat = "dd/mm/yyyy"
.Value = j
nghi = nghi + ActiveCell.Count
.Offset(1, 0).Select
End With
Next
If Weekday(DateSerial(2010, 9, 2)) <> 1 Then ActiveCell = DateSerial(2010, 9, 2)
MsgBox "Tong ngay lam viec la: " & tongngay - le - nghi
End Sub
Tuy nhiên chỗ ActiveCell muốn nó nằm ở cột A thì làm sao nhỉ? Không lẽ phải thêm 1 vòng lặp nữa?
Một cách để cho kết quả từ A1:
_ Tạo một biến, thí dụ : Dim K as Integer
_ With ActiveCell thay bằng With [A1].Offset(K) hoặc With Cells(K + 1, 1)
_ Thay .Offset(1, 0).Select bằng K= K + 1
 
Upvote 0
Câu C bài số 4 trong trường hợp tổng quát, giả sử tô 1 vùng bất kỳ bởi 2 màu, khi đó ta sẽ thấy tập các ô có tính chất (Cột+Dòng) là 1 số chẵn sẽ được tô 1 màu, tập các ô có tính chất (Cột+Dòng) là 1 số lẻ được tô 1 màu. Như vậy nếu để tô mà không cần theo quy luật về đường đi thì các bạn chỉ cần duyệt và tô theo tính chất trên sẽ rất đơn giản. Còn về quy luật đường đi thì theo cách của bác ptm theo tôi là chuẩn nhất rồi. Vậy để giải quyết bài này theo hướng tổng quát nhất ta có thể đi theo mấy bước như sau:
1. Duyệt tất cả các ô, đẩy tất cả các ô cần tô(có cùng tính chất Dòng+Cột chẵn hoặc lẻ) vào 1 danh sách
2. Chọn ngẫu nhiên 1 ô trong danh sách, thực hiện tô màu cho ô này, sau khi tô thì loại ô đó ra khỏi danh sách, sau khi loại khỏi danh sách mà hết danh sách thì dừng.
3. Thực hiện di chuyển từ ô vừa tô theo nguyên tắc di chuyển(di chuyển đến ô nào thì kiểm tra nếu ô đó có trong danh sách thì loại ô đó ra khỏi danh sách), gặp dấu hiệu bị lặp thì dừng di chuyển và quay lại bước 2.
Tôi xin gửi các bạn code của cả 3 câu của bài 4 như sau:
Câu a
Mã:
Sub Row1()
    Dim iValue As Long, iCol As Long, iRow As Long, iRows As Long, iCols As Long
    iCols = InputBox("Nhap so cot:")
    iRows = InputBox("Nhap so dong:")
    For iValue = 1 To iRows * iCols
        iRow = (iValue - 1) \ iCols + 1
        iCol = (iValue - 1) Mod iCols + 1
        Cells(iRow, iCol).Interior.ColorIndex = 4
        Sleep 100
    Next
End Sub
Câu b
Mã:
Sub Row2()
    Dim iValue As Long, iCol As Long, iRow As Long, iRows As Long, iCols As Long
    iCols = InputBox("Nhap so cot:")
    iRows = InputBox("Nhap so dong:")
    For iValue = 1 To iRows * iCols
        iRow = (iValue - 1) \ iCols + 1
        iCol = IIf(iRow Mod 2 = 1, (iValue - 1) Mod iCols + 1, iCols - ((iValue - 1) Mod iCols))
        Cells(iRow, iCol).Interior.ColorIndex = 4
        Sleep 100
    Next
End Sub
Câu c
Mã:
Sub Caro1()
    Dim iValue As Long, iCol As Long, iRow As Long, iRows As Long, iCols As Long, objDic As New 

Dictionary, EpRow As Long, EpCol As Long
    iCols = InputBox("Nhap so cot:")
    iRows = InputBox("Nhap so dong:")
    For iValue = 1 To iCols * iRows
        iRow = (iValue - 1) \ iCols + 1
        iCol = (iValue - 1) Mod iCols + 1
        If ((iRow + iCol) Mod 2 = 0) Then objDic.Add iValue, iValue
    Next
    Randomize
    Do While objDic.Count > 0
        EpRow = IIf(Rnd() > 0.5, 1, -1)
        EpCol = IIf(Rnd() > 0.5, 1, -1)
        iValue = Int(Rnd() * objDic.Count)
        iRow = (objDic.Keys(iValue) - 1) \ iCols + 1
        iCol = (objDic.Keys(iValue) - 1) Mod iCols + 1
        Cells(iRow, iCol).Interior.ColorIndex = 4
        Sleep 200
        objDic.Remove objDic.Keys(iValue)
        Do While objDic.Count > 0
            If iRow + EpRow < 1 Or iRow + EpRow > iRows Then EpRow = EpRow * (-1)
            If iCol + EpCol < 1 Or iCol + EpCol > iCols Then EpCol = EpCol * (-1)
            iRow = iRow + EpRow
            iCol = iCol + EpCol
            iValue = (iRow - 1) * iCols + iCol
            Cells(iRow, iCol).Interior.ColorIndex = 4
            Sleep 100
            If objDic.Exists(iValue) Then
                objDic.Remove iValue
            Else
                If iRow = 1 Or iRow = iRows Or iCol = 1 Or iCol = iCols Then Exit Do
            End If
        Loop
    Loop
    MsgBox "OK!"
End Sub
Các bạn thử cải tiến thành 3 câu như sau:
Câu a thành tô theo từng cột từ trên xuống dưới
Câu b thành tô theo từng cột từ trên xuống dưới rồi lại từ dưới lên trên
Câu c thành tô với 2 màu, khi nào tô hết màu thứ nhất thì tô tiếp màu thứ 2 để thành 1 bàn cờ với 2 màu.
 
Upvote 0
Câu a và b chr cần thay đổi vị trí của cells(iRow,iCol) thành cells(iCol,iRow) là được.
Mã:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Câu a:
Mã:
Sub Row1()
    Dim iValue As Long, iCol As Long, iRow As Long, iRows As Long, iCols As Long
    Cells.Clear
    iCols = InputBox("Nhap so cot:")
    iRows = InputBox("Nhap so dong:")
    For iValue = 1 To iRows * iCols
        iRow = (iValue - 1) Mod iCols + 1
        iCol = (iValue - 1) \ iCols + 1
        Cells(iRow, iCol).Interior.ColorIndex = 4
        Sleep 50
    Next
End Sub
Câu b:
Mã:
Sub Row2()
    Dim iValue As Long, iCol As Long, iRow As Long, iRows As Long, iCols As Long
    Cells.Clear
    iCols = InputBox("Nhap so cot:")
    iRows = InputBox("Nhap so dong:")
    For iValue = 1 To iRows * iCols
        iCol = (iValue - 1) \ iCols + 1
        iRow = IIf(iCol Mod 2 = 1, (iValue - 1) Mod iCols + 1, iCols - ((iValue - 1) Mod iCols))
        Cells(iRow, iCol).Interior.ColorIndex = 4
        Sleep 100
    Next
End Sub
Đoạn code tô caro sao Em chạy nó bị báo lỗi ở khai báo objDic As New Dictionary nhỉ?
 

File đính kèm

  • GPE.xls
    26 KB · Đọc: 20
Upvote 0
Đoạn code tô caro sao Em chạy nó bị báo lỗi ở khai báo objDic As New Dictionary nhỉ?
Vào menu Tools\References và check vào mục Microsoft scripting runtime là hết lỗi ngay

untitled.JPG


Ngoài ra ra còn cách khác:
PHP:
Sub Caro1()
  Dim objDic
  Set objDic = CreateObject("Scripting.Dictionary")
  .....
  ....
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom