VBA 텍스트 상자에서 MM/DD/YYY 날짜 형식 지정
VBA 텍스트 박스의 날짜를 MM/DD/YYY 형식으로 자동 포맷하는 방법을 찾고 있는데, 사용자가 입력하는 대로 포맷하고 싶습니다.예를 들어, 사용자가 두 번째 숫자를 입력하면 프로그램이 자동으로 "/"를 입력합니다.다음 코드와 함께 두 번째 대시도 작동했습니다.
Private Sub txtBoxBDayHim_Change()
If txtBoxBDayHim.TextLength = 2 or txtBoxBDayHim.TextLength = 5 then
txtBoxBDayHim.Text = txtBoxBDayHim.Text + "/"
End Sub
이것은 타이핑할 때 매우 효과적입니다.단, 삭제하려고 할 때는 여전히 대시에 입력되기 때문에 사용자는 하나의 대시를 삭제할 수 없습니다(대시를 삭제하면 길이가 2 또는5가 되고 서브가 다시 실행되어 다른 대시를 추가합니다).더 좋은 방법이 없을까요?
날짜를 받아들이기 위해 텍스트 상자나 입력 상자를 사용하는 것은 절대 권장하지 않습니다.너무 많은 것들이 잘못될 수 있어요.mscal.ocx 또는 mscomct2.ocx를 등록해야 한다는 점에서는 Calendar Control 또는 Date Picker를 사용하는 것도 권장할 수 없습니다.또한 이러한 파일은 자유롭게 배포할 수 없기 때문에 매우 어렵습니다.
여기 제가 추천하는 것이 있습니다.사용자 지정 달력을 사용하여 사용자로부터 날짜를 수락할 수 있습니다.
장점:
- 사용자가 잘못된 정보를 입력할 염려가 없습니다.
- 사용자가 텍스트 상자에 붙여넣을 염려가 없습니다.
- 메이저 코드 작성에 대해 걱정할 필요는 없습니다.
- 매력적인 GUI
- 응용 프로그램에 쉽게 통합할 수 있습니다.
- mscal.ocx 또는 mscomct2.ocx와 같은 라이브러리를 참조할 필요가 있는 컨트롤을 사용하지 않습니다.
단점:
음... 음...생각이 안 나는데...
사용방법(드롭박스에서 파일이 누락되었습니다.캘린더의 업그레이드 버전에 대해서는, 투고 하단을 참조해 주세요.)
Userform1.frm★★★★★★★★★★★★★★★★★」Userform1.frx여기서부터요.- 에서는, 「VBA Import」(가져오기)」 「Import(가져오기)」를 만 하면 .
Userform1.frm아래 그림과 같이.
양식 가져오기

IT의 운용
어떤 절차에서도 호출할 수 있습니다.예를들면
Sub Sample()
UserForm1.Show
End Sub
스크린샷 동작 중

메모: "달력을 새로운 수준으로 끌어올리기"도 참조할 수 있습니다.
이것은 Siddharth Route의 답변과 같은 개념이다.하지만 저는 어떤 프로젝트에서 사용하든 모양과 느낌을 맞출 수 있도록 완전히 커스터마이즈할 수 있는 달력 보기를 원했습니다.
이 링크를 클릭하여 내가 생각해낸 사용자 지정 달력 보기를 다운로드할 수 있습니다.다음은 동작 중인 폼의 스크린샷입니다.

