ロゴ(青) Excel/VBA Tips ロゴ(緑)

Tips06-3: API で DTPicker コントロールを利用する (Ver1)

このページで解説しているもの(Ver1 : 井上さん作成版 + 配色変更機能)よりも、
    更に使い易く改良した『Ver3.3 』があります。


  DTPicker コントロールは、元々Windows(IE) が持っているコモンコントロールですので、API を
使う事で呼び出す事ができます。「VisualBasic が有ると利用できる」というのは、
        「この面倒くさいAPI 回りの処理を隠蔽したActiveXコントロールとして実装されるので、
          ユーザーはVBE上で簡単に貼り付けたり、プロパティ操作だけで利用できる。」
という事です。
  逆に言えば、小難しいAPI 処理を厭わなければ、VisualBasic が無くても利用できるという事
になります。
  この方法を使うと、アドインソフトもAccess/VisualBasic も必要なく、どのPCであってもカレンダー
コントロールが利用できます。この事は、作成したブックを他のPCへ持って行く場合に、
      ・相手PCの環境(アドインソフト/Access/VisualBasic の有無)
      ・配布方法(アドインソフトのインストールや参照設定)
に気を使う必要が無いという事です。

ここで紹介するのは、井上 治さんが、EUC (MOUGの前身)時代に、青山 彩さんという方からアドバイスを受けたノウハウを元にして作ったコードです。 (AddinBoxサイトで公開する事に関しては、井上さんより了解を得ています。  moug スレッド Archive :  1  ,  2  )
『Excelでお仕事!』では【API関連 & ダウンロード】の項に解説が載っています。

     サンプルブックDTPickerClass.lzh Ver1.1    25KB  )
        (サンプルブック更新履歴)
          2003/8/10  井上さん作のクラスモジュールの仕組みを AddinBox で解説(当ページ)。
          2004/4/27  [ Ver 1.0 ]  配色変更機能を追加。バージョン表記を AddinBox 版 [ 1.0 ] とする。
          2004/5/2  [ Ver 1.1 ]  配色変更でシステムカラー指定を可能にしました。


【 この手法の基本的な考え方 】


    1.DTPicker コントロールは実行時(UserFormの表示時)に動的に生成します。
    2.したがって、フォーム設計時にはコントロールを貼り付け出来ません。
    3.しかし、これでは DTPickerコントロールを「どこにどのサイズで作る」のか決められません
        ので、代わりにComboBoxを貼り付けて設計します。
            土台となるコントロールには、何も「コンボボックスでなければ駄目」という理由はありません。
                テキストボックスでも構いません。クラスモジュールでの定義をテキストボックスに変えてやりさえ
                すれば問題なく動作します。しかし、DTPickerは普段 コンボボックス形状ですから、やはりコンボ
                ボックスを土台にした方が、レイアウト設計上は楽でしょう(ドロップボタン部分のサイズもありますので)。


    4.フォーム表示時に、このComboBoxと同じサイズ/位置でピッタリ重なるように、DTPicker
        コントロールを動的に生成します。
    5.ComboBoxは、レイアウト設計の為だけに使っているので、マクロ内では
                [ComboBox1.Value]
        といった風に使われる事はありません。
    6.現在の所、この手法で作成したDTPicker コントロールに対するイベント処理は行なえません
        (DTPicker で日付を指定して、コンボボックス部の内容が変化した時に何かの処理をする等)。
        したがって、他のイベント処理(コマンドボタンのClick イベント等)内で、DTPicker コントロール
        の内容を「参照する」という使い方しか出来ません。

  (注意事項)
      (1) この方法では、フレーム/マルチページ上のコンボボックスに[DTPicker]を載せる事が
          出来ません。フレーム/マルチページへの配置は控えて下さい。
      (2) コンボボックスのプロパティ[TabStop]は【False 】にして下さい。
      (3) この方法で作成したDTPicker コントロールは、タブ送り(Tab/Shift+Tab)の流れには
          入りません。ドロップボタン部分のマウスクリックでのみアクセス出来ます。



【 この手法の使い方 】
  1.先ず、上記のサンプルブックをダウンロードして下さい。
  2.利用するブックのVBEでユーザーフォームを用意してください。
  3.そのユーザーフォームには上記で説明したように、[DTPicker ]コントロールを貼り付けたい
      位置に、代わりのコンボボックスを貼り付けます。
  4.その後、サンプルブックからモジュールをコピーします。


