Bạn có biết một sự kiện lịch sử nào đó xảy ra vào thứ mấy ?

Liên hệ QC
Trời... nếu nói vậy thì phải xem lại toàn bộ hệ thống chương trình Visual Basic rồi ---> Cái này thì tôi xin thua!
Nếu bạn nói Excel có sai sót thì tôi chấp nhận, còn nói Visual Basic có sai về ngày tháng thì... e rằng bạn nói hơi qua
Nếu bạn cảm thấy không tin tưởng độ chình xác của Visual Basic thì tự mình tìm lấy đáp án khác vậy!
Ẹc... Ẹc...

Năm 1900 không phải năm nhuận, điều này là đương nhiên khỏi phải bàn cải ---> Có tìm khắp Google cũng là câu trả lời đó mà thôi
Em không nói VB sai ngày tháng mà chỉ muốn nói thuật toán trong đoạn code test ở bài #14, dùng nó để test thì có vẻ không được thuyết phục. Nếu anh dùng thuật toán đó để test trên công thức Excel thì kết quả cũng không có gì thay đổi.
 
Em không nói VB sai ngày tháng mà chỉ muốn nói thuật toán trong đoạn code test ở bài #14, dùng nó để test thì có vẻ không được thuyết phục. Nếu anh dùng thuật toán đó để test trên công thức Excel thì kết quả cũng không có gì thay đổi.
Tôi thấy rất hợp lý, không có gì là không thuyết phục cả:
- Trước tiên ta phải chấp nhận rằng hệ thống ngày tháng của VB là chuẩn ---> Ví nếu ngay cả điều cơ bản này mà không chuẩn thì toàn bị giải thuật sau đó sẽ phá sản
- Tiếp theo, lấy WEEKDAY của ngày cần tính (là ngày 1/1/ 1900)
- Từ kết quả trên ta cứ tính tiếp đến hôm nay (dùng toán tự MOD, không dùng WEEKDAY)... nếu cách tính bằng toán tử mod cho kết quả = WEEKDAY(hôm nay) thì chứng tỏ cái WEEKDAY đầu tiên là đúng
---------------------------------------------------
Điều cốt lỏi ở đây là phải chấp nhận hệ thống ngày tháng của VB là chuẩn ---> Điều này thì tôi không đủ dũng cảm để nghi ngờ
Còn nếu làm trên Excel thì không chắc lắm... Ta thừa biết Excel luôn có những sai sót kỳ lạ và ngớ ngẩn
Tóm lại: Nếu triển khai giải thuật trên Excel thì mới là không thuyết phục còn trên VB thì.. quá OK (Excel không hề biết năm 1900 là năm không nhuận)
---------------------------------------------------
Mà thôi... điều quan trọng là tôi đã biết được chính xác ngày 4 tháng 7 năm 1776 và ngày 1 tháng 1 năm 1900 thuộc thứ mấy là đủ rồi
 
Co AddIn này để xử lý ngày tháng năm từ năm 100 trở đi
http://j-walk.com/ss/excel/files/xdate.htm
Ta biết rằng hệ thống ngày tháng của VB là rất chuẩn, vậy thay vì dùng 1 Add-In nào đó, tự ta cũng viết được vậy
Theo đường link trên, ta có danh sách tên người cùng ngày sinh, ngày chết như sau:

presidents.gif


Đây phần lớn đều là ngày tháng trước năm 1900 nên không thể dùng công thức thông thường tính được (kể cả DATEDIF)... nhưng VB code hoàn toàn làm được điều này
PHP:
Function xDateYearDIF(ByVal Date1, ByVal Date2) As Long
  xDateYearDIF = Year(Date2) - Year(Date1) + (Format(Date2, "mmdd") < Format(Date1, "mmdd"))
End Function
Yêu cầu nhập liệu:
- Hoặc là nhập đúng quy định trong Control Panel
- Hoặc là luôn nhập ngày tháng theo chuẩn yyyy/mm/dd
---------------------
Với VB code thì dù tính Weekday hay bất cứ cái gì liên quan đến ngày tháng trước năm 1900 đều được tuốt
 

File đính kèm

  • xDateYearDIF.xls
    22 KB · Đọc: 9
