워크시트에서는 날짜 차이를 계산하는 함수명이 DateDif인데, VBA에서는 DateDiff로 다릅니다.
1. 구문
DateDiff(interval, date1, date2, [ firstdayofweek, [ firstweekofyear ]] )
o interval(간격)의 유형
Setting | Description |
yyyy | Year (연) |
q | Quarter (분기) |
m | Month (월) |
y | Day of year (몇번째 날) |
d | Day (일) |
w | Weekday (같은 요일에 해당하는 주의 수) |
ww | Week (firstdayofweek 설정에 따라 일요일인 경우는 일요일부터 일요일까지의 주의 수) |
h | Hour (시) |
n | Minute (분) |
s | Second (초) |
- w와 ww의 차이점
간격이 요일(weekday, "w")인 경우 DateDiff는 두 날짜 사이의 주 수를 반환합니다. date1이 월요일이면 DateDiff는 date2까지의 월요일 수를 계산합니다. date2는 계산하지만 date1은 계산하지 않습니다. 그러나 간격이 주(week, "ww")인 경우 DateDiff 함수는 firstdayofweek 설정에 따라 달력을 기준으로 두 날짜 사이의 주 수를 반환합니다. firstdayofweek 설정이 vbSunday이거나 지정하지 않으면, date1과 date2 사이의 일요일 수를 계산합니다. DateDiff는 date2가 일요일이면 계산하며, date1이 일요일이더라도 date1은 계산되지 않습니다. |
o date1, date2
DateDif 함수와 달리 시작일, 종료일 순일 필요는 없으며, 종료일, 시작일 순이면 마이너스 값이 구해집니다.
o firstdayofweek(주의 첫째 날)
Visual Basic 상수 | 값 | 설명 |
vbUseSystem | 0 | Use the NLS(National Language Support) API setting(나라별 언어 지원 API 설정 사용) |
vbSunday | 1 | Sunday (default) (일요일) |
vbMonday | 2 | Monday (월요일) |
vbTuesday | 3 | Tuesday (화요일) |
vbWednesday | 4 | Wednesday (수요일) |
vbThursday | 5 | Thursday (목요일) |
vbFriday | 6 | Friday (금요일) |
vbSaturday | 7 | Saturday (토요일) |
o firstweekofyear(연도의 첫번째 주) : 이것은 특별한 의미가 없는 듯 합니다.
VB 상수 | 값 | 설명 |
vbUseSystem | 0 | Use the NLS API setting. (나라별 언어 지원 API 설정 사용) |
vbFirstJan1 | 1 | Start with week in which January 1 occurs (default). (1.1일이 첫번째 주임, 기본값) |
vbFirstFourDays | 2 | Start with the first week that has at least four days in the new year. (ISO 8601에 의하면 한 주는 월요일부터 시작하고, 첫번째 주는 첫번째 목요일임) |
vbFirstFullWeek | 3 | Start with first full week of the year. (7일이 모두 있는 첫번째 주) |
3. DateDif 함수와 비교
DATEDIF(start_date,end_date,unit)
https://lsw3210.tistory.com/entry/%EB%82%A0%EC%A7%9C%EA%B0%84%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EA%B3%84%EC%82%B01-DateDif 참고
구분 | DateDif 함수(Worksheet 함수) | DateDiff 함수(VBA) |
날짜 입력 순서 | start_date와 end_date의 순서가 다르면 에러 발생 | date1이 date2보다 작아야 하는데, 크다면 마이너스 값 반환 |
interval, unit 입력 순서 | unit를 맨 뒤에 입력 | interval을 맨 앞에 입력 |
연 | unit : y | interval : yyyy |
일 | unit : d | interval : y 또는 d |
주 | unit : 없음 | interval : w 또는 ww |
연도를 무시한 월 차이 | unit : ym | interval : 없음 |
연도를 무시한 일 차이 | unit : yd | interval : 없음 |
4. 예제
아래와 같이 시작일과 종료일을 대상으로 DateDif함수와 DateDiff함수의 값을 비교해보겠습니다.
가. DateDif 함수
D열의 수식은 unit이 있기 때문에
D2셀의 수식은 =DATEDIF(A2,B2,C2)이며, 이 수식을 D6셀까지 복사하면 주소가 자동으로 변경되기 때문에 쉽게 연, 월과 일 수, 연도를 무시한 월 수, 연도를 무시한 일 수를 쉽게 구할 수 있습니다.
나. DateDiff 함수
(1) interval, date1, date2만 입력한 경우
DateDiff 함수는 VBA에서 사용하는 함수이기 때문에 삽입 - 모듈 메뉴를 눌러 모듈을 추가한 다음
오른쪽 VB Editor 창에 sub 프로세스를 작성해야 합니다.
Sub datediff1의 내용은 아래와 같습니다.
Sub datediff1()
For i = 2 To 13
'Cells(i, "h") = DateDiff(Cells(i, "e"), Cells(i, "a"), Cells(i, "b"))
Range("h" & i) = DateDiff(Range("e" & i), Range("a" & i), Range("b" & i))
Next
End Sub
Range 프로퍼티를 이용할 수도 있고, 주석으로 처리해서 녹색으로 표시되는 Cells 프로퍼티를 이용해 셀 주소를 지정해서 수식을 특정 셀에 입력할 수 있습니다.
Range("h" & i) = DateDiff(Range("e" & i), Range("a" & i), Range("b" & i)) |
h열 i번째 행에 DateDiff 함수를 이용한 값을 입력하는데, 인수로 첫번째는 interval을 지정하기 윈한 것으로 E열의 i번째 행 값을 입력하고, 두번째는 시작일이므로 A열 i번째 행의 값, 세번째는 종료일로 B열 i행의 값을 입력합니다.
구해진 값은 아래와 같습니다.
D2셀과 H2셀은 연도 차이로 2023년도로 같기 때문에 0이고,
D3셀과 H3셀은 월 차이인데, 모두 4월기 때문에 마찬가지로 0입니다.
D4셀과 H4셀은 일 차이로, 11에서 10을 빼면 모두 1이 됩니다.
D5셀은 unit이 ym으로 연도를 무시한 월수를 반환하기 때문에 연도는 2022와 2023으로 다르더라도 4월에서 4월을 뺀 값을 반환하기 때문에 D5셀의 값은 0입니다.
그러나 DateDiff함수의 경우는 월 차이를 구하는 interval만 있고, 연도를 무시한 월 차이를 구하는 interval은 없어서 m을 적용해 12가 구해졌습니다.
D6셀도 unit이 yd로 연도를 무시하고 일 수를 구하기 때문에 4/17에서 4/10을 빼면 7이 됩니다.
그러나, H6셀의 값을 yd unit에 해당하는 interval이 없어 d를 적용해 372가 나왔습니다.
H7셀은 날짜 사이의 분기 수를 구하는 것으로 2022/03부터 2023/04까지 2/4, 3/4, 4/4, 1/4분기가 있기 때문에 5가 구해집니다.
H8셀은 interval이 y로 d와 같습니다.
H9셀은 같은 요일을 기준으로 주 수를 구하는 것으로
2022/1/2은 일요일이고, 2022/1/10은 월요일인데, 일요일의 개수를 구하는데, date1은 무시하기 때문에 1/9 1개이므로 1이 반환됩니다.
H10셀은 firstdayofweek, 다시 말해 주의 시작일을 기준으로 주 수를 구하는 것으로 기본값이 일요일이기 때문에
1/9 하나뿐이 없어서 1이 반환됩니다.
H11셀은 시간 차이, H12셀은 분 차이, H13셀은 초 차이를 구한 것입니다.
(2) interval, date1, date2에 firstdayofweek 값까지 입력한 경우
datediff2 프로세스의 내용은 아래와 같습니다.
Sub datediff2()
For i = 2 To 13
Range("k" & i) = DateDiff(Range("e" & i), Range("a" & i), Range("b" & i), Range("K14").Value)
Range("l" & i) = DateDiff(Range("e" & i), Range("a" & i), Range("b" & i), Range("L14").Value)
Next
End Sub
시작일과 종료일, interval은 같은데, firstdayofweek를 vbSunday와 vbMonday로 구분해서 값을 구하면
다른 것은 모두 같고, interval이 ww일 때문만 vbSunday일 때는 1인 것이 vbMonday로 하면 2가 반환되는 점이 다릅니다.
K1과 L1셀의 상수명을 이용할 경우 문자열로 인식해서 상수로 인식되지 않아 에러가 발생하기 때문에 K14와 L14셀에 1과 2를 입력했습니다.
firstdayofweek가 vbSunday(값 1)일 때 interval이 ww인 경우 date1은 계산하지 않고, date2가 일요일인 것의 개수를 세는데,
아래 달력을 보면 1/2과 1/10 사이에 일요일이 1/2과 1/9 두 개가 있는데, 1/2는 계산하지 않으므로 한 개이기 때문에 vbSunday의 값은 1이고,
vbMonday(값 2)는 월요일이 1/3과 1/10로 2개이기 때문에 2가 반환되는 것입니다.
(3) interval, date1, date2, firstdayofweek, firstweekofyear 값을 모두 입력한 경우
N15셀에서 vbSunday와 vbMonday 값을 입력받고, N14셀부터 P14셀까지 있는 firstweekofyear 값을 참고하여 DateDiff3 매크로를 실행해서 N2셀부터 P13셀까지의 값을 구합니다.
매크로 내용은 아래와 같습니다.
Sub datediff3()
Dim firstdayofweek As Integer
firstdayofweek = Range("N15")
For i = 2 To 13
For j = 14 To 16
Cells(i, j) = DateDiff(Range("e" & i), Range("a" & i), Range("b" & i), firstdayofweek, Cells(14, j))
Next
Next
For i = 17 To 28
For j = 14 To 16
Cells(i, j) = "DateDiff(""" & Range("e" & (i - 15)) & """ , """ & Range("a" & (i - 15)) & """ , """ & Range("b" & (i - 15)) _
& """ , " & firstdayofweek & ", " & Cells(14, j) & ")"
Next
Next
End Sub
실행해보면 interval이 ww일 경우 firstweekofyear 값은 영향이 없고, firstdayofweek에 따라 값이 달라집니다.
firstdayofweek가 2(vbMonday)인 경우는 firstweekofyear와 관계없이 모두 2를 반환하고,
1(vbSunday)인 경우는 1을 반환합니다.
'EXCEL - VBA' 카테고리의 다른 글
DateAdd함수 - 지정된 기간만큼 떨어진 날짜를 반환(2) - 값 자동 변경 (0) | 2023.04.19 |
---|---|
DateAdd함수 - 지정된 기간만큼 떨어진 날짜를 반환(1) (0) | 2023.04.18 |
일정한 간격으로 된 값 합계 구하기 - 매크로 (2) | 2023.03.21 |
일정한 간격으로 된 값 합계 구하기 - 사용자 정의 함수 (2) | 2023.03.20 |
엑셀에서 전체 범위 선택하기 - VBA (2) | 2023.03.15 |