[Bài tập vui]: Tìm ra mươi ngày 13 rơi vào thứ sáu gần hôm nay nhất! (1 người xem)

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

Người dùng đang xem chủ đề này

SA_DQ

/(hông là gì!
Thành viên danh dự
Tham gia
8/6/06
Bài viết
14,689
Được thích
23,043
Nghề nghiệp
U80
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!

Chúc các bạn vui vẻ & mạnh khỏe nhân dịp xuân về!
 
Gần trong tương lai hay cả quá khứ bác Sa nhỉ?
 
Cả quá khứ nữa chứ!
 
Bác cho hỏi thêm 1 câu, dùng Excel 365 hay phải chơi để Excel 2010 dùng được.
 
Xài 'dao' nào cũng được, miễn là có thể biến gà thành mồi!
 
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!

Chúc các bạn vui vẻ & mạnh khỏe nhân dịp xuân về!
Cái này chắc bác sa phải nói rõ ra, công thức excel nhưng dùng một công thức hay thế nào? có cột phụ gì không? chứ chơi kiểu kéo 13/01/1921...13/02/1921.. cho đến 13/12/2121 rồi một cột là weekday(a1,1)=6 cũng kéo hết ra true, xong filter cũng cho kết quả
 
3 xị có thể đổ vô 2 chai mà, bạn!
Cái này chắc bác sa phải nói rõ ra, công thức excel nhưng dùng một công thức hay thế nào? có cột phụ gì không? chứ chơi kiểu kéo 13/01/1921...13/02/1921.. cho đến 13/12/2121 rồi một cột là weekday(a1,1)=6 cũng kéo hết ra true, xong filter cũng cho kết quả
Về công thức thì mình mù, các bạn làm sao cũng xong! Nhưng không lọc à nha!
 
Lần chỉnh sửa cuối:
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!

Chúc các bạn vui vẻ & mạnh khỏe nhân dịp xuân về!
A2 = today()

Các ngày sau ngày hiện hành
B2 =SMALL(IF(WEEKDAY(EOMONTH($A$2,ROW($1:$100)-IF(DAY($A$2)>13,1,2))+13)=6,EOMONTH($A$2,ROW($1:$100)-IF(DAY($A$2)>13,1,2))+13,""),ROW(A1))

Các ngày gần nhất trước và sau ngày hiện hành
D2 =LOOKUP(2,1/(IF(WEEKDAY(EOMONTH($A$2,ROW($1:$200)-100)+13)=6,ABS($A$2-EOMONTH($A$2,ROW($1:$200)-100)+13),"")=SMALL(IF(WEEKDAY(EOMONTH($A$2,ROW($1:$200)-100)+13)=6,ABS($A$2-EOMONTH($A$2,ROW($1:$200)-100)+13),""),ROW(A1))),EOMONTH($A$2,ROW($1:$200)-100)+13)
Có khả năng sai với xác suất rất bé

Cả 2 là công thức mảng: Ctrl+Shift+Enter
Copy xống 10 dòng
 

File đính kèm

3 xị có thể đổ vô 2 chai mà, bạn!

Về công thức thì mình mù, các bạn làm sao cũng xong! Nhưng không lọc à nha!
Làm đại như này bác à, vì sắp hết giờ nên chưa kịp nghiên cứu thêm zụ abs gì đó nữa :
Mã:
=AGGREGATE(15,6,1/(WEEKDAY(DATE(ROW(INDIRECT("2010:2030")),{1,2,3,4,5,6,7,8,9,10,11,12},13),1)=6)*DATE(ROW(INDIRECT("2010:2030")),{1,2,3,4,5,6,7,8,9,10,11,12},13),ROW(A1))
 
VBA cho kết quả vầy nè:
STTNgàyThứ
10
4/13/2018​
6​
8
7/13/2018​
6​
6
9/13/2019​
6​
4
12/13/2019​
6​
3
3/13/2020​
6​
1
11/13/2020​
6​
2
8/13/2021​
6​
5
5/13/2022​
6​
7
1/13/2023​
6​
9
10/13/2023​
6​
 
Tôi nhớ có luật rằng "Thứ Sáu 13 sẽ nằm vào tháng bắt đầu bằng ngày chủ nhật".
Câu hỏi: có thể dựa vào đó để làm thuật toán?
 
1613817007643.png

Mã:
=SMALL(IF(WEEKDAY(EOMONTH(TODAY(),ROW(INDIRECT("1:1000"))-500)+13)=6,EOMONTH(TODAY(),ROW(INDIRECT("1:1000"))-500)+13),ROW(A1))
Bài đã được tự động gộp:

1613817084698.png


=INDEX($G$12:$G$118,MATCH(SMALL(ABS($G$12:$G$118-TODAY()),ROW(A1)),ABS($G$12:$G$118-TODAY()),0))
Bài đã được tự động gộp:

Chưa chứng mình được là không thể tồn tại hai ngay thỏa mãn điều kiện mà cùng cách ngày hiện tại những lượng bằng nhau, nên công thức chưa ngọt ngào như ý.
 
Lần chỉnh sửa cuối:
VBA cho kết quả vầy nè:
STTNgàyThứ
10
4/13/2018​
6​
8
7/13/2018​
6​
6
9/13/2019​
6​
4
12/13/2019​
6​
3
3/13/2020​
6​
1
11/13/2020​
6​
2
8/13/2021​
6​
5
5/13/2022​
6​
7
1/13/2023​
6​
9
10/13/2023​
6​
Góp vui: Chỉ lấy 10 ngày như kết quả của anh gửi.
Mã:
A1=AGGREGATE(15,6,MOD(AGGREGATE(15,6,ABS(TODAY()-EDATE(EOMONTH(TODAY(),0)+13,61-ROW($1:$121)))*10^6+EDATE(EOMONTH(TODAY(),0)+13,61-ROW($1:$121))/(WEEKDAY(EDATE(EOMONTH(TODAY(),0)+13,61-ROW($1:$121)))=6),ROW($1:$10)),10^6),ROW())
Enter.

Chúc anh em ngày vui.

Thân
 

File đính kèm

Ôi phải nói là quá ư siêu luôn! Các bạn khác có công nhận với mình không vậy?

& cũng nhờ bài tập này mà mình gặp lại bạn hiền; Lâu nay vắng bóng xứ nào vậy!

Cho biết địa chỉ để mình gởi 3 xị rượu tổ iến đến bạn & hạn ngạch thới gian là 1 tháng; Cũng có thể đến nhận thưởng tại nhà luôn nha, khi đó báo trước 1 buổi để còn chuẩn bị mồi!
 
Ôi phải nói là quá ư siêu luôn! Các bạn khác có công nhận với mình không vậy?

& cũng nhờ bài tập này mà mình gặp lại bạn hiền; Lâu nay vắng bóng xứ nào vậy!

Cho biết địa chỉ để mình gởi 3 xị rượu tổ iến đến bạn & hạn ngạch thới gian là 1 tháng; Cũng có thể đến nhận thưởng tại nhà luôn nha, khi đó báo trước 1 buổi để còn chuẩn bị mồi!
Dạ! tại anh thương em út nên mới khen như vậy, chứ lúc này trên diễn đàn của mình xuất hiện nhiều sao sáng và lạ nữa, còn em của anh thì rút lui vào bóng râm ở ẩn rồi anh. Lâu rồi mở trang GPE ra thấy anh có câu đố nên ngứa tay ngứa chân mà giải đố cho vui chung với anh em, chứ bài em giải 'dài ngoằn ngoèo' có hay gì đâu anh.

Xứ em ở mới bị bão tuyết nên mất điện, mất nước đang nằm co ro chờ ngày bình minh đến. Vừa may có điện, lướt qua 'nhà cũ' lại gặp anh 'nắm đầu kéo vô'.
Vậy em xin lưu giữ thịnh tình của anh dành cho em, hẹn một ngày không còn 'mắc dịch' nữa anh em hội mình sẽ tái hội.

Chúc anh và anh em sức khỏe, nhiều, càng nhiều, càng càng nhiều sức khỏe và may mắn, vui tươi.

Em của anh.
 
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!

Chúc các bạn vui vẻ & mạnh khỏe nhân dịp xuân về!
Em cũng làm thử, nhưng kết quả có vẻ khác của bác lấy trước tháng 2/2021 5 ngày, sau tháng 2/2021 cũng 5 ngày:
Mã:
=SMALL(AGGREGATE({15,14},6,TEXT(MID(SUBSTITUTE(TEXT(EOMONTH(TODAY(),ROW($1:$150)-75)+13,"ddd ddmmmy"),"Fri",REPT(" ",11)),13,7),{"[<","[>="}&TODAY()&"];")^{1,-1}*{-1,1},ROW($1:$5))^{1,-1}*{-1,1},ROW(1:1))
 
Lần chỉnh sửa cuối:
/(ết quả do VBA đưa lại là không thể chối cải, nha! Nó tính ngay từ mốc ngày hiện hành luôn & đi theo 2 chiều âm & dương.
Gặp ngày nào trước là nó đưa vô danh sách thôi. (& nó thoát khi đã hoàn thành nhiệm vụ đề ra - không thiếu hay không dư)

Rất cảm ơn bạn nhiều!

Chúc các bạn vui, khỏe & hạnh phúc!
 
/(ết quả do VBA đưa lại là không thể chối cải, nha! Nó tính ngay từ mốc ngày hiện hành luôn & đi theo 2 chiều âm & dương.
Gặp ngày nào trước là nó đưa vô danh sách thôi. (& nó thoát khi đã hoàn thành nhiệm vụ đề ra - không thiếu hay không dư)

Rất cảm ơn bạn nhiều!

Chúc các bạn vui, khỏe & hạnh phúc!
Của em dựa vào tiêu chí trước và sau, nên cũng không chính xác lắm nếu xét theo ngày gần nhất. Nếu dựa vào ngày gần nhất thì sẽ phải trừ cho ngày hiện tại và tìm 10 ngày sát nhất.
Chắc em đã hiểu nhầm vấn đề :eek: :eek:
 
Cách của bạn chỉ tìm 1 trong mười ngày đó mà thôi;
Đề bài là tìm cả mười ngày thứ sáu 13 gần nhất trong 1 lúc cơ!

Mình thử viết hàm mảng tự tạo & có nội dung sau:
PHP:
Function T6N13(Optional Dat As Date)
 ReDim Arr(1 To 10, 1 To 3)
 Dim J As Long, W As Integer
 
 If Dat < 9 Then Dat = Date
 If Day(Dat) = 13 Then Dat = Dat - 1
 For J = 1 To 10000
 If Day(J + Dat) = 13 And Weekday(J + Dat) = 6 Then
    W = W + 1:                  Arr(W, 2) = Format(J + Dat, "MM/DD/yy")
    Arr(W, 3) = J:              Arr(W, 1) = W
 End If
 If W = 10 Then Exit For
 If Day(Dat - J) = 13 And Weekday(Dat - J) = 6 Then
    W = W + 1:                  Arr(W, 2) = Format(Dat - J, "MM/DD/yy")
    Arr(W, 3) = Space(1) & -J:  Arr(W, 1) = W
 End If
 If W = 10 Then Exit For
 Next J
 T6N13 = Arr()
End Function
 
Lần chỉnh sửa cuối:
Mình thử viết hàm mảng tự tạo & có nội dung sau:
PHP:
...
For J = 1 To 10000
If Day(J + Dat) = 13 And Weekday(J + Dat) = 6 Then
...
Một tháng chỉ có một ngày 13. Chỉ cần lấy một lần ngày 13, sau có cứ +/- tháng (hàm DateAdd)
 
Lúc đầu mình cũng định đi theo hướng như vậy, nhưng 1 vài trường hợp cụ thể thì không thỏa yêu cầu & sẽ bị ai đó khó tính cự nự:

STTNgàyDel ta
112/13/19-45=T6N13(DATE(2020,1,27))
203/13/20
46
309/13/19-136
411/13/20
291​
507/13/18-563
608/13/21
564​
704/13/18-654
810/13/17-836
905/13/22
837​
1001/13/23
1082​

Chúc các bạn có mùa xuân vui vẻ & hạnh phúc!
 
Một tháng chỉ có một ngày 13. Chỉ cần lấy một lần ngày 13, sau có cứ +/- tháng (hàm DateAdd)
Em góp vui với hàm tự tạo dựa theo ý tưởng của thầy VetMini với hàm tự tạo của thầy SA_DQ :D

PHP:
Function T6N13_2(Dat As Date, Count As Long)
    ReDim Arr(1 To Count, 1 To 3)
    Dim i As Long, j As Long, Year_Dat As Long
    Dim W As Long
    i = Month(Dat)
    j = Month(Dat)
    Year_Dat = Year(Dat)
    Do Until W = Count
        If (Weekday(DateSerial(Year_Dat, i, 13))) = 6 Then
            W = W + 1
            Arr(W, 1) = W
            Arr(W, 2) = Format(DateSerial(Year_Dat, i, 13))
            Arr(W, 3) = DateDiff("d", Dat, DateSerial(Year_Dat, i, 13))
        End If
        If W = Count Then Exit Do
        If (Weekday(DateSerial(Year_Dat, j, 13))) = 6 Then
            W = W + 1
            Arr(W, 1) = W
            Arr(W, 2) = Format(DateSerial(Year_Dat, j, 13))
            Arr(W, 3) = DateDiff("d", Dat, DateSerial(Year_Dat, j, 13))
        End If
        i = i + 1: j = j - 1
    Loop
    T6N13_2 = Arr()
End Function
 
Theo thống kê thì chỉ có tháng 2 thì mệnh đề
i = i + 1:
mới vậy thôi, còn các tháng khác ta có thể
i = i + 2:
Thậm chí 1 số tháng ta có thể
i = i + 3:

Xin các bạn cho ý kiến nhận xét của mình tiếp về vấn đề này (?)
 
Lúc đầu mình cũng định đi theo hướng như vậy, nhưng 1 vài trường hợp cụ thể thì không thỏa yêu cầu & sẽ bị ai đó khó tính cự nự:
Nếu vậy thì chỉ cần xét số nào kiểm tra trước, số nào kiểm tra sau thôi, đỡ hơn là kiểm tra từng ngày.
Mã:
Function T6N13(Dat As Date)
    Dim Arr(1 To 10, 1 To 3)
    Dim a As Long, z As Long, i As Date, k As Long, d As Long, m As Long, y As Long
    d = Day(Dat):   m = Month(Dat): y = Year(Dat)
    If d < 13 Then a = -1
    z = a + 1
    Do Until k = 10
        If Dat - DateSerial(y, m + a, 13) < DateSerial(y, m + z, 13) - Dat Then
            i = DateSerial(y, m + a, 13):   a = a - 1
        Else
            i = DateSerial(y, m + z, 13):   z = z + 1
        End If
        If Weekday(i) = 6 Then
            k = k + 1:      Arr(k, 2) = Format(i, "dd/mm/yyyy")
            Arr(k, 1) = k:  Arr(k, 3) = i - Dat
        End If
    Loop
    T6N13 = Arr
End Function
 
Xài bộ lọc và vài hàm đơn giản cho nhàn! Tính từ 1900 đến 4637 luôn! :D

View attachment 265615
 
Bần đạo tu trên núi lâu quá không biết bằng hữu đàm đạo chuyện này. Thôi thì góp vui vậy. Lưu ý dùng excel phiên bản tầng thứ 9 cửu âm chân kinh 365 mới được.
Cho trước 1 ngày cột mốc nào đó (ví dụ hôm nay), Cho trước số lần tìm Thứ Sáu ngày 13 (ví dụ 10 ngày),

Danh sách các ngày thứ sáu 13 trở về trước (trước ngày cột mốc):
=LET(MyDay,$B$1-SEQUENCE(5000),MDate1,TEXT(MyDay,"DDD"),MDate2,TEXT(MyDay,"DD"),mRange,FILTER(MyDay,(MDate1="Fri")*(MDate2="13"),"Not Found"),mOrder,SEQUENCE(COUNTA(mRange)),FILTER(mRange,mOrder<=$B$2,"Not Found"))

Danh sách các ngày thứ sáu 13 trở về sau (sau ngày cột mốc):
=LET(MyDay,$B$1+SEQUENCE(5000),MDate1,TEXT(MyDay,"DDD"),MDate2,TEXT(MyDay,"DD"),mRange,FILTER(MyDay,(MDate1="Fri")*(MDate2="13"),"Not Found"),mOrder,SEQUENCE(COUNTA(mRange)),FILTER(mRange,mOrder<=$B$2,"Not Found"))

Nối 2 danh sách bên trên lại thành 1 danh sách gom bỏ vô trong 1 cột (Kiểu như "append data"):
=LET(Array1,OFFSET($A4,,,$B$2),Array2,OFFSET($B4,,,$B$2),ColToAppend,CHOOSE({1,2},Array1,Array2),FILTER(INDEX(ColToAppend,MOD(SEQUENCE(ROWS(ColToAppend)*COLUMNS(ColToAppend),,0),ROWS(ColToAppend))+1,SEQUENCE(ROWS(ColToAppend)*COLUMNS(ColToAppend),,0,1/ROWS(ColToAppend))+1),NOT(ISERROR(INDEX(ColToAppend,MOD(SEQUENCE(ROWS(ColToAppend)*COLUMNS(ColToAppend),,0),ROWS(ColToAppend))+1,SEQUENCE(ROWS(ColToAppend)*COLUMNS(ColToAppend),,0,1/ROWS(ColToAppend))+1)))))

test.jpg
 

File đính kèm

Lần chỉnh sửa cuối:
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!

Chúc các bạn vui vẻ & mạnh khỏe nhân dịp xuân về!
Dạo này có tuổi nên HÀM yếu lắm rồi bác, mà vẫn xin 3 xị rượu nhé bác Sa, hẹn 1 ngày gần nhất ở SG.
 
Nối 2 danh sách bên trên lại thành 1 danh sách gom bỏ vô trong 1 cột (Kiểu như "append data"):
Nếu đã có 2 danh sách ở A4 và B4 thì nối lại như sau:

=LET(db,A4#,da,B4#,rwb,ROWS(db),rwa,ROWS(da),IF(SEQUENCE(rwb+rwa)<=rwb,INDEX(db,SEQUENCE(rwb+rwa),1),INDEX(da,SEQUENCE(rwb+rwa)-rwb,1)))
 
Nếu đã có 2 danh sách ở A4 và B4 thì nối lại như sau:

=LET(db,A4#,da,B4#,rwb,ROWS(db),rwa,ROWS(da),IF(SEQUENCE(rwb+rwa)<=rwb,INDEX(db,SEQUENCE(rwb+rwa),1),INDEX(da,SEQUENCE(rwb+rwa)-rwb,1)))
Nay bần lão được thọ giáo chiêu A4# (thay cho offset) của tiên sinh, quả thật khâm phục, khâm phục!
 
Lần chỉnh sửa cuối:
Bần đạo tu trên núi lâu quá không biết bằng hữu đàm đạo chuyện này. Thôi thì góp vui vậy. Lưu ý dùng excel phiên bản tầng thứ 9 cửu âm chân kinh 365 mới được.
Cho trước 1 ngày cột mốc nào đó (ví dụ hôm nay), Cho trước số lần tìm Thứ Sáu ngày 13 (ví dụ 10 ngày),

Danh sách các ngày thứ sáu 13 trở về trước (trước ngày cột mốc):


Danh sách các ngày thứ sáu 13 trở về sau (sau ngày cột mốc):


Nối 2 danh sách bên trên lại thành 1 danh sách gom bỏ vô trong 1 cột (Kiểu như "append data"):


View attachment 265746
Vì bài này mảng là Date nên có thể dùng cách này để gom 2 mảng
Mã:
=LET(a,A4#,b,B4#,SMALL((a,b),SEQUENCE(COUNT(a,b))))

Nếu đã có 2 danh sách ở A4 và B4 thì nối lại như sau:

=LET(db,A4#,da,B4#,rwb,ROWS(db),rwa,ROWS(da),IF(SEQUENCE(rwb+rwa)<=rwb,INDEX(db,SEQUENCE(rwb+rwa),1),INDEX(da,SEQUENCE(rwb+rwa)-rwb,1)))
Nếu đặt thêm biến nữa công thức sẽ gọn, so index thì 2 mảng không cùng cấu trúc vẫn được vì nó luôn xét từ trên xuống
Mã:
=LET(db,A4#,da,B4#,lst,SEQUENCE(ROWS(db)+ROWS(db))-ROWS(db),IF(lst<=0,db,INDEX(da,lst)))


Góp vui dùng 365 cho bài này không tách khớp
Mã:
=LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,"dd ddd")="13 Fri"),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))
 
Lần chỉnh sửa cuối:
Góp vui dùng 365 cho bài này không tách khớp
Mã:
=LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,"dd ddd")="13 Fri"),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))
Khà khà khà, đúng là ngọa hổ tàng long. Mong anh em bằng hữu có dịp đàm đạo luận kiếm, cầm tay uống rượu!
 
