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

Tips28: 新元号対応 日付変換関数 [ EraFormat / EraCDate ]

        EraFormat  …  2018/11/13 : 暫定版 Ver 0.10  ,  2018/11/23 : Ver 0.11  ,  2018/11/27 : Ver 0.12 , 2019/1/2 : Ver 0.20
        EraCDate  …  2018/11/20 : 暫定版 Ver 0.10  ,  2018/11/22 : Ver 0.20 , 2019/1/2 : Ver 0.30

( 参考 ) 経済産業省 主催の 「改元に伴う システム 改修 に対する説明会
             Microsoft 配布資料 ( PDF , 118 頁 ) 詳細に各アプリケーションの対応状況/対応方法が記載されています

------------------------------------------------------------------------------------------------
Microsoft による [ 新元号 ] 対応アップデート 対象外の Excel 2003 / Excel 2007 でも 新元号が扱える ようになります!

EraFormat ( シリアル値 ⇒ 日付文字列 ) , EraCDate ( 日付文字列 ⇒ シリアル値 )
1.  開発 の 経緯
2.  EraFormat / EraCDate 関数 の ヘルプ
3.  EraFormat / EraCDate 関数 の マクロ コード
4.  補  足
5.  運用面 ( 対応作業上 )での注意点

---- 配布ファイル ----
    NewEraMacro_P2.zip ( 201 KB , 暫定版 第2版 2019/1/3 )
            I
            +-- NewEraMacro_ReadMe.txt
            +-- NewEraHelp.chm    ( ヘルプファイル )
            +-- EraFormat.txt     ( EraFormat マクロコード )
            +-- EraCDate.txt      ( EraCDate マクロコード )

  【 使用条件 】
      EraFormat/EraCDate 関数はフリーウェアです。
      御自由に各自のプログラムに組み込んで利用して戴いて構いません。
      但し、プログラム先頭のコメントも必ず一緒に コピーしてください。
      EraFormat/EraCDate 関数を組み込んだプログラムの再頒布にも制限はありません。

この記事に関する お問い合わせ ⇒ [ 掲示板 足跡ぼーど ] [ メール送信 ]

( お断り )  新元号の公表前ですので、以下の関数では暫定で 徳仁親王の "徳仁 ( N )" を使っています
              新元号発表後に正式版 を リリースします。


[ この場所への リンク ]

1.  開発の経緯
来年(2019年) 5月1日に、平成 から 新元号 への改元が行なわれます(新元号の公表は
「1ヶ月前 を想定」と言われています)。マイクロソフトの発表では、新元号が公表され次第、
Office2010 以降の製品に対して、新元号対応アップデートのネット配信を行なうとの事です。
  参照 : Microsoft 新元号サポートブログ ( https://blogs.technet.microsoft.com/jperablog/ )

そうしますと、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 で対応予定)。



[ この場所への リンク ]

2.  EraFormat / EraCDate 関数の ヘルプ
        ( お断り ) 新元号の公表前ですので、以下の関数では暫定で 徳仁親王の "徳仁 ( N )" を使っています
                    新元号発表後に正式版をリリースします。


----- EraFormat 関数 -----  2019/1/2 Ver 0.20 で 「"元年" 表記」機能を追加しました。
    2019年5月1日からの新元号に対応した TEXT/Format 関数の代替関数です。
    Office2007以前 または 対応アップデートが施されていない環境で 新元号の和暦変換を提供します。
    ( 補 ) 日付専用 ( 第1引数 が Date 型 ) ですので、数値変換 ( カンマ編集, 通貨編集 等 )等には使用しないで
            ください。 数値変換等には 通常の TEXT / Format 関数を使用してください 。

