【2020年12月21日更新】
古くなってExcelのバージョンも変わったため更新記事を書きました。
touch-sp.hatenablog.com
こちらを見てください。
過去の投稿はそのまま残しておきます。
【以下はオリジナル記事(2017年1月12日投稿)です。】
簡単にコピペで再現できるようにボタンなどのコントロールの配置やそのプロパティはすべてコードに記述。フォームやモジュールを追加して下記をコピペするだけで完成。
①カレンダーフォーム「Calender」を追加する
Option Explicit Private Sub UserForm_Initialize() 'widthとinsidewidthの差は4.5 (5*2+30*7+4.5=224.5) Me.Width = 224.5 Me.Height = 285 Me.Caption = "カレンダー" End Sub
②標準モジュール「CalenderModule」を追加する
Option Explicit Public calender_date As String Function open_calender(ByVal text_date As String) As String Dim my_date As Date If (IsDate(text_date)) Then my_date = CDate(text_date) Else my_date = Date End If calender_date = text_date Load Calender Dim NewBtn(1 To 42) As Object Dim NewTxt As Object Dim NewCombo As Object Dim NewSpin As Object Dim days_label(0 To 6) As Object Dim obj1 As Object Dim obj2 As Object Dim obj3 As Object With Calender Set obj1 = .Controls.Add("Forms.Label.1", "year_label") Set obj2 = .Controls.Add("Forms.Label.1", "month_label") Set obj3 = .Controls.Add("Forms.Label.1", "year_month_label") With obj1 .Height = 12 .Width = 12 .Font.Size = 12 .Caption = "年" .Top = 21 .Left = 90 End With With obj2 .Height = 12 .Width = 12 .Font.Size = 12 .Caption = "月" .Top = 21 .Left = 170 End With With obj3 .Height = 21 .Width = 210 .Font.Size = 16 .Top = 55 .Left = 5 .SpecialEffect = fmSpecialEffectEtched .BackColor = RGB(255, 255, 255) .TextAlign = fmTextAlignCenter End With Dim i As Integer For i = 1 To 42 Set NewBtn(i) = New ControlSetting Set NewBtn(i).myButton = .Controls.Add("Forms.CommandButton.1", "button" & i) With NewBtn(i).myButton .Height = 25 .Width = 30 .Top = 105 + ((i - 1) \ 7) * 25 .Left = 5 + ((i - 1) Mod 7) * 30 If (i - 1) Mod 7 = 0 Then .ForeColor = RGB(255, 0, 0) If (i - 1) Mod 7 = 6 Then .ForeColor = RGB(0, 0, 255) End With Next i Dim days As String days = "日月火水木金土" Dim days_i As Integer For days_i = 0 To 6 Set days_label(days_i) = .Controls.Add("Forms.Label.1", "days_label" & days_i) With days_label(days_i) .Height = 18 .Width = 30 .Top = 87 .Left = 5 + days_i * 30 .Font.Size = 14 .Font.Bold = True .TextAlign = fmTextAlignCenter .Caption = Mid(days, days_i + 1, 1) If days_i = 0 Then .ForeColor = RGB(255, 0, 0) If days_i = 6 Then .ForeColor = RGB(0, 0, 255) End With Next days_i Set NewTxt = New ControlSetting Set NewTxt.myTxt = .Controls.Add("Forms.TextBox.1", "year_txt") With NewTxt.myTxt .Height = 18 .Width = 66 .Top = 18 .Left = 15 .Font.Size = 12 .TextAlign = fmTextAlignCenter .IMEMode = fmIMEModeDisable .Text = Year(my_date) End With Set NewCombo = New ControlSetting Set NewCombo.myCombo = .Controls.Add("Forms.ComboBox.1", "month_txt") With NewCombo.myCombo .Height = 18 .Width = 48 .Top = 18 .Left = 115 .Font.Size = 12 .TextAlign = fmTextAlignCenter .Style = fmStyleDropDownCombo .ListRows = 12 Dim month_i As Integer For month_i = 1 To 12 .AddItem month_i Next month_i .ListIndex = Month(my_date) - 1 End With Set NewSpin = New ControlSetting Set NewSpin.mySpin = .Controls.Add("Forms.SpinButton.1", "updown") With NewSpin.mySpin .Height = 25.5 .Width = 12.75 .Top = 14 .Left = 190 End With End With Dim num As Integer Dim dd As String dd = Day(my_date) For num = 1 To 42 If Calender.Controls("button" & num).Caption = dd And Calender.Controls("button" & num).Enabled Then Calender.Controls("button" & num).SetFocus End If Next num Calender.Show open_calender = calender_date End Function Function calender_hantei() As Boolean Dim kekka As Boolean If Not IsNumeric(Calender.Controls("year_txt").Text) Then kekka = False Else Calender.Controls("year_txt").Text = Int(Calender.Controls("year_txt").Text) kekka = True End If calender_hantei = kekka End Function Function calender_reload() Dim yy As Integer yy = Calender.Controls("year_txt").Text If yy < 1800 Then Exit Function If yy > 3000 Then Exit Function Dim button_i As Integer For button_i = 1 To 42 Calender.Controls("button" & button_i).Caption = "" Calender.Controls("button" & button_i).Font.Size = 10 Calender.Controls("button" & button_i).Enabled = False Next button_i Dim mm As Integer Dim d As Date Dim start_position As Integer Dim end_day As Integer yy = Calender.Controls("year_txt").Text mm = Calender.Controls("month_txt").Text Calender.Controls("year_month_label").Caption = yy & "年" & mm & "月" d = yy & "/" & mm & "/" & 1 start_position = Weekday(d) Dim days_number As Integer '何日あるか days_number = Day(DateSerial(yy, mm + 1, 0)) Dim start_day As Date start_day = d - (start_position - 1) Dim index As Integer For index = 1 To 42 Calender.Controls("button" & index).Caption = Day(start_day + index - 1) If Month(start_day + index - 1) = mm Then Calender.Controls("button" & index).Font.Size = 12 Calender.Controls("button" & index).Enabled = True End If Next index End Function
③クラスモジュール「ControlSetting」を追加する
Option Explicit Public WithEvents myButton As CommandButton Public WithEvents myTxt As MSForms.TextBox Public WithEvents myCombo As MSForms.ComboBox Public WithEvents mySpin As MSForms.SpinButton Private Sub myButton_Click() calender_date = Calender.Controls("year_month_label").Caption & myButton.Caption & "日" Unload Calender End Sub Private Sub myTxt_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = vbKeyReturn Then Dim hantei As Boolean hantei = calender_hantei If Not (hantei) Then Exit Sub Call calender_reload End If End Sub Private Sub myCombo_Change() If Not (Me.myCombo.MatchFound) Then Exit Sub Dim hantei As Boolean hantei = calender_hantei If Not (hantei) Then Exit Sub Call calender_reload End Sub Private Sub mySpin_SpinDown() Dim hantei As Boolean hantei = calender_hantei If Not (hantei) Then Exit Sub Dim index As String index = Calender.Controls("month_txt").ListIndex If (index = -1) Then Exit Sub If (index = 0) Then Calender.Controls("year_txt").Text = Calender.Controls("year_txt").Text - 1 index = 11 Else index = index - 1 End If Calender.Controls("month_txt").ListIndex = index End Sub Private Sub mySpin_SpinUp() Dim hantei As Boolean hantei = calender_hantei If Not (hantei) Then Exit Sub Dim index As String index = Calender.Controls("month_txt").ListIndex If (index = 11) Then Calender.Controls("year_txt").Text = Calender.Controls("year_txt").Text + 1 index = 0 Else index = index + 1 End If Calender.Controls("month_txt").ListIndex = index End Sub
使い方は、例としてテキストボックス「TextBox1」とコマンドボタン「CommandButton1」がセットされているユーザーフォームで
Private Sub CommandButton1_Click() TextBox1.Text = open_calender(TextBox1.Text) End Sub