In desperate Need of Help

I am almost finished with my project and hit a brick wall.

I am getting information from a programs ini file and changing various sections. All was going well until I found one of the sections has mutliple keys.
example:
[section1]
name=name
address=address
address=address2
address=address3
address=address4

everytime I try to load the values of address=  all I get is the 1st one and not the others.

Any Ideas on a way to iterate thru them untill it hits either a blank line or another key?

Any and all help will be greatly appreciated so I can get this monkey off my back.
CritterOHAsked:
Who is Participating?
 
appariConnect With a Mentor Commented:
astrx returns you an array of strings.

Private Sub Command1_Click()
Dim strX As String
Dim X As Long, i as integer
dim astrX
strX = Space$(1000)
X = GetPrivateProfileSection("Section1", strX, 1000, "XYZ.INI")
astrX = Split(strX, vbNullChar)
for i = lbound(astrx) to ubound(astrx)
   debug.print astrx(i)
next i
MsgBox strX
End Sub


hope this helps
0
 
appariCommented:
KeyName should be unique within a section. If they are repeating it gets the first first key it finds. so better option is to change your ini file to something like this


[section1]
name=name
address1=address
address2=address2
address3=address3
address4=address4

and in VB Code you can run in a loop till you get a null string. like
i=1
strReturn="Start"
while strReturn<>""
strReturn=""
Ret= GetPrivateProfileString ("Section1", "address" & i ,"",strReturn,255,"xyz.ini")
i=i+1
wend


the problem with this approach is if in INI suppose address3 value is "" then it wont read further. to avoid this you can either fix no of address keys or maitain the no of address lines in another key as

[section1]
name=name
TotalLines=4
address1=address
address2=address2
address3=address3
address4=address4

first read TotalLines key value and using for loop can read addresses.

hopee this helps

0
 
CritterOHAuthor Commented:
Thanks for the quick response:)

That would make life simple, but (and there always is) The ini file goes to a specific program that reads it in that fashion so if i change the keyname the program either wont read it or bombs out :(
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
appariCommented:
off course you need to change the program accordingly.
the part where it writes to INI and the part reading ini need to be changed,
0
 
CritterOHAuthor Commented:
Boy don't I wish,

the program is not mine and I have no access to the source code as it is a commercial program.

and thanks again for your speedy responce.
0
 
CritterOHAuthor Commented:
ok from what I have so far all i need to do is list the values in a listbox, no editing or saving of them needed.
0
 
appariCommented:
if you cannot change ini structure then you can read the contents of whole section using GetPrivateProfileSection API

Public Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Private Sub Command1_Click()
Dim strX As String
Dim X As Long
strX = Space$(1000)
X = GetPrivateProfileSection("Section1", strX, 1000, "XYZ.INI")
MsgBox strX
End Sub


see strX, that you can divide to individual keys

0
 
CritterOHAuthor Commented:
ok getting closer :)
When i use the code you supplied I get the 1st line in the message box, but if I goto immediates window and type ?strX I get everything in that section.

So now I find out why it wont display all and is there a way to get it to start at address=  since there are a few lines above those (they can and do get changed by the original program)
0
 
CritterOHAuthor Commented:
I think it has to do with being tab delimited as when i put my cursor over strX in the code window it shows all the keys with a little square box dividing them.
0
 
appariCommented:
the keys are separated with a vbnullstring
0
 
appariCommented:

Private Sub Command1_Click()
Dim strX As String
Dim X As Long
dim astrX
strX = Space$(1000)
X = GetPrivateProfileSection("Section1", strX, 1000, "XYZ.INI")
astrX = Split(strX, vbNullChar)
MsgBox strX
End Sub


0
 
CritterOHAuthor Commented:
when useing strx it still only shows the first keyvalue.
and when I place the cursor over astx it shows nothing and when i try to get it to display I get "Type Missmatch"
0
 
sharmonCommented:
You could always make your own routines to read and write, I spent a few minutes making the read routine, if you need help with the write routine let me know.

Copy the following code to a form or module and run the Test routine, you need to of course update it to where your file really is and the Section/Key pairs you need.  I made it case sensitive for Sections and Keys, you could easily change it if needed for some reason.

Option Explicit

Sub Test()
    Dim lngRet As Long
    Dim arrResults() As String
    lngRet = ReadValue("c:\test.ini", "section1", "address", arrResults())

    Select Case lngRet
        Case -2 'File was not found
        Debug.Print "File was not found!"
       
        Case -1 'Section was not found
        Debug.Print "Section not found!"
       
        Case 0  'Key was not found
        Debug.Print "Key not found!"
       
        Case 1  'Only one result value
        Debug.Print arrResults(0)
       
        Case 2  'Multiple result values
        Dim i As Integer
        For i = 0 To UBound(arrResults)
            Debug.Print arrResults(i)
        Next i
    End Select
End Sub

