Bài tập vòng lặp VBA cho người mới bắt đầu:

  • Thread starter Thread starter SA_DQ
  • Ngày gửi Ngày gửi
Liên hệ QC

SA_DQ

/(hông là gì!
Thành viên danh dự
Tham gia
8/6/06
Bài viết
14,567
Được thích
22,873
Nghề nghiệp
U80
Hãy giúp tôi lập danh sách các ngày trong thế kỹ này đã, đang & sẽ có ngày 31 (của tháng) rơi vô chủ nhật.
 
Bi giờ bài này là "Bài tập về ngày tháng cho lập trình nâng cao" chứ đâu phải là "Vòng lặp cho người mới bắt đầu" nữa.

Bài tập căn bản phải đại khái như vầy:
- Đặt mảng a(1 To 100)
- Ghi số ngẫu nhiên 1~1000 cho 100 phần tử này (gợi ý: dùng hàm Application.RandBetween(1,1000))
- Tìm vị trí số lớn nhất trong mảng
 
Upvote 0
Em nhặt nhạnh và chắp vá lại các ý kiến luôn.
Array nhanh thật!!!
If CurrentDate Mod 7 = 1 Then
Làm sao biết CurrentDate Mod 7 = 1 chắc chắn là chủ nhật?
(/ậy bạn nghỉ Y2K là như thế nào?
Y2K là sự cố năm 2000, không liên quan gì đến thế kỷ, nó là năm kế tiếp năm cuối cùng của hệ thống máy tính có 2 số đầu là 19. Qua năm 2000 thì máy tính nhầm 2000 với 1900 sinh ra rối chuyện gọi là sự cố Y2K.
Nếu thế kỷ 21 bắt đầu từ năm 2000, đến năm 2099 là đủ 100 năm; vậy thế kỷ 1 bắt đầu từ năm nào? Hay là bắt đầu từ năm 0 đến hết năm 99 mà vẫn đủ 100 năm? Nghĩa là thế gian này có năm 0 và năm 0 có đủ 365 ngày như những năm khác á?
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
Làm sao biết CurrentDate Mod 7 = 1 chắc chắn là chủ nhật?
Em thử với hàm mod trên bảng tính. Vô tình nó ứng thứ 2 đến thứ 6 là 2->6, thứ 7 là 0, và 1 là chủ nhật.

Vậy phát sinh vấn đề: có phải "thứ trong tuần" ra đời là do được chế biến từ phép chia dư 7 ngày hay không mà lại trùng hợp thế. :wallbash: :wallbash: :wallbash:
 
Upvote 0
Mã:
Sub DanhSachNgay31ChuNhatCuoiThang()
    Dim yearStart As Integer
    Dim yearEnd As Integer
    Dim currentYear As Integer
    Dim currentDate As Date
    
    ' Thiết lập khoảng năm (từ năm 2000 đến 2099)
    yearStart = 2000
    yearEnd = 2099
    
    ' Xóa nội dung trong cột A, B, C nếu có
    Columns("A:C").ClearContents
    
    ' Thiết lập tiêu đề
    Range("A1").Value = "Năm"
    Range("B1").Value = "Tháng"
    Range("C1").Value = "Ngày 31"
    
    ' Bắt đầu từ hàng thứ 2
    Dim row As Integer
    row = 2
    
    ' Lặp qua mỗi năm từ yearStart đến yearEnd
    For currentYear = yearStart To yearEnd
        ' Lặp qua mỗi tháng từ tháng 1 đến tháng 12
        For currentMonth = 1 To 12
            ' Tạo ngày 1 của tháng tiếp theo
            currentDate = DateSerial(currentYear, currentMonth + 1, 1)
            ' Trừ đi 1 ngày để lấy ngày cuối cùng của tháng hiện tại
            currentDate = currentDate - 1
            ' Kiểm tra xem ngày cuối cùng của tháng đó rơi vào Chủ nhật và có phải là ngày 31 không
            If Weekday(currentDate) = vbSunday And Day(currentDate) = 31 Then
                ' Đưa thông tin vào cột A, B, C
                Cells(row, 1).Value = currentYear
                Cells(row, 2).Value = currentMonth
                Cells(row, 3).Value = Format(currentDate, "dd/mm/yyyy")
                row = row + 1
            End If
        Next currentMonth
    Next currentYear
End Sub
Chuẩn không phải chỉnh
 
Upvote 0
vậy em sửa lại đoạn này là được
yearStart = 2001
yearEnd = 2100

Mã:
Sub DanhSachNgay31ChuNhatCuoiThang()
    Dim yearStart As Integer
    Dim yearEnd As Integer
    Dim currentYear As Integer
    Dim currentDate As Date
   
    ' Thiết lập khoảng năm (từ năm 2001 đến 2100)
    yearStart = 2001
    yearEnd = 2100
   
    ' Xóa nội dung trong cột A, B, C nếu có
    Columns("A:C").ClearContents
   
    ' Thiết lập tiêu đề
    Range("A1").Value = "Năm"
    Range("B1").Value = "Tháng"
    Range("C1").Value = "Ngày 31"
   
    ' Bắt đầu từ hàng thứ 2
    Dim row As Integer
    row = 2
   
    ' Lặp qua mỗi năm từ yearStart đến yearEnd
    For currentYear = yearStart To yearEnd
        ' Lặp qua mỗi tháng từ tháng 1 đến tháng 12
        For currentMonth = 1 To 12
            ' Tạo ngày 1 của tháng tiếp theo
            currentDate = DateSerial(currentYear, currentMonth + 1, 1)
            ' Trừ đi 1 ngày để lấy ngày cuối cùng của tháng hiện tại
            currentDate = currentDate - 1
            ' Kiểm tra xem ngày cuối cùng của tháng đó rơi vào Chủ nhật và có phải là ngày 31 không
            If Weekday(currentDate) = vbSunday And Day(currentDate) = 31 Then
                ' Đưa thông tin vào cột A, B, C
                Cells(row, 1).Value = currentYear
                Cells(row, 2).Value = currentMonth
                Cells(row, 3).Value = Format(currentDate, "dd/mm/yyyy")
                row = row + 1
            End If
        Next currentMonth
    Next currentYear
End Sub
 
Upvote 0
Cỡ trình độ quý vị mà viết code như vậy xoàng quá, thiếu tư duy ưu hóa thuật toán.

1. Kiểu 1 - dùng chủ nhật làm mốc.
Tìm chủ nhật đầu tiên, vòng lặp đi từ ngày ấy đến ngày cuối của năm cuối, step 7.
2001->2100: vòng lặp chạy 5200 lượt. Nhiều hơn hiện tại (hiện tại là 1200 lượt), nhưng tránh được nhiều con toán tính.

2. Kiểu 2 - dùng ngày 31 làm mốc.
Đăt a = Array(1, 2, 2, 2, 1, 2, 2) ---> số thàng 12>1>3>5>7>8>10>12
Đặt ngày bắt đầu là 31/12 của năm trước.
Vòng lặp Do While thay vì For
Vòng lăp For Each st In a
Dùng hàm EDate của WorkSheet để nhảy sang tháng kế
Nếu quá năm cuối thì thoát cả hai vòng lặp
Nếu là chủ nhật thì in ra
Next st
Loop
Như vậy code chạy 700 lượt cho 100 năm và code giảm được một vài con toán.
 
Upvote 0
Web KT

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

Back
Top Bottom