VBA100本ノック 7本目:日付データの扱い
日付データに関する問題です。
そもそも日付とはどのようなデータなのかも考えてみましょう。
ツイートでの見やすさを考慮して、ブック・シート指定等を適宜省略しています。
出題
A列は文字列データ(表示形式が文字列)で日付が入っています。
日付とみなされる場合はB列に月末日付をmmddの形式で出力してください。
日付け以外の場合は空欄にしてください。
例.B2は「0930」と出力する。
※何をもって日付とみなすかも含めて考えてください。
https://excel-ubara.com/vba100sample/VBA100_07.xlsm
https://excel-ubara.com/vba100sample/VBA100_07.zip
VBA作成タイム
この下に頂いた回答へのリンクと解説を掲載しています。
途中まででも良いので、できるだけ自分でVBAを書いてみましょう。
他の人の回答および解説を見て、書いたVBAを見直してみましょう。
頂いた回答
解説
日付の判定はIsDate関数を使います。
ただし人が日付と認識するものとは少しずれがあります。
どのような経緯で発生したデータかによって注意して使ってください。
添付ではIsDateでFalse判定される中から"."区切りだけを救っています。
シート指定は省略しています。
Sub VBA100_07()
Dim i As Long
Dim d As Variant
For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
d = Replace(Cells(i, 1).Value, ".", "/")
If IsDate(d) Then
d = CDate(d)
Cells(i, 2) = Format(DateSerial(Year(d), Month(d) + 1, 0), "'mmdd")
Else
Cells(i, 2) = ""
End If
Next
End Sub
問題文は「mmddの形式で出力」なので、表示形式ではなくデータとしてmmddで出力しました。
元号の合字はIsDateがFalseになります。
これを救うには1文字ずつ変換するしかありません。
※何をもって日付とするかは適宜変わってくると思います。
元号の合字を変換するFunctionのVBAサンプルも掲載しておきました。
補足
特に文字列として日付が入っている場合は、それが日付なのかどうか判断に困る場合も多々あります。
今回の主題としては、IsDate関数とCDate関数の挙動について把握することにあります。
それ以外に、人間が見た時に日付とみなされそうなものを救って見ようという主旨で作成しました。
という事になりますが、VBAが扱うデータはエクセルで入力したものとは限りません。
他システムからの出力データやWEBからのコピーデータを扱う事も多いので、日付けデータの形式については理解しておきましょう。
これは、Date型(つまりシリアル値)に変換可能かの判定になります。
あくまでVBAがDate型に変換できるかどうかであり、人の見た目で日付とみなすかどうかとは関係ありません。
この点に注意して使ってください。
日付 | IsDate |
2020/9/1 | True |
2020/9/02 | True |
10/3 | True |
20 10 4 | True |
2020.10.5 | False |
2020-10-6 | True |
令和元年10月 | True |
令1年11月2日 | True |
令元年11月03日 | True |
㋿元年11月04日 | False |
IsDate関数でTrueならCDateでシリアル値に変換できます。
DateSerial関数のDayに0を指定すると、前月末日になります。
末日より大きい数値を指定した場合は、超えた日数分の翌月の日付けになります。
Monthに0と指定すれば、前年の12月、13と指定すれば翌年の1月
そこで、文字列にするにあたり、セルの表示形式を"@"で文字列にしておいてももちろん良いのですが、
上記のVBAでは、
"'mmdd"
これで先頭に"'"をつけて文字列としてセルに入れています。
これらの文字については、IsDateは元号として認識しません。
またVBAで固定文字として入れようとした時、
これは、?となってしまいます。
これは文字コードの問題です。
以下のFunctionは、この元号の合字をIsDateが認識できる元号に変換するものです。
Function EditDate(ByVal d As String) As String
Dim g1, g2
g1 = Array(&H337E, &H337D, &H337C, &H337B, &H32FF)
g2 = Array("明治", "大正", "昭和", "平成", "令和")
Dim i As Long
For i = LBound(g1) To UBound(g1)
If InStr(d, ChrW(g1(i))) > 0 Then
d = Replace(d, ChrW(g1(i)), g2(i))
Exit For
End If
Next
EditDate = d
End Function
令和以外はVBAに直接合字を記入できますが、令和に合わせて文字コードで記載しました。
サイト内関連ページ
同じテーマ「VBA100本ノック」の記事
8本目:点数の合否判定
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
- ホーム
- マクロVBA入門編
- VBA100本ノック
- 7本目:日付データの扱い
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。