VB6, VBA でレジストリから元号を取得
VB6, VBA でレジストリから元号(和暦情報)を配列で取り出す関数をベタなAPIのみで構成
format関数って、ee年 のように eの直後に年が続くと 1年ではなく元年と表記されるんですね~
得られる配列は今の所、下記の形
※古い順である保証はありません
※2019/3/13頃のOSアップデートで、レジストリの値が全角合成文字(㍻)から先頭文字(平)に変更されています
配列から取得
モジュール本体
format関数って、ee年 のように eの直後に年が続くと 1年ではなく元年と表記されるんですね~
得られる配列は今の所、下記の形
※古い順である保証はありません
※2019/3/13頃のOSアップデートで、レジストリの値が全角合成文字(㍻)から先頭文字(平)に変更されています
Dim Gengo()
Dim I As Long
Dim S As String
Gengo = GetGengoDimFromReg()
For I = UBound(Gengo, 2) To 0 Step -1
S = S & Gengo(0, I) & " = " & Gengo(1, I) & Chr(13) & Chr(10)
Next I
' S
FormatJ関数
s = FormatJ(Now, "g gg ggg e ee yyyy-mm-dd hh:nn")
モジュール本体
Option Compare Database
Option Explicit
Private Declare Function RegOpenKeyEx Lib "ADVAPI32" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "ADVAPI32" (ByVal hKey As Long) As Long
Private Declare Function RegQueryValueExstr Lib "ADVAPI32" Alias "RegQueryValueExA" (ByVal hKey&, ByVal lpValueName$, ByVal lpReserved&, ByVal lpType&, ByVal lpData$, lpcbData&) As Long
Private Declare Function RegEnumValue Lib "ADVAPI32" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const ERROR_SUCCESS = 0
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private GengoDimCache()
Function FormatJ(ByVal iDate As Date, ByVal FormatStr As String)
Dim refGengo() As String
Dim refWareki As Long
If DateToWareki(iDate, refGengo, refWareki) Then
FormatStr = Replace(FormatStr, "ggg", """" & refGengo(2) & """") ' 平成
FormatStr = Replace(FormatStr, "gg", """" & refGengo(3) & """") ' 平
FormatStr = Replace(FormatStr, "g", """" & refGengo(5) & """") ' H
If refWareki = 1 Then
' Format関数は eの後に年があると「元年」表示となる
FormatStr = Replace(FormatStr, "ee年", """元年""")
FormatStr = Replace(FormatStr, "ee\年", """元年""")
FormatStr = Replace(FormatStr, "e年", """元年""")
FormatStr = Replace(FormatStr, "e\年", """元年""")
End If
FormatStr = Replace(FormatStr, "ee", """" & Right("0" & Trim(Str(refWareki)), 2) & """")
FormatStr = Replace(FormatStr, "e", """" & Trim(Str(refWareki)) & """")
End If
FormatJ = Format(iDate, FormatStr)
End Function
Function DateToWareki(ByVal iDate As Date, ByRef refGengo() As String, ByRef refWareki As Long) As Boolean
Dim Gengo()
Dim I As Long
Dim J As Long
Dim S As String
Dim TempDate As Date
DateToWareki = False
Gengo = GetGengoDim()
If Sgn(Gengo) <> 0 Then
TempDate = 0
For I = 0 To UBound(Gengo, 2)
If (Gengo(0, I) > TempDate) And (iDate >= Gengo(0, I)) Then
TempDate = Gengo(0, I)
ReDim refGengo(UBound(Gengo, 1))
For J = UBound(Gengo, 1) To 0 Step -1
refGengo(J) = Gengo(J, I)
Next J
refWareki = Year(iDate) - Year(Gengo(0, I)) + 1
DateToWareki = True
End If
Next I
End If
End Function
' レジストリから元号を取得して配列で返す
Function GetGengoDimFromReg()
If Sgn(GengoDimCache) <> 0 Then
GetGengoDimFromReg = GengoDimCache ' キャッシュ
Exit Function
End If
Dim hKey As Long
Dim dwIndex As Long
Dim lpName As String
Dim lpcbName As Long
Dim lpType As Long
Dim lpData As String
Dim lpcbData As Long
Dim lpValue As String
Dim lpcbValue As Long
Dim DimLen As Long
Dim YMD() As String
Dim Gengo() As String
Dim Result()
If (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras", 0, KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS, hKey) = ERROR_SUCCESS) Then
dwIndex = 0
Do
lpType = 0
lpcbName = 256
lpName = String(lpcbName, Chr(0))
lpcbData = 256
lpData = String(lpcbData, Chr(0))
' エントリ取得
If (RegEnumValue(hKey, dwIndex, lpName, lpcbName, 0, lpType, lpData, lpcbData) = ERROR_SUCCESS) Then
lpName = Left(lpName, InStr(1, lpName, Chr(0)) - 1) ' "1989 01 08"
' データ取得
lpcbValue = 256
lpValue = String(lpcbValue, Chr(0))
If (RegQueryValueExstr(hKey, lpName, 0, 0, lpValue, lpcbValue) = ERROR_SUCCESS) Then
lpValue = Left(lpValue, InStr(1, lpValue, Chr(0)) - 1) ' "平成_㍻_Heisei_H" winUpdate→ "平成_平_Heisei_H"
' 配列へ
If Sgn(Result) = 0 Then
ReDim Preserve Result(5, 0)
Else
ReDim Preserve Result(5, UBound(Result, 2) + 1)
End If
DimLen = UBound(Result, 2)
YMD = Split(lpName, " ", 3) ' "1989 01 08"
Result(0, DimLen) = DateSerial(Int(YMD(0)), Int(YMD(1)), Int(YMD(2)))
Result(1, DimLen) = lpValue ' 平成_平_Heisei_H
Gengo = Split(lpValue, "_", 4)
Result(2, DimLen) = Gengo(0) ' 平成
Result(3, DimLen) = Gengo(1) ' 平
Result(4, DimLen) = Gengo(2) ' Heisei
Result(5, DimLen) = Gengo(3) ' H
End If
dwIndex = dwIndex + 1
Else
Exit Do
End If
Loop
Call RegCloseKey(hKey)
End If
GengoDimCache = Result
GetGengoDimFromReg = Result
End Function
コメント