Thấy mấy bạn dùng hàm tôi hoảng hồn.
 
Một công thức thôi, nhập vào ô bất kỳ (chỉ dùng Excel 2007 hoặc 2010)
Mã:
=IF(ROWS(A$1:A1)<11,AGGREGATE(14,6,(EDATE(EDATE(TODAY()-DAY(TODAY())+13,-(DAY(TODAY())<=13)),1-ROW($1:$120)))/
(WEEKDAY(EDATE(EDATE(TODAY()-DAY(TODAY())+13,-(DAY(TODAY())<=13)),1-ROW($1:$120)))=6),11-ROWS(A$1:A1)),
IF(ROWS(A$1:A1)<21,AGGREGATE(15,6,(EDATE(EDATE(TODAY()-DAY(TODAY())+13,--(DAY(TODAY())>13)),ROW($1:$120)-1))/(WEEKDAY(EDATE(EDATE(TODAY()-DAY(TODAY())+13,--(DAY(TODAY())>13)),ROW($1:$120)-1))=6),ROWS(A$1:A1)-10),""))
Kết thúc bình thường Enter.

Kéo xuống dưới thành 20 dòng.

10 dòng đầu là 10 ngày trước, 10 dòng sau là 10 ngày sau. 20 ngày theo đúng thứ tự tăng dần từ quá khứ tới tương lai.

