- ベストアンサー
VBAで年月日から日曜日に当たる日の文字を赤くする方法
- VBAを使用して、指定した年月日が日曜日に当たる場合に、該当する日の文字を赤くする方法について質問があります。
- 質問者は、TextBox2に年号(西暦)、ComboBox1に月、TextBox7に日を入力し、Label1からLabel31を押下して、日付けを入力したいと述べています。
- さらに、ComboBoxで日付けをダウンリスト表示する方法についても質問者は知りたいとしています。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
【別解】カレンダー描画時に色を設定する! Option Compare Database Private Sub Form_Load() Me.年 = Year(Date) Me.月 = Month(Date) Me.日 = Day(Date) ViewMyCalender Me.年, Me.月 End Sub Private Sub ViewMyCalender(ByVal intYear As Integer, ByVal intMonth As Integer) Dim I As Integer Dim J As Integer Dim W As Integer Dim strName As String Dim strDate As String Dim dteDate As Date strDate = Format(intYear, "0000") & "/" & _ Format(intMonth, "00") & "/" & _ "01" W = GetWeekday(strDate) For I = 1 To 37 strName = "日付_" & Format(I, "00") If I >= W Then Me.Controls(strName).Caption = I - W + 1 strDate = Format(intYear, "0000") & "/" & _ Format(intMonth, "00") & "/" & _ Format(I - W + 1, "00") J = GetWeekday(strDate) If J > 0 Then Me.Controls(strName).ForeColor = IIf(J = 1, 255, 0) Else Me.Controls(strName).Caption = "" End If Else Me.Controls(strName).Caption = "" End If Next I End Sub このように、カレンダーを描画する際に日付の前景色を設定するのもありです。もちろん、添付図のようにカレンダー形式で配置して場合には、最初から日曜日は朱記するのでワザワザ設定することはないと思います。 添付図は、上記のコードを持つフォームを表示した場合のそれです。
その他の回答 (6)
- imogasi
- ベストアンサー率27% (4737/17069)
>ComboBoxで日付けをダウンリスト表示したかったのですが >2列に表示する方法を知らないもので 1つのユーザーフォーム上に、左右に1つずつ2個のコンボボックスを配置し、 各コンボのリストの中身を、各々1-15日、16-31日にすれば済むことでしょう。しかしどちらのコンボをクリックすると、その期間の日々が出てくるかは、常識的に使い慣れていないので、キャプションでも付けて、判るようにしないと、使う人は戸惑うのではないか。 >日曜日に当たる日の文字を赤くする は年、月、日から、関数で日付シリアル値を導出し、Weekday関数を用いて、日曜日を判定し、コンボのその日付の特定行だけ、行の地の色を赤にすればよい。 しかしエクセルのユーザーフォームのコンボボックスの指定行を選択するVBAのコードが(WEB記事をしらべたが)見つからなかった。 だからラベルでも31個か30個(小の月)並べて、該当の日にちのラベルの色を赤くするほかない。 しかし最も難点は、そのラベルをクリックしたものがどれかを、31日分のクリックイベントコードを書かないで、割り出すコードがむつかしいのです。 ExcelVBAでは、コントロール配列が使えず、日ごろ使い慣れない、クラスの利用になったりするからです。 また、2013、2016では、DateTimePickerも使うのは大変(敷居が高い)のようだ。 ーー 日も(コンボ出なくて)テキストボックスに入力させる方法が、良いのでは。
- HohoPapa
- ベストアンサー率65% (455/693)
日付を入力、あるいは選択させるインターフェースは、 スプレッドシートにせよ、フォームにせよ、 基本機能だけでスマートに実装するのはなかなか手強いです。 私は多くの場合 http://www.asahi-net.or.jp/~ef2o-inue/download/sub09_020_025.html のコードを使っています。 一見難解でハードルが高そうですが 使うだけなら難しくありません。 それでもよくわからなければ、 課題サイトの最下行にあるダウンロードボタンで マクロブックをダウンロードし、 これをベースに作り上げるという対応でも大丈夫です。 よかったら挑戦してみてください。 なお、このサイトと私は無関係です。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
Option Compare Database Private Sub Form_Load() Me.年 = Year(Date) Me.月 = Month(Date) Me.日 = Day(Date) ViewMyCalender Me.年, Me.月 UpdateWeekdayColor Me.年, Me.月 End Sub Private Sub UpdateWeekdayColor(ByVal strYear As String, ByVal strMonth As String) Dim I As Integer Dim strName As String Dim strYYYYMM As String Dim strDate As String strYYYYMM = strYear & "/" & strMonth For I = 1 To 37 strName = "日付_" & Format(I, "00") strDate = strYYYYMM & "/" & Me.Controls(strName).Caption Me.Controls(strName).ForeColor = IIf(GetWeekday(strDate) = 1, 255, 0) Next I End Sub 添付図のカレンダーの日付の色は、上記のコードで決定しています。For-Next文で前景色を変更することを想定して、日付を表示するラベルコントロールの名前は、”日付_XX”としています。 UpdateWeekdayColor()はフォームロード時にコールしていますが、当然に、年月をチェンジしたら再表示する為にコールすることになります。 GetWeekday()は、このように利用します。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
【訂正の訂正】修正ミスでした! Public Function GetWeekday(ByVal strDate As String) As Integer On Error GoTo Err_GetWeekDay Dim intWeekday As Integer intWeekday = Weekday(CDate(strDate)) Exit_GetWeekDay: GetWeekday = intWeekday Exit Function Err_GetWeekDay: On Error GoTo 0 Resume Exit_GetWeekDay End Function PS、実は、次のコードでも同じ結果を得られます。 Public Function GetWeekday2(ByVal strDate As String) As Integer On Error Resume Next GetWeekday2 = Weekday(CDate(strDate)) End Function
補足
f_a_007 様 早速の回答ありがとうございます。 このコードはどこに記したらよいのでしょうか。 無識ですみません。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
訂正:dteDate = strDateは無用でした。 Public Function GetWeekday(ByVal strDate As String) As Integer On Error GoTo Err_GetWeekDay Dim intWeekday As Integer intWeekday = Weekday(CDate(dteDate)) Exit_GetWeekDay: GetWeekday = intWeekday Exit Function Err_GetWeekDay: On Error GoTo 0 Resume Exit_GetWeekDay End Function
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
Public Function GetWeekday(ByVal strDate As String) As Integer On Error GoTo Err_GetWeekDay Dim intWeekday As Integer dteDate = strDate intWeekday = Weekday(CDate(dteDate)) Exit_GetWeekDay: GetWeekday = intWeekday Exit Function Err_GetWeekDay: On Error GoTo 0 Resume Exit_GetWeekDay End Function GetWeekday() をイミディエイトウインドウでテストすると・・・ 【イミディエイトウインドウ】 >GetWeekday("2018/12/01") 7 >GetWeekday("2018/12/02") 1 >GetWeekday("2018/12/99") 0 と、正しい日付を受け取った時は、1~7の曜日を示す値を返します。エラーが発生した時には0を戻します。質問の案件を解決するには、このGetWeekday()を利用するといいでしょう。 【検討事項1】年と月が確定した時点で日付をセットする。 その時に、添付図のように並べると曜日で文字色を変える必要はない。何等かの事情で、フォームに横一列で並べるのであれば、その際に文字色をGetWeekday()を利用してセットする。なお、ラベルの名前を"日付_01"、"日付_02"・・・"日付_35"とすれば、For-Nextでセットできると思います。 【検討事項2】ラベルクリックイベントを書かない策も・・・。 問題は、最低で31個、最高37個のラベルコントロールのどれがクリックされたかをキャッチし《日付》を更新しなければならない点です。ここは、全てのラベルコントロールに共通するクリックイベントを発生させて目的を達成させたいもの。ただし、この件は、別に質問されたがいいです。タイトルは、「共通するイベントを発生させるには?」などで・・・。 フォーム画面が示されていませんので、ここら辺りで・・・
お礼
f_a_007 様 お力添えありがとうございました。 解決しました。 今後もよろしくお願いします。