Bác nhỉ.chủ nhật
Bác ấy đang tính xem trong thế kỷ này sẽ uống rượu được bao nhiêu ngày chủ nhật nữa. Với điều kiện là ngày ấy phải đặc biệt chứ không đại trà. Tức là rượu có chọn lọc.mục đich của bài tập
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.
Sub SundaysWith31st()
Dim startDate As Date
Dim endDate As Date
Dim currentDate As Date
startDate = DateSerial(2000, 1, 1)
endDate = DateSerial(2099, 12, 31)
currentDate = startDate
Do While currentDate <= endDate
If Day(currentDate) = 31 And Weekday(currentDate) = vbSunday Then
Debug.Print currentDate
End If
currentDate = DateSerial(Year(currentDate), Month(currentDate), Day(currentDate) + 1)
Loop
End Sub
Vòng lặp thì đúng, nhưng nên có cách hạn chế số lần lặp, thay vì lặp đủ 36525 lầnDạ em xin trả bài ạ. Nhờ bác chữa giúp em.
Chỉ đếm các tháng 1, 3, 5, 7, 8, 10, 12; và ghép giá trị luôn hả anhVòng lặp thì đúng, nhưng nên có cách hạn chế số lần lặp, thay vì lặp đủ 3675 lần
Sub Count31Sundays()
Dim ArrMonth()
Dim checkDate As Date
Dim List31Sunday() As Date
ArrMonth = Array(1, 3, 5, 7, 8, 10, 12)
count = 0
For yr = 2000 To 2099
For Each mth In ArrMonth
checkDate = DateSerial(yr, mth, 31)
If Weekday(checkDate, vbSunday) = 1 Then
count = count + 1
ReDim Preserve List31Sunday(1 To count)
List31Sunday(count) = checkDate
End If
cnt = cnt + 1
Next mth
Next yr
Range("A1").Resize(count, 1) = Application.Transpose(List31Sunday)
End Sub
Sub zzz()
For y = 2000 To 2099 Step 1
For m = 1 To 12 Step 1
currentDate = DateSerial(y, m, 31)
If Day(currentDate) = 31 And Weekday(currentDate) = vbSunday Then
Debug.Print currentDate
End If
Next
Next
End Sub
Ngày | Thứ | Delta | ||||||||||||||||
12/29/2000 | 6 | |||||||||||||||||
3/29/2002 | 6 | 455 | ||||||||||||||||
8/29/2003 | 6 | 518 | ||||||||||||||||
10/29/2004 | 6 | 427 | ||||||||||||||||
7/29/2005 | 6 | 273 | ||||||||||||||||
12/29/2006 | 6 | 518 | ||||||||||||||||
8/29/2008 | 6 | 609 | ||||||||||||||||
5/29/2009 | 6 | 273 | ||||||||||||||||
1/29/2010 | 6 | 245 | ||||||||||||||||
10/29/2010 | 6 | 273 | ||||||||||||||||
7/29/2011 | 6 | 273 | ||||||||||||||||
3/29/2013 | 6 | 609 | ||||||||||||||||
8/29/2014 | 6 | 518 | ||||||||||||||||
5/29/2015 | 6 | 273 | ||||||||||||||||
1/29/2016 | 6 | 245 | ||||||||||||||||
7/29/2016 | 6 | 182 | ||||||||||||||||
12/29/2017 | 6 | 518 | ||||||||||||||||
3/29/2019 | 6 | 455 | ||||||||||||||||
5/29/2020 | 6 | 427 | ||||||||||||||||
1/29/2021 | 6 | 245 | ||||||||||||||||
10/29/2021 | 6 | 273 | ||||||||||||||||
7/29/2022 | 6 | 273 | ||||||||||||||||
12/29/2023 | 6 | 518 | ||||||||||||||||
3/29/2024 | 6 | 91 | ||||||||||||||||
8/29/2025 | 6 | 518 | ||||||||||||||||
5/29/2026 | 6 | 273 | ||||||||||||||||
1/29/2027 | 6 | 245 | ||||||||||||||||
10/29/2027 | 6 | 273 | ||||||||||||||||
12/29/2028 | 6 | 427 | ||||||||||||||||
3/29/2030 | 6 | 455 | ||||||||||||||||
8/29/2031 | 6 | 518 | ||||||||||||||||
10/29/2032 | 6 | 427 | ||||||||||||||||
7/29/2033 | 6 | 273 | ||||||||||||||||
12/29/2034 | 6 | 518 | ||||||||||||||||
8/29/2036 | 6 | 609 | ||||||||||||||||
5/29/2037 | 6 | 273 | ||||||||||||||||
1/29/2038 | 6 | 245 | ||||||||||||||||
10/29/2038 | 6 | 273 | ||||||||||||||||
7/29/2039 | 6 | 273 | ||||||||||||||||
3/29/2041 | 6 | 609 | ||||||||||||||||
8/29/2042 | 6 | 518 | ||||||||||||||||
5/29/2043 | 6 | 273 | ||||||||||||||||
1/29/2044 | 6 | 245 | ||||||||||||||||
7/29/2044 | 6 | 182 | ||||||||||||||||
12/29/2045 | 6 | 518 | ||||||||||||||||
3/29/2047 | 6 | 455 |
Logic thông thường: 36525 ngày, lặp 36525 lần.2. Vòng lặp do lô gic Toán số. Mục đích để tránh sự lặp lại vô ích.
Mượn code của bạn cantl và theo gợi ý của anh @ptm0412 tôi code lại thế này.Logic thông thường: 36525 ngày, lặp 36525 lần.
Thêm "logic toán số":
Logic 1: Một tuần chỉ có 1 chủ nhật. Nếu lặp theo tuần thì chỉ 5200 tuần & 5200 vòng lặp
Logic 2: Một tháng chỉ có 1 ngày cuối tháng. Nếu lặp theo tháng thì chỉ lặp 1200 vòng lặp
Logic 3: 1 năm chỉ có 7 tháng có ngày 31. Nếu tìm cách lặp theo logic này thì chỉ lặp 700 vòng lặp.
Vậy nên chọn theo logic 3.
Option Explicit
Sub zzz()
Dim Thang, t&, y&, m&, CurrentDate As Date
Thang = Array(1, 3, 5, 7, 8, 10, 12)
For y = 2000 To 2099
For m = LBound(Thang) To UBound(Thang)
CurrentDate = DateSerial(y, Thang(m), 31)
If Weekday(CurrentDate) = vbSunday Then
t = t + 1
Sheet2.Range("A" & t) = CurrentDate
End If
Next
Next
End Sub
Option Explicit
Sub zzz()
Dim Thang, t&, y&, m, CurrentDate As Date
Dim List31Sunday()
Dim Count&, i&
Dim tmr#
tmr = Timer
Count = 0
Thang = Array(1, 3, 5, 7, 8, 10, 12)
For y = 2001 To 2100
For Each m In Thang
i = i + 1
CurrentDate = DateSerial(y, m, 31)
If CurrentDate Mod 7 = 1 Then
Count = Count + 1
ReDim Preserve List31Sunday(1 To Count)
List31Sunday(Count) = CurrentDate
End If
Next
Next
Range("A1").Resize(Count, 1) = Application.Transpose(List31Sunday)
MsgBox "lap " & i & " vong lap trong " & ((Timer - tmr) * 1000) & " miligiay"
End Sub
=LET(a,SEQUENCE(100,,2001),c,MAP(a,LAMBDA(x,TEXTJOIN(",",1,CHOOSE(WEEKDAY(DATE(x,3,31),1),3,8,{5,13},10,7,12,"")+12*(x-2000)))),TEXT(DATE(2000,TEXTSPLIT(TEXTJOIN(",",1,IF(WEEKDAY(MIN(a)&"/1/31",1)=1,1,""),IFERROR(c,"")),,","),31),"ddd dd mm yyyy"))
Sub ListSundays()
Dim i As Integer, J As Integer, K As Integer, Year As Integer
Dim Month As Integer, LastDay As Integer, DayOfWeek As Integer, Count As Integer
Dim sundays() As String
ReDim sundays(0 To 0)
Count = 0
For i = 20 To 99
Year = i * 100
For J = 1 To 12
Month = J
LastDay = Day(DateSerial(Year, Month + 1, 0))
For K = 1 To LastDay
DayOfWeek = Weekday(DateSerial(Year, Month, K))
If K = 31 And DayOfWeek = 1 Then
ReDim Preserve sundays(0 To Count)
sundays(Count) = Format(DateSerial(Year, Month, K), "dd/mm/yyyy")
Count = Count + 1
End If
Next K
Next J
Next i
If Count = 0 Then
MsgBox "Không có ngày 31 nào trong các tháng của thế kỷ này roi vào chủ nhật."
Else
MsgBox "Các ngày 31 trong các tháng của thế kỷ này roi vào chủ nhật là: " & Join(sundays, ", ")
End If
End Sub
Nó hiểu thế kỷ từ 2000, vậy là nó hiểu sai giống em.For i = 20 To 99
Year = i * 100
nó là sự cố, nghĩa là YKK, hình như là 1 loại khóa kéo bác ạ.
Làm sao biết CurrentDate Mod 7 = 1 chắc chắn là chủ nhật?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
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.(/ậy bạn nghỉ Y2K là như thế nào?
Thế anh có tin nó không? Nó duyệt các năm 2000, 2100, 2200, 2300, ... , 9900. Một giai đoạn kéo dài 80 thế kỷCòn đây là ChartGPT 4 dạy cho mình:
PHP:For i = 20 To 99 Year = i * 100
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.Làm sao biết CurrentDate Mod 7 = 1 chắc chắn là chủ nhật?
Phát sinh vấn đề là quy nạp vội, nhưng may. May ở chỗ ngày 1/1/1900 là chủ nhật và mod 7 = 1Vậy phát sinh vấn đề
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
vậy em sửa lại đoạn này là đượcCần đọc lại bài 23
View attachment 297823
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