Công thức có 2 nhánh (2 IF) để tính 10 trước và 10 ngày sau. Nếu muốn tính 10 ngày trước và 10 ngày sau riêng rẽ ở 2 cột thì "cắt" từ công thức ở trên ra.
 
Mình không biết dùng hàm mình ngồi mình đếm thủ công tầm 10 năm từ 1/1/2021 đến 31/12/2031 thì có 17 ngày thứ sáu ngày 13:

1631273379214.png
Bài đã được tự động gộp:

Cách của bạn chỉ tìm 1 trong mười ngày đó mà thôi;
Đề bài là tìm cả mười ngày thứ sáu 13 gần nhất trong 1 lúc cơ!

Mình thử viết hàm mảng tự tạo & có nội dung sau:
PHP:
Function T6N13(Optional Dat As Date)
 ReDim Arr(1 To 10, 1 To 3)
 Dim J As Long, W As Integer
 
 If Dat < 9 Then Dat = Date
 If Day(Dat) = 13 Then Dat = Dat - 1
 For J = 1 To 10000
 If Day(J + Dat) = 13 And Weekday(J + Dat) = 6 Then
    W = W + 1:                  Arr(W, 2) = Format(J + Dat, "MM/DD/yy")
    Arr(W, 3) = J:              Arr(W, 1) = W
 End If
 If W = 10 Then Exit For
 If Day(Dat - J) = 13 And Weekday(Dat - J) = 6 Then
    W = W + 1:                  Arr(W, 2) = Format(Dat - J, "MM/DD/yy")
    Arr(W, 3) = Space(1) & -J:  Arr(W, 1) = W
 End If
 If W = 10 Then Exit For
 Next J
 T6N13 = Arr()