サンプルブックを開いてVBEを見ると
左記のモジュール構成になっています。
      (1) 先ず、
                標準モジュール[modDTPikcerOnComboBox]
                クラスモジュール[clsDTPickerOnComboBox]
          の2つのモジュールを適当なフォルダへエクスポートします。
      (2) 次に、利用先ブック内に、この2つのモジュールをインポートします。
      (3) [UserForm1]のコードウィンドウを開き、中のコードを全て利用先ブックのユーザーフォーム
           モジュール内にコピーして下さい。

  5.クラスモジュール[clsDTPickerOnComboBox]の内容は一切変更する必要はありません
          2004/4/27 配色変更用のプロパティを追加しました。
          2004/5/2 配色変更の際に、システムカラーを指定できるようにしました。
              5/2 以前にダウンロードしている方は現在のサンプルブックをダウンロードして、クラスモジュール
              [clsDTPickerOnComboBox ]のみ、そのまま差し替えてください。

  6.標準モジュール[modDTPickerOnComboBox]の内容は下記になります。
      ここで変更する箇所は太字の2ヶ所だけです。他はそのままにして下さい。
'DTPicker の日付表示形式
Public Const g_strDateFormat As String = "yyyy/M/d"  '(注)月は大文字

'DTPickerが載るComboBoxオブジェクトの配列要素数最大値
Public Const g_lngComboBox_Max = 3  'クラスの宣言
Public clsDTPCBox(1 To g_lngComboBox_Max) As New clsDTPickerOnComboBox

'クラスの廃棄
Public Sub GP_DestroyClass_ALL()
Dim IX As Integer
  For IX = 1 To g_lngComboBox_Max
    clsDTPCBox(IX).Destroy
    Set clsDTPCBox(IX) = Nothing
  Next IX
End Sub
 
      (1) [g_strDateFormat]には、DTPicker コントロールでの日付編集形式を指定します([月]の指定
            部分は、小文字の"m"にすると、時間の[分]と解釈されますので大文字にして下さい)。
            『2004年3月21日』ならば "yyyy''M''d''" とします(平成14年 といった和暦年の編集
            はできません)。

【 DTPicker コントロールに指定できる日付編集文字列 】        (2004/4/26 追記)
y 1または2桁の西暦年
yy 2桁の西暦年(年の下2桁が0〜9の場合、頭に0が付く)
yyy or yyyy 4桁の西暦年
M 1または2桁の月
MM or MMM 2桁の月(1〜9では、頭に0が付く)
MMMM 月の後に"月"の文字が付く(1月, 2月, ‥‥‥ 12月)
d 1または2桁の日
dd 2桁の日(1〜9では、頭に0が付く)
ddd 1文字の曜日(日, 月, ‥‥‥ 土)
dddd 3文字の曜日(日曜日, 月曜日, ‥‥‥ 土曜日)
その他の文字 アポストロフィ()で括って記述した文字は、そのまま表示される
(アポストロフィは省略しても問題ない)
(例)
      "'本日は'MM'月'dd'日です'"    ⇒    本日は04月26日です
      "yyy'年'MMMMd'日('dddd')'"   ⇒    2004年4月26日(月曜日)

      (2) [g_lngComboBox_Max]には、DTPicker コントロールを載せるコンボボックスの数を指定します。
            上記サンプルブックの例では、UserForm上に3個のDTPickerを作成するので「3」を指定して
            います(当然、コンボボックスも3個必要になります)。1個だけで良いなら「1」に、5個なら「5」に
            変更します。
      1ブック内で複数のUserFormに、この手法のDTPickerコントロールを使う場合には、もう少し配慮
      する必要があります(後述)。


  7.サンプルブックの[UserForm1]のコードは下記になります。
      DTPicker を載せるコンボボックスの数( g_lngComboBox )だけ下記のようにコレクションへ
      追加して、DTPicker 用クラスを作成していきます。
