怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

VBA: iniファイルを読み取るには | GetPrivateProfileStringA関数

VBA で ini ファイルから文字列を読み取るには、Win32API の GetPrivateProfileStringA 関数を使う。

サンプルコード

以下に GetPrivateProfileStringA 関数を使った読み取りのサンプルを示す。

Option Explicit

'GetPrivateProfileStringA 関数を宣言する
Private Declare PtrSafe Function GetPrivateProfileStringA Lib "kernel32" ( _
    ByVal lpAppName As String, _
    ByVal lpKeyName As Any, _
    ByVal lpDefault As String, _
    ByVal lpReturnedString As String, _
    ByVal nSize As Long, _
    ByVal lpFileName As String _
) As Long

Public Sub Main()

    'バッファを確保する
    Dim buffer As String
    buffer = String$(512, vbNullChar)

    'iniファイルを読み取る
    Dim ret As Long
    ret = GetPrivateProfileStringA("TestSection", _
                                   "TestKey", _
                                   "default value", _
                                   buffer, _
                                   Len(buffer), _
                                   ThisWorkbook.Path & "\app.ini")

    If ret = 0 Then
        MsgBox "読み取り失敗"
    Else
        'バッファから読み取った文字列を抽出する
        Dim iniValue As String
        iniValue = Left$(buffer, InStr(buffer, vbNullChar) - 1)

        MsgBox iniValue
    End If

End Sub

サンプルを実行する前の下準備として、以下の内容の ini ファイルをマクロブックと同じ場所に置いておく。
ファイル名は app.ini にする。
ファイルの文字コードはシフトJIS、改行コードは CRLF にすること。

; app.ini
[TestSection]
TestKey=読み取りテスト

マクロを実行すると「読み取りテスト」と表示される。

解説

まずはモジュールの宣言セクション(Declarations)で GetPrivateProfileStringA 関数を宣言する。

Private Declare PtrSafe Function GetPrivateProfileStringA Lib "kernel32" ( _
    ByVal lpAppName As String, _
    ByVal lpKeyName As Any, _
    ByVal lpDefault As String, _
    ByVal lpReturnedString As String, _
    ByVal nSize As Long, _
    ByVal lpFileName As String _
) As Long

関数は以下の引数を取る。

  • lpAppName: セクション名
  • lpKeyName: キー名
  • lpDefault: キーが見つからない場合に使う既定の文字列。末尾に空白を含む値を指定した場合は取り除かれるので注意
  • lpReturnedString: 取得した文字列を格納する変数
  • nSize: returnedString に指定した変数のサイズ
  • lpFileName: ini ファイルのパス

関数は取得した値のバイト数を返す。
(文字数ではなくバイト数)


次に取得した文字列を格納するためのバッファを確保する。
String 関数で必要なサイズ分のヌル文字を設定することで、バッファを確保できる。
バッファのサイズはギリギリではなく、余裕を持った長さにしておいたほうがよい。

たとえば次のコードでは、512バイト分のバッファを確保している。

Dim buffer As String
buffer = String$(512, vbNullChar)


その後 GetPrivateProfileStringA 関数を呼び出し ini ファイルを読み取る。
マクロブックと同じ場所にある app.ini より TestSection セクションの TestKey キーを読み取るように指定している。

Dim ret As Long
ret = GetPrivateProfileStringA("TestSection", _
                               "TestKey", _
                               "default value", _
                               buffer, _
                               Len(buffer), _
                               ThisWorkbook.Path & "\app.ini")


最後に、バッファに格納された値を取得する。
バッファをそのまま参照するとバッファ確保時に設定したヌル文字も取得されてしまう。
よって、バッファの先頭から、最初に現れるヌル文字の前の文字までを抽出する。

Dim iniValue As String
iniValue = Left$(buffer, InStr(buffer, vbNullChar) - 1)


もし ini ファイルにシングルバイトの文字しか設定しないのであれば、次のように関数の戻り値を使う方法でもよい。

iniValue = Left$(buffer, ret)

マルチバイト文字が含まれると、余計なヌル文字も抽出してしまう。
たとえば、読み取った値が「あ」だとすると、文字数は1だがバイト数は2となり、2文字を抽出してしまう。

Left\$() の代わりに LeftB\$() を使えばよいのでは? という気もするが、InStr() で抽出する文字数を求める方法で十分だろう。
ただしこちらも、ヌル文字がなかった場合のパターンを想定しておかないといけないので、そこは注意する。