Làm việc với ngày tháng

tuhocvba

Administrator
Thành viên BQT
Tôi đã có vài trao đổi với Nguyễn Hồng Quang . Những trao đổi đó dựa vào kinh nghiệm .
Vì liên quan tới dự án hỗ trợ code cho thành viên hiện đang được tiến hành, hôm nay tôi muốn thảo luận với các bạn về một việc khác, đó là tìm ngày đầu tiên của tuần, tìm vị trí của tuần trong năm.
Đây không phải là thử thách, cũng không phải là việc tôi không làm được,chỉ đơn thuần là trao đổi với các bạn mà thôi.
Tôi rất vui nếu chúng ta cùng nhau đặt ra các vấn đề có thể có, rồi cùng nhau giải quyết. Topic tương tác như vậy sẽ dẫn tới nhiều vấn đề được gợi mở và giải quyết.
Vậy cho phép tôi được bắt đầu.
INPUT: tháng/ngày/năm
OUPUT: Trả về vị trí tuần trong năm chứa ngày đó.
Mã:
Sub test()
    Dim d1  As String
    Dim d   As Date
    d1 = "1/14/2020"
    d1 = Format(d1, "mm/dd/yyyy")
    d = CDate(d1)
    MsgBox Application.WeekNum(d)
End Sub
kết quả các bạn được là 3.
Tức là ngày 13 tháng 1 năm 2020 nằm ở tuần thứ 3 trong năm.

Vấn đề:
Input: tuần thứ 3 trong năm (Tuần được định nghĩa là ngày đầu tiên trong tuần là thứ 2, kết thúc vào CN)
Ouput: Ra ngày đầu tiên của tuần thứ 3. Ngày 13 tháng 1 năm 2020
 
D

Deleted member 1392

Guest
INPUT: Số tuần (d1) trong năm (d2)
OUTPUT: Ngày đầu tiên trong tuần theo input (d3).

Dựa theo logic đó ta có code như sau:
Mã:
Sub test()
    Dim d1, d2 As Long
    Dim d3   As Date
 
    '//INPUT: SO TUAN TRONG NAM
    d1 = 3
    d2 = 2020
 
    '//OUTPUT: NGAY DAU TIEN TRONG TUAN TU INPUT
    d3 = Format(d3, "mm/dd/yyyy")
    d3 = DateSerial(d2, 1, (d1 - 1) * 7 - Weekday(DateSerial(d2, 1, 1), vbMonday) + 2)
 
    '//MSGBOX KET QUA
    MsgBox d3
End Sub
Vấn đề:
INPUT:
Ngày bất kì trong năm (vd: 13.01.2020)
OUTPUT: Ngày cuối cùng của tháng từ INPUT (vd: 31.01.2020)
 
Sửa lần cuối bởi điều hành viên:
D

Deleted member 208

Guest
d3 = DateSerial(d2, 1, (d1 - 1) * 7 - Weekday(DateSerial(d2, 1, 1), vbMonday) + 2)
Mình không hiểu công thức này.
d2 là năm: 2002
1: là gì vậy bạn
Mã:
(d1 - 1) * 7 - Weekday(DateSerial(d2, 1, 1), vbMonday) + 2
Công thức trên được tính dựa trên suy nghĩ logic nào?
Bạn có thể giải thích cho mình hiểu được không?
 
B

bvtvba

Guest
Vấn đề:
Input: tuần thứ 3 trong năm (Tuần được định nghĩa là ngày đầu tiên trong tuần là thứ 2, kết thúc vào CN)
Ouput: Ra ngày đầu tiên của tuần thứ 3. Ngày 13 tháng 1 năm 2020
Cách đặt vấn đề thế này không hay lắm ạ. Vì thông tin thiếu năm.
Tuần thứ 3 nhưng của năm 2020 hay của năm 2019. Vì vậy không thể tự nhiên ra 13/1/2020. Tại sao lại là năm 2020.

Em nghĩ đặt vấn đề như sau:
Vấn đề 1:
Input: d1
Output: Ra vị trí tuần như bài #1

Vấn đề 2:
Input: d1
Output: d2 là ngày đầu tuần, tuần mà chứa ngày d1. (Tuần: thứ 2 =>CN)

Mình không hiểu công thức này.
d2 là năm: 2002
1: là gì vậy bạn
Mã:
(d1 - 1) * 7 - Weekday(DateSerial(d2, 1, 1), vbMonday) + 2
Công thức trên được tính dựa trên suy nghĩ logic nào?
Bạn có thể giải thích cho mình hiểu được không?
Công thức #2 mình không hiểu lắm.
Nhưng suy nghĩ logic cũng tính được ra như thế này:
Ví dụ xét trong năm 2020.
Ngày 1/1/2020 (ngày-tháng-năm cho dễ nói chuyện) bao giờ cũng là tuần 1.
+7 ngày bao giờ cũng ra tuần 2.
+7 ngày sẽ ra tuần 3.
...

Như vậy tuần thứ n ta cần lấy một ngày bất kỳ trong tuần này, sẽ xác định = ngày 1/1/2020 + (n-1)*7. Gọi ngày này là d. xác định nó là thứ 4 thì trừ 2 để về thứ 2. Nếu là thứ 5 thì trừ 3 để về thứ 2. Việc xác định thứ của một ngày là việc làm đươc. Đấy, logic nó như vậy.
 