Private Sub UserForm_Initialize()
Dim colCmbBox As New Collection
Dim IX As Integer

  ' DTPickerが載るComboBoxのコレクションを作成
  With colCmbBox
    .Add Item:=ComboBox1
    .Add Item:=ComboBox2
    .Add Item:=ComboBox3
     
      :  以下、DTPicker を載せるコンボボックスを全て[Add Item]する
     
  End With

  For IX = 1 To g_lngComboBox_Max
    ' クラスインスタンス生成
    Set clsDTPCBox(IX) = New clsDTPickerOnComboBox
    With clsDTPCBox(IX)
      .Cmd = colCmbBox(IX)
      .UserForm = Me
      .Create    ' DTPickerを生成
      '初期表示を本日日付以外にする場合は、Create後の
      'この位置で[Value]プロパティに代入する
      ' .Value = DateValue("2003/8/10")    '(代入例)
    End With
  Next IX
End Sub

Private Sub UserForm_Terminate()
  ' クラスインスタンス廃棄
  Call GP_DestroyClass_ALL
End Sub

        最初に、コンボボックスをコレクション化(colCmbBox への Add Item)してまとめている理由は、
      DTPicker用クラスへの登録処理のループに載せる為です。
        したがって、DTPicker が1つだけなら、コンボボックスをコレクション化する必要も無く、
      下記のように簡素化しても良いです(将来、DTPicker を増やす修正が必要になる場合を考
      慮すれば、1個の場合でも上記のままに、一端コレクション化してループで登録するようにし
      た方が良いでしょう)。
Private Sub UserForm_Initialize()
  ' クラスインスタンス生成
  Set clsDTPCBox(1) = New clsDTPickerOnComboBox
  With clsDTPCBox(1)
    .Cmd = ComboBox1
    .UserForm = Me .Create    ' DTPickerを生成
    '初期表示を本日日付以外にする場合は、Create後の
    'この位置で[Value]プロパティに代入する
    ' .Value = DateValue("2003/8/10")    '(代入例)
  End With
End Sub

Private Sub UserForm_Terminate()
  ' クラスインスタンス廃棄
  Call GP_DestroyClass_ALL
End Sub


  8.[DTPicker ]コントロールの値の取得/設定方法は、下記のように[clsDTPCBox ]の
      『Value プロパティ』を通して
行ないます。Value プロパティの属性はシリアル値です。
      DTPicker の下敷きになっているコンボボックスのValue プロパティ等は一切利用しません。
Dim dtmDate2 As Date
dtmDate2 = clsDTPCBox(2).Value
clsDTPCBox(2).Value = DateValue("2003/8/10")
MsgBox Format(clsDTPCBox(2).Value , "yyyy年m月d日")


 9.複数のUserFormに、このDTPicker を利用する場合は、標準モジュール内の
          [ g_lngComboBox_Max ] [ clsDTPCBox ][ GP_DestroyClass_All ]
      を、各々のUserForm用に別個に用意して下さい(コピーして末尾に 2, 3, ‥‥と番号
      を付けてリネームするとか)。
      当然、各々のUserFormモジュール内での上記3つの名前の部分は、それに合わせて
      修正する必要があります。下記は2つのUserFormで利用する場合の例です。

      == 標準モジュール modDTPickerOnComboBox ==
' DTPicker の日付表示形式
Public Const g_strDateFormat As String = "yyyy/M/d"  '(注)月は大文字

' DTPickerが載るComboBoxオブジェクトの配列要素数最大値
Public Const g_lngComboBox_Max1 = 3
Public Const g_lngComboBox_Max2 = 5

' クラスの宣言
Public clsDTPCBox1(1 To g_lngComboBox_Max1) As New clsDTPickerOnComboBox
Public clsDTPCBox2(1 To g_lngComboBox_Max2) As New clsDTPickerOnComboBox

' クラスの廃棄
Public Sub GP_DestroyClass_ALL1()
Dim IX As Integer
  For IX = 1 To g_lngComboBox_Max1
    clsDTPCBox1(IX).Destroy
    Set clsDTPCBox1(IX) = Nothing
  Next IX
End Sub

Public Sub GP_DestroyClass_ALL2()
Dim IX As Integer
  For IX = 1 To g_lngComboBox_Max2
    clsDTPCBox2(IX).Destroy
    Set clsDTPCBox2(IX) = Nothing
  Next IX
End Sub


      == UserFormモジュール UserForm1 ==