End Function
Mình viết code thấy nó ngắn gọn sao các bác viết dài thòn vậy ta?

PHP:
Sub Test()
    Dim arrDate()
    Dim n As Long
    Dim d As Date, dteFromDate As Date, dteToDate As Date
    dteFromDate = Date
    dteToDate = DateSerial(2031, 12, 31)
    For d = dteFromDate To dteToDate
        If Weekday(d) = 6 And Day(d) = 13 Then
            n = n + 1
            ReDim Preserve arrDate(1 To n)
            arrDate(n) = d
            If n = 10 Then Exit For
        End If
    Next
    Range("F5").Resize(n).Value = WorksheetFunction.Transpose(arrDate)
End Sub
 
Lần chỉnh sửa cuối:
Mình không biết dùng hàm mình ngồi mình đếm thủ công tầm 10 năm từ 1/1/2021 đến 31/12/2031 thì có 17 ngày thứ sáu ngày 13:

View attachment 265791
Có năm có 1, có năm có 2, 3 thứ 6 ngày 13. Trong công thức ở bài #35 tôi lấy trung bìng là 1 năm 1 lần thứ 6 ngày 13. Vì thế để xét 10 lần thứ 6 ngày 13 thì tôi xét 10 năm, tức 120 tháng. Vì thế có con số 120 - ROW($1:$120)
 
