VBA에서 Leapyear를 어떻게 찾습니까?
VBA에서 IsLapYear 기능을 잘 구현한 것은 무엇입니까?
편집: if-then 및 DateSerial 구현을 타이머로 감싼 상태에서 실행한 결과 DateSerial이 평균적으로 1-2ms 더 빨랐습니다(300회 반복 5회 실행, 평균 셀 워크시트 공식 1회 작동).
Public Function isLeapYear(Yr As Integer) As Boolean
' returns FALSE if not Leap Year, TRUE if Leap Year
isLeapYear = (Month(DateSerial(Yr, 2, 29)) = 2)
End Function
저는 원래 칩 피어슨의 훌륭한 엑셀 사이트에서 이 기능을 얻었습니다.
public function isLeapYear (yr as integer) as boolean
isLeapYear = false
if (mod(yr,400)) = 0 then isLeapYear = true
elseif (mod(yr,100)) = 0 then isLeapYear = false
elseif (mod(yr,4)) = 0 then isLeapYear = true
end function
위키백과에서 자세한 내용...http://en.wikipedia.org/wiki/Leap_year
효율성이 고려 사항이고 예상 연도가 임의인 경우 가장 빈번한 경우를 먼저 수행하는 것이 약간 더 나을 수 있습니다.
public function isLeapYear (yr as integer) as boolean
if (mod(yr,4)) <> 0 then isLeapYear = false
elseif (mod(yr,400)) = 0 then isLeapYear = true
elseif (mod(yr,100)) = 0 then isLeapYear = false
else isLeapYear = true
end function
Chip Pearson 솔루션의 변형으로, 당신은 또한 다음과 같이 시도할 수 있습니다.
Public Function isLeapYear(Yr As Integer) As Boolean
' returns FALSE if not Leap Year, TRUE if Leap Year
isLeapYear = (DAY(DateSerial(Yr, 3, 0)) = 29)
End Function
CodeToad에서 이 재미있는 것을 발견했습니다.
Public Function IsLeapYear(Year As Varient) As Boolean
IsLeapYear = IsDate("29-Feb-" & Year)
End Function
함수에서 IsDate를 사용하는 것은 아마도 여러 if, elseifs보다 느릴 것이라고 확신합니다.
성능 문제를 해결하기 위한 늦은 답변.
TL/DR: 수학 버전이 약 5배 더 빠릅니다.
여기 두 그룹의 답이 보입니다.
- 윤년 정의의 수학적 해석
- Excel Date/Time 기능을 활용하여 Feb 29를 탐지합니다(날짜를 문자열로 작성하는 경우와 그렇지 않은 경우).
게시된 모든 답변에 대해 시간 테스트를 실행해보니 수학 방법이 날짜/시간 방법보다 약 5배 빠릅니다.
그리고 나서 방법을 최적화해서 생각해냈습니다. (믿거나 말거나)Integer
보다 약간 빠릅니다.Long
이 경우, 이유를 알 수 없습니다.
Function IsLeapYear1(Y As Integer) As Boolean
If Y Mod 4 Then Exit Function
If Y Mod 100 Then
ElseIf Y Mod 400 Then Exit Function
End If
IsLeapYear1 = True
End Function
비교를 위해, 제가 올라왔습니다 (게시된 버전과 거의 차이가 없습니다)
Public Function IsLeapYear2(yr As Integer) As Boolean
IsLeapYear2 = Month(DateSerial(yr, 2, 29)) = 2
End Function
날짜를 문자열로 작성하는 Date/Time 버전은 다시 훨씬 느려지기 때문에 할인됩니다.
시험은 다음과 같이 하기로 되어 있었습니다.IsLeapYear
100년동안..9999, 1000번 반복
결과.
- 수학 버전 : 640ms
- 날짜/시간 버전 : 3360ms
테스트 코드는
Sub Test()
Dim n As Long, i As Integer, j As Long
Dim d As Long
Dim t1 As Single, t2 As Single
Dim b As Boolean
n = 1000
Debug.Print "============================="
t1 = Timer()
For j = 1 To n
For i = 100 To 9999
b = IsYLeapYear1(i)
Next i, j
t2 = Timer()
Debug.Print 1, (t2 - t1) * 1000
t1 = Timer()
For j = 1 To n
For i = 100 To 9999
b = IsLeapYear2(i)
Next i, j
t2 = Timer()
Debug.Print 2, (t2 - t1) * 1000
End Sub
Public Function ISLeapYear(Y As Integer) AS Boolean
' Uses a 2 or 4 digit year
'To determine whether a year is a leap year, follow these steps:
'1 If the year is evenly divisible by 4, go to step 2. Otherwise, go to step 5.
'2 If the year is evenly divisible by 100, go to step 3. Otherwise, go to step 4.
'3 If the year is evenly divisible by 400, go to step 4. Otherwise, go to step 5.
'4 The year is a leap year (it has 366 days).
'5 The year is not a leap year (it has 365 days).
If Y Mod 4 = 0 Then ' This is Step 1 either goto step 2 else step 5
If Y Mod 100 = 0 Then ' This is Step 2 either goto step 3 else step 4
If Y Mod 400 = 0 Then ' This is Step 3 either goto step 4 else step 5
ISLeapYear = True ' This is Step 4 from step 3
Exit Function
Else: ISLeapYear = False ' This is Step 5 from step 3
Exit Function
End If
Else: ISLeapYear = True ' This is Step 4 from Step 2
Exit Function
End If
Else: ISLeapYear = False ' This is Step 5 from Step 1
End If
End Function
Public Function isLeapYear(Optional intYear As Variant) As Boolean
If IsMissing(intYear) Then
intYear = Year(Date)
End If
If intYear Mod 400 = 0 Then
isLeapYear = True
ElseIf intYear Mod 4 = 0 And intYear Mod 100 <> 0 Then
isLeapYear = True
End If
End Function
데이트 기능에 대한 추가적인 이해와 사용법을 나타내는 많은 훌륭한 개념들을 볼 수 있습니다. 이 개념들은...에서 배울 수 있는 멋진 것들입니다.코드 효율성 측면에서..함수를 실행하는 데 필요한 기계 코드를 고려합니다.
복잡한 날짜 함수보다는 꽤 빠른 정수 함수만 사용합니다. 베이직은 GOTO 위에 구축되어 있습니다. 아래와 같은 것이 더 빠른 것 같습니다.
Function IsYLeapYear(Y%) As Boolean
If Y Mod 4 <> 0 Then GoTo NoLY ' get rid of 75% of them
If Y Mod 400 <> 0 And Y Mod 100 = 0 Then GoTo NoLY
IsYLeapYear = True
노리:
End Function
여기 또 하나의 간단한 옵션이 있습니다.
Leap_Day_Check = Day(DateValue("01/03/" & Required_Year) - 1)
Leap_Day_Check = 28이면 윤년이 아니고 29이면 윤년입니다.
VBA는 1년 후 3월 1일 이전 날짜를 알고 있으며, 2월 28일 또는 29일로 설정할 예정입니다.
언급URL : https://stackoverflow.com/questions/128104/how-do-you-find-leapyear-in-vba
'prosource' 카테고리의 다른 글
JDB를 이용하여 지도 데이터를 가져오는 방법CT 템플릿.queryForMap (0) | 2023.10.30 |
---|---|
앱에 키트 저장 잘못된 제품 식별자 구매 (0) | 2023.10.30 |
mysql 타임스탬프 열 (0) | 2023.10.30 |
Powershell로 이진 파일 읽기/파싱 (0) | 2023.10.30 |
Red Hat 리눅스 기반 MariaDB ODBC (0) | 2023.10.30 |