달력 보기를 사용하려면 CalendarForm.frm 파일을 VBA 프로젝트로 가져오기만 하면 됩니다.위의 각 캘린더는 단일 함수 호출로 얻을 수 있습니다.결과는 사용하는 인수에 따라 달라지기 때문에(모두 옵션), 원하는 만큼만 커스터마이즈할 수 있습니다.
예를 들어 왼쪽의 가장 기본적인 캘린더는 다음 코드 행으로 얻을 수 있습니다.
MyDateVariable = CalendarForm.GetDate
그게 다예요.여기서 원하는 대로 원하는 인수를 포함하면 됩니다.다음 함수 호출은 오른쪽에 녹색 달력을 생성합니다.
MyDateVariable = CalendarForm.GetDate( _
SelectedDate:=Date, _
DateFontSize:=11, _
TodayButton:=True, _
BackgroundColor:=RGB(242, 248, 238), _
HeaderColor:=RGB(84, 130, 53), _
HeaderFontColor:=RGB(255, 255, 255), _
SubHeaderColor:=RGB(226, 239, 218), _
SubHeaderFontColor:=RGB(55, 86, 35), _
DateColor:=RGB(242, 248, 238), _
DateFontColor:=RGB(55, 86, 35), _
SaturdayFontColor:=RGB(55, 86, 35), _
SundayFontColor:=RGB(55, 86, 35), _
TrailingMonthFontColor:=RGB(106, 163, 67), _
DateHoverColor:=RGB(198, 224, 180), _
DateSelectedColor:=RGB(169, 208, 142), _
TodayFontColor:=RGB(255, 0, 0), _
DateSpecialEffect:=fmSpecialEffectRaised)
여기에 포함되어 있는 기능의 일부를 소개합니다.모든 옵션은 사용자 폼모듈 자체에 완전히 설명되어 있습니다.
- 사용의 용이성.사용자 양식은 완전히 독립되어 있으며, VBA 프로젝트로 Import할 수 있으며 추가 코딩이 필요한 경우 크게 사용하지 않고 사용할 수 있습니다.
- 심플하고 매력적인 디자인.
- 기능, 크기, 색상표 완전 맞춤 가능
- 특정 날짜 범위로 사용자 선택 제한
- 요일 중 첫 번째 요일을 선택합니다.
- 주 번호 및 ISO 표준 지원 포함
- 헤더의 월 또는 연도 레이블을 클릭하면 선택 가능한 콤보 상자가 나타납니다.
- 날짜 위에 마우스를 놓으면 날짜 색이 바뀝니다.
길이를 추적하기 위해 무언가를 추가하고 사용자가 텍스트를 추가하는지 또는 빼는지 "확인"할 수 있도록 합니다.이것은 현재 테스트되지 않았지만 이와 유사한 기능이 작동합니다(특히 사용자 양식이 있는 경우).
'add this to your userform or make it a static variable if it is not part of a userform
private oldLength as integer
Private Sub txtBoxBDayHim_Change()
if ( oldlength > txboxbdayhim.textlength ) then
oldlength =txtBoxBDayHim.textlength
exit sub
end if
If txtBoxBDayHim.TextLength = 2 or txtBoxBDayHim.TextLength = 5 then
txtBoxBDayHim.Text = txtBoxBDayHim.Text + "/"
end if
oldlength =txtBoxBDayHim.textlength
End Sub
저도 어떻게 해서든 같은 딜레마에 빠졌습니다.【VBA】Date Picker우리 모두를 위해 무언가를 창조할 수 있는 멋진 일을 해낸 Sid에게 감사한다.
그럼에도 불구하고, 나는 나만의 것을 만들어야 할 지경에 이르렀다.그리고 많은 사람들이 이 게시물에 도착해서 혜택을 받고 있다고 확신하기 때문에 이 게시물을 여기에 올립니다.
임시 워크시트를 사용하지 않는 것 외에는 Sid가 하는 일은 매우 간단했다.계산이 아주 간단하고 간단해서 다른 곳에 버릴 필요가 없다고 생각했어요.캘린더의 최종 출력은 다음과 같습니다.

셋업 방법:
- 성 4242를 작성
Label및 이 라벨에는 으로 표시된 회색 라벨이 포함되어 있습니다.255( ) 참참참참주 。.LabelLabel_01, Label_02 등으로 컨트롤합니다.42개의 라벨을 모두 설정하다Tag을 property property로 설정합니다.dts. - 더 만들기 7개 더 만들기
Label헤더 컨트롤(Su, Mo, Tu... 포함) - 더 만들기 2개 더 만들기 2개
Label컨트롤, 하나는 수평선(높이 1로 설정) 및 다른 하나는 월 및 년 표시용입니다.이름 붙이기LabelLabel_MthYr 월 및 연도를 표시하는 데 사용됩니다. - 2 2 22
Image컨트롤, 하나는 이전 달에 스크롤할 왼쪽 아이콘을 포함하고 다른 하나는 다음 달에 스크롤할 수 있습니다(단순한 왼쪽 및 오른쪽 화살표 아이콘을 선호합니다).을 대라!Image_Left★★★★★★★★★★★★★★★★★」Image_Right
레이아웃은 대략 이와 같습니다(이것을 사용하는 사람은 창의성을 맡깁니다).

