- ベストアンサー
VBA曜日のデータ
- VBAを使って日付シートの曜日データを自動的にコピーするコードの一部について、エラーの原因を調べたいです。
- 日付シートのB5セルには日曜日なら「日」、月曜日なら「月」と入っていますが、コードの一部で一致確認がなされていないようです。
- コードは日付シートの曜日データを別のシートにコピーするためのもので、条件分岐の部分でエラーが発生しているようです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
No.1です。 >MsgBox ws.Range("B5") としてみたら 1900/01/01となりました。 >これはどういう意味なのでしょう。 日付(曜日、時刻を含む)はシリアル値です。 これは数式バー上では下記のように表示されます。 0=1900/01/00 0.5=1900/01/00 12:00:00 1=1900/01/01 2=1900/01/02 366=1900/12/31 367=1901/01/01 なので1900/01/01は1ということです。 確認したいならB5の表示形式を標準に戻してから MsgBox ws.Range("B5")を実行してみてください。
その他の回答 (4)
- imogasi
- ベストアンサー率27% (4737/17069)
エクセルの基本的なことだろう。エクセルの(日付関係の)基本がわかってなくてVBAをやっていると思う。 セルの書式(表示形式が)を「日」と出るようにしていても、そのセルの(特定のための検索などに)「日」で聞いたらダメです。 IFと=で聞くのは、通常は「セルの値」を聞いているのであって、質問の場合は、セルの値は日付シリアル値(整数)のままだろう。 (1)日付シリアル値のままaaaで「日」になるし、yyyy/mm/dd(aaa)、yyyy/mm/ddaaaで日付と曜日があわせて1つのセルに表示される。 別列に日付をコピーし書式をaaa二すると曜日が見える。 (2)WEEKDAY関数の結果の1=CHOOSE(WEEKDAY(A1),"日","月","火",・・) などのどちらかだろう。 (質問に日付と曜日が同一セルに見えているのか、はっきり書いてないが。) 曜日が表示されてなくて、日付だけなら (1)曜日文字で聞く (2)Weekdayの返り値のコードで聞く のどちらかになるだろう。 ーー もうひとつわかっているかどうか >If ws.Range("B5") = "日" Then のRange("B5")のあとは正式には,.Valueが略してあるとを知ってますか。(これをつけることを奨励する人も多い) 質問の「日」はセルの値でなく表示形式の結果・見た目です。両者を比べてはならない。 ーー 質問のままにするには日付列の隣列に=TEXT(A1,"aaa")とすることだが、別列に出すことなる。 ーー だからVBAでのWeekday関数を使ってでも曜日を判断すべきだ。(返り値は1,2,,3、--7ですが)。VBAではWeekday関数の日曜日は1だ。関数のように3種類はありません。 ーー VBAでは曜日文字を取るのは Sub test01() i = 1 wd = Format(Cells(i, "A"), "aaa") If wd = "火" Then MsgBox "火曜日です" Else MsgBox "火曜日ではありません" End If End Sub のように、TEXTではなくなります。
- tom04
- ベストアンサー率49% (2537/5117)
No.3です! たびたびごめんなさい。 投稿した後で間違いに気づきました。 大きな勘違いをしていました。 1~31は曜日のSheetではなく、各日にちのSheetですね! 前回の方法は無視してください。 >If ws.Range("B5") = "日" Then の部分を >If WorksheetFunction.Text(ws.Range("B5"), "aaa") = "日" Then ・・・ とすれば、お示しのコードがそのまま使えると思います。 何度も失礼しました。m(_ _)m
- tom04
- ベストアンサー率49% (2537/5117)
こんばんは! 「日付シート」はシリアル値になっていますので、No.1さんが仰っているような方法か 他の方法としては、TEXT関数でシリアル値を文字列(日~土)にすればそのままSheet名として使用できると思います。 一つの方法ですが・・・ For i = 1 To 31 If Worksheets(i).Name = WorksheetFunction.Text(Worksheets("日付シート").Range("B5"), "aaa") Then Worksheets(i).Range("A1:D3") _ .Copy Destination:=ws.Range("A7") ws.Tab.ColorIndex = 45 ・・・ といったようにしてみてはどうでしょうか? そうすればIFで各曜日ごとに分岐せずに済むと思います。 参考にならなかったらごめんなさいね。m(_ _)m
- mshr1962
- ベストアンサー率39% (7417/18945)
>weekday()関数とユーザー定義の書式のaaaにより 数式が上記のものだと表示内容と実際の値が異なります。 表示 値 日 → 1 月 → 2 火 → 3 水 → 4 木 → 5 金 → 6 土 → 7 ですので If ws.Range("B5") = "日" Then → If ws.Range("B5") = 1 Then または If ws.Range("B5") = "日" Then → If Format(ws.Range("B5"),"aaa") = "日" Then なら機能するはずです。 あとIF文を使うよりSelect Caseを使った方がいいかもしれません。 Select Case ws.Range("B5") Case 1 Worksheets("日").Range("A1:D3") _ .Copy Destination:=ws.Range("A7") ws.Tab.ColorIndex = 45 Case 2 Worksheets("月").Range("A1:D3") _ .Copy Destination:=ws.Range("A7") ws.Tab.ColorIndex = xlNone ・ ・ End Select
お礼
ありがとうございます。助かりました。 Formatを使うとうまくいきました。 ところで、weekday()の戻り値の1,2...は、実際にどのような数値が 戻ってきているのかと思い MsgBox ws.Range("B5") としてみたら 1900/01/01と なりました。 これはどういう意味なのでしょう。