【 構 文 】
    EraFormat ( 日付 , 編集文字 , [ 元年表記 ] )

    返却値     ……  Variant 型( String 型  or  #VALUE! )
    日付        ……  Date 型 ( シリアル値  or  日付文字列 )
    編集文字  ……  String 型
    元年表記  ……  Boolean 型 ( 省略可 , 既定値 : False )   Ver 0.20 で追加

【 返却値 】
    編集文字で指定した書式定義にしたがって日付を編集した結果が返ります。

    元号/和暦年の書式文字 ( ggg , gg , g , ee , e , rr , r ) については、
    使用環境・Office バージョン に係わらず 新元号に対応 した結果が得られます。

    元年表記=True とすると、各元号の 「1年」 が "元年" と編集されます。
    ( 但し、元号2文字 & "年"表記付きに限ります )


    編集文字列が空文字の場合は #VALUE! が返ります。

【 パラメータ 内容 】
    [ 日付 ]
          任意の日付 ( シリアル値  or  日付文字列 ) を指定します。
          ( 注 ) 新元号に対応していない環境 ( Office2007 以前 もしくは 対応アップデートが
                  施されていないOffice2010 以降 ) では、新元号表記の日付文字列 は指定でき
                  ません
。 尚、この場合でも EraCDate 関数を経由すれば指定可能です。

    [ 編集文字 ]
          Excel および VBA で規定された表示書式文字を使った文字列を指定します。
          TEXT 関数 / Format 関数 で使用可能な表示書式文字は全て使用できます。

    [ 元年表記 ]  Ver 0.20 で追加
          省略可能です。 省略した場合は False になります。
          True を指定すると、各元号の 1年 (元号施行日以降) を "元年" と編集します。
          但し、「元号2文字 & "年"表記付き」に限ります。
          編集文字で表すと、ggge年 or gggee年 です。

      EraFormat("1989/1/7", "ggge年m月d日", True) ⇒ 昭和64年1月7日
      EraFormat("1989/1/8", "ggge年m月d日", True) ⇒ 平成元年1月8日
      EraFormat("1990/1/1", "ggge年m月d日", True) ⇒ 平成2年1月1日
      EraFormat("1989/1/8", "ggge/m/d", True)     ⇒ 平成1/1/8
      EraFormat("1989/1/8", "ggge年", 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/1/2  Ver 0.30 で [ xx 元年 ] という表記の日付文字列の変換機能を追加しました。
    2019年5月1日からの新元号に対応した DATEVALUE 関数の代替関数です。
    Office2007以前 または 対応アップデートが施されていない環境で [ 新元号の和暦日付 ⇒ シリアル値 ] 変換
    を提供します。

【 構 文 】
    EraCDate ( 日付文字列 , [ 元号範囲 ] )

    返却値         ……  Variant 型( Date 型  or  #VALUE! )
    日付文字列   ……  String 型
    元号範囲      ……  Boolean 型 ( 省略可 , 既定値 : False )

【 返却値 】
    日付文字列 を シリアル値に変換した結果が返ります。
    使用環境・Office バージョン に係わらず 新元号にも対応 した結果が得られます。

    日付文字列が不正の場合は #VALUE! が返ります。
    [ 元号範囲 = True ] 指定では、元号の範囲を超えている日付文字列 の場合は #VALUE! が返ります。
    セル の式で利用する場合、1900 (明治33)/3/1 より前の日付では #VALUE! が返ります。

【 パラメータ 内容 】
    [ 日付文字列 ]
        指定可能な 日付フォーマット は以下の通りです。
          ( 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 ]  [ 徳仁 , , N/n ]
                ( 注 ) 暫定版 ( Ver 0.20 ) では、新元号の代わりに徳仁親王の "徳仁 ( 徳 , N )" を使っています。
          ( c )  西暦年 も変換可能です ( 年は 4 桁 )
                [ 2019年4月30日 ]  [ 2019/4/30 ]  [ 2019-4-30 ]  [ 2019.4.30 ]
          ( d )  平成 32 年 等の 改元以後の年数 でも OK としています
                但し、[ 元号範囲 = True ] 指定の場合は 元号期間内の日付のみが OK となります。
          ( e )  "明治元年", "大正元年", "昭和元年", "平成元年", "徳仁元年" という
                表記の日付文字列も可とします( "明治1年", "大正1年", "昭和1年", "平成1年", "徳仁1年" として扱います)。
                但し、"H元年5月1日" や "平成元/5/1" などはエラーになります。
                ( Ver 0.30 で機能追加 )

    [ 元号範囲 ]
        省略可能です。 省略した場合は 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 (N1)/ 5/ 1 ~ 9999 (---)/12/31


【 解 説 】
    2019年5月1日に、平成 から 新元号 への改元が行なわれます。

    マイクロソフトの発表では、新元号が公表され次第、Office2010 以降の製品に対して、
    新元号対応アップデートのネット配信を行なうとの事です。

    そうしますと、Office2007 以前の環境では新元号で記述された和暦日付 を シリアル値に変換する事が
    できません。また、Office2010以降の環境でも諸々の事情により アップデートが施されない場合には、
    同じように和暦日付 を シリアル値に変換する事ができません

    この EraCDate 関数を使えば、新元号で記述された和暦日付 も シリアル値に変換することが可能です。
    UserForm 等での入力値チェック としても活用できます。


[ この場所への リンク ]

3.  EraFormat / EraCDate 関数のマクロ コード

 
  ( お断り ) 新元号の公表前ですので、このマクロでは暫定で 徳仁親王の "徳仁 ( N )" を使っています
             新元号発表後に正式版をリリースします。


  (修正案内) ピリオド区切り編集に不具合がありましたので Ver0.12 で修正しました。不具合内容はコメントを参照。

  このマクロではReplaceFormatしか使っていませんのでVisualBasic6.0でも利用可能です
  VisualBasic 6 で使用する場合は、CVErr(xlErrValue) を CVErr(450) 等に変更してください。
  ( エラー番号 450 : 引数の数が一致していません。または不正なプロパティを指定しています。)
  Access/VBA で使用する場合には 引数=NULL への対策などを適宜追加してください。



  '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  '_/
  '_/    [新元号] 対応 日付変換関数 EraFormat  ( シリアル値 ⇒ 日付文字列 )
  '_/
  '_/    Ver 0.10 : 2018/11/13 (新元号発表以前の暫定版)
  '_/    Ver 0.11 : 2018/11/23 (Format関数自体のエラー処理を追加)
  '_/    Ver 0.12 : 2018/11/27 (ピリオド区切り編集の不具合修正)
  '_/    Ver 0.20 : 2019/ 1/ 2 ("xx1年⇒xx元年"表記機能の追加)
  '_/
  '_/    AddinBox 角田 ( http://addinbox.sakura.ne.jp/Excel_Tips28.htm )
  '_/
  '_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  '_/    新元号に対応していないシステム(Office2007以前 or 対応
  '_/    アップデートを施していないOffice2010以降)でも、新元号に
  '_/    基づく和暦変換を可能にする関数です。
  '_/
  '_/    (注) 新元号に対応していない環境(Office2007以前 or 対応アップデート
  '_/         が施されていないOffice2010以降)では、EraFormat関数の第1引数
  '_/         (日付)に新元号表記の日付文字列を指定する事はできません
  '_/
  '_/    ExcelのTEXT関数/VBAのFormat関数の代わりに使用してください。
  '_/    [元号/和暦年]以外の編集文字を一緒に使用しても問題ありません。
  '_/    また、新元号に対応済みのシステムで使用しても問題ありません。
  '_/
  '_/    尚、EraFormat は AddinBox/kt関数アドイン(Ver5.30)に
  '_/    ktEraFormat の名前で収録する予定です。
  '_/
  '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


  Public Function EraFormat(ByVal 日付 As Date, ByVal 編集文字 As String, _
                              Optional ByVal 元年表記 As Boolean = False) As Variant

  Const cst新元号開始日 As Date = #5/1/2019#

  ' 暫定版(Ver0.20)では、新元号の代わりに徳仁親王の "徳仁" を使っています。
  ' 新元号発表後に正しい元号に差し替えたバージョン(Ver1.00)をリリースします。

  Const cstEra1 As String = "徳仁"      ' <--- 正しい元号に書き換える事!
  Const cstEra2 As String = ""
  Const cstEra3 As String = "N"

  Const cstReplace_Era3 As String = "α"    ' 和暦年の迂回置換用の代用文字
  Const cstReplace_ee As String = "β"
  Const cstReplace_e As String = "γ"
  Const cstReplace_Period As String = "Ω"    ' ピリオド区切りの代用文字

  Dim strDateFormat As String
  Dim Result As String

      '(注意事項)
      ' 1. LCase/UCase による小文字/大文字変換は、
      '    g/e以外の編集定義を壊すかもしれないので使わない。
      ' 2. 元号半角 および 和暦年編集後の "0" が数値/日付編集文字と
      '    重複するケースを回避するために、Format関数の実施前では
      '    代用文字(α,β,γ)で迂回置換し、Format実施後に改めて置換する。


      '--- rr書式 ( = gggee ) / r書式 ( = ee)の変換(Format関数では不可) ---
      ' (rr ⇒ r の順で置換する)

      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 (日付 < cst新元号開始日) Or _
         (Format(cst新元号開始日, "gemmdd") <> "H310501") Then
          On Error Resume Next
          Result = Format(日付, strDateFormat)
          If (Err.Number <> 0) Then
              EraFormat = CVErr(xlErrValue)
          End If
          On Error GoTo 0
          EraFormat = prvFirstYearEdit(元年表記, 日付, Result)
          Exit Function
      End If

      '----- 以降、日付≧2019/5/1 & [新元号]未対応環境 -----

      'ロケールID が有れば取り除く
      'Format関数ではロケールID が無くても期待通りに変換される

      strDateFormat = Replace(strDateFormat, "[$-411]", "")
      If (strDateFormat = "") Then
          EraFormat = CVErr(xlErrValue)
          Exit Function
      End If

      '--- ggg⇒"徳仁" , gg⇒"徳" , g⇒"N"(代用文字α) に変換する ---
      ' (ggg ⇒ gg ⇒ g の順で置換する)

      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) に変換する(代用文字 β,γ) ---
      ' (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(日付, strDateFormat)
      If (Err.Number <> 0) Then
          EraFormat = CVErr(xlErrValue)
          Exit Function
      End If
      On Error GoTo 0

      ' 迂回置換の代用文字(α,β,γ,Ω)に本来の値(元号半角, 和暦年2桁固定, 和暦年, ピリオド)を書き込む
      Result = Replace(Result, cstReplace_Era3, cstEra3)
      Result = Replace(Result, cstReplace_ee, Format(Year(日付) - 2018, "00"))
      Result = Replace(Result, cstReplace_e, Format(Year(日付) - 2018, "0"))
      Result = Replace(Result, cstReplace_Period, ".")

      EraFormat = prvFirstYearEdit(元年表記, 日付, Result)
  End Function



  ' "平成01年"/"平成1年" 等のみ "元年"表記に修正する。
  ' 元号2文字&"年"表記が付いているデータのみを対象とする。
  ' 元号1文字/元号なし/"年"表記なし は対象外(当然、スラッシ区切り等も対象外)

  Private Function prvFirstYearEdit(ByVal FirstYear As Boolean, ByVal SerialDate As Date, _
                                    ByVal EditDate As String) As String
  Dim Result As String

      If (FirstYear = False) Then
          prvFirstYearEdit = EditDate    '元年表記の指示なし
          Exit Function
      End If

      Select Case Format(SerialDate, "yyyymmdd")
        Case "18681023" To "18681231"    '明治 元年
          Result = Replace(EditDate, "明治01年", "明治元年")
          Result = Replace(Result, "明治1年", "明治元年")

        Case "19120730" To "19121231"    '大正 元年
          Result = Replace(EditDate, "大正01年", "大正元年")
          Result = Replace(Result, "大正1年", "大正元年")

       Case "19261225" To "19261231"    '昭和 元年
          Result = Replace(EditDate, "昭和01年", "昭和元年")
          Result = Replace(Result, "昭和1年", "昭和元年")

        Case "19890108" To "19891231"    '平成 元年
          Result = Replace(EditDate, "平成01年", "平成元年")
          Result = Replace(Result, "平成1年", "平成元年")

        Case "20190501" To "20191231"    '徳仁 元年 <--- 正しい元号に書き換える事!
          Result = Replace(EditDate, "徳仁01年", "徳仁元年")
          Result = Replace(Result, "徳仁1年", "徳仁元年")

        Case Else
          '明治以前 or 各元号の[2年~]
          Result = EditDate
      End Select

      prvFirstYearEdit = Result
  End Function




 
  ( お断り ) 新元号の公表前ですので、このマクロでは暫定で 徳仁親王の "徳仁 ( N )" を使っています
             新元号発表後に正式版をリリースします。


  このマクロではReplaceDateValueしか使っていませんのでVisualBasic6.0でも利用可能です
  VisualBasic 6 で使用する場合は、CVErr(xlErrValue) を CVErr(450) 等に変更してください。
  ( エラー番号 450 : 引数の数が一致していません。または不正なプロパティを指定しています。)
  また、関数最後の Application.Caller よる判定は不要です。
  Access/VBA で使用する場合には 引数=NULL への対策などを適宜追加してください。



  '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  '_/
  '_/    [新元号]対応 日付変換関数 EraCDate  ( 日付文字列 ⇒ シリアル値 )
  '_/
  '_/    Ver 0.10 : 2018/11/20 (新元号発表以前の暫定版)
  '_/    Ver 0.20 : 2018/11/22 (元号範囲チェックを追加)
  '_/    Ver 0.30 : 2019/ 1/ 2 ("元年"表記の日付文字列の変換機能を追加)
  '_/
  '_/    AddinBox 角田 ( http://addinbox.sakura.ne.jp/Excel_Tips28.htm )
  '_/
  '_/    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  '_/    新元号に対応していないシステム(Office2007以前 or 対応
  '_/    アップデートを施していないOffice2010以降)でも、新元号に
  '_/    基づく和暦日付を日付データ(シリアル値)に変換できる関数です。
  '_/
  '_/    新元号に対応済みのシステムで使用しても問題ありません。
  '_/
  '_/    尚、EraCDate は AddinBox/kt関数アドイン(Ver5.30)に
  '_/    ktEraCDate の名前で収録する予定です。
  '_/    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  '_/   【 EraCDate でサポートする日付文字列のフォーマット 】
  '_/      a) 区切り形式
  '_/           [H31年4月30日] [H31/4/30] [H31-4-30] [H31.4.30]
  '_/      b) 元号
  '_/           [明治,明,M/m] [大正,大,T/t] [昭和,昭,S/s] [平成,平,H/h] [徳仁,徳,N/n]
  '_/           (注) 暫定版(Ver0.10)では、新元号の代わりに徳仁親王の "徳仁(徳,N)" を使っています。
  '_/      c) 西暦年も変換可能です
  '_/           [2019年4月30日] [2019/4/30] [2019-4-30] [2019.4.30]
  '_/      d) 平成32 等の改元以後の年数でもOKとしています
  '_/         但し、[ 元号範囲 = True ] 指定の場合は 元号期間内の日付のみが OK となります。
  '_/      e) "明治元年","大正元年","昭和元年","平成元年","徳仁元年"という表記も可とします。
  '_/
  '_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


  Public Function EraCDate(ByVal 日付文字列 As String, _
                            Optional ByVal 元号範囲 As Boolean = False) As Variant

  ' 暫定版(Ver0.30)では、新元号の代わりに徳仁親王の "徳仁(徳,N)" を使っています。
  ' 新元号発表後に正しい元号に差し替えたバージョン(Ver1.00)をリリースします。


  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 = "[αβγδε明大昭平MTSHNmtshn]" ' <--- 正しい元号に書き換える事!

      ' "明治元年","大正元年","昭和元年","平成元年","徳仁元年"を "xx1年" に置換する
      ' 尚、EraFormat に合わせている為、"H元年","H元/5/1" 等は対象外とする

      strTemp = Replace(日付文字列, "明治元年", "明治1年")
      strTemp = Replace(strTemp, "大正元年", "大正1年")
      strTemp = Replace(strTemp, "昭和元年", "昭和1年")
      strTemp = Replace(strTemp, "平成元年", "平成1年")
      strTemp = Replace(strTemp, "徳仁元年", "徳仁1年")    ' <--- 正しい元号に書き換える事!

      ' 元号(2文字)の判定処理が Like 演算子で行なえる様に代替文字(1文字)で置換する
      strTemp = Replace(strTemp, "明治", "α")
      strTemp = Replace(strTemp, "大正", "β")
      strTemp = Replace(strTemp, "昭和", "γ")
      strTemp = Replace(strTemp, "平成", "δ")
      strTemp = Replace(strTemp, "徳仁", "ε")    ' <--- 正しい元号に書き換える事!

      '=== 日付文字列のパターンチェック ===
      '=== 年はここで数字判定を完了する,月日の数字判定はDateValueに任せる ===
      '--- 和暦(年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)
              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)
              Exit Function
          Else
              strDate = prvEraYear4EraCDate(Mid(strTemp, 1, 1), Mid(strTemp, 2, 2), Mid(strTemp, 4), intEra)
          End If
      '--- 西暦(年4桁) ---
      ElseIf (日付文字列 Like "####年#*月#*日") Or _
             (日付文字列 Like "####/#*/#*") Or _
             (日付文字列 Like "####.#*.#*") Or _
             (日付文字列 Like "####-#*-#*") Then
          'ピリオド区切りがDateValueでは変換できないので / に置換する
          strDate = Replace(日付文字列, ".", "/")
          intEra = 0
      Else
          EraCDate = CVErr(xlErrValue)
          Exit Function
      End If

      On Error Resume Next
      dtmDate = DateValue(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(N1)/ 5/ 1 ~ 9999(---)/12/31

              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) >= dtmDate) Then
                  '元号範囲内
              Else
                  EraCDate = CVErr(xlErrValue)
                  Exit Function
              End If
          End If
      End If

      If (TypeName(Application.Caller) = "Range") Then
          'セルでは1900(明治33)/3/1 以降のみを可とする
          '60==> セル:1900/2/29 , VBA:1900/2/28 とズレる為

          If (dtmDate < 61) Then
              EraCDate = CVErr(xlErrValue)
          Else
              EraCDate = dtmDate
          End If
      Else
          EraCDate = dtmDate
      End If
  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 "ε", "", "N", "n"                         ' <--- 正しい元号に書き換える事!
          strDate = (CLng(年) + 2018) & strMMDD  '徳仁
          元号フラグ = 5
      End Select
      prvEraYear4EraCDate = strDate
  End Function



[ この場所への リンク ]

4.  補  足
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 みたいだから、わたし 半月 遅れを取ったわぁ ~


[ この場所への リンク ]

5.  運用面( 対応作業上 )での注意点
          以下、「新元号に対応していない環境 ( Office2007 以前  or  対応アップデートが施されていない Office2010 以降 )」 を
          「新元号未対応環境」 と記します。


( 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 専用のアドインブックを作成して利用します。

      マクロ無しブックは、そのまま「マクロ無しブック」として運用できますし、EraFormat/EraCDateを利用する
      全てのワークブックにマクロを登録する手間も要りません。

      セルでは、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 になります

      マクロ無しブックは、そのまま「マクロ無しブック」として運用できますし、EraFormat/EraCDateを利用する
      全てのワークブックにマクロを登録する手間も要りません。

      セルでは、EraFormat関数を以下のように使用します(ブック参照を記述する必要はありません)。
          =ktEraFormat(A1,"ggge年m月d日")

      マクロ内でEraFormat/EraCDate関数を使用する為には、kt関数アドインへの「参照設定」が必要になります。
      ( VBE メニュー > ツール > 参照設定 )

      Ver 5.30 のリリースは新元号が公表された後(2019年4月)の予定です。
      kt関数アドイン では xla版 と xlam 版を提供しています。[ Excel2003以前 ⇔ Excel2007以降 ] 間
      でワークブックの遣り取りがある場合には、xla版の kt関数アドインを利用してください。


Home   Back Page   Next Page

ACR WEB
ロゴ(ゴールド)   ロゴ(ピンク)

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