Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 153
  • Last Modified:

saving object data

Can anyone suggest a good method for the following?

I have several different classes, and numerous objects of each class stored in collections.  I need a way to store the data in the objects to a file, and then to be able to restore them again.

Each class is just a bunch of public variables, I would make them types, but I need to be able to add them to collections.  

Currently, my only idea is to create a type for each class containing the necessary variables, and having a method to put the class info into the type, then putting it to a file, and then having a method to get the type from the file, and put the variables back into the class.  However, this seems like an ass-backwards approach, so I'm wondering if there's something I haven't considered yet.
0
Kail
Asked:
Kail
  • 3
  • 3
1 Solution
 
VbmasterCommented:
Why convert it to a type at all? If you have a lot of small variables you can allocate a byte array with the needed size and using the API RtlMoveMemory (also called CopyMem) to copy the small variables into that byte array, then you can save all the variables to the file with only one Put statement (= faster than adding all variables one-by-one).
0
 
KailAuthor Commented:
Heh, I have almost no idea what you mean.

Could you give me an example?

And also, wouldn't strings be a problem?  You can't use fixed-length strings as public vars in objects(stupid VB).
0
 
VbmasterCommented:
Variable-length strings can be stored by first adding a numerical value that sais how long the string is and then add the string. This way when the program reads back the information it will know exactly how long the string should be and reads that number of characters and store it into the string.

I can probably put a example showing how to do it, or perhaps you could show what kind of variables you want to store and I can show you how to do it. It's really not that hard. At least I do not think so. ;)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
KailAuthor Commented:
Please post the example.  I need to store about 50 strings, 2 integers, and 2 collections of strings.

Thanks...:)
0
 
VbmasterCommented:
Here's a example I have created, hopefully this will show how you do it. This is not optimized using CopyMem API, this means a lot more work and I'm not sure about how much performance difference you will get.

I'm not really familiar with Collections, I do not use 'em because they do not give too good performance, do your Collections contained keys? Because I could not find a way to extract the keys. Besides from that storing collections works fine.


VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Class1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Private m_OneString As String
Private m_AnotherString As String
Private m_OneInteger As Integer
Private m_AnotherInteger As Integer
Private m_Collection As New Collection

Public Sub Load(Optional Filename As String, Optional Filenr As Integer)

  Dim a As Long
  Dim CollSize As Long
  Dim StringLen As Long
  Dim CollItem As String
  Dim CloseFile As Boolean
 
  If (Filenr = 0) Then
    Filenr = FreeFile
    Open Filename For Binary As #Filenr
    CloseFile = True
  End If
 
  'Clear the values
  m_OneString = ""
  m_AnotherString = ""
  m_OneInteger = 0
  m_AnotherInteger = 0
 
  'Read the first string
  Get #Filenr, , StringLen
  m_OneString = Space$(StringLen)
  Get #Filenr, , m_OneString
 
  'Read another string
  Get #Filenr, , StringLen
  m_AnotherString = Space$(StringLen)
  Get #Filenr, , m_AnotherString
 
  'Read a integer (always 2 bytes)
  Get #Filenr, , m_OneInteger
 
  'Read another integer (always 2 bytes)
  Get #Filenr, , m_AnotherInteger
 
  'Clear the collection (we don't want the old items)
  Set m_Collection = New Collection
 
  'Read the collection
  Get #Filenr, , CollSize
  For a = 1 To CollSize
    Get #Filenr, , StringLen
    CollItem = Space$(StringLen)
    Get #Filenr, , CollItem
    Call m_Collection.Add(CollItem)
  Next
 
  If CloseFile Then Close #Filenr

End Sub

Public Sub Save(Optional Filename As String, Optional Filenr As Integer)

  Dim a As Long
  Dim CollSize As Long
  Dim CollItem As String
  Dim StringLen As Long
  Dim CloseFile As Boolean
 
  If (Filenr = 0) Then
    Filenr = FreeFile
    Open Filename For Binary As #Filenr
    CloseFile = True
  End If
 
  'Store the first string
  StringLen = Len(m_OneString)
  Put #Filenr, , StringLen
  Put #Filenr, , m_OneString
 
  'Store another string
  StringLen = Len(m_AnotherString)
  Put #Filenr, , StringLen
  Put #Filenr, , m_AnotherString
 
  'Store a integer (always 2 bytes)
  Put #Filenr, , m_OneInteger
 
  'Store another integer (always 2 bytes)
  Put #Filenr, , m_AnotherInteger
 
  'Store the collection
  CollSize = m_Collection.Count
  Put #Filenr, , CollSize
  For a = 1 To m_Collection.Count
    CollItem = m_Collection.Item(a)
    StringLen = Len(CollItem)
    Put #Filenr, , StringLen
    Put #Filenr, , CollItem
  Next
 
  If CloseFile Then Close #Filenr
 
End Sub

Private Sub Class_Initialize()

  Dim a As Long
 
  'Initialize some dummy values so you can see that the Save
  'and Load procedures works like they are supposed to
  m_OneString = "Test string"
  m_AnotherString = "Contains something else"
  m_OneInteger = 37
  m_AnotherInteger = 400
 
  For a = 1 To 10
    Call m_Collection.Add("Collection String " & a, "key" & a)
  Next
 
End Sub



Let's say you add these two procedures to your class, called OneClass. Then you can save/load the class' variables using code like...

  Call OneClass.Save("C:\Test.txt")   'Save the variables
  Call OneClass.Load("C:\Test.txt")   'Load the variables


However you might want to save multiple classes in the same file, this can easily be done using the Filenr parameter like...

  'Save the variables
  Dim Filenr As Integer
  Filenr = FreeFile
  Open "C:\Test.txt" For Binary As #Filenr
  Call OneClass.Save( , Filenr)
  Call TwoClass.Save( , Filenr)
  'You can add more classes here if you like
  Close #Filenr

  'Load the variables
  Dim Filenr As Integer
  Filenr = FreeFile
  Open "C:\Test.txt" For Binary As #Filenr
  Call OneClass.Load( , Filenr)
  Call TwoClass.Load( , Filenr)
  'You can add more classes here if you like
  Close #Filenr
0
 
KailAuthor Commented:
Cool, thanks a bunch Vbmaster.

Though, I would like to add that its a lot easier if you write and use generic GetStr() and PutStr() functions...:)
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now