Mình viết code thấy nó ngắn gọn sao các bác viết dài thòn vậy ta?

PHP:
Sub Test()
    Dim arrDate()
    Dim n As Long
    Dim d As Date, dteFromDate As Date, dteToDate As Date
    dteFromDate = Date
    dteToDate = DateSerial(2031, 12, 31)
    For d = dteFromDate To dteToDate
        If Weekday(d) = 6 And Day(d) = 13 Then
            n = n + 1
            ReDim Preserve arrDate(1 To n)
            arrDate(n) = d
            If n = 10 Then Exit For
        End If
    Next
    Range("F5").Resize(n).Value = WorksheetFunction.Transpose(arrDate)
End Sub
Từ hiện tại phải dò theo 2 hướng chứ bạn?
 
Từ hiện tại phải dò theo 2 hướng chứ bạn?
Hướng nào và hướng nào?

Còn dùng hàm còn ngắn gọn hơn nữa!
PHP:
Function FindFriday13th(ByVal intCount As Integer) As Variant
    Dim arrDate(), d As Date, n As Long
    d = Date
    Do
        If Weekday(d) = 6 And Day(d) = 13 Then
            n = n + 1
            ReDim Preserve arrDate(1 To n)
            arrDate(n) = d
            If n = intCount Then Exit Do
        End If
        d = d + 1
    Loop
    FindFriday13th = WorksheetFunction.Transpose(arrDate)
