LoginSignup
0
2

More than 5 years have passed since last update.

Excelマクロ(日付選択)

Posted at
Sheet1.cls
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Sheet1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Public Sub Button1_Click()
    Call CalForm.SetSelectDate(Range("A1").Value)
    CalForm.Show
    If Not CalForm.Cancel Then
        Range("A1").Value = Format(CalForm.SelectDate, "yyyy/mm/dd")
    End If
    Unload CalForm
End Sub

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    If Target.Address(False, False) = "A2" Then
        Call CalForm.SetSelectDate(Range("A2").Value)
        CalForm.Show
        If Not CalForm.Cancel Then
            Range("A2").Value = Format(CalForm.SelectDate, "yyyy/mm/dd")
        End If
        Unload CalForm
    End If
End Sub

```CalForm.frm
VERSION 5.00
Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} CalForm 
   Caption         =   "日付選択"
   ClientHeight    =   3615
   ClientLeft      =   45
   ClientTop       =   330
   ClientWidth     =   4455
   OleObjectBlob   =   "CalForm.frx":0000
   StartUpPosition =   1  'オーナー フォームの中央
End
Attribute VB_Name = "CalForm"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Private Const LIMITMINDATE As Date = #3/1/1900#
Private Const LIMITMAXDATE As Date = #12/31/9999#

Private WithEvents CalLabel As ArrayLabelHandler
Attribute CalLabel.VB_VarHelpID = -1
Private BaseDate As Date
Private LoadForm As Boolean

Private mySelectDate As Date
Private myCancel As Boolean

Public Property Get SelectDate() As Date
    SelectDate = mySelectDate
End Property

Public Property Get Cancel() As Boolean
    Cancel = myCancel
End Property

Public Sub SetSelectDate(SelectDate As String)
    LoadForm = False

    If IsDate(SelectDate) Then
        mySelectDate = CDate(SelectDate)
    End If

    If mySelectDate < LIMITMINDATE Then
        mySelectDate = Date
    End If

    Call SetComboboxValue(ComboBoxMonth, Month(mySelectDate))
    Call SetComboboxValue(ComboBoxYear, Year(mySelectDate))
    Call MakeCalendar

    myCancel = False
    LoadForm = True
End Sub

Private Sub UserForm_Initialize()
    Dim i As Integer

    Set CalLabel = New ArrayLabelHandler
    With CalLabel
        For i = 1 To 42
            .Add Me.Controls("Label" & i)
        Next i
        .Regist
    End With

    With ComboBoxMonth
        For i = 1 To 12
            .AddItem i
        Next i
    End With

    With ComboBoxYear
        For i = 1900 To 9999
            .AddItem i
        Next i
    End With

    LoadForm = True
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Call CommandButtonCancel_Click

    If CloseMode = vbFormControlMenu Then
        Cancel = True
    End If
End Sub

Private Sub UserForm_Terminate()
    CalLabel.Clear
    Set CalLabel = Nothing
End Sub

Private Sub ComboBoxMonth_Change()
    LabelMonth.Caption = ComboBoxMonth.Value

    If LoadForm = False Then
        Exit Sub
    End If

    Call MakeCalendar
End Sub

Private Sub ComboBoxYear_Change()
    LabelYear.Caption = ComboBoxYear.Value

    If LoadForm = False Then
        Exit Sub
    End If

    Call MakeCalendar
End Sub

Private Sub calLabel_Click(ByVal Index As Integer)
    If CalLabel.Item(Index).Item.Caption = vbNullString Then
        Exit Sub
    End If

    Dim WorkDate As Date
    WorkDate = BaseDate + (Index - 1)
    If WorkDate < LIMITMINDATE Then
        Exit Sub
    End If

    mySelectDate = WorkDate
    Me.Hide
End Sub

Private Sub CommandButtonCancel_Click()
    myCancel = True
    Me.Hide
End Sub

Private Sub MakeCalendar()
    Dim FirstDate As Date
    Dim LastDate As Date
    Dim WorkDate As Date
    Dim LimitOver As Boolean
    Dim Offset As Integer
    Dim i As Integer

    FirstDate = DateSerial(ComboBoxYear.Value, ComboBoxMonth.Value, 1)

    If Format(FirstDate, "yyyymm") = Format(LIMITMAXDATE, "yyyymm") Then
        LastDate = LIMITMAXDATE
    Else
        LastDate = DateSerial(ComboBoxYear.Value, ComboBoxMonth.Value + 1, 0)
    End If

    BaseDate = (FirstDate - Weekday(FirstDate)) + 1

    Offset = 0
    For i = CalLabel.MinIndex To CalLabel.MaxIndex
        With CalLabel.Item(i).Item
            If Not LimitOver Then
                WorkDate = BaseDate + Offset
                .Caption = Day(WorkDate)
            Else
                WorkDate = LIMITMINDATE
                .Caption = ""
            End If

            If WorkDate < FirstDate Or WorkDate > LastDate Then
                .BackColor = vbButtonFace
                .ForeColor = vbGrayText
                .SpecialEffect = fmSpecialEffectFlat
                .BorderStyle = fmBorderStyleSingle
            Else
                If WorkDate = mySelectDate Then
                    .BackColor = vbButtonShadow
                    .ForeColor = vbButtonText
                    .SpecialEffect = fmSpecialEffectSunken
                    .BorderStyle = fmBorderStyleNone
                Else
                    .BackColor = vbButtonFace
                    .ForeColor = vbHighlight
                    .SpecialEffect = fmSpecialEffectFlat
                    .BorderStyle = fmBorderStyleSingle
                End If
            End If
        End With

        If WorkDate >= LIMITMAXDATE Then
            LimitOver = True
        End If

        Offset = Offset + 1
    Next i
End Sub

Private Sub SetComboboxValue(ByVal Combbox As MSForms.ComboBox, ByVal Value)
    With Combbox
        .Style = fmStyleDropDownCombo
        .Value = Value
        .Style = fmStyleDropDownList
    End With
End Sub
ArrayLabelHandler.cls
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "ArrayLabelHandler"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Public Event Click(ByVal Index As Integer)

Private myItem() As ArrayLabel
Private myLabels As Collection

Private Sub Class_Initialize()
    Set myLabels = New Collection
End Sub

Public Sub Add(ByVal Label As MSForms.Label)
    myLabels.Add Label
End Sub

Public Sub Regist()
    Dim i As Integer
    ReDim myItem(1 To myLabels.Count)
    For i = 1 To myLabels.Count
        Set myItem(i) = New ArrayLabel
        With Item(i)
            .Item = myLabels(i)
            .Index = i
            .Handler = Me
        End With
    Next i
End Sub

Public Sub Clear()
    Dim i As Integer
    For i = LBound(myItem) To UBound(myItem)
        myItem(i).Clear
    Next i
    Erase myItem
    Set myLabels = Nothing
End Sub

Public Property Get MinIndex() As Integer
    MinIndex = LBound(myItem)
End Property

Public Property Get MaxIndex() As Integer
    MaxIndex = UBound(myItem)
End Property

Public Property Get Item(ByVal Index As Integer) As ArrayLabel
    Set Item = myItem(Index)
End Property

Public Sub RaiseClick(ByVal Index As Integer)
    RaiseEvent Click(Index)
End Sub
ArrayLabel.cls
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "ArrayLabel"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Private WithEvents myItem As MSForms.Label
Attribute myItem.VB_VarHelpID = -1
Private myIndex As Integer
Private myHandler As ArrayLabelHandler

Public Sub Clear()
    Set myItem = Nothing
    Set myHandler = Nothing
End Sub

Public Property Let Item(Item As MSForms.Label)
    Set myItem = Item
End Property

Public Property Get Item() As MSForms.Label
    Set Item = myItem
End Property

Public Property Let Index(Index As Integer)
    myIndex = Index
End Property

Public Property Let Handler(Handler As ArrayLabelHandler)
    Set myHandler = Handler
End Property

Private Sub myItem_Click()
    myHandler.RaiseClick myIndex
End Sub
0
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2