★★★★
선택된 현재 달을 유지하기 위해 맨 위에 선언된 변수 하나가 필요합니다.
Option Explicit
Private curMonth As Date
개인 절차 및 기능:
Private Function FirstCalSun(ref_date As Date) As Date
'/* returns the first Calendar sunday */
FirstCalSun = DateSerial(Year(ref_date), _
Month(ref_date), 1) - (Weekday(ref_date) - 1)
End Function
Private Sub Build_Calendar(first_sunday As Date)
'/* This builds the calendar and adds formatting to it */
Dim lDate As MSForms.Label
Dim i As Integer, a_date As Date
For i = 1 To 42
a_date = first_sunday + (i - 1)
Set lDate = Me.Controls("Label_" & Format(i, "00"))
lDate.Caption = Day(a_date)
If Month(a_date) <> Month(curMonth) Then
lDate.ForeColor = &H80000011
Else
If Weekday(a_date) = 1 Then
lDate.ForeColor = &HC0&
Else
lDate.ForeColor = &H80000012
End If
End If
Next
End Sub
Private Sub select_label(msForm_C As MSForms.Control)
'/* Capture the selected date */
Dim i As Integer, sel_date As Date
i = Split(msForm_C.Name, "_")(1) - 1
sel_date = FirstCalSun(curMonth) + i
'/* Transfer the date where you want it to go */
MsgBox sel_date
End Sub
이미지 이벤트:
Private Sub Image_Left_Click()
If Month(curMonth) = 1 Then
curMonth = DateSerial(Year(curMonth) - 1, 12, 1)
Else
curMonth = DateSerial(Year(curMonth), Month(curMonth) - 1, 1)
End If
With Me
.Label_MthYr.Caption = Format(curMonth, "mmmm, yyyy")
Build_Calendar FirstCalSun(curMonth)
End With
End Sub
Private Sub Image_Right_Click()
If Month(curMonth) = 12 Then
curMonth = DateSerial(Year(curMonth) + 1, 1, 1)
Else
curMonth = DateSerial(Year(curMonth), Month(curMonth) + 1, 1)
End If
With Me
.Label_MthYr.Caption = Format(curMonth, "mmmm, yyyy")
Build_Calendar FirstCalSun(curMonth)
End With
End Sub
했고, 가 라벨을 클릭하는 하기 위해 추가했습니다.Image_Right제어도 가능합니다.
Private Sub Image_Left_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Me.Image_Left.BorderStyle = fmBorderStyleSingle
End Sub
Private Sub Image_Left_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Me.Image_Left.BorderStyle = fmBorderStyleNone
End Sub
「이것들」은 다음과 같습니다.
것은 (이러한 라벨은 42개입니다.Label_01로로 합니다.Lable_42)
힌트: 처음 10개를 빌드하고 나머지 10개는 Find and Replace를 사용합니다.
Private Sub Label_01_Click()
select_label Me.Label_01
End Sub
날짜를 가리키거나 클릭 효과를 얻기 위한 것입니다.
Private Sub Label_01_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Me.Label_01.BorderStyle = fmBorderStyleSingle
End Sub
Private Sub Label_01_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Me.Label_01.BackColor = &H8000000B
End Sub
Private Sub Label_01_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Me.Label_01.BorderStyle = fmBorderStyleNone
End Sub
User Form 이벤트:
Private Sub UserForm_Initialize()
'/* This is to initialize everything */
With Me
curMonth = DateSerial(Year(Date), Month(Date), 1)
.Label_MthYr = Format(curMonth, "mmmm, yyyy")
Build_Calendar FirstCalSun(curMonth)
End With
End Sub
다시 말씀드리지만, 날짜 넘기기 효과 때문에요.
Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
With Me
Dim ctl As MSForms.Control, lb As MSForms.Label
For Each ctl In .Controls
If ctl.Tag = "dts" Then
Set lb = ctl: lb.BackColor = &H80000005
End If
Next
End With
End Sub
이치노이것은 생으로 만들 수 있고 당신은 그것에 자신만의 트위스트를 추가할 수 있습니다.
오랫동안 사용해 왔지만, 문제 없습니다(퍼포먼스와 기능 면에서).
.Error Handling게게관관관관관을을을것요요요요요요 。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
는 '로 가느냐'에서할 수 있습니다.select_labelHTH
그냥 재미삼아 개별 텍스트박스에 대한 Siddharth의 제안을 받아들여 콤보박스를 만들었다.관심 있는 사람이 있으면 cboDay, cboMonth 및 cboYear라는 이름의 3개의 콤보박스가 있는 사용자 폼을 추가하여 왼쪽에서 오른쪽으로 정렬합니다.그런 다음 아래 코드를 UserForm의 코드 모듈에 붙여넣습니다.필요한 콤보 상자 속성은 UserForm에서 설정됩니다.초기화이므로 추가 준비는 필요하지 않습니다.
어려운 부분은 연월 변경으로 인해 무효가 되는 날을 바꾸는 것이다.이 코드는 이 경우 01로 리셋하고 cboDay를 강조 표시합니다.
한동안 이런 암호는 안 해봤는데언젠가 누군가 관심을 가질 수 있기를 바랍니다.재밌지 않았다면!
Dim Initializing As Boolean
Private Sub UserForm_Initialize()
Dim i As Long
Dim ctl As MSForms.Control
Dim cbo As MSForms.ComboBox
Initializing = True
With Me
With .cboMonth
' .AddItem "month"
For i = 1 To 12
.AddItem Format(i, "00")
Next i
.Tag = "DateControl"
End With
With .cboDay
' .AddItem "day"
For i = 1 To 31
.AddItem Format(i, "00")
Next i
.Tag = "DateControl"
End With
With .cboYear
' .AddItem "year"
For i = Year(Now()) To Year(Now()) + 12
.AddItem i
Next i
.Tag = "DateControl"
End With
DoEvents
For Each ctl In Me.Controls
If ctl.Tag = "DateControl" Then
Set cbo = ctl
With cbo
.ListIndex = 0
.MatchRequired = True
.MatchEntry = fmMatchEntryComplete
.Style = fmStyleDropDownList
End With
End If
Next ctl
End With
Initializing = False
End Sub
Private Sub cboDay_Change()
If Not Initializing Then
If Not IsValidDate Then
ResetMonth
End If
End If
End Sub
Private Sub cboMonth_Change()
If Not Initializing Then
ResetDayList
If Not IsValidDate Then
ResetMonth
End If
End If
End Sub
Private Sub cboYear_Change()
If Not Initializing Then
ResetDayList
If Not IsValidDate Then
ResetMonth
End If
End If
End Sub
Function IsValidDate() As Boolean
With Me
IsValidDate = IsDate(.cboMonth & "/" & .cboDay & "/" & .cboYear)
End With
End Function
Sub ResetDayList()
Dim i As Long
Dim StartDay As String
With Me.cboDay
StartDay = .Text
For i = 31 To 29 Step -1
On Error Resume Next
.RemoveItem i - 1
On Error GoTo 0
Next i
For i = 29 To 31
If IsDate(Me.cboMonth & "/" & i & "/" & Me.cboYear) Then
.AddItem Format(i, "0")
End If
Next i
On Error Resume Next
.Text = StartDay
If Err.Number <> 0 Then
.SetFocus
.ListIndex = 0
End If
End With
End Sub
Sub ResetMonth()
Me.cboDay.ListIndex = 0
End Sub
빠른 해결을 위해서 저는 보통 이렇게 해요.
이 방법을 사용하면 사용자는 텍스트 상자에 원하는 형식으로 날짜를 입력할 수 있으며 편집이 완료되면 마지막으로 mm/dd/yyy 형식으로 형식을 지정할 수 있습니다.따라서 유연성이 매우 높습니다.
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If TextBox1.Text <> "" Then
If IsDate(TextBox1.Text) Then
TextBox1.Text = Format(TextBox1.Text, "mm/dd/yyyy")
Else
MsgBox "Please enter a valid date!"
Cancel = True
End If
End If
End Sub
하지만 Sid가 개발한 것은 훨씬 더 나은 접근법이라고 생각합니다. 즉, 완전한 달력 보기 제어입니다.
텍스트 상자에 입력 마스크를 사용할 수도 있습니다.마스크를 다음과 같이 설정하면##/##/####입력된 날짜가 정확한지 확인하는 것 외에 코딩할 필요가 없습니다.
쉬운 대사 몇 개면
txtUserName.SetFocus
If IsDate(txtUserName.text) Then
Debug.Print Format(CDate(txtUserName.text), "MM/DD/YYYY")
Else
Debug.Print "Not a real date"
End If
아래의 답변에 기재되어 있는 내용에 동의하지만, 대량의 에러 체크가 포함되지 않는 한, 이것은 유저 폼에 있어서 매우 나쁜 설계라고 하는 것을 시사하고 있습니다.
코드의 변경을 최소한으로 억제하고, 필요한 것을 실현하기 위해서, 2개의 어프로치가 있습니다.
텍스트 상자에 Change 이벤트 대신 KeyUp() 이벤트를 사용합니다.다음은 예를 제시하겠습니다.
Private Sub TextBox2_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) Dim TextStr As String TextStr = TextBox2.Text If KeyCode <> 8 Then ' i.e. not a backspace If (Len(TextStr) = 2 Or Len(TextStr) = 5) Then TextStr = TextStr & "/" End If End If TextBox2.Text = TextStr End Sub또는 Change() 이벤트를 사용해야 할 경우 다음 코드를 사용합니다.이것에 의해, 동작이 변경되어 유저는 다음의 순서로 번호를 계속 입력합니다.
12072003
그가 타이핑한 결과는 로 나타나지만
12/07/2003
그러나 '/' 문자는 DD의 첫 번째 문자(0/7)를 입력한 경우에만 나타납니다.이상적이지는 않지만 백스페이스를 처리할 수 있습니다.
Private Sub TextBox1_Change()
Dim TextStr As String
TextStr = TextBox1.Text
If (Len(TextStr) = 3 And Mid(TextStr, 3, 1) <> "/") Then
TextStr = Left(TextStr, 2) & "/" & Right(TextStr, 1)
ElseIf (Len(TextStr) = 6 And Mid(TextStr, 6, 1) <> "/") Then
TextStr = Left(TextStr, 5) & "/" & Right(TextStr, 1)
End If
TextBox1.Text = TextStr
End Sub
Private Sub txtBoxBDayHim_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If KeyAscii >= 48 And KeyAscii <= 57 Or KeyAscii = 8 Then 'only numbers and backspace
If KeyAscii = 8 Then 'if backspace, ignores + "/"
Else
If txtBoxBDayHim.TextLength = 10 Then 'limit textbox to 10 characters
KeyAscii = 0
Else
If txtBoxBDayHim.TextLength = 2 Or txtBoxBDayHim.TextLength = 5 Then 'adds / automatically
txtBoxBDayHim.Text = txtBoxBDayHim.Text + "/"
End If
End If
End If
Else
KeyAscii = 0
End If
End Sub
난 이거면 돼.:)
당신의 코드가 나에게 많은 도움을 주었다.감사합니다!
저는 브라질 사람이고 영어가 서툴러요.실수해서 죄송합니다.
언급URL : https://stackoverflow.com/questions/12012206/formatting-mm-dd-yyyy-dates-in-textbox-in-vba
'programing' 카테고리의 다른 글
| Swift에서 UIAlertView를 작성하려면 어떻게 해야 하나요? (0) | 2023.04.17 |
|---|---|
| Python 목록 반복기 동작 및 next(반복기) (0) | 2023.04.17 |
| 영구 테이블과 동일한 열과 유형을 가진 임시 테이블을 생성하는 가장 좋은 방법 (0) | 2023.04.17 |
| 공백이 있는 여러 줄 문자열(삽입된 부분 보존) (0) | 2023.04.17 |
| Mac OS X 10.6에서 하드웨어 비프음을 내는 방법 (0) | 2023.04.12 |