End Function

Nếu như trong bài đếm số lượng 10 ngày gần đây nhất thì công thức: =FindFriday13th(10)
 
Hướng nào và hướng nào?

Còn dùng hàm còn ngắn gọn hơn nữa!
PHP:
Function FindFriday13th(ByVal intCount As Integer) As Variant
    Dim arrDate(), d As Date, n As Long
    d = Date
    Do
        If Weekday(d) = 6 And Day(d) = 13 Then
            n = n + 1
            ReDim Preserve arrDate(1 To n)
            arrDate(n) = d
            If n = intCount Then Exit Do
        End If
        d = d + 1
    Loop
    FindFriday13th = WorksheetFunction.Transpose(arrDate)
End Function

Nếu như trong bài đếm số lượng 10 ngày gần đây nhất thì công thức: =FindFriday13th(10)
Thì chủ thớt đã nói rồi đó chi. Gần nhất 10 ngày là phải tính 5 ngày từ hiện tại đến tương lai + 5 ngày từ hiện tại đến quá khứ.
 
Thì chủ thớt đã nói rồi đó chi. Gần nhất 10 ngày là phải tính 5 ngày từ hiện tại đến tương lai + 5 ngày từ hiện tại đến quá khứ.
Dễ òm chứ gì, sắp xếp theo trình tự thời gian luôn nè.