Em cũng hay thường nghiên cứu dạng ngày tháng năm lắm.nhưng hôm nay thầy ndu và anh bebo cho em thấy được cái hay của ngày tháng rồi cám ơn su phụ ndu và anh bebo nhiều nhé.
 
Đó là năm 1800 và năm 1900 chăng?
Năm này chia hết 100 nhưng không chia hết cho 400
Theo đó thì trong VBA nó "biết" được không có ngày 29 tháng 2 năm 1900 nhưng công thức Excel thì không biết điều này
Code kiểm chứng
PHP:
Sub Test()
 MsgBox DateSerial(1900, 2, 29)
End Sub
Đúng vậy, chạy code này sẽ chỉ ra hai năm đó không nhuận:
Mã:
Sub Test()
  Dim dat1 As Date, dat2 As Date, i As Date, j As Long, k As Long
  dat1 = DateSerial(1776, 7, 4)
  dat2 = Date
  For i = dat1 To dat2
    If Day(i) = 28 And Month(i) = 2 And Year(i) Mod 4 = 0 Then j = 1
    If Day(i) = 29 And Month(i) = 2 And Year(i) Mod 4 = 0 Then k = 1
    If Day(i) = 1 And Month(i) = 3 And Year(i) Mod 4 = 0 Then
        If j <> k Then MsgBox Year(i)
        k = 0: j = 0
    End If
  Next
End Sub
Đồng thời phù hợp với quy luật của lịch Gregory
 
Đúng vậy, chạy code này sẽ chỉ ra hai năm đó không nhuận:
Mã:
Sub Test()
  Dim dat1 As Date, dat2 As Date, i As Date, j As Long, k As Long
  dat1 = DateSerial(1776, 7, 4)
  dat2 = Date
  For i = dat1 To dat2
    If Day(i) = 28 And Month(i) = 2 And Year(i) Mod 4 = 0 Then j = 1
    If Day(i) = 29 And Month(i) = 2 And Year(i) Mod 4 = 0 Then k = 1
    If Day(i) = 1 And Month(i) = 3 And Year(i) Mod 4 = 0 Then
        If j <> k Then MsgBox Year(i)
        k = 0: j = 0
    End If
  Next
End Sub
Đồng thời phù hợp với quy luật của lịch Gregory
Biết rằng năm 1776 là năm nhuận, vậy ta chỉ cần xét duy nhất tháng 2 từng 4 năm 1 lần là được rồi
Vòng lập vầy sẽ nhanh hơn:
PHP:
Sub Test2()
  Dim dat As Date, m As Long
  Do
    dat = DateSerial(1776, 2 + m, 28)
    If Month(dat + 1) = 3 And (Year(dat) Mod 4 = 0) Then MsgBox Year(dat)
    m = m + 48
  Loop Until dat >= Date
End Sub
Từ đó có thể biết được từ năm 100 đến nay có bao nhiêu năm chia hết cho 4 nhưng lại không phải năm nhuận:
PHP:
Sub Test3()
  Dim dat As Date, m As Long
  Do
    dat = DateSerial(100, 2 + m, 28)
    If Month(dat + 1) = 3 And (Year(dat) Mod 4 = 0) Then MsgBox Year(dat)
    m = m + 48
  Loop Until dat >= Date
End Sub
 
Lần chỉnh sửa cuối:
cháu dùng hàm INT và MOD cũng tính được bác xem thử, hôm trước cháu tính sai vì không biết năm có tận cùng là 00 mà không chia hết 400 không phải năm nhuận --=0
 
cháu dùng hàm INT và MOD cũng tính được bác xem thử, hôm trước cháu tính sai vì không biết năm có tận cùng là 00 mà không chia hết 400 không phải năm nhuận --=0
Bạn tính thế nào gửi lên đây xem thử có chính xác không?
 
cháu sửa ở đầu topic , vì trả lời nhanh cháu không biết attach file --=0
 
