I've successfully adapted this INI File reader to work with Access. Maybe what you need?
Option Explicit
Enum IniFileErrors
ERR_BASE = 8192
ERR_FILEWRITE = 1
ERR_FILEREAD = 2
ERR_NOSECTION = 3
ERR_NOKEYNAME = 4
End Enum
Const ERR_NOSECTIONSTRING = "No section was specified. Function aborted."
Const ERR_NOKEYNAMESTRING = "No key name was specified. Function aborted."
Const DEFAULT_VALUE = "<NULL>"
Private Declare Function GetPrivateProfileString Lib "Kernel32.dll" Alias "GetPrivateProfileStringA" ( _
ByVal lpAppName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Integer, _
ByVal lpFileName As String _
) As Integer
Private Declare Function GetPrivateProfileKeys Lib "Kernel32.dll" Alias "GetPrivateProfileStringA" ( _
ByVal lpAppName As String, _
ByVal lpKeyName As Long, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Integer, _
ByVal lpFileName As String _
) As Integer
Private Declare Function GetPrivateProfileSectionNames Lib "Kernel32.dll" Alias "GetPrivateProfileSectionNamesA" ( _
ByVal lpReturnBuffer As String, _
ByVal nSize As Long, _
ByVal lpFileName As String _
) As Long
Private m_sFilename As String
Private m_cData As Collection
Property Get Filename() As String
Filename = m_sFilename
End Property
Property Let Filename(s As String)
m_sFilename = s
parse
End Property
Private Function GetKeyValue(ByVal sSectionName As String, ByVal sKeyName As String) As String
On Error GoTo e_Handler
'dims
Dim hr As Long
Dim sBuf As String
Dim lSize As Long
'default buffer size
lSize = 128
'first things first, we really need a section name here
If Len(sSectionName) = 0 Then
Err.Raise ERR_BASE + ERR_NOSECTION, , ERR_NOSECTIONSTRING
ElseIf Len(sKeyName) = 0 Then
Err.Raise ERR_BASE + ERR_NOKEYNAME, , ERR_NOKEYNAMESTRING
End If
Do
'default buffer size
sBuf = Space$(lSize)
'call the API to get the key value
hr = GetPrivateProfileString(sSectionName, sKeyName, DEFAULT_VALUE, sBuf, Len(sBuf), m_sFilename)
'see API documentation for more info, suffice to say if the return val is size-1 then buffer was too small
If hr = lSize - 1 Then
'increase buffer size
lSize = lSize * 2
Else
'success
lSize = 0
End If
'if lSize <> 0 then needs to loop again
Loop While lSize
'trim null chars
sBuf = Left$(sBuf, hr)
'return the value
GetKeyValue = sBuf
Exit Function
e_Handler:
'do nothing
Exit Function
End Function
Property Get KeyNames(ByVal sSectionName As String) As Variant
On Error GoTo e_Handler
'dims
Dim hr As Long
Dim sBuf As String
Dim lSize As Long
'default buffer size
lSize = 128
'first things first, we really need a section name here, throw error if not available
If Len(sSectionName) = 0 Then
Err.Raise ERR_BASE + ERR_NOSECTION, , ERR_NOSECTIONSTRING
End If
Do
sBuf = Space$(lSize)
hr = GetPrivateProfileKeys(sSectionName, 0, "", sBuf, Len(sBuf), m_sFilename)
'since key name will always be null we're looking for an hr = size - 2
If hr = lSize - 2 Then
'this wasn't big enough, increase buffer size
lSize = lSize * 2
Else
'success
lSize = 0
End If
'if the size is non-zero then this needs doing again, so loop
Loop While lSize
'trim
sBuf = Left$(sBuf, hr - 1)
'return an array
KeyNames = Split(sBuf, Chr(0))
Exit Property
e_Handler:
'do nothing
Exit Property
End Property
Property Get SectionNames() As Variant
On Error GoTo e_Handler
'the dims
Dim hr As Long
Dim sBuf As String
Dim lSize As Long
'default buffer size
lSize = 128
Do
'create the empty buffer
sBuf = Space$(lSize)
'run the API call
hr = GetPrivateProfileSectionNames(sBuf, lSize, m_sFilename)
'if the return val = size - 2 then the buffer wasn't big enough (see API documentation for more info)
If hr = lSize - 2 Then
'make the buffer bigger
lSize = lSize * 2
Else
'success
lSize = 0
End If
'if the buffer wasn't big enough, then size will be non-zero, loop again (having doubled the size
Loop While lSize
'trim thr buffer down
sBuf = Left$(sBuf, hr - 1)
'return a variant containing a safearray of strings
SectionNames = Split(sBuf, Chr(0))
Exit Property
e_Handler:
'do nothing
Exit Property
End Property
Public Property Get Data() As Collection
Set Data = m_cData
End Property
Private Sub parse()
Dim vSectionNames As Variant
Dim vSectionName As Variant
Dim vKeyNames As Variant
Dim vKeyName As Variant
Dim vKeyValue As Variant
Dim cSections As Collection
Dim cKeys As Collection
Set cSections = New Collection
vSectionNames = Me.SectionNames
For Each vSectionName In vSectionNames
'create a new keys collection
Set cKeys = New Collection
'now get keys for this section
vKeyNames = Me.KeyNames(vSectionName)
'loop through each key and get it's value
For Each vKeyName In vKeyNames
'get the actual value
vKeyValue = GetKeyValue(vSectionName, vKeyName)
'pop this into the collection
cKeys.Add vKeyValue, vKeyName
Next vKeyName
'we should now have a complete keyset for this section. pop the key collection into our master section one
cSections.Add cKeys, vSectionName
Next vSectionName
Set m_cData = cSections
End Sub