PHP:
Function Find2DFriday13th(ByVal intCount As Integer) As Variant
    Dim intBefore As Integer, intAfter As Integer
    Dim arrDate, d1 As Date, d2 As Date, blnLimit As Boolean
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    d1 = Date: d2 = d1
    intBefore = Fix(intCount / 2): intAfter = intBefore
    Do
        If Not blnLimit Then
            If Weekday(d1) = 6 And Day(d1) = 13 Then
                arrDate(intBefore, 1) = d1
                intBefore = intBefore - 1
                If intBefore = 0 Then blnLimit = True
            End If
            d1 = d1 - 1
        Else
            If Weekday(d2) = 6 And Day(d2) = 13 Then
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d2
                If intAfter = intCount Then Exit Do
            End If
            d2 = d2 + 1
        End If
    Loop
    Find2DFriday13th = arrDate
End Function

Tính số lẻ đi cho nó máu!

=Find2DFriday13th(13)
 
Mà bài #41 nó dài dòng quá nhỉ? Vậy thì rút gọn lại thôi!

PHP:
Function Find2DFriday13th_New(ByVal intCount As Integer) As Variant
    Dim arrDate, d As Date, intBefore As Integer, intAfter As Integer
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    intBefore = Fix(intCount / 2): intAfter = intBefore: d = Date
    Do
        d = IIf(intBefore, d - 1, d + 1)
        If Weekday(d) = 6 And Day(d) = 13 Then
            If intBefore > 0 Then
                arrDate(intBefore, 1) = d
                intBefore = intBefore - 1
                If intBefore = 0 Then d = Date
            Else
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d
            End If
        End If
    Loop Until intAfter = intCount
    Find2DFriday13th_New = arrDate
End Function
 
Bài đã được tự động gộp:


Mình viết code thấy nó ngắn gọn sao các bác viết dài thòn vậy ta?
Mấy cái code này thế giới giải đầy ra rồi vụ thứ sáu ngày 13. chỉ là tập thể dục thôi. Dài ngắn quan trọng gì.
Ngon viết thứ sáu ngày 20 đi. Nhớ viết bằng công thức nha. Yêu cầu của thớt là công thức. còn VBA thì người ta giải cách đây 20 năm rồi.
 
Ủa mà quên, mỗi tháng chỉ có một ngày 13 duy nhất, mắc mớ gì mình tính theo ngày chi ta? Cập nhật lại:
PHP:
Function Find2DFriday13th_HTN(ByVal intCount As Integer) As Variant
    Dim arrDate, d As Date, intBefore As Integer, intAfter As Integer
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    intBefore = Fix(intCount / 2): intAfter = intBefore
    d = DateSerial(Year(Date), Month(Date), 13)
    Do
        d = DateSerial(Year(d), Month(d) + IIf(intBefore, -1, 1), 13)
        If Weekday(d) = 6 Then
            If intBefore > 0 Then
                arrDate(intBefore, 1) = d
                intBefore = intBefore - 1
                If intBefore = 0 Then d = DateSerial(Year(Date), Month(Date) - 1, 13)
            Else
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d
            End If
        End If
    Loop Until intAfter = intCount
    Find2DFriday13th_HTN = arrDate
End Function

Mấy cái code này thế giới giải đầy ra rồi vụ thứ sáu ngày 13. chỉ là tập thể dục thôi. Dài ngắn quan trọng gì.
Ngon viết thứ sáu ngày 20 đi. Nhớ viết bằng công thức nha. Yêu cầu của thớt là công thức. còn VBA thì người ta giải cách đây 20 năm rồi.
Nói có sách, mách có chứng, xin nguồn.
Còn hiện tại ở bài này, ngắn thì nói ngắn.
 
Lần chỉnh sửa cuối:
Ủa mà quên, mỗi tháng chỉ có một ngày 13 duy nhất, mắc mớ gì mình tính theo ngày chi ta? Cập nhật lại:
PHP:
Function Find2DFriday13th_HTN(ByVal intCount As Integer) As Variant
    Dim arrDate, d As Date, intBefore As Integer, intAfter As Integer
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    intBefore = Fix(intCount / 2): intAfter = intBefore
    d = DateSerial(Year(Date), Month(Date), 13)
    Do
        d = DateSerial(Year(d), Month(d) + IIf(intBefore, -1, 1), 13)
        If Weekday(d) = 6 Then
            If intBefore > 0 Then
                arrDate(intBefore, 1) = d
                intBefore = intBefore - 1
                If intBefore = 0 Then d = DateSerial(Year(Date), Month(Date) - 1, 13)
            Else
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d
            End If
        End If
    Loop Until intAfter = intCount
    Find2DFriday13th_HTN = arrDate
End Function
Bài đã được tự động gộp:


Nói có sách, mách có chứng, xin nguồn.
Còn hiện tại ở bài này, ngắn thì nói ngắn.
Topic này yêu cầu là công thức mà các hạ!???? VBA ai chả biết!
 
Topic này yêu cầu là công thức mà các hạ!???? VBA ai chả biết!
Ủa các hạ không để ý sao? Tôi trích bài #20 của chính tác giả, và tác giả dùng VBA để viết hàm, nên tôi mới dùng VBA để so sánh. Mà GPE đã từng có tiền lệ ai viết code ngắn nhất và có thời gian nhanh nhất hay sao??????
 