cháu sửa ở đầu topic , vì trả lời nhanh cháu không biết attach file --=0
Tính cũng hay lắm
Để tôi thử cách tính của tôi xem thế nào
- Cell C3 là NĂM
- Cell C4 là THÁNG
- Cell C5 là NGÀY
- Cell C6 là công thức tính WEEKDAY:
PHP:
=TEXT(MOD(C3+INT((C3-1)/4)-INT((C3-1)/100)+INT((C3-1)/400)+DATE(IF(MOD(C3,100)=0,IF(MOD(C3,400)>0,1,0),IF(MOD(C3,4)=0,0,1)),C4,C5)-DATE(IF(MOD(C3,100)=0,IF(MOD(C3,400)>0,1,0),IF(MOD(C3,4)=0,0,1)),1,1)+1,7),"[$-42A]dddd")
Một công thức duy nhất, không cột phụ
Kiêm tra lại xem có sai sót gì không nha!
 

File đính kèm

  • Weekday_NDU.xls
    36.5 KB · Đọc: 15
Tính cũng hay lắm
Để tôi thử cách tính của tôi xem thế nào
- Cell C3 là NĂM
- Cell C4 là THÁNG
- Cell C5 là NGÀY
- Cell C6 là công thức tính WEEKDAY:
PHP:
=TEXT(MOD(C3+INT((C3-1)/4)-INT((C3-1)/100)+INT((C3-1)/400)+DATE(IF(MOD(C3,100)=0,IF(MOD(C3,400)>0,1,0),IF(MOD(C3,4)=0,0,1)),C4,C5)-DATE(IF(MOD(C3,100)=0,IF(MOD(C3,400)>0,1,0),IF(MOD(C3,4)=0,0,1)),1,1)+1,7),"[$-42A]dddd")
Một công thức duy nhất, không cột phụ
Kiêm tra lại xem có sai sót gì không nha!
híc! Thầy có mở lớp đào tạo Ex,hay có đệ tự nào mở lớp ngoài Hà nội không cho em xin địa chỉ em đến học với.
Nhìn thầy và mọi người mà em thấy khát quá!
 
Nhân đây xin hỏi các bạn 1 câu:
Như tôi nói ở trên thì ngày 4 tháng 7 năm 1776 thuộc thứ năm ---> Vậy ta dùng phương pháp gì để kiểm chứng kết quả?

Nhân đây xin hỏi các bạn 1 câu:
Như tôi nói ở trên thì ngày 4 tháng 7 năm 1776 thuộc thứ năm ---> Vậy ta dùng phương pháp gì để kiểm chứng kết quả?
1- Tôi đến Link nầy nhờ Google với câu hỏi: Tính toán ngày trước 1/1/1900.
2- Rất thú vị và Cảm ơn khi https://www.giaiphapexcel.com/ đã tìm ra cách tính các ngày trước 1/1/1900: Nhờ IDE (Integrated Development Environment) hay Môi trường tích hợp. Cái nầy ít chặt chẽ, chúng cứ xem dãy String đúng quy cách là chuyển qua trị số Long, mà không cần kiểm tra trước hay sau 1/1/1900 (Function IsDate). Nghĩa là chúng cứ áp dụng quy tắc của Microsoft mở rộng cho cả những ngày trước mốc, là số âm. Các phép toán hoàn toàn chính xác nếu thêm hàm Abs để biến thành dương.
3- Chỉ lưu ý là thời điểm tháng 10/1582, Date là (m/d/y) 10/15/1582 là ngày bắt đầu lịch Gregorius. Trước 15/10/1582 là ngày 4/10/1582 (Lịch Julius) = nhảy 10 ngày.
Vd: Tìm WeekDay của ngày (m/d/y) 10/14/1582 mà thực tế lịch Gregorius không có ngày nầy, hàm WeekDay vẫn trả về là 5, và tương tự ngày (m/d/y) 10/4/1582 thực tế có của lịch Julius là Thứ Năm, nhưng hàm WeekDay trả về là 2.
Code IDE: Msgbox WeekDay("10/4/1582")
[Nếu cần thiết: Điều nầy đòi hỏi chúng ta phải viết một hàm riêng mà giá trị trả về là String chứ không phải Date để thích hợp với lịch Julius trước thời điểm đó].
 

File đính kèm

  • october1582-copy.png
    october1582-copy.png
    171.2 KB · Đọc: 2
Web KT
Back
Top Bottom