[ Next 記事 => Tips29: JavaScript で電話番号(局番)の検証/編集 ] |
2018/11/13 : Ver 0.10 ( 暫定版 )
2019/4/3 : Ver 1.00 ( 正式版 , 新元号 : 令和 対応 )
2019/4/9 : Ver 1.10 ( EraIsDate を追加 )
2019/4/13 : Ver 1.20 ( EraFormat / EraCDate の[日付]引数に指定できる対象を広げました )
Microsoft による [ 新元号 ] 対応アップデート 対象外の Excel 2003 / Excel 2007 でも 新元号が扱える ようになります!
( 注 ) EraFormat 等は 「書式設定 / 条件付き書式」 の定義には利用できません。
EraFormat ( シリアル値 ⇒ 日付文字列 ) , EraCDate ( 日付文字列 ⇒ シリアル値 ) , EraIsDate ( 日付データ の妥当性判定 )
1. Microsoft の 対応状況
2. 開発 の 経緯
3. EraFormat / EraCDate / EraIsDate 関数 の ヘルプ [ EraFormat ] [ EraCDate ] [ EraIsDate ]
4. EraFormat / EraCDate / EraIsDate 関数 の マクロ コード
5. 補 足
6. 運用面 ( 対応作業上 )での注意点
---- 配布ファイル ----
NewEraFunction120.zip ( 242 KB , 正式版 Ver 1.20 2019/4/13 )
I
+-- NewEraFunction_ReadMe.txt
+-- NewEraHelp.chm ( ヘルプファイル )
+-- NewEraFunction.bas ( EraFormat / EraCDate / EraIsDate マクロコード )
+-- NewEraFunction.xla ( アドインブック )
※ NewEraFunction.bas は [ VBE > ファイル > インポート ] で ワークブック に取り込んで使います。
NewEraFunction.xla はアドインフォルダ [ Library フォルダ ] に保存するだけで利用できます。
Excel では、アドインブック ( NewEraFunction.xla ) を利用するのが最も簡単です。
※ このマクロではReplace / Format 等の基本関数しか使っていませんのでVisualBasic6.0 でも利用可能です
VisualBasic 6 で使用する場合は、CVErr(xlErrValue) を CVErr(450) 等に変更してください。
( エラー番号 450 : 引数の数が一致していません。または不正なプロパティを指定しています。)
Access/VBA で使用する場合には 引数 = NULL への対策 などを適宜追加してください。
※ kt関数アドイン( Ver 5.30 ) にも ktEraFormat / ktEraCDate / ktEraIsDate の名前で収録しています。
---- Ver 1.20 変更内容 ----
( 1 ) EraCDate の [ 日付 ] 引数で [ 数値 ] をサポートします ( シリアル値と見做します )。
( 2 ) EraCDate の [ 日付 ] 引数で [ 日付文字列+時刻文字列 ] をサポートします。
EraFormat / EraIsDate の [ 日付 ] 引数でも同様にサポートします。
( 3 ) EraCDate の [ 日付 ] 引数で 西暦年3桁(100〜999年) / 西暦年2桁(2000年代と解釈) をサポートします。
( 4 ) [ 令和 ] 未対応環境でも EraFormat の [ 日付 ] 引数に [ 令和 ] 日付文字列を指定可能とします。
( 5 ) 配布ファイル に アドインブック を追加しました。
---- 使用条件 ----
EraFormat / EraCDate / EraIsDate 関数はフリーウェアです。
御自由に各自のプログラムに組み込んで利用して戴いて構いません。
但し、プログラム先頭のコメントも必ず一緒に コピーしてください。
EraFormat / EraCDate / EraIsDate 関数を組み込んだプログラムの再頒布にも制限はありません。
この記事に関する お問い合わせ ⇒ [ 掲示板 足跡ぼーど ] [ メール送信 ]
[ この場所への リンク ]
1. Microsoft の 対応状況
経済産業省 主催の 「改元に伴う システム 改修 に対する説明会」
Microsoft 配布資料 ( PDF , 118 頁 ) 詳細に各アプリケーションの対応状況/対応方法が記載されています
[ KB4469068 : 日本の元号の変更について ] の中程の記述 ( 上記の PDF ( 73 頁以降 ) にも記述あり )
日本の元号がサポートされている機能 / 元年対 1年
・ Windows は、元号の初年度にあたる"元年"と"1年"の両方をサポートします。 ( 以下、略 )
・ すべてのバージョンの .NET Framework は、既定で"元年"をサポートします ( 以下、略 )
・ Microsoft Excel および Microsoft Access は、"元年"をサポートしていませんが、Office の
VBA プログラミングは OLE に依存しており、VBA コード で"元年"をサポートしています。 ( 以下、略 )
------------------------------------------------------------------------------------------------
( 以下の情報は [ Windows 版 Office ] に関してです。[ Mac 版 Office ] では対応状況が異なるようです。)
※ Excel の日付関数 ( DATEVALUE , DATEDIF , WEEKDAY , WORKDAY 等 ) の 日付引数 に 令和日付 を
文字列で指定 ( "令和1年5月1日" 等 ) してみましたが、問題なく動作しました ( "元年" はNG )。
※ Excel 2013 / Access 2013 注意事項 ※
Win 7/8.1 の Excel2013/Access2013 では、最新の アップーデート により Format が奇妙な結果を返す不具合が出ているようです。
参考: Microsoft コミュニティ
・ 新元号に対応したExcel2013のVBAでのFormat関数について
・ Excel2013 32bit 版(クイック実行インストール版)の新元号対応のテスト確認手順について
EraFormat では [ 2019/4/30 以前の日付 ] については Format 関数に丸投げしていますので、EraFormat も上記の不具合の
影響を受けます。 ( 他の Office2010/2016 等 および Win10 の Office2013 は問題ありません )
2019/4/11 のアップデートで サポート状況に変化が有りました。
Excel 2010 の場合 [ 2019/4/9 リリース KB4464520 , KB4462230 , KB4462223 ] の アップデート と思われます。
--- 改善 ポイント ---
( a ) VBA の CDate / DateValue / IsDate 関数 について
新元号 [ 令和 ] に対応し、[令和]表記の和暦日付が変換可能になりました。
それに伴い、[ 令和元年 ]表記の和暦日付も変換可能になっています ( 平成元年 はアップデート前でも可能でした)。
( b ) VBA の Format 関数における [ 元年 ] 編集について
「"元年"固定」 から 「下記 レジストリ 設定に従う」 ように修正されました。
[ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese ]
の InitialEraYear キー値 : "元年" or "1年" の何れかで指定します。
InitialEraYear = 元年 の場合 … Format ("2019/5/1", "ggge年m月d日") ⇒ 令和元年5月1日
InitialEraYear = 1年 の場合 … Format ("2019/5/1", "ggge年m月d日") ⇒ 令和1年5月1日
※ アップデートの適用状況 だけでなく、更に レジストリ 設定によっても、
Format 関数の結果が "元年" or "1年" となる PC が混在 する状況が、今後、問題 となります。
--- 以下、上記 アップデート 適用前の状況です ---
( 1 ) 2019年4月9日 時点での 新元号[ 令和 ] 対応状況
( a ) Windows/Office アップデート ( レジストリ の 新元号登録 含む) が済んでいる環境では、
下記 において、ggge 等の編集文字により 新元号「令和」が表示できます。
・ VBA の Format 関数
・ Excel の TEXT 関数
・ Excel の セル書式
また、Excel の DATEVALUE 関数も 新元号[令和] 表記の日付文字列を変換可能になっています。
セルへの 新元号[令和]表記の日付文字列 の手入力も可能です(日付として正しくシリアル値になります)。
( b ) VBA の CDate / DateValue / IsDate 関数は 未対応
Windows/Office アップデート ( レジストリ の 新元号登録 含む) が済んでいる環境においても、
これらの VBA 関数は 新元号[令和] に対応していません。
CDate ("令和1年5月1日") ⇒ 実行時エラー
DateValue ("令和1年5月1日") ⇒ 実行時エラー
IsDate ("令和1年5月1日") ⇒ False
( 2 ) 2019年4月9日 時点での "元年"表記 について
Microsoft の 新元号対応 アップデート の中で、VBA 関数の Format が "元年"表記を 標準 とする
ように変更されました。 加えて、CDate / DateValue / IsDate も "元年"表記の日付文字列 をサポート
するように変更されました。 ( アップデートが済んでいる環境が前提です)
Format 関数では ggge 編集 で [ 平成1年 ⇒ 平成元年 , 令和1年 ⇒ 令和元年 ] と "元年" 固定
で編集されます。 今後、「令和1年」 が欲しい場合には Replace 関数で 「"元年" ⇒ "1年"」 変換が
必要となります。
Format ("2019/5/1", "ggge年m月d日") ⇒ 令和元年5月1日
Replace (Format ("2019/5/1", "ggge年m月d日"), "元年", "1年") ⇒ 令和1年5月1日
※ アップデートの適用状況 によって、Format 関数の結果が "元年" or "1年" となる PC が混在 する状況が、
今後、問題 となります。
CDate / DateValue 関数については [ 平成元年1月8日 ⇒ 1989/1/8 , 平成1年1月8日 ⇒ 1989/1/8 ]
と 、元年/1年 の どちらでも日付変換が可能です。
IsDate 関数では [ 平成元年1月8日 , 平成1年1月8日] と 元年/1年 の どちらでも True が返ります。
尚、前項の通り、CDate / DateValue / IsDate 関数は新元号[令和] 表記を現時点ではサポートして
いませんので、[ 令和元年5月1日 ] は実行時エラー ( IsDate は False ) となります。
( 注 ) ワークシート上での 日付入力 / セル書式 / TEXT 関数 / DATEVALUE 関数 は
"元年"表記 を サポート していません。
[ 令和 ] 限定ですが、下記の セル書式( ユーザー書式定義 )で "元年"表示が可能です。
[<43586]ggge"年"m"月"d"日";[>43830]ggge"年"m"月"d"日";ggg"元年"m"月"d"日"
( 43586 ⇒ 2019/5/1 , 43830 ⇒ 2019/12/31 )
[ この場所への リンク ]
2. 開発の経緯
2019年 5月1日に、平成 から 新元号( 令和 )への改元が行なわれます。マイクロソフトの発表では、
新元号が公表され次第、Office2010 以降の製品に対して、新元号対応アップデートのネット配信を
行なうとの事です。
参照 : 2019年5月の日本の元号変更に関する更新プログラム
そうしますと、Office2007 以前の環境では新元号( 令和 ) &和暦年の表示/変換が行なえず、
『平成』のままとなります。また、Office2010以降の環境でも諸々の事情によりアップデートが施さ
れない場合には、同じように新元号( 令和 )&和暦年の表示/変換が行なえません。
そこで、新元号( 令和 ) に未対応な環境においても「新元号( 令和 )&和暦年の表示/変換」が
行なえるように変換関数【 EraFormat / EraCDate 】を作成しました。
( kt関数アドイン Ver 5.30 にも [ ktEraFormat / ktEraCDate ] の名前で収録します)。
セル上の TEXT関数/マクロ内のFormat関数を差し替えるだけ( [ 引数/編集文字の定義 ] は
そのままで、関数名のみ書き換え)で利用できます。
=TEXT(日付 , "本日は yyyy(ggge)年m月d日 (aaaa) です") ・・・ セル内の式
Format(日付 , "本日は yyyy(ggge)年m月d日 (aaaa) です") ・・・ VBAマクロ
EraFormat(日付 , "本日は yyyy(ggge)年m月d日 (aaaa) です")
※ 編集文字は そのまま 同じものが使えます。
これよって、新元号が未対応な環境で「本日は 2019(平成31)年5月1日 (水曜日) です」 という
表示が 「本日は 2019(令和1)年5月1日 (水曜日) です」という表示に変わります。
但し、当然ですが「セルの書式設定/条件付き書式」の定義には利用できません。
UserForm 等で入力された日付文字列のチェック&シリアル値変換には EraCDate 関数を利用
してください。
kt関数アドインではサポート対象を 「Excel 2000 以降」としていますが、EraFormat 関数を使用
する事により、下図のように新元号にも簡単に対応できます(Ver 5.30 で対応予定)。
[ この場所への リンク ]
3. EraFormat / EraCDate / EraIsDate 関数の ヘルプ
----- EraFormat 関数 -----
2019年5月1日からの新元号( 令和 ) に対応した Excel の TEXT 関数 / VBA の Format 関数 の代替関数です。
Office2007以前 または 対応アップデートが施されていない環境で 新元号の和暦変換を提供します。
( 補 ) 日付専用 ですので、数値変換 ( カンマ編集, 通貨編集 等 )等には使用しないでください。
数値変換等には 通常の TEXT / Format 関数を使用してください 。
【 構 文 】
EraFormat ( 日付 , 編集文字 , [ 元年表記 ] )
返却値 …… Variant 型( String 型 or #VALUE! )
日付 …… Variant 型 ( シリアル値 or 日付文字列 )
編集文字 …… String 型
元年表記 …… Boolean 型 ( 省略可 , 既定値 : False )
【 返却値 】
編集文字で指定した書式定義にしたがって日付を編集した結果が返ります。
元号/和暦年の書式文字 ( ggg , gg , g , ee , e , rr , r ) については、
使用環境・Office バージョン に係わらず 新元号に対応 した結果が得られます。
元年表記=True とすると、各元号の 「1年」 が "元年" と編集されます。
( レジストリ の InitialEraYear キー値 : "元年" or "1年" には影響されません )
編集文字列が空文字の場合は #VALUE! が返ります。
(注) 日付に シリアル値 [ 0 〜60 ] の値を指定した場合に得られる日付編集は、
シート上での [ 書式 or TEXT 関数 ] による 結果 とは 1日ズレ ます。
-- EraFormat による 編集結果 --
0 ⇒ M 32/12/30 , 1 ⇒ M 32/12/31 , 2 ⇒ M 33/1/1 , 60 ⇒ M 33/2/28 , 61 ⇒ M 33/3/1
-- シート上での [ 書式 or TEXT 関数 ] による 編集結果 --
0 ⇒ M 33/1/0 , 1 ⇒ M 33/1/1 , 2 ⇒ M 33/1/2 , 60 ⇒ M 33/2/29 , 61 ⇒ M 33/3/1
( Excel は Lotus1-2-3互換の為に [ 1900/1/1〜1900/2/29 ] の シリアル値を敢えてズラしています )
【 パラメータ 内容 】
[ 日付 ]
任意の日付 ( シリアル値 or 日付文字列 or 日付データ のセル 等 ) を指定します。
日付文字列 に 時刻文字列 が付随していても構いません ( 時刻情報も一緒に読み込みます)。
新元号に対応していない環境 ( Office2007 以前 もしくは 対応アップデートが施されていない
Office2010 以降 ) でも [令和] 日付 を直接指定可能です( EraCDate を経由する必要はありません )。
記述可能 な 日付文字列 の フォーマット は EraCDate 関数の 仕様に準拠します。
[ 編集文字 ]
Excel および VBA で規定された表示書式文字( 日付 , 時刻 ) を使った文字列を指定します。
TEXT 関数 / Format 関数 で使用可能な表示書式文字( 日付 , 時刻 ) は全て使用できます。
[ 元年表記 ]
省略可能です。 省略した場合は False になります。
True … 各元号の 1年 (元号施行日以降) を "元年" と編集します。
False … 各元号の 1年 (元号施行日以降) は [ 1年 ] のままで編集します。
VBA / Format 関数が "元年" と編集する レジストリ 設定になっていても [ 1年 ] で編集されます。
2019/4/11 現在、最新の アップデート まで実施済みの Format 関数では下記の レジストリ 設定にしたがって、
元号最初の年を [ 元年 or 1年 ] の何れかに編集しますが、EraFormat 関数は この レジストリ 設定の影響を受けません。
[元年表記] 引数の指定にしたがって編集します。
[ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese ]
の InitialEraYear キー値 : "元年" or "1年"
[ 元年表記 ] は編集文字 として [ g + e + "年" ] もしくは [ e + "年" ] の パターン に限ります ( "年" の文字が必須 )
g は ggg or gg or g , e は ee or e です。
EraFormat("2019/4/30", "ggge年m月d日", True) ⇒ 平成31年4月30日
EraFormat("2019/5/1", "ggge年m月d日", True) ⇒ 令和元年5月1日
EraFormat("2019/5/1", "ggge年m月d日", False) ⇒ 令和1年5月1日
EraFormat("2020/1/1", "ggge年m月d日", True) ⇒ 令和2年1月1日
EraFormat("2019/5/1", "ggge/m/d", True) ⇒ 令和1/5/1
EraFormat("2019/5/1", "ggge年", True) ⇒ 令和元年
EraFormat("2019/5/1", "e年", True) ⇒ 元年
【 解 説 】
2019年5月1日に、平成 から 新元号( 令和 ) への改元が行なわれます。
マイクロソフトの発表では、新元号が公表され次第、Office2010 以降の製品に対して、
新元号対応アップデートのネット配信を行なうとの事です。
そうしますと、Office2007 以前の環境では新元号&和暦年の表示/変換が行なえず、
『平成』のままとなります。また、Office2010以降の環境でも諸々の事情により アップ
デートが施されない場合には、同じように新元号&和暦年の表示/変換が行なえません。
この EraFormat 関数を利用すれば、セル上の TEXT 関数 / マクロ内の Format 関数 を
差し替える ( [ 引数/編集文字の定義 ] はそのままで、関数名のみ書き換え ) だけで
新元号に対応した和暦変換が可能です。
但し、「セルの書式設定」 の定義には利用できません。
--- セル内の式 ---
=TEXT(日付 , "本日は yyyy(ggge)年m月d日 (aaaa) です")
--- VBA マクロ ---
Format(日付 , "本日は yyyy(ggge)年m月d日 (aaaa) です")
上記の式で 「 関数名だけを書き換える」
EraFormat(日付 , "本日は yyyy(ggge)年m月d日 (aaaa) です")
これだけで、新元号が未対応な環境であっても
「本日は 2019(平成31)年5月1日 (水曜日) です」
という表示が
「本日は 2019(令和1)年5月1日 (水曜日) です」
という新元号に対応した表示に変わります。
EraFormat 関数では、元号/和暦年の書式文字 ( ggg , gg , g , ee , e , rr , r ) についてのみ
関数内で独自に処理し、それ以外の部分の編集については Format 関数に委ねています。
その為、TEXT 関数 / Format 関数 で使用可能な表示書式文字は全て使用できます。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
----- EraCDate 関数 -----
2019年5月1日からの新元号( 令和 ) に対応した Excel の DATEVALUE 関数 / VBA の DateValue / CDate 関数
の代替関数です。Office2007以前 または 対応アップデートが施されていない環境で [ 新元号の和暦日付 文字列
⇒ シリアル値 ] 変換を提供します。
【 構 文 】
EraCDate ( 日付文字列 , [ 元号範囲 ] )
返却値 …… Variant 型( Date 型 or #VALUE! )
日付文字列 …… String 型 ( 補足 も参照の事 )
元号範囲 …… Boolean 型 ( 省略可 , 既定値 : False )
【 返却値 】
日付文字列 を シリアル値に変換した結果が返ります。
使用環境・Office バージョン に係わらず 新元号にも対応 した結果が得られます。
日付文字列が不正の場合は #VALUE! が返ります。
[ 元号範囲 = True ] 指定では、元号の範囲を超えている日付文字列 の場合は #VALUE! が返ります。
(注) 日付文字列に [ 1900/1/1〜1900/2/29 ] の期間の日付を指定した場合に得られる
シリアル値は、シート上に入力した値/DATEVALUE 関数の結果 とは 1日ズレます。
-- EraCDate による 変換結果 --
1900/1/1 ⇒ 2 , 1900/2/28 ⇒ 60 , 1900/3/1 ⇒ 61 ( 1900/2/29 はエラーになります )
-- シート上での [ 手入力 or DATEVALUE 関数 ] による シリアル値 --
1900/1/1 ⇒ 1 , 1900/2/28 ⇒ 59 , 1900/2/29 ⇒ 60 , 1900/3/1 ⇒ 61
( Excelは Lotus1-2-3互換の為に [ 1900/1/1〜1900/2/29 ] のシリアル値を敢えて ズラしています )
【 パラメータ 内容 】
[ 日付文字列 ] ( 補足 も参照の事 )
指定可能な 日付フォーマット は以下の通りです。
( a ) 区切り 形式 ( 年月日 , スラッシュ , ハイフン , ピリオド )
[ H31年4月30日 ] [ H31/4/30 ] [ H31-4-30 ] [ H31.4.30 ]
和暦年/月/日 は 1 桁 or 2 桁
( b ) 元 号
[ 明治 , 明 , M/m ] [ 大正 , 大 , T/t ] [ 昭和 , 昭 , S/s ] [ 平成 , 平 , H/h ] [ 令和 , 令 , R/r ]
( c ) 西暦年 も変換可能です ( 年は 4 桁 , 3桁 , 2桁 ) 2桁年は 2000年代と見做します。
尚、西洋式の [ 月/日/年 or 日/月/年 ] フォーマットはサポートしていません。
[ 2019年4月30日 ] [ 2019/4/30 ] [ 2019-4-30 ] [ 2019.4.30 ]
( d ) 平成 32 年 等の 改元以後の年数 でも OK としています。
但し、[ 元号範囲 = True ] 指定の場合は 元号期間内の日付のみが OK となります。
( e ) "明治元年", "大正元年", "昭和元年", "平成元年", "令和元年" という表記の日付文字列も
可 とします( "明治1年", "大正1年", "昭和1年", "平成1年", "令和1年" として扱います)。
下記 も指定可能です。
"明元年","大元年","昭元年","平元年","令元年"
"M元年","T元年","S元年","H元年","R元年"
但し、"平成元/5/1" など "年" が無いフォーマットはエラーになります。
( 補足 ) [ 文字列 ] 以外のデータ を指定した場合の挙動に付いて
・ Date 型 データ を指定した場合
Date 型 データ ・・・ [ Date 型の変数 ] [ DateValue / DateSerial / CDate の結果 ] [ 日付書式のセル ]
日付文字列 変換 されて 【 "yyyy/m/d" 形式の日付文字列 】 として受け取り、対応する シリアル値 として返します。
[ 日付書式のセル ] は和暦書式であっても "yyyy/m/d" 形式 として受け取ります。
・ 数値 or 数字文字列 を指定した場合
Date 型の範囲 [ 100/1/1 ( -657434 ) 〜 9999/12/31 ( 2958465 ) ] 内であれば シリアル値 として返します。
範囲外の場合は #VALUE! が返ります。
・ [ 空セル ] を指定した場合
「空文字」 として受け取りますので、 #VALUE! が返ります。
[ 元号範囲 ]
省略可能です。 省略した場合は False になります。
日付文字列 に指定した 和暦日付 が、元号の範囲に入っているかも 合わせて チェック する場合には True を
指定します。日付文字列 が 和暦 の場合のみ有効です。
明治:1868 (M1)/10/23 〜 1912 (M45)/ 7/29
大正:1912 (T1)/ 7/30 〜 1926 (T15)/12/24
昭和:1926 (S1)/12/25 〜 1989 (S64)/ 1/ 7
平成:1989 (H1)/ 1/ 8 〜 2019 (H31)/ 4/30
令和:2019 (R1)/ 5/ 1 〜 9999 (---)/12/31
尚、[ 和暦日付書式 の セル ] を [日付文字列] 引数に指定した場合は機能しません( 上記:補足 参照 )。
【 解 説 】
2019年5月1日に、平成 から 新元号( 令和 ) への改元が行なわれます。
マイクロソフトの発表では、新元号が公表され次第、Office2010 以降の製品に対して、
新元号対応アップデートのネット配信を行なうとの事です。
そうしますと、Office2007 以前の環境では新元号で記述された和暦日付 を シリアル値に変換する事が
できません。また、Office2010以降の環境でも諸々の事情により アップデートが施されない場合には、
同じように和暦日付 を シリアル値に変換する事ができません。
この EraCDate 関数を使えば、新元号で記述された和暦日付 も シリアル値に変換することが可能です。
UserForm 等での入力値チェック としても活用できます。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
----- EraIsDate 関数 -----
2019年5月1日からの新元号( 令和 ) に対応した VBA の IsDate 関数 の代替関数です。
Office2007以前 または 対応アップデートが施されていない環境で 「日付 として妥当か否か」 の
判定を行ないます。
【 構 文 】
EraIsDate ( 日付データ )
返却値 …… Boolean 型
日付データ …… Varianr 型 ( 日付文字列 or シリアル値 )
【 返却値 】
日付データ ( 日付文字列 or シリアル値 ) が 『 日付 として妥当か否か 』 を True / False で返します。
使用環境・Office バージョン に係わらず 新元号にも対応 した結果が得られます。
[ 元年 表記 ] の日付文字列 も 日付として有効と判定します。
【 パラメータ 内容 】
[ 日付データ ]
日付文字列 または シリアル値 ( 数値 or 数字文字列 ) を指定します。
指定可能な 日付フォーマット は以下の通りです。
( a ) 区切り 形式 ( 年月日 , スラッシュ , ハイフン , ピリオド )
[ H31年4月30日 ] [ H31/4/30 ] [ H31-4-30 ] [ H31.4.30 ]
和暦年/月/日 は 1 桁 or 2 桁
( b ) 元 号
[ 明治 , 明 , M/m ] [ 大正 , 大 , T/t ] [ 昭和 , 昭 , S/s ] [ 平成 , 平 , H/h ] [ 令和 , 令 , R/r ]
( c ) 西暦年 も変換可能です ( 年は 4 桁 , 3桁 , 2桁 ) 2桁年は 2000年代と見做します
尚、西洋式の [ 月/日/年 or 日/月/年 ] フォーマットはサポートしていません。
[ 2019年4月30日 ] [ 2019/4/30 ] [ 2019-4-30 ] [ 2019.4.30 ]
( d ) 平成 32 年 等の 改元以後の年数 でも OK としています
但し、[ 元号範囲 = True ] 指定の場合は 元号期間内の日付のみが OK となります。
( e ) "明治元年", "大正元年", "昭和元年", "平成元年", "令和元年" という
表記の日付文字列も可とします( "明治1年", "大正1年", "昭和1年", "平成1年", "令和1年" として扱います)。
下記 も指定可能です。
"明元年","大元年","昭元年","平元年","令元年"
"M元年","T元年","S元年","H元年","R元年"
但し、"平成元/5/1" など "年" が無いフォーマットはエラーになります。
( f ) 数値 or 数字文字列 の場合は、シリアル値の有効範囲( 下記 ) 内であれば OK となります。
[ -657434 ( 100/1/1 ) 〜 2958465 ( 999/12/31 ) ]
[ この場所への リンク ]
4. EraFormat / EraCDate / EraIsDate 関数のマクロ コード
配布ファイル ( NewEraFunction.bas ) の先頭には モジュール名を指定する Attribute ステートメント が
入っていますので、そのまま [ VBE > ファイル > インポート ] で取り込めば 「標準モジュール , モジュール名:
NewEraFunction ] として組み込まれます。
このマクロではReplace と Format しか使っていませんのでVisualBasic6.0 でも利用可能です
VisualBasic 6 で使用する場合は、CVErr(xlErrValue) を CVErr(450) 等に変更してください。
( エラー番号 450 : 引数の数が一致していません。または不正なプロパティを指定しています。)
Access/VBA で使用する場合には 引数 = NULL への対策 などを適宜追加してください。
( Coloring by SyntaxHighlighter )
Attribute VB_Name = "NewEraFunction" Option Explicit '######################################################################### '# '# [新元号:令和]対応 日付変換関数 Ver 1.20 '# '# EraFormat ( シリアル値 ⇒ 日付文字列 ) '# EraCDate ( 日付文字列 ⇒ シリアル値 ) '# EraIsDate ( 日付データ ⇒ True or False ) '# '# Ver 0.10 , 2018/12/ 1 暫定版 初版 ( EraFormat / EraCDate ) '# Ver 0.20 , 2019/ 1/ 3 暫定版 2版 '# '# Ver 1.00 , 2019/4/3 '# (1) 正式版(EraFormat / EraCDate)リリース '# '# Ver 1.10 , 2019/4/9 '# (1) EraIsDate を追加 '# それに伴い[EraCDateのセル制限(0〜60)]を解除 '# '# Ver 1.20 , 2019/4/13 '# (1) EraCDateの[日付]引数で[数値]をサポートします(シリアル値と見做します) '# (2) EraCDateの[日付]引数で[日付文字列+時刻文字列]をサポートします '# EraFormat/EraIsDateの[日付]引数でも同様にサポートします '# (3) EraCDateの[日付]引数で西暦年3桁(100〜999年), '# 西暦年2桁(2000年代と解釈)をサポートします '# (4) [令和]未対応環境でもEraFormatの[日付]引数に '# [令和]日付文字列を指定可能とします '# '# 作者: AddinBox 角田 桂一 '# ( http://addinbox.sakura.ne.jp/Excel_Tips28.htm ) '# '# -- 使用条件 -- '# (a) EraFormat/EraCDate/EraIsDate 関数はフリーウェアです。 '# 御自由に各自のプログラムに組み込んで利用して戴いて構いません。 '# 但し、プログラム先頭のコメントも必ず一緒に コピーしてください。 '# '# (b) EraFormat/EraCDate/EraIsDate 関数を組み込んだプログラムの '# 再頒布にも制限はありません。 '# '######################################################################### '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ '_/ '_/ [新元号:令和]対応 日付変換関数 EraFormat ( シリアル値 ⇒ 日付文字列 ) '_/ '_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '_/ 新元号に対応していないシステム(Office2007以前 or 対応 '_/ アップデートを施していないOffice2010以降)でも、新元号に '_/ 基づく和暦変換を可能にする関数です。 '_/ '_/ ExcelのTEXT関数/VBAのFormat関数の代わりに使用してください。 '_/ [元号/和暦年]以外の編集文字を一緒に使用しても問題ありません。 '_/ '_/ また、新元号に対応済みのシステムで使用しても問題ありません。 '_/ '_/ 尚、EraFormat は AddinBox/kt関数アドイン(Ver5.30)に '_/ ktEraFormat の名前で収録します。 '_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '_/ (注) 日付にシリアル値[0〜60]の値を指定した場合に得られる日付編集は、 '_/ シート上の書式/TEXT関数で得られる結果と1日ズレます。 '_/ EraFormat: 0⇒1899/12/30, 1⇒1899/12/31, 2⇒1900/1/1, 60⇒1900/2/28, 61⇒1900/3/1 '_/ シート上 : 0⇒1900/1/0 , 1⇒1900/1/1 , 2⇒1900/1/2, 60⇒1900/2/29, 61⇒1900/3/1 '_/ (Excelは Lotus1-2-3互換の為に[1900/1/1〜1900/2/29]のシリアル値を敢えてズラしています) '_/ '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Public Function EraFormat(ByVal 日付 As Variant, ByVal 編集文字 As String, _ Optional ByVal 元年表記 As Boolean = False) As Variant Const cst新元号開始日 As Date = #5/1/2019# Const cstEra1 As String = "令和" Const cstEra2 As String = "令" Const cstEra3 As String = "R" Const cstReplace_Era3 As String = "α" '和暦年の迂回置換用の代用文字 Const cstReplace_ee As String = "β" Const cstReplace_e As String = "γ" Const cstReplace_Period As String = "Ω" 'ピリオド区切りの代用文字 Dim dtm日付 As Date Dim strDateFormat As String Dim Result As String '(注意事項) ' 1. LCase/UCase による小文字/大文字への統一変換は、 ' g/e以外の編集定義を壊すかもしれないので使わない ' 2. 元号半角 および 和暦年編集後の "0" が数値/日付編集文字と ' 重複するケースを回避するために、Format関数の実施前では ' 代用文字(α,β,γ)で迂回置換し、Format実施後に改めて置換する。 ' 3. 正規表現による検索/置換は利用しません(VBAではVBScriptを必要とする為) If EraIsDate(日付) Then '[令和]未対応環境でも [日付]引数に [令和]日付文字列を指定可能とする '[元年]表記の日付文字列も可としているので、[Formatで対応可能]判定の前に 'EraCDateでシリアル値変換を行なう dtm日付 = EraCDate(日付) Else EraFormat = CVErr(xlErrValue) Exit Function End If '--- rr書式 ( = gggee ) / r書式 ( = ee)の変換(Format関数では不可) --- ' (rr ⇒ r の順で置換する) ' ※ LCase/UCase非使用の注意事項を参照 strDateFormat = Replace(編集文字, "rr", "gggee") strDateFormat = Replace(strDateFormat, "rR", "gggee") strDateFormat = Replace(strDateFormat, "Rr", "gggee") strDateFormat = Replace(strDateFormat, "RR", "gggee") strDateFormat = Replace(strDateFormat, "r", "ee") strDateFormat = Replace(strDateFormat, "R", "ee") '以下の何れかの条件では問題がないので全て Format関数に任せて完了とする。 ' (1) [平成]以前(2019/4/30 以前)の日付 ' (2) 新元号対応バージョン or 新元号対応アップデート実施済の環境 If (dtm日付 < cst新元号開始日) Or _ (Format(cst新元号開始日, "geemmdd") = "R010501") Then On Error Resume Next Result = Format(dtm日付, strDateFormat) ' Format関数による編集 If (Err.Number <> 0) Then EraFormat = CVErr(xlErrValue) Exit Function End If On Error GoTo 0 ' 元年⇔1年 編集 EraFormat = prvFirstYearEdit(元年表記, dtm日付, Result, 編集文字) Exit Function End If '#################################################################### '### ### '### 以降 [日付≧2019/5/1 & [新元号]未対応環境] 限定の変換処理 ### '### ### '#################################################################### 'ロケールIDが有れば取り除く([$-411] : 日本 , [$-409] : 米国) 'Format関数ではロケールIDが無くても期待通りに変換される strDateFormat = Replace(strDateFormat, "[$-411]", "") strDateFormat = Replace(strDateFormat, "[$-409]", "") If (strDateFormat = "") Then EraFormat = CVErr(xlErrValue) Exit Function End If '--- ggg⇒"令和" , gg⇒"令" , g⇒"R"(代用文字α) に変換する --- ' (ggg ⇒ gg ⇒ g の順で置換する) ' ※ LCase/UCase非使用の注意事項を参照 strDateFormat = Replace(strDateFormat, "ggg", cstEra1) strDateFormat = Replace(strDateFormat, "Ggg", cstEra1) strDateFormat = Replace(strDateFormat, "gGg", cstEra1) strDateFormat = Replace(strDateFormat, "ggG", cstEra1) strDateFormat = Replace(strDateFormat, "GGg", cstEra1) strDateFormat = Replace(strDateFormat, "GgG", cstEra1) strDateFormat = Replace(strDateFormat, "gGG", cstEra1) strDateFormat = Replace(strDateFormat, "GGG", cstEra1) strDateFormat = Replace(strDateFormat, "gg", cstEra2) strDateFormat = Replace(strDateFormat, "gG", cstEra2) strDateFormat = Replace(strDateFormat, "Gg", cstEra2) strDateFormat = Replace(strDateFormat, "GG", cstEra2) strDateFormat = Replace(strDateFormat, "g", cstReplace_Era3) strDateFormat = Replace(strDateFormat, "G", cstReplace_Era3) '--- ee / e を和暦年(西暦年 - 2018) に変換する(代用文字 β,γ) --- ' ※ ここまで処理が流れて来るのは2019/5/1以降の日付のみ。 ' 平成以前(2019/4/30以前)の日付は、ここまで流れて来ないので ' 和暦年の換算式は[西暦年-2018]固定で大丈夫 ' (補) [和暦年]編集文字は e / ee のみ。eee は無い。 ' eee年は [ee]+[e年]と解釈(1年⇒ 011年 になる)される。 ' (ee ⇒ e の順で置換する) strDateFormat = Replace(strDateFormat, "ee", cstReplace_ee) strDateFormat = Replace(strDateFormat, "eE", cstReplace_ee) strDateFormat = Replace(strDateFormat, "Ee", cstReplace_ee) strDateFormat = Replace(strDateFormat, "EE", cstReplace_ee) strDateFormat = Replace(strDateFormat, "e", cstReplace_e) strDateFormat = Replace(strDateFormat, "E", cstReplace_e) '---【 g , e 以外の編集は Format関数に任せる 】--- ' ' 但し、Formmat に任せる前に ピリオドも代用文字に置換しておく必要がある。 ' 理由:"ge.m.d"⇒"αγ.m.d" となるが、[年]編集文字が無くなる為に ' 最初のピリオドが小数点と解釈されてしまいます。 ' その結果、シリアル値がピリオド位置に数値として表示されます。 ' 残りの "m.d" も月日編集文字ではなく単なる固定表示文字として ' 解釈されて、m.d の文字でそのまま表示されます。 strDateFormat = Replace(strDateFormat, ".", cstReplace_Period) On Error Resume Next Result = Format(dtm日付, strDateFormat) ' Format関数による編集 If (Err.Number <> 0) Then EraFormat = CVErr(xlErrValue) Exit Function End If On Error GoTo 0 '---------------------------------------------------- ' 迂回置換の代用文字(α,β,γ,Ω)に ' 本来の値(元号半角, 和暦年2桁, 和暦年1桁, ピリオド)を書き込む ' ※ ここまで処理が流れて来るのは2019/5/1以降の日付のみ。 ' 平成以前(2019/4/30以前)の日付は、ここまで流れて来ないので ' 和暦年の換算式は[西暦年-2018]固定で大丈夫 Result = Replace(Result, cstReplace_Era3, cstEra3) Result = Replace(Result, cstReplace_ee, Format(Year(dtm日付) - 2018, "00")) Result = Replace(Result, cstReplace_e, Format(Year(dtm日付) - 2018, "0")) Result = Replace(Result, cstReplace_Period, ".") ' 元年⇔1年 編集 EraFormat = prvFirstYearEdit(元年表記, dtm日付, Result, 編集文字) End Function '----------------------------------------------------------------------------- ' "平成01年"/"平成1年"/"平01年"/"平1年"/"H01年"/"H1年" 等を"元年"表記に改めます。 ' ' (注) 改元関連のアップデートでVBAのFormat関数自体に「元年」表記の機能が追加されました。 ' (レジストリ(InitialEraYear)で[元年]指定が必要) ' -- アップデート済環境 , 未アップデート環境 ' Format("2019/5/1","ggge年") ⇒ "令和元年" , "令和1年 ' Format("2019/5/1","gge年") ⇒ "令元年" , "令1年" ' Format("2019/5/1","ge年") ⇒ "R元年" , "R1年" ' ' Format関数により既に"元年"と編集されているケースでは、 ' EraFormat関数の[元年表記]引数の指定に合わせて、 ' False(元年表記なし)の場合には "元年"⇒"1年" or "01年" に戻します。 '----------------------------------------------------------------------------- Private Function prvFirstYearEdit(ByVal FirstYear As Boolean, _ ByVal SerialDate As Date, _ ByVal EditDate As String, _ ByVal EditPattern As String) As String Dim strEdit As String If (LCase(EditPattern) Like "*e年*") Then ' [和暦+"年"]編集あり Else ' [和暦+"年"]編集なし … [1年⇔元年]変換処理は不要 prvFirstYearEdit = EditDate Exit Function End If If (FirstYear = False) Then ' "令和元年"⇒"令和1年" 等、"1年"表記に戻す ' 既に"元年"表記になっているものなので月日までチェックする必要なし Select Case Year(SerialDate) Case 1868, 1912, 1926, 1989, 2019 ' 明治1年(1868), 大正1年(1912), 昭和1年(1926), 平成1年(1989), 令和1年(2019) strEdit = prvFormat_GannenTo1st(EditDate, EditPattern) Case Else '明治以前 or 各元号の[2年〜] strEdit = EditDate End Select Else ' "令和1年"⇒"令和元年" 等、"元年"表記に改める Select Case Format(SerialDate, "yyyymmdd") Case "18681023" To "18681231" '明治 元年 strEdit = prvFormat_1stToGannen(EditDate) Case "19120730" To "19121231" '大正 元年 strEdit = prvFormat_1stToGannen(EditDate) Case "19261225" To "19261231" '昭和 元年 strEdit = prvFormat_1stToGannen(EditDate) Case "19890108" To "19891231" '平成 元年 strEdit = prvFormat_1stToGannen(EditDate) Case "20190501" To "20191231" '令和 元年 strEdit = prvFormat_1stToGannen(EditDate) Case Else '明治以前 or 各元号の[2年〜] strEdit = EditDate End Select End If prvFirstYearEdit = strEdit End Function '----------------------------------------------------------------------------- ' [元年⇒1年] for EraFormat '----------------------------------------------------------------------------- ' (a) 編集文字には ee年 or e年 の[元号なし]のパターンも有り得るので ' ターゲットを[元号+"元年"]等にしては駄目 ' (b) ee年⇒"01年" , e年⇒"1年" ' ' (補) [和暦年]編集文字は e / ee のみ。eee は無い。 ' eee年は [ee]+[e年]と解釈(1年⇒ 011年 になる)される。 '----------------------------------------------------------------------------- Private Function prvFormat_GannenTo1st(ByVal EditDate As String, _ ByVal EditPattern As String) As String Dim strEdit As String If (LCase(EditPattern) Like "*ee年*") Then strEdit = Replace(EditDate, "元年", "01年") Else strEdit = Replace(EditDate, "元年", "1年") End If prvFormat_GannenTo1st = strEdit End Function '----------------------------------------------------------------------------- ' [01年 or 1年⇒元年] for EraFormat '----------------------------------------------------------------------------- ' (a) 編集文字には ee年 or e年 の[元号なし]のパターンも有り得るので ' ターゲットを[元号+1年]等にしては駄目 ' (b) "yyyy年(gggee年)"のように[西暦年]と併記のパターンでも ' この関数が呼び出されるのは元年(1868,1912,1926,1989,2019)の場合だけなので ' [西暦年]部分が "01年"/"1年"になることはない。 ' ' (補) [和暦年]編集文字は e / ee のみ。eee は無いので、"001年"の変換は不要。 ' eee年は [ee]+[e年]と解釈(1年⇒ 011年 になる)される。 '----------------------------------------------------------------------------- Private Function prvFormat_1stToGannen(ByVal EditDate As String) As String Dim strEdit As String ' "01年"の置換 ⇒ "1年"の置換 の順で行なう事 strEdit = Replace(EditDate, "01年", "元年") strEdit = Replace(strEdit, "1年", "元年") prvFormat_1stToGannen = strEdit End Function '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ '_/ '_/ [新元号:令和]対応 日付変換関数 EraCDate ( 日付文字列 ⇒ シリアル値 ) '_/ '_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '_/ 新元号に対応していないシステム(Office2007以前 or 対応 '_/ アップデートを施していないOffice2010以降)でも、新元号に '_/ 基づく和暦日付を日付データ(シリアル値)に変換できる関数です。 '_/ '_/ ExcelのDATEVALUE関数/VBAのCDate/DateValue関数の代わりに使用してください。 '_/ '_/ 新元号に対応済みのシステムで使用しても問題ありません。 '_/ '_/ 尚、EraCDate は AddinBox/kt関数アドイン(Ver5.30)に '_/ ktEraCDate の名前で収録します。 '_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '_/ 【 EraCDate でサポートする日付文字列のフォーマット 】 '_/ a) 区切り形式(和暦年は1〜3桁,4桁以上はエラー) '_/ [H31年4月30日] [H31/4/30] [H31-4-30] [H31.4.30] '_/ b) 元号 '_/ [明治,明,M/m] [大正,大,T/t] [昭和,昭,S/s] [平成,平,H/h] [令和,令,R/r] '_/ c) 西暦年(4桁,3桁,2桁)も変換可能です(2桁は2000年代と解釈します) '_/ [2019年4月30日] [2019/4/30] [2019-4-30] [2019.4.30] '_/ 尚、西洋式の[月/日/年 or 日/月/年]フォーマットはNGです '_/ d) 平成32 等の改元以後の年数でもOKとしています '_/ 但し、[元号範囲=True]指定の場合は元号期間内の日付のみが OK となります。 '_/ e) "明治元年","大正元年","昭和元年","平成元年","令和元年"という表記も可とします。 '_/ f) 時刻文字列が続いている場合、時刻込みで変換します。 '_/ 但し、その時刻文字列がVBAのCDate関数で変換可能なフォーマットに限ります。 '_/ '_/ (注) 日付文字列に[1900/1/1〜1900/2/29]の期間の日付を指定した場合に得られる '_/ シリアル値は、シート上に入力した場合の値とは1日ズレます。 '_/ EraCDate : 1900/1/1⇒2, 1900/2/28⇒60, 1900/2/29⇒#VALUE!, 1900/3/1⇒61 '_/ シート上 : 1900/1/1⇒1, 1900/2/28⇒59, 1900/2/29⇒60 , 1900/3/1⇒61 '_/ (Excelは Lotus1-2-3互換の為に[1900/1/1〜1900/2/29]のシリアル値を敢えてズラしています) '_/ '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Public Function EraCDate(ByVal 日付文字列 As String, _ Optional ByVal 元号範囲 As Boolean = False) As Variant '※ 引数[日付文字列]にDate型データを指定した場合、 ' 日付文字列変換されて【"yyyy/m/d"形式の日付文字列】として受け取る。 ' Date型データ:[Date型の変数][DateValue/DateSerial/CDateの結果][日付書式のセル値] ' [日付書式のセル値]は和暦書式であっても "yyyy/m/d"形式となって受け取る ' '※ 引数[日付文字列]に数値 or 数字文字列を指定した場合、 ' Date型の範囲 [100/1/1(-657434)〜9999/12/31(2958465)] 内であればシリアル値として返す。 ' '※ 引数[日付文字列]に「空セル」を指定した場合は「空文字」として受け取るのでエラーになる。 Dim strDate As String Dim dtmDate As Date Dim strTemp As String Dim intEra As Integer ' 0:西暦, 1:明治, 2:大正, 3:昭和, 4:平成, 5:令和 Dim aryEraRange As Variant Const cstPattern As String = "[αβγδε明大昭平令MTSHRmtshr]" ' "平成元年","平元年","H元年" 等の"元年"を"1年"表記に改める ' 元号が付かない"元年"のみは年代が特定できない為、変換エラーです strTemp = prvCDate_GannenTo1st(日付文字列, "明治", "明", "M") strTemp = prvCDate_GannenTo1st(strTemp, "大正", "大", "T") strTemp = prvCDate_GannenTo1st(strTemp, "昭和", "昭", "S") strTemp = prvCDate_GannenTo1st(strTemp, "平成", "平", "H") strTemp = prvCDate_GannenTo1st(strTemp, "令和", "令", "R") ' 元号(2文字)の判定処理が Like 演算子で行なえる様に代替文字(1文字)で置換する strTemp = Replace(strTemp, "明治", "α") strTemp = Replace(strTemp, "大正", "β") strTemp = Replace(strTemp, "昭和", "γ") strTemp = Replace(strTemp, "平成", "δ") strTemp = Replace(strTemp, "令和", "ε") '=== 日付文字列のパターンチェック === '=== 年はここで数字判定を完了(# 〜 #### パターン)する '=== 月日の数字判定はCDateに任せる(最低限,1桁数字は保証) '=== [日付文字列+時刻文字列]も対象とする(末尾の*で時刻文字列 等が有ってもOKになる) '--- 和暦(年1桁) --- If (strTemp Like cstPattern & "#年#*月#*日*") Or _ (strTemp Like cstPattern & "#/#*/#*") Or _ (strTemp Like cstPattern & "#.#*.#*") Or _ (strTemp Like cstPattern & "#-#*-#*") Then If (Mid(strTemp, 2, 1) = "0") Then EraCDate = CVErr(xlErrValue) ' 0年 はエラー Exit Function Else '[元号+和暦年]⇒[西暦年]変換 strDate = prvEraYear4EraCDate(Mid(strTemp, 1, 1), Mid(strTemp, 2, 1), Mid(strTemp, 3), intEra) End If '--- 和暦(年2桁) --- ElseIf (strTemp Like cstPattern & "##年#*月#*日*") Or _ (strTemp Like cstPattern & "##/#*/#*") Or _ (strTemp Like cstPattern & "##.#*.#*") Or _ (strTemp Like cstPattern & "##-#*-#*") Then If (Mid(strTemp, 2, 2) = "00") Then EraCDate = CVErr(xlErrValue) ' 00年 はエラー Exit Function Else '[元号+和暦年]⇒[西暦年]変換 strDate = prvEraYear4EraCDate(Mid(strTemp, 1, 1), Mid(strTemp, 2, 2), Mid(strTemp, 4), intEra) End If ' (補) [和暦年]編集文字は e / ee のみ。eee は無いので、和暦(年3桁)の判定は不要。 ' eee年は [ee]+[e年]と解釈(1年⇒ 011年 になる)される。 '--- 西暦(年4桁) --- ' 西洋式の[月/日/年 or 日/月/年]フォーマットはNGです ElseIf (日付文字列 Like "####年#*月#*日*") Or _ (日付文字列 Like "####/#*/#*") Or _ (日付文字列 Like "####.#*.#*") Or _ (日付文字列 Like "####-#*-#*") Then 'ピリオド区切りがDateValueでは変換できないので / に置換する strDate = Replace(日付文字列, ".", "/") intEra = 0 '--- 西暦(年3桁) --- (そのまま 100〜999年と解釈する) ElseIf (日付文字列 Like "###年#*月#*日*") Or _ (日付文字列 Like "###/#*/#*") Or _ (日付文字列 Like "###.#*.#*") Or _ (日付文字列 Like "###-#*-#*") Then 'ピリオド区切りがDateValueでは変換できないので / に置換する strDate = Replace(日付文字列, ".", "/") intEra = 0 '--- 西暦(年2桁) --- (2000年代と解釈する) ElseIf (日付文字列 Like "##年#*月#*日*") Or _ (日付文字列 Like "##/#*/#*") Or _ (日付文字列 Like "##.#*.#*") Or _ (日付文字列 Like "##-#*-#*") Then 'ピリオド区切りがDateValueでは変換できないので / に置換する strDate = "20" & Replace(日付文字列, ".", "/") '先頭に"20"を付加して2000年代 intEra = 0 '--- 数値 or 数字文字列 --- ' ここで、即 CDate変換(単なるDate型への型変換)して値を返す ElseIf IsNumeric(日付文字列) Then '※ カンマ編集数値の場合はカンマを取り除く ' カンマも日付区切り文字として扱われてしまい、 ' 省略形の日付文字列として予想外の日付と見做される ' CDate("2,500")⇒500/2/1 と解釈(m,yyy)される On Error Resume Next dtmDate = CDate(Replace(日付文字列, ",", "")) If (Err.Number <> 0) Then 'シリアル値範囲外 [100/1/1(-657434)〜9999/12/31(2958465)] EraCDate = CVErr(xlErrValue) Else EraCDate = dtmDate End If On Error GoTo 0 Exit Function '--- 他はエラー --- Else EraCDate = CVErr(xlErrValue) Exit Function End If '=== CDateによる日付文字列(時刻文字列を含んでも可)⇒シリアル値 変換 === ' 和暦年は西暦年に変換済 On Error Resume Next dtmDate = CDate(strDate) If (Err.Number <> 0) Then EraCDate = CVErr(xlErrValue) Exit Function End If On Error GoTo 0 If (元号範囲 = True) Then If (intEra = 0) Then '西暦は範囲無し Else ' 明治[1]:1868(M1)/10/23 〜 1912(M45)/ 7/29 ' 大正[2]:1912(T1)/ 7/30 〜 1926(T15)/12/24 ' 昭和[3]:1926(S1)/12/25 〜 1989(S64)/ 1/ 7 ' 平成[4]:1989(H1)/ 1/ 8 〜 2019(H31)/ 4/30 ' 令和[5]:2019(R1)/ 5/ 1 〜 9999(---)/12/31 ' ※[時刻]も指定されている場合には小数があるので、 ' 終端の判定は[終了日+1より小]とする aryEraRange = _ Array(Array(0, 0), Array(#10/23/1868#, #7/29/1912#), _ Array(#7/30/1912#, #12/24/1926#), Array(#12/25/1926#, #1/7/1989#), _ Array(#1/8/1989#, #4/30/2019#), Array(#5/1/2019#, #12/31/9999#)) If (aryEraRange(intEra)(0) <= dtmDate) And _ ((aryEraRange(intEra)(1) + 1) > dtmDate) Then '元号範囲内でOK Else EraCDate = CVErr(xlErrValue) Exit Function End If End If End If EraCDate = dtmDate End Function '----------------------------------------------------------------------------- ' [元年⇒1年] for EraCDate Era1:令和, Era2:令, Era3:R 等 '----------------------------------------------------------------------------- Private Function prvCDate_GannenTo1st _ (ByVal EditDate As String, ByVal Era1 As String, _ ByVal Era2 As String, ByVal Era3 As String) As String Dim strEdit As String strEdit = Replace(EditDate, (Era1 & "元年"), (Era1 & "1年")) strEdit = Replace(strEdit, (Era2 & "元年"), (Era2 & "1年")) strEdit = Replace(strEdit, (Era3 & "元年"), (Era3 & "1年")) strEdit = Replace(strEdit, (LCase(Era3) & "元年"), (Era3 & "1年")) prvCDate_GannenTo1st = strEdit End Function '----------------------------------------------------------------------------- ' [元号+和暦年] ⇒ [西暦年]変換 , 元号を[元号フラグ]で返す ' ' 2文字元号はα(明治),β(大正),γ(昭和),δ(平成),ε(令和)に置換されている ' [年]は 1〜2文字の数字 ' [月日]には[年]数字以降の日付文字列(時刻文字列を含む)の部分が渡される '----------------------------------------------------------------------------- Private Function prvEraYear4EraCDate(ByVal 元号 As String, ByVal 年 As String, _ ByVal 月日 As String, ByRef 元号フラグ As Integer) As String Dim strDate As String Dim strMMDD As String 'ピリオド区切りがDateValueでは変換できない為、スラッシュに置換する strMMDD = Replace(月日, ".", "/") '元号に応じて西暦年に変換する(年は Like演算により数字のチェック済) Select Case 元号 Case "α", "明", "M", "m" strDate = (CLng(年) + 1867) & strMMDD '明治 元号フラグ = 1 Case "β", "大", "T", "t" strDate = (CLng(年) + 1911) & strMMDD '大正 元号フラグ = 2 Case "γ", "昭", "S", "s" strDate = (CLng(年) + 1925) & strMMDD '昭和 元号フラグ = 3 Case "δ", "平", "H", "h" strDate = (CLng(年) + 1988) & strMMDD '平成 元号フラグ = 4 Case "ε", "令", "R", "r" strDate = (CLng(年) + 2018) & strMMDD '令和 元号フラグ = 5 End Select prvEraYear4EraCDate = strDate End Function '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ '_/ '_/ [新元号:令和]対応 日付判定関数 EraIsDate ( 日付データ ⇒ True/False ) '_/ '_/ 新元号に対応していないシステム(Office2007以前 or 対応 '_/ アップデートを施していないOffice2010以降)でも、新元号に '_/ 基づく和暦日付を含め、「日付として妥当か否か」を判定する関数です。 '_/ '_/ EraIsDate がサポートする日付文字列のフォーマットはEraCDateに準じます。 '_/ '_/ 新元号に対応済みのシステムで使用しても問題ありません。 '_/ '_/ 尚、EraIsDate は AddinBox/kt関数アドイン(Ver5.30)に '_/ ktEraIsDate の名前で収録します。 '_/ '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Public Function EraIsDate(ByVal 日付データ As Variant) As Boolean Dim strData As String Dim Result As Variant If IsError(日付データ) Then EraIsDate = False ElseIf IsEmpty(日付データ) Then '空セルはEmpty値 EraIsDate = False ElseIf IsDate(日付データ) Then 'IsDateの判定対象:「日付文字列」「Date型のデータ」 '(1) EraCDateでもIsDate判定が可能だが、効率の面から ' IsDateで対応可能な部分は先にIsDateで済ませる ' '(2) [IsDate(Date型データ) ⇒ True] ' '(3) [IsDate("明治33年2月29日") ⇒False] ' シート上でのシリアル値60に対する日付文字列 ' EraCDateでも False になる ' '(4) [IsDate("昭和65年1月1日")⇒False (元号範囲オーバー)] … 後のEraCDateで救済 ' [IsDate(数値)⇒False] … 次の IsNumericで救済 ' '(5) VBAなのでマイナスのシリアル値に対応する ' 日付文字列("M1/10/23" , "1899/1/1" 等)も True になる ' '(6) [令和]日付文字列 ' 新元号アップデート済 ⇒ True ' 新元号アップデート未 ⇒ False … 後のEraCDateで救済 ' '(7) "平成元年1月8日"等の[元年表記] ' 新元号アップデート済 ⇒ True ' 新元号アップデート未 ⇒ False … 後のEraCDateで救済 EraIsDate = True ElseIf IsNumeric(日付データ) Then 'IsNumericの判定対象:「数値 , 数字文字列」 '(1) 単なる数値判定なのでマイナス値(1899年以前の日付)も True になる ' '(2) シリアル値の範囲は 100/1/1(-657434)〜9999/12/31(2958465) If (VarType(日付データ) = vbString) Then If (CDbl(日付データ) >= -657434) And (CDbl(日付データ) <= 2958465) Then EraIsDate = True Else EraIsDate = False End If ElseIf (日付データ >= -657434) And (日付データ <= 2958465) Then EraIsDate = True Else EraIsDate = False End If Else 'Elseの判定対象: ' 数値/文字列以外のデータ型⇒False ' IsDate で弾かれた日付文字列(下記)の救済⇒True '(1) [令和]日付文字列 '(2) "平成元年1月8日"等の[元年表記] '(3) "昭和65年1月1日"等の元号範囲オーバー On Error Resume Next strData = CStr(日付データ) If (Err.Number <> 0) Then EraIsDate = False '数値/文字列以外のデータは対象外 Exit Function End If On Error GoTo 0 Result = EraCDate(strData, False) 'EraCDateで検証する(元号範囲は無視) If IsError(Result) Then EraIsDate = False Else EraIsDate = True End If End If End Function
[ この場所への リンク ]
5. 補 足
TEXT 関数で、1つの編集文字内に 西暦年 と 和暦年 を共に定義した場合、下記の通りバージョン によって
異なる結果となります。尚、[$-411] は日本 / [$-409] は米国を表すロケールID です。
(VBA の Format関数では問題なく正しく変換されます)
2018/1/1 を変換 Excel2003 SP3 Excel2007 SP3 Excel2010 SP2 Excel2016 ggge(yyyy)年 平成30(30)年 平成30(30)年 平成30(30)年 平成30(30)年 [$-411]ggge(yyyy)年 平成30(30)年 平成30(30)年 平成30(30)年 平成30(30)年 ggge([$-409]yyyy)年 平成30(2018)年 2018(2018)年 2018(2018)年 平成30(30)年 [$-411]ggge([$-409]yyyy)年 #VALUE! #VALUE! #VALUE! #VALUE! yyyy(ggge)年 2018(平成30)年 2018(平成30)年 2018(平成30)年 2018(平成30)年 yyyy([$-411]ggge)年 2018(平成30)年 2018(平成30)年 2018(平成30)年 2018(平成30)年 [$-409]yyyy(ggge)年 2018(2018)年 2018(2018)年 2018(2018)年 2018(平成30)年 [$-409]yyyy([$-411]ggge)年 #VALUE! #VALUE! #VALUE! #VALUE!
EraFormat 関数では、上記の全てのケースで "平成30(2018)年" / 2018(平成30)年" の結果が得られます。
( 閑話 ) ふと思い付いたのが 昨日(11/12) で、2日掛けて作成し、今日( 2018/11/13 19:00 ) サイトにアップロードした後、
EraFormat が検索結果に挙がっているか チェック してみたら ・・・・
全く 同じ問題(ターゲット) に取り組み、同じアプローチ に辿り着き、そして、極め付けに 同じ命名センス で
EraFormat という 名前を出来上がった関数に付けるという 他人とは思えぬ処 ( 山口システム開発 ) を発見♪
やっぱり、この問題を片付けようとしたら、この アプローチ しかない ですよね〜 。
そちらの リリース日は 2018/10/31 みたいだから、わたし 半月 遅れを取ったわぁ 〜
[ この場所への リンク ]
6. 運用面( 対応作業上 )での注意点
以下、「新元号に対応していない環境 ( Office2007 以前 or 対応アップデートが施されていない Office2010 以降 )」 を
「新元号未対応環境」 と記します。
※ Excel では、添付してある アドインブック ( NewEraFunction.xla ) を利用するのが最も簡単です。
( 1 ) 新元号未対応環境では、「新元号の和暦」による日付入力が不可。
セル への入力では「新元号の和暦日付」を入力しても『文字列 扱い』となり、日付データ
(シリアル値) に変換されません。新元号未対応環境では、2019年5月1日以降の日付を
セルに和暦入力する場合は『平成32年 〜』等と平成の年号で入力する必要があります。
UserFormでの日付入力では、EraCDate 関数を利用する事により、「新元号の和暦日付」
についても チェック および シリアル値変換 が可能です。
( 2 ) 新元号未対応環境では、セルの書式定義による「新元号の和暦」の表示が不可。
新元号未対応環境では、和暦年の書式定義(ggge) では2019/5/1以降も『平成』になります。
当然の事ですが、ユーザー定義関数であるEraFormat関数を書式定義に記述する事はできません。
( 3 ) 新元号未対応環境では、( 1 ) & ( 2 ) の制限により、入力日付( or 基本となる
日付データ )セルと表示用和暦年セルを分ける必要があります。
新元号未対応環境では、書式定義による 「新元号の和暦」をセルに表示する事が出来ま
せんので、以下のような式で編集することになります。つまり、和暦日付セルの式で参照する
「日付データセル」が別に必要となります。
=IF(TEXT(日付セル,"yyyymmdd")<"20190501",
TEXT(日付セル,"ggge年m月d日"),
"令和"&(YEAR(日付セル)-2018) & TEXT(日付セル,"年m月d日"))
もしくは
=EraFormat(日付セル,"ggge年m月d日")
( 4 ) EraFormat / EraCDate関数の組み込みに際して留意すべき点
EraFormat/EraCDate関数はマクロで作成されたユーザー定義関数です。
したがって、EraFormat/EraCDate関数を利用するためには以下の何れかの方法で、
EraFormat/EraCDate関数のマクロを登録/実行できるようにする必要があります。
( a ) ワークブック内にマクロを登録する(マクロ付きワークブックにする)。
( b ) 個人用マクロブック( Personal.xls / Personal.xlsb )にマクロを登録する。
( c ) アドインブック( xxxx.xla / xxxx.xlam )を作成して、そこにマクロを登録する。
( d ) 新元号に対応したkt関数アドイン(Ver 5.30) を利用する。
以下、(5)〜(8) で説明していきます。
( 5 ) ワークブック内にマクロを登録する(マクロ付きワークブックにする)
ワークブック参照等も必要なく、セルのTEXT関数/マクロのFormat関数を単純に "EraFormat"と
書き改めるだけで済みます。
=EraFormat(A1,"ggge年m月d日")
当然の事ですが、EraFormat/EraCDate 関数を利用する全てのワークブックに対してマクロ登録
の作業が必要です。
また、個々のワークブックに同じEraFormat/EraCDate 関数のマクロが登録される訳ですから、
EraFormat/EraCDate 関数を使うワークブックを同時に複数開いた場合、自ワークブックと他
ワークブックのEraFormat/EraCDate関数が存在する事になります。
最も、敢えて「ワークブック参照付き」の方を選ばない限り(故意にブック参照付きでEraFormat関数を
記述する)は問題ないですから、特に気にする必要はないでしょう。
また、VBAでは、他ワークブックへの参照設定を行なわない限り、他ワークブックのマクロを呼び出す
事ができませんから元々気にする必要はありません。
元々、マクロ付きワークブックであったならば構いませんが、マクロ無しワークブックに新たに「EraFormat
/EraCDate関数のマクロを登録する」と、以後、ワークブックを開いた際にセキュリティ警告が出る事になり
ます。また、97-2003形式( xls )ならばマクロを追加しても元々のファイル名でそのまま使えますが、2007
形式( xlsx )では拡張子が変わる( xlsx ⇒ xlsm )為に別ファイルとなります。
( 6 ) 個人用マクロブック( Personal.xls / Personal.xlsb )にマクロを登録する。
個々のブックにマクロを登録する代わりに、共用マクロブックである個人用マクロブックにEraFormat
/EraCDate 関数のマクロを登録します。
マクロ無しブックは、そのまま「マクロ無しブック」として運用できますし、EraFormat/EraCDate 関数を
利用する全てのワークブックにマクロを登録する手間も要りません。
セルでは、EraFormat関数を以下のようにブック参照付きで使用します。
=PERSONAL.XLS!EraFormat(A1,"ggge年m月d日")
マクロ内でEraFormat/EraCDate 関数を使用する為には、個人用マクロブックへの「参照設定」が
必要になります( VBE メニュー > ツール > 参照設定 )。尚、参照設定する為には個人用マクロ
ブックのオブジェクト名を既定の VBAProject から変更しておく必要があります(後述の図を参照)。
個人用マクロブックの場所はOS・ユーザーによって下記のように異なるパスとなります。
尚、エクセルのバージョンによる違いはありません。
[ Windows XP ]
C:\Documents and Settings\ユーザー名\Application Data\Microsoft\Excel\XLSTART
[ Windows Vista 以降 ]
C:\Users\ユーザー名\AppData\Roaming\Microsoft\Excel\XLSTART
XLSTARTフォルダはファイルリンクに当たって特殊フォルダの扱いになる為、パスの違いを意識
する必要はありません(リンクエラーにはなりません)。
参考 : Tips21 Excel の リンクの管理と格納
§4. リンク 情報の整理
§6-3. アドインブック を 「スタートアップフォルダ(XLSTART フォルダ)」 に格納している場合
Excel2007以降では個人用マクロブックの既定のファイル名が Personal.xlsb に変更されましたが、
Personal.xls でも問題なく動作します。また、Personal.xls が在る場合にはExcel2007以降でマクロ
記録した結果は Personal.xls に書き込まれます(別に Personal.xlsb が作成されるという動作はし
ません)。
[ Excel2003以前 ⇔ Excel2007以降 ] 間でワークブックの遣り取りがある場合には Personal.xls の
方にしてください。
--- 個人用マクロブックの作成方法 ---
上記の場所に個人用マクロブックが無い場合には、「マクロの記録」を行なって作成してください。
[ Excel2003 ] ツール > マクロ > 新しいマクロの記録
[ Excel2007以降 ] 開発タブ > マクロの記録
保存先を「個人用マクロブック」にしてOKボタンを押した後、適当なセルを選択してから 「記録終了」
ボタンを押すと個人用マクロブックが作成されます。
個人用マクロブック( Personal.xls or xlsb )のオブジェクト名を既定の VBAProject から変更
( PersonalMacro 等 )し、標準モジュールに EraFormat/EraCDate 関数のマクロをコピーし
ます(マクロ記録で書き込まれたマクロは不要なので削除します)。
エクセル終了時に個人用マクロブックの保存確認を問われますのでOKしてください。
( 7 ) アドインブック( xxxx.xla / xxxx.xlam )を作成して、そこにマクロを登録する。
個人用マクロブックの代わりに、EraFormat/EraCDate/EraIsDate 専用のアドインブックを作成して利用します。
( 配布ファイルに NewEraFunction.xla を同梱してありますので、そのまま利用してください )
マクロ無しブックは、そのまま「マクロ無しブック」として運用できますし、EraFormat/EraCDate/EraIsDate
を利用する全てのワークブックにマクロを登録する手間も要りません。
セルでは、EraFormat関数を以下のように使用します(ブック参照を記述する必要はありません)。
=EraFormat(A1,"ggge年m月d日")
マクロ内でEraFormat/EraCDate関数を使用する為には、アドインブックへの「参照設定」が必要になり
ます( VBE メニュー > ツール > 参照設定 )。
アドインブックは Library フォルダ( Excel のバージョンによってパスが異なります) に保存します。
このフォルダであれば、各種OS・Excel バージョン・ユーザー間でワークブックを遣り取りする場合
でもリンクエラーにはなりません。
参考 : Tips21 Excel の リンクの管理と格納
§4. リンク 情報の整理
§6-2. アドインブック を 「Officeアプリケーション アドインフォルダ (Library フォルダ)」 に格納している場合
Excel2007以降ではアドインブックの拡張子が xlam に変更されましたが、xla でも問題なく動作します。
[ Excel2003以前 ⇔ Excel2007以降 ] 間でワークブックの遣り取りがある場合には、アドインブックを
拡張子 xla で作成してください。
( 8 ) 新元号対応の kt関数アドイン(Ver 5.30) を利用する。
EraFormat/EraCDate 専用アドインブックの代わりに 新元号対応の kt関数アドイン を利用します。
尚、kt関数アドインでは関数名が ktEraFormat / ktEraCDate / ktEraIsDateになります。
マクロ無しブックは、そのまま「マクロ無しブック」として運用できますし、EraFormat/EraCDate/EraIsDate
を利用する全てのワークブックにマクロを登録する手間も要りません。
セルでは、EraFormat関数を以下のように使用します(ブック参照を記述する必要はありません)。
=ktEraFormat(A1,"ggge年m月d日")
マクロ内でEraFormat/EraCDate関数を使用する為には、kt関数アドインへの「参照設定」が必要になります。
( VBE メニュー > ツール > 参照設定 )
Ver 5.30 のリリースは新元号が公表された後(2019年4月)の予定です。
kt関数アドイン では xla版 と xlam 版を提供しています。[ Excel2003以前 ⇔ Excel2007以降 ] 間
でワークブックの遣り取りがある場合には、xla版の kt関数アドインを利用してください。
|
||
角田 桂一 Mail:addinbox@h4.dion.ne.jp CopyRight(C) 2016 Allrights Reserved. |