Ủa các hạ không để ý sao? Tôi trích bài #20 của chính tác giả, và tác giả dùng VBA để viết hàm, nên tôi mới dùng VBA để so sánh. Mà GPE đã từng có tiền lệ ai viết code ngắn nhất và có thời gian nhanh nhất hay sao??????
À, nếu so ngắn dài, thì ngắn bằng này hông các hạ?? Viết code VBA chi cho dài dòng vậy cà!
LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,"dd ddd")="13 Fri"),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))
 
Code VBA thì ngắn từng này thôi (nếu xét về độ ngắn)

Sub ChaubaThong()
Sheet1.[A1].Formula2 = "=LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,""dd ddd"")=""13 Fri""),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))"
End Sub

Khà khà khà
-----------
Xoá 1 phần bài viết bởi ptm0412
 
Chỉnh sửa lần cuối bởi điều hành viên:
VBA cho kết quả vầy nè:
STTNgàyThứ
10
4/13/2018​
6​
8
7/13/2018​
6​
6
9/13/2019​
6​
4
12/13/2019​
6​
3
3/13/2020​
6​
1
11/13/2020​
6​
2
8/13/2021​
6​
5
5/13/2022​
6​
7
1/13/2023​
6​
9
10/13/2023​
6​
Nếu code chạy ngày 20.02.2021 thì kết quả sai. Vì không đúng với giả thiết là liệt kê 5 ngày trước và 5 ngày sau ngày hiện hành. Kết quả trên có 6 ngày trước và 4 ngày sau ngày hiện hành.
 
Ủa các hạ không để ý sao? Tôi trích bài #20 của chính tác giả, và tác giả dùng VBA để viết hàm, nên tôi mới dùng VBA để so sánh.
Bài #20 không tính vì lúc đó trạng thái là đã uống hết 1 xị rồi (ngồi đợi quen tay cứ rót thôi). Muốn biết lúc tỉnh táo thế nào thì xem bài #1
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!
 
Code VBA thì ngắn từng này thôi (nếu xét về độ ngắn)

Sub ChaubaThong()
Sheet1.[A1].Formula2 = "=LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,""dd ddd"")=""13 Fri""),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))"
End Sub

Khà khà khà
Bài đã được tự động gộp:


Google sheet thì qua Google sheet chơi cho vui đi, vô đây làm gì ta!?? Excel 365 là Excel 365, chẳng lẽ quay lại excel 2003, hay thích quay lại Lotus 123??? Mà thôi, VBA sắp lạc hậu rồi các hạ à!
Vẫn còn dài lắm các hạ ơi!

Mã:
Sub N()
    [A1].Resize(20).Formula = Find2DFriday13th_HTN(20)
End Sub
 
Code ngắn chưa hẳn là nhanh, code dài chưa hẳn là không tối ưu. GPE không có "tiền lệ", việc đánh giá code ngon căn cứ vào tốc độ và độ dài ngắn chỉ là 1 số người trên GPE chứ không phải nguyên GPE.
Code VBA thì ngắn từng này thôi (nếu xét về độ ngắn)
Đây là code ăn gian.
Công thức dùng hàm VBA, hay hàm VBA dùng công thức (Formula) cũng đều là ăn gian.
365 xài Lambda mới là đỉnh của rút gọn công thức.
 
Mấy bài nhảm nhàm không liên quan không có ích cho diễn đàn, hy vọng các cao nhân soi sét dẹp bớt cho thiên hạ thái bình!
befaint có lý mà. Nếu so sánh ngắn gài, nhanh chậm thì phải xét trong cùng bối cảnh. Vd. phải cùng phiên bản. Nếu so sánh phiên bản 365 với 2010 thì khác gì anh chơi cờ mà lại có lợi con xe. Mà dùng 365 thì hỏa lực của anh hạn chế rồi. Có rất nhiều người không chạy được công thức dùng 365.
 
Phàm nếu thứ sáu ngày 13 thì ngày đầu tháng đó là chủ nhật, ngày chúa nghỉ ngơi!
Còn ông Như lai hay Ala có nghỉ hay không không chắc á nha!

Chúc các bạn vui khỏe & hẹn gặp nhau sau mùa dịch!
 
Chỗ tôi ảnh hưởng bão Conson, mưa quá trời luôn. Mưa quá chẳng ngủ được. Bác Sa dậy sớm hay là cũng không ngủ được vậy?
 
Tên bão đó do VN đăng ký, nên phải viết chí ít là Con Son, khà, khà, khà,. . . .
Mình vừa trãi qua 1 đêm ngon giấc đó bạn!

Chúc 1 buổi sáng tốt lành!
 

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

Back
Top Bottom