「vba iniファイル セクション 取得」
という検索ワードで、当サイトへのアクセスがありました。

INIファイルとは

VBAでも外部の設定ファイルを利用したい場合があります。

その場合に利用される1つの方法がINIファイルです。

Microsoftは設定内容の保存はINIファイルではなくレジストリやXMLファイルを使うことを推奨していますが、今でもINIファイルは多くの開発現場で利用されています。

INIファイルはShift-JISで書かれたただのテキストファイルですが、WindowsにおけるINIファイルは一般的に以下のような構成をします。

[Section]
key=value

①GetPrivateProfileString関数を利用する場合は、INIファイルの文字コードはShift-JISである必要があります。文字コードがUTF-8など場合は設定値に全角文字が含まれている場合、取得した値が文字化けを起こします。

②Sectionは[]で囲まれている必要があります。

③次のSectionが定義されるまでのkeyとvalueは直前のSectionに所属しているとみなされます。

④Sectionが異なっていればkey名は重複しても構いません。

⑤valueの値が半角スペースで終わっている場合、後述するGetPrivateProfileString関数で取得した場合、半角スペースを除いた値を取得します。

サンプルコード

上記のINIファイルを読み込み、最終的には構造体に格納するまでの流れのサンプルコードです。


Visual Basic
Type ST_INI
    Server_IP       As String
    Server_PORT     As String
    Client_IP       As String
    Client_PORT     As String
End Type

Sub IniToDictionary()
    Dim sIniPath                    '// INIファイルのパス
    Dim fn                          '// ファイル番号
    Dim sLine                       '// ファイル読み込み行
    Dim sLeftChar                   '// 左端の文字
    Dim sSection                    '// セクション
    Dim sKey                        '// キー
    Dim sValue                      '// 値
    Dim v                           '// キーと値
    Dim dic     As New Dictionary   '// INIファイル登録Dictionary
    Dim t       As ST_INI           '// INIファイル構造体
    
    '// INIファイルのパスを設定
    sIniPath = "C:\test\tcp.ini"
    
    fn = FreeFile
    
    Open sIniPath For Input As #fn
    
    '// ファイル行ループ
    Do Until EOF(fn)
        '// 1行読み込み
        Line Input #fn, sLine
        
        '// 空行の場合は次行へ
        If Len(sLine) = 0 Then
            GoTo CONTINUE
        End If
        
        '// 左端の文字を取得
        sLeftChar = Left(sLine, 1)
        
        '// コメント行の場合は次行へ(左端が;の場合)
        If sLeftChar = ";" Then
            GoTo CONTINUE
        '// セクション行の場合(左端が[の場合)
        ElseIf sLeftChar = "[" Then
            '// セクション文字列を取得
            sSection = Mid(sLine, 2, Len(sLine) - 2)
            GoTo CONTINUE
        '// データ設定行の場合(=を含む場合)
        ElseIf InStr(1, sLine, "=") > 0 Then
            v = Split(sLine, "=")
            sKey = v(0)
            sValue = v(1)
        End If
        
        '// Dictionaryに登録(セクション+キー、値)
        Call dic.Add(sSection & sKey, sValue)
CONTINUE:
    Loop
    
    Close #fn
    
    '// 構造体の各項目にDictionaryから値を取得する
    t.Server_IP = dic.Item("TCP_SERVER" & "IP")
    t.Server_PORT = dic.Item("TCP_SERVER" & "PORT")
    t.Client_IP = dic.Item("TCP_CLIENT" & "IP")
    t.Client_PORT = dic.Item("TCP_CLIENT" & "PORT")
End Sub

Type ST_INI
    Server_IP       As String
    Server_PORT     As String
    Client_IP       As String
    Client_PORT     As String
End Type
 
Sub IniToDictionary()
    Dim sIniPath                    '// INIファイルのパス
    Dim fn                          '// ファイル番号
    Dim sLine                       '// ファイル読み込み行
    Dim sLeftChar                   '// 左端の文字
    Dim sSection                    '// セクション
    Dim sKey                        '// キー
    Dim sValue                      '// 値
    Dim v                           '// キーと値
    Dim dic     As New Dictionary   '// INIファイル登録Dictionary
    Dim t       As ST_INI           '// INIファイル構造体
    
    '// INIファイルのパスを設定
    sIniPath = "C:\test\tcp.ini"
    
    fn = FreeFile
    
    Open sIniPath For Input As #fn
    
    '// ファイル行ループ
    Do Until EOF(fn)
        '// 1行読み込み
        Line Input #fn, sLine
        
        '// 空行の場合は次行へ
        If Len(sLine) = 0 Then
            GoTo CONTINUE
        End If
        
        '// 左端の文字を取得
        sLeftChar = Left(sLine, 1)
        
        '// コメント行の場合は次行へ(左端が;の場合)
        If sLeftChar = ";" Then
            GoTo CONTINUE
        '// セクション行の場合(左端が[の場合)
        ElseIf sLeftChar = "[" Then
            '// セクション文字列を取得
            sSection = Mid(sLine, 2, Len(sLine) - 2)
            GoTo CONTINUE
        '// データ設定行の場合(=を含む場合)
        ElseIf InStr(1, sLine, "=") > 0 Then
            v = Split(sLine, "=")
            sKey = v(0)
            sValue = v(1)
        End If
        
        '// Dictionaryに登録(セクション+キー、値)
        Call dic.Add(sSection & sKey, sValue)
CONTINUE:
    Loop
    
    Close #fn
    
    '// 構造体の各項目にDictionaryから値を取得する
    t.Server_IP = dic.Item("TCP_SERVER" & "IP")
    t.Server_PORT = dic.Item("TCP_SERVER" & "PORT")
    t.Client_IP = dic.Item("TCP_CLIENT" & "IP")
    t.Client_PORT = dic.Item("TCP_CLIENT" & "PORT")
End Sub