tuhocvba

Administrator
Thành viên BQT
Vấn đề:
INPUT:
Ngày bất kì trong năm (vd: 13.01.2020)
OUTPUT: Ngày cuối cùng của tháng từ INPUT (vd: 31.01.2020)
Vấn đề này mình giải quyết rồi nhé.

Cảm ơn bạn @bvtvba , bạn đặt vấn đề rất hay, trình bày rất logic, dễ hiểu.
 

NhanSu

SMod
Thành viên BQT
Nếu input là d1 as date, output d2 là ngày cuối tháng thì có thể có một số cách:
Mã:
Dim d1 as date, d2 as date
D1=#4/25/2020#
D2=day(dateserial(year(d1),month(d1)+1,0)
D2=worksheetfunction.eomonth(d1,0)
Hoặc có thể tính trực tiếp dựa vào tháng và năm. Năm nhuận là các năm chia hết cho 4 nhưng không chia hết cho 100 hoặc các năm chia hết cho 400.
 
D

Deleted member 208

Guest
Mã:
Dim d1 as date, d2 as date
D1=#4/25/2020#
D2=day(dateserial(year(d1),month(d1)+1,0)
D2=worksheetfunction.eomonth(d1,0)
Dòng code số 3 đỏ, báo lỗi anh ơi.
Bạn cần đăng nhập để thấy hình ảnh
 

NhanSu

SMod
Thành viên BQT
Mình viết trên điện thoại nên nhầm, dòng màu đỏ là
Mã:
D2=dateserial(year(d1),month(d1)+1,0)
 
T

thanhphong

Guest
Vấn đề 2:
Input: d1
Output: d2 là ngày đầu tuần, tuần mà chứa ngày d1. (Tuần: thứ 2 =>CN)
Mã:
Sub test()
    Dim d1  As String
    Dim d   As Date
    d1 = "2020/5/2"
    d = CDate(Format(d1, "yyyy/mm/dd"))
    d = layngaythu2(d)
    MsgBox d
End Sub
'INPUT: 2020/5/2
'OUTPUT: 2020/4/27
Function layngaythu2(ByVal d As Date) As Date
    layngaythu2 = d - Weekday(d, vbSunday) + 2
End Function
Nhân tiện nói tới ngày tháng: Dân kỹ thuật có lẽ ít phải xử lý ngày tháng, nhưng người làm kế toán, kế hoạch thì phải sử dụng tới ngày tháng rất nhiều. Định dạng ngày tháng thì vô vàn, thậm chí người dùng có thể tự định nghĩa.
Một kiểu ngày tháng chúng ta hay gặp là:
Bạn cần đăng nhập để thấy hình ảnh

20-Apr là giá trị hiển thị nhưng giá trị thực sự của nó là 2020/4/20 (năm-tháng-ngày).
Vậy bây giờ vấn đề đặt ra là tôi có giá trị ngày 2020/4/20, làm sao để hiển thị là 20-Apr. Nếu có file excel thì bạn chỉ cần chuột phải vào cells rồi chọn format, bạn sẽ thấy định dạng của nó là d-mmm.
Mã:
Sub test()
    Dim d1  As String
    Dim d   As Date
    d1 = "2020/5/2"
    d = CDate(Format(d1, "yyyy/mm/dd"))
    d = layngaythu2(d)
    d1 = Format(d, "d-mmm")
    MsgBox d1
End Sub
'INPUT: 2020/5/2
'OUTPUT: 2020/4/27
Function layngaythu2(ByVal d As Date) As Date
    layngaythu2 = d - Weekday(d, vbSunday) + 2
End Function
Vấn đề: Tôi có d as date.
d = 27/4/2020 (ngày-tháng-năm)
Ghi d vào cells A1 và có hiển thị là 27-Apr. Không convert ra string. Làm sao để khi click chuột vào cells A1 phải hiển thị ra là 27/4/2020 (có thể tùy thuộc vào thiết định trên máy tính mà hiển thị là 2020/4/27 hoặc 4/27/2020 nhưng điều tôi muốn nói là định dạng cells A1 phải là date chứ không phải string).
Bạn cần đăng nhập để thấy hình ảnh
 

PTHhn

Yêu THVBA như điếu đổ
Vấn đề: Tôi có d as date.
d = 27/4/2020 (ngày-tháng-năm)
Ghi d vào cells A1 và có hiển thị là 27-Apr. Không convert ra string. Làm sao để khi click chuột vào cells A1 phải hiển thị ra là 27/4/2020 (có thể tùy thuộc vào thiết định trên máy tính mà hiển thị là 2020/4/27 hoặc 4/27/2020 nhưng điều tôi muốn nói là định dạng cells A1 phải là date chứ không phải string).
Bạn cần đăng nhập để thấy hình ảnh
Bạn kiểm tra:
Mã:
Sub Macro1()
    Dim d As Date
    d = CDate(Format("5/4/2020", "dd/mm/yyyy"))
    ThisWorkbook.Sheets(1).Cells(1, 1) = d
    ThisWorkbook.Sheets(1).Cells(1, 1).NumberFormatLocal = "d-mmm"
End Sub
 
Top