Function ReadValue(ByVal strFileName, _
                          ByVal strSection As String, _
                          ByVal strKey As String, _
                          ByRef arrResults() As String) _
                          As Long
   
    On Error GoTo PROC_ERR
   
    Dim strBuffer As String
    Dim fFoundSection As Boolean
    Dim fSectionInit As Boolean
    Dim fArrayInit As Boolean
    Dim i As Integer
    Dim ff As Integer
   
    ff = FreeFile
    ReadValue = 0
   
    Open strFileName For Input As #ff
    Do Until EOF(ff)
        Line Input #ff, strBuffer
        If Len(Trim$(strBuffer)) Then
            If Not fFoundSection Then
                If strBuffer = "[" & strSection & "]" Then
                    fFoundSection = True
                End If
            End If
           
            If fFoundSection And fSectionInit Then
                If Left$(strBuffer, Len(strKey)) = strKey Then
                    i = InStr(1, strBuffer, "=")
                    If i Then
                        strBuffer = Mid(strBuffer, i + 1)
                        If Not fArrayInit Then
                            fArrayInit = True
                            ReDim arrResults(0)
                            arrResults(0) = strBuffer
                            ReadValue = 1
                        Else
                            ReDim Preserve arrResults(UBound(arrResults) + 1)
                            arrResults(UBound(arrResults)) = strBuffer
                            ReadValue = 2
                        End If
                    End If
               
                Else
                    If Left$(strBuffer, 1) = "[" And _
                        InStr(1, strBuffer, "]") Then Exit Do
                End If
            Else
                fSectionInit = True
            End If
        End If
    Loop
   
    If Not fFoundSection Then ReadValue = -1
   
PROC_EXIT:
    Close #ff
    Exit Function

PROC_ERR:
    If Err.Number = 53 Then
        ReadValue = -2
    Else
        MsgBox "Error: " & Err.Number & vbCrLf & _
               "Description: " & Err.Description
    End If
   
    Resume PROC_EXIT
End Function
0
 
sharmonCommented:
Sorry, had a small bug in the routine, here it is again fixed....just copy it over the previous....

Function ReadValue(ByVal strFileName, _
                          ByVal strSection As String, _
                          ByVal strKey As String, _
                          ByRef arrResults() As String) _
                          As Long
   
    On Error GoTo PROC_ERR
   
    Dim strBuffer As String
    Dim fFoundSection As Boolean
    Dim fSectionInit As Boolean
    Dim fArrayInit As Boolean
    Dim i As Integer
    Dim ff As Integer
   
    ff = FreeFile
    ReadValue = 0
   
    Open strFileName For Input As #ff
    Do Until EOF(ff)
        Line Input #ff, strBuffer
        If Len(Trim$(strBuffer)) Then
            If Not fFoundSection Then
                If strBuffer = "[" & strSection & "]" Then
                    fFoundSection = True
                End If
            End If
           
            If fFoundSection And fSectionInit Then
                If Left$(strBuffer, Len(strKey)) = strKey Then
                    i = InStr(1, strBuffer, "=")
                    If i Then
                        strBuffer = Mid(strBuffer, i + 1)
                        If Not fArrayInit Then
                            fArrayInit = True
                            ReDim arrResults(0)
                            arrResults(0) = strBuffer
                            ReadValue = 1
                        Else
                            ReDim Preserve arrResults(UBound(arrResults) + 1)
                            arrResults(UBound(arrResults)) = strBuffer
                            ReadValue = 2
                        End If
                    End If
               
                Else
                    If Left$(strBuffer, 1) = "[" And _
                        InStr(1, strBuffer, "]") Then Exit Do
                End If
            ElseIf fFoundSection Then
                fSectionInit = True
            End If
        End If
    Loop
   
    If Not fFoundSection Then ReadValue = -1
   
PROC_EXIT:
    Close #ff
    Exit Function

PROC_ERR:
    If Err.Number = 53 Then
        ReadValue = -2
    Else
        MsgBox "Error: " & Err.Number & vbCrLf & _
               "Description: " & Err.Description
    End If
   
    Resume PROC_EXIT
End Function
0
 
omerfarooqueCommented:
Try using another variable e.g. addlist in the ini and use that to read all the values that are present in the address
Illustarted below -->

<begin illustration>

[section1]
name=name
address=address
address=address2
address=address3
address=address4

addlist=address|address2|address3|address4

<end illustration>

I am using the pipe as a field seperator here you could read addlist instead of trying to read address. I guess the amount of code change involved here is less.
The cost you would incur in incorporating this would be that you would have to update this field everytime the list gets changed.

Later
Omer
0
 
appariCommented:
omerfarooque :
  when there is simple way to read ini section and divide the keys as suggested in my comment is this long routine required?

and please have a look at "Tips on Comments and Answers" below this question.
0
 
omerfarooqueCommented:
Hey appari,
Shouldnt have posted it as an answer, sorry about that.
About the simple wayto read the ini, there is always more than one. What I gave here was what I would faced with this situation.

0
 
LunchyCommented:
Rejecting answer as omerfarooque admits locked in error.

Lunchy
Friendly Neighbourhood Community Support Moderator
0
 
CritterOHAuthor Commented:
I would like to thank everyone fot their input and help.
appari hit it right on the head and with a little tweeking I was able to pull out exactly what I needed :)
Now to move on with the program .
0
All Courses

From novice to tech pro — start learning today.