Solved

Error retrieving data by string index from collection

Posted on 2001-07-29
8
213 Views
Last Modified: 2010-05-02
Code is located here:

http://www.oz.net/~inthane/template.zip

It takes two files, which both contain lines such as

const foo = "bar",

and where the value of the const varies in the second file from the first, it replaces it with the value in the second file. Otherwise, it leaves the first file untouched.

It works by scanning the source file for const <foo> = <bar>, then dropping <bar> into a collection with <foo> as the index. It then opens the template file, and looks for const <foo> = <bar>, then uses <foo> as an index to retrieve <bar.>

It's failing on the retrevial function, and nothing I'm doing is working.  Originally, I was dumping the string <bar> into the collection, with <foo> as the index - and I was getting error messages.  I tried converting over to a class/class module combination, with no luck.  Any help would be much appreciated.
0
Comment
Question by:inthane
  • 7
8 Comments
 
LVL 5

Expert Comment

by:KDivad
ID: 6333004
So the template is the correct file when there is a conflict?

Looking...
0
 
LVL 5

Expert Comment

by:KDivad
ID: 6333008
First problem:

This line removes the first quote:

currline = Right(currline, Len(currline) - 3)

This line then rejects the value because the first quote is missing:

If Left(thisvalue, 1) = Chr(34) Then ' String also must begin with a quote.
0
 
LVL 5

Expert Comment

by:KDivad
ID: 6333028
There's also another problem I'm having a bit of trouble puzzling out. If you like, I'll rewrite your project to do what you need it to.
0
 
LVL 5

Expert Comment

by:KDivad
ID: 6333086
I got curious and rewrote it after all.

Since your two classes were little more than data holders, I removed them and replaced them with appropriate substitutes. (colConstants - Collection, Constants(Class) - Constants(UDT)) The collection by itself and the UDT experience much faster access than the classes would have.

I also made an adjustment as per the error I mentioned above regarding quotes.

I then made an adjustment to theseConstants.Add that removed the need for the UDT. (A=B,C=A - C=B)

Much as I was tempted to make several more changes (preference more than anything), I decided to play nice and leave as much of your code alone as I could. <grin>

Remove both classes from your project and replace all the code in the form with what is in the next post.
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 5

Accepted Solution

by:
KDivad earned 75 total points
ID: 6333088
'Private Type Constants
'    Key As String
'    Value As String
'End Type
Dim theseConstants As Collection
Private Sub cmdBrowseDestination_Click()

    Dim tmpstr As String
    CommonDialog1.Flags = cdlOFNNoReadOnlyReturn & cdlOFNHideReadOnly
    tmpstr = GetFile()
    If tmpstr <> vbNullString Then
        txtDestination.Text = tmpstr
    End If

End Sub
Private Sub cmdBrowseSource_Click()

    Dim tmpstr As String
    CommonDialog1.Flags = cdlOFNFileMustExist & cdlOFNHideReadOnly
    tmpstr = GetFile()
    If tmpstr <> vbNullString Then
        txtSource.Text = tmpstr
    End If

End Sub
Private Sub cmdBrowseTemplate_Click()

    Dim tmpstr As String
    CommonDialog1.Flags = cdlOFNFileMustExist & cdlOFNHideReadOnly
    tmpstr = GetFile()
    If tmpstr <> vbNullString Then
        txtTemplate.Text = tmpstr
    End If

End Sub

Private Function GetFile() As String

    ' Triggers the CommonDialog control with the proper commands, and returns the file.
    CommonDialog1.CancelError = True
    On Error GoTo ErrHandler
    CommonDialog1.ShowOpen
    GetFile = CommonDialog1.filename
    GoTo EndFunc
ErrHandler:
    GetFile = vbNullString
EndFunc:

End Function
Private Sub ReadSource()

    ' Reads the source file, and strips it of constants, which are placed in the collection.
    Dim filename As String
    Dim currline As String
    Dim thisconst As String
    Dim thisvalue As String
'    Dim thisset As Constants
    Set theseConstants = New Collection
   
    filename = txtSource.Text
   
    Open filename For Input As #1
    Do While Not EOF(1)
        Line Input #1, currline
        currline = Trim(currline)
        If LCase(Left(currline, 5)) = "const" Then
            thisconst = GetLWord(currline)
            thisconst = GetLWord(currline)
            If Left(currline, 1) = "=" And Right(currline, 1) = Chr(34) Then ' String must end with a " mark
                currline = Right(currline, Len(currline) - 2)
                thisvalue = Left(currline, Len(currline) - 1)
                If Left(thisvalue, 1) = Chr(34) Then ' String also must begin with a quote.
                    thisvalue = Right$(thisvalue, Len(thisvalue) - 1)
                    theseConstants.Add thisvalue, thisconst
'                    thisset.Value = thisvalue
'                    thisset.Key = thisconst
'                    theseConstants.Add thisset.Key, thisset.Value, thisset.Key
                End If
            End If
        End If
    Loop
    Close #1

End Sub
Function GetLWord(currline As String) ' Gets the leftmost word, then trims it off.

    Dim theword As String
    Dim thischar As String
   
    Do While Not (Left(currline, 1) = " ")
        thischar = Left(currline, 1)
        currline = Right(currline, Len(currline) - 1)
        theword = theword + thischar
    Loop
    currline = Trim(currline)
    GetLWord = theword

End Function
Private Sub cmdResolve_Click()

    If txtSource.Text = txtDestination.Text Or txtSource.Text = txtTemplate.Text Or txtTemplate.Text = txtDestination.Text Then
        MsgBox "Files cannot be the same!"
    Else
        ReadSource
        OutputFinal
    End If

End Sub
Private Sub OutputFinal()

    Open txtTemplate.Text For Input As #1
    Open txtDestination.Text For Output As #2
   
    Dim currline As String
    Dim statline As String
    Dim thisconst As String
    Dim thisvalue As String
       
On Error Resume Next

    Do While Not EOF(1)
        Line Input #1, currline
        statline = currline
        If (LCase(Left(Trim(currline), 5)) = "const") Then
            thisconst = GetLWord(currline)
            thisconst = GetLWord(currline)
           
            thisvalue = vbNullString
            thisvalue = theseConstants(thisconst)
           
            If thisvalue = vbNullString Then GoTo dontchange
           
            Print #2, "const " & thisconst & " = " & Chr(34) & thisvalue & Chr(34)
        Else
dontchange:
            Print #2, statline
        End If
    Loop
    Close #1
    Close #2
    MsgBox "All done now!"

End Sub
0
 
LVL 5

Expert Comment

by:KDivad
ID: 6333095
Looks like two of those lines are split and will have to be fixed.

Anyway, that should do as you wish.

I suppose you're tired of getting email notifs about me posting, so I'll try and make this the last one. <grin>

Later,
KDL
0
 

Author Comment

by:inthane
ID: 6334412
That did it alright!

It looks like this all came from the initial quote-stripping bug you noticed.  I actually thought the problem I was having there was caused by something else from an earlier rev of the program, and tried to "fix" it.

At that point, I started getting an error that seemed similar to another error I used to get when I first started using collections, and I couldn't remember what had caused that error to start with.  That's when I added the class modules, in an attempt to abstract the error.  Of course, when one complicates their own code to solve the problem, one inevitably makes the problem worse.

Thank you!
0
 
LVL 5

Expert Comment

by:KDivad
ID: 6336318
Even if it doesn't make the problem worse, it often adds it's own problems.

Glad I could help you out!
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
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 utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

760 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

22 Experts available now in Live!

Get 1:1 Help Now