4

I'm trying to parse a CSV File into a VB6 application in order to update multiple records on a table on SQL with existing single record updating code already in the form. The CSV Files will have a header row whixh can be used to validate the information going into the correct place in the ADODB recordset. In C++ you can use a map to say like

map<String s, int x> column 
 column<"First Name", -1>
 column<"Last Name",-1>

Then create a counter across the comma delimited values where if the third value is Last Name then the code could be written to change column<"Last Name",-1> to column<"Last Name",3> and if x != -1 in any of the maps the file is valid for use, I would then loop through the remaining records and parse into a container using something similar to

strLastName = Array<column[3]>

to assign the record values to the correct variables. I am still very new to VB6, how can I accomplish something similar in VB6 and what containers should be used? So far I have

Public Sub GetImportValues()
On Error GoTo GetImportValues_Error:
Dim intFileNum As Integer

Open Path For Input As #intFileNum

Do Until EOF(intFileNum)

Line Input #intFileNum, vbCrLf

FunctionThatSavesInformationToSQL

Loop

Close #intFileNum



GetImportValues_Exit:
    Exit Sub

GetImportValues_Error:
    Err.Source = "frmMemberAdd.GetImportValues" & " | " & Err.Source
    Err.Raise Err.Number, Err.Source, Err.Description
End Sub

with a dialog box returning the path as a string using App.path in a separate Function

*****************************************************Slight change to answer The collection was on track for what I had asked but I did have to change it to dictionary because you cannot return items on a collection which kept me from comparing the items and changing the keys but dictionary can. Make sure if you use dictionary you switch the item and key.

Davidp04
  • 145
  • 1
  • 7
  • 17
  • 1
    Is it your choice to use VB6? I'm only asking because it's very old and outdated tecnology and using VB.Net or C# would be much easier (and modern so whatever you learn would be more applicable in the future). – xxbbcc Feb 18 '15 at 23:07
  • It is not my choice, I have to use VB6 for this application. I usually use C# – Davidp04 Feb 18 '15 at 23:23

1 Answers1

4

If I understand your question correctly, you're trying to create a map (Dictionary<string, int> in C#). In VB6, you can use Collection for this purpose - it's roughly equivalent to C#'s Dictionary<string, object>. It uses String keys and stores all values as Variant. For example:

Dim oColl As Collection

Set oColl = New Collection
oColl.Add -1, "ColumnName"

Dim nColumnIndex As Long

'Get column index for column name.
nColumnIndex = oColl.Item("ColumnName")

If nColumnIndex = -1 Then
    nColumnIndex = ...

    'When you want to update a column index in the collection, you
    'first have to remove the item and then add it back with the right
    'index.
    oColl.Remove "ColumnName"
    oColl.Add nColumnIndex, "ColumnName"
End If

Edit 1:

One word of warning regarding VB6: you'll see many samples doing this:

Dim oObj As New SomeClass

It's ok to do this in VB.Net but don't ever do this in VB6. Declare and instantiate the object on separate statements because the single-statement form generates code where oObj is checked for Nothing and set to an instance before each use. This slows down your code (unnecessary checks) and creates hard-to-find bugs if you're using an instance that's supposed to be gone.

Always do this instead:

Dim oObj As SomeClass
Set oObj = New SomeClass
...

'Clean up the object when you're done with it. Remember, there's
'no garbage collection in COM / VB6, you have to manage object
'lifetimes.
Set oObj = Nothing

Also, use Long instead of Integer as much as you can - Long is a 32-bit integer, while Integer is only 16-bits. VB6 type names can be misleading frequently. Here's an old answer of mine with a bit more detail (not strictly related to your question but useful).

Alternatively, you can create a simplified wrapper around the .NET Dictionary class and expose it as a COM object: this would allow you to call it from VB6. This would likely be (somewhat) slower than Collection and it'd require the .NET Framework for your VB6 project to run.

Edit 2:

As @CMaster commented, Dictionary is available from the Microsoft Scripting Runtime library - you need to add a reference to it to use it (this is why I prefer Collection - it has no dependency). This answer has details about how to use it.

Community
  • 1
  • 1
xxbbcc
  • 16,930
  • 5
  • 50
  • 83
  • 1
    If you want a dictionary in VB6, you can get one easier than that. Project -> References -> Microsoft Scripting Runtime. This makes the dictionary class available to use. – CMaster Feb 19 '15 at 09:31
  • @CMaster You're right - I'll update my answer with your comment. I forgot about Dictionary class since Collection is part of VB directly and there are a number of better implementations for fast collection replacements. – xxbbcc Feb 19 '15 at 15:11
  • @Davidp04 I'm glad it was useful. – xxbbcc Feb 19 '15 at 21:43
  • Vb6/COM has no garbage collection but uses reference counters to manage object lifetimes instead. Since exiting procedure automatically destroys variables declared within it, reference counting will make sure that the object is destroyed to. No need to explicitly set the reference to Nothing. – Milan Oparnica Oct 25 '17 at 07:24
  • @MilanOparnica That's true but is only correct when the variable is local to a function. If a variable is global, it'll stay around until the process exists, unless it's explicitly released when it's not needed anymore. (Proper scoping / helper classes would help with this but I've seen many examples where it wasn't done right.) Furthermore, setting a variable to `Nothing` is what decrements the ref count. – xxbbcc Oct 25 '17 at 13:21