Solved

In desperate Need of Help

Posted on 2001-09-03
19
141 Views
Last Modified: 2012-08-13
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.
0
Comment
Question by:CritterOH
  • 7
  • 7
  • 2
  • +2
19 Comments
 
LVL 39

Expert Comment

by:appari
ID: 6451877
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
 

Author Comment

by:CritterOH
ID: 6451899
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
 
LVL 39

Expert Comment

by:appari
ID: 6451903
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
 

Author Comment

by:CritterOH
ID: 6451909
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
 

Author Comment

by:CritterOH
ID: 6451938
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
 
LVL 39

Expert Comment

by:appari
ID: 6451940
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
 

Author Comment

by:CritterOH
ID: 6451955
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
 

Author Comment

by:CritterOH
ID: 6451962
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
 
LVL 39

Expert Comment

by:appari
ID: 6451967
the keys are separated with a vbnullstring
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 39

Expert Comment

by:appari
ID: 6451971

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
 

Author Comment

by:CritterOH
ID: 6451995
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
 
LVL 39

Accepted Solution

by:
appari earned 40 total points
ID: 6452049
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
 
LVL 6

Expert Comment

by:sharmon
ID: 6452248
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
 
LVL 6

Expert Comment

by:sharmon
ID: 6452260
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
 

Expert Comment

by:omerfarooque
ID: 6452501
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
 
LVL 39

Expert Comment

by:appari
ID: 6452526
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
 

Expert Comment

by:omerfarooque
ID: 6452548
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
 
LVL 2

Expert Comment

by:Lunchy
ID: 6453297
Rejecting answer as omerfarooque admits locked in error.

Lunchy
Friendly Neighbourhood Community Support Moderator
0
 

Author Comment

by:CritterOH
ID: 6454802
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

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now