Private Sub UserForm_Initialize()
Dim colCmbBox As New Collection
    :
    :
  For IX = 1 To g_lngComboBox_Max1
    ' クラスインスタンス生成
    Set clsDTPCBox1(IX) = New clsDTPickerOnComboBox
    With clsDTPCBox1(IX)
      .Cmd = colCmbBox(IX)
        :
        :
    End With
  Next IX
End Sub

Private Sub UserForm_Terminate()
  ' クラスインスタンス廃棄
  Call GP_DestroyClass_ALL1
End Sub


      == UserFormモジュール UserForm2 ==
Private Sub UserForm_Initialize()
Dim colCmbBox As New Collection
    :
    :
  For IX = 1 To g_lngComboBox_Max2
    ' クラスインスタンス生成
    Set clsDTPCBox2(IX) = New clsDTPickerOnComboBox
    With clsDTPCBox2(IX)
      .Cmd = colCmbBox(IX)
        :
        :
    End With
  Next IX
End Sub

Private Sub UserForm_Terminate()
  ' クラスインスタンス廃棄
  Call GP_DestroyClass_ALL2
End Sub

      コンボボックスのコレクション用変数『colCmbBox』は「Initialize イベント」内でのみ使用される
      ローカル変数です。したがって、上記例のようにUserForm1/UserForm2で同じ名前にしても
      大丈夫です。

 10.DTPicker の配色を変更 (2004/4/27 追加)
      DTPicker のタイトルバー色やカレンダー文字色などを変更する事ができます(1UserForm内の
      複数のDTPicker を個別に配色変更できます)。
            4/26以前にサンプルブックをダウンロードしている方は、現在のサンプルブックを再度ダウンロードして、
            クラスモジュール[clsDTPickerOnComboBox ]のみ差し替えて下さい。

      尚、この部分のマクロは
              新山(へろぱ)のホームページ  ( Archive )
              [自作ソフト/クラスのデモ/その4 DTPicker クラス]
      で公開されているコードを参考にしました。
      プロパティにカラー値を代入すれば、下記のような配色にする事が可能です(前月/翌月部分を
      非表示にする場合は、前月/翌月文字色をカレンダー部分の背景色と同じにします)。


      配色変更用プロパティには
CalendarForeColor カレンダー部分の文字色
CalendarBackColor カレンダー部分の背景色
CalendarTitleForeColor タイトルバー(年月)の文字色
CalendarTitleBackColor タイトルバーの背景色・曜日の文字色・選択日付のマーク色
CalendarTrailingForeColor [前月/翌月]部分の文字色
      の5つがあります。

      Initialize イベントで、DTPickerクラスの【 Create 】後にカラー値を設定して下さい。
      尚、カラー値として「vbButtonFace(&H8000000F), vbButtonText(&H80000012) 」などの
      システムカラー定数は指定できません。
        2004/5/2 配色変更でシステムカラー指定を可能にしました。
            5/2以前にサンプルブックをダウンロードしている方は、現在のサンプルブックを再度ダウンロードして、
            クラスモジュール[clsDTPickerOnComboBox ]のみ差し替えて下さい。

      カラー値の指定では
          ・16進定数
          ・「vbWhite , vbBlack 」などのカラー定数
          ・「vbButtonFace , vbWindowText 」などのシステムカラー定数
      で指定して下さい。
     (設定例:上図の左下の場合)
          With clsDTPCBox(1)
              .CalendarForeColor = &H0&    'または vbBlack
              .CalendarBackColor = &HFFFFFF  'または vbWhite
              .CalendarTitleForeColor = &H0&  'または vbBlack
              .CalendarTitleBackColor = &HC0C0&
              .CalendarTrailingForeColor = &HFFFFFF  'または vbWhite
          End With


      サンプルブックのサンプルフォームに配色変更ボタンを追加してありますので、実際に配色を
      決める際の参考ツールとして使って下さい。

    クラスモジュールで使っているAPI の詳細(SendMessage のメッセージ内容)を知りたい方は
            MSDN Library / Date and Time Picker Control Reference  (英語)
       を参照して下さい。

 Home   Back Page   

ロゴ(ゴールド)   ロゴ(ゴールド)

角田 桂一 Mail:addinbox@h4.dion.ne.jp CopyRight(C) 2004 Allrights Reserved.