Need Help Simplifying

I want to port a VB6 app to VB2005 while simplifying as much as possible. The current program uses multiple random access files to store data, both for user options and individual companies that are independent projects. My question is about converting multiple complex user-defined types into structures and then saving them in two files-- user options and company-specific. This is what I intend doing but would appreciate suggestions on a better way.

1. Create structures for the types, combining as many as make sense into single structures. The user options will be one structure. These structures must be available throughout the entire application.

2. Create a collection of company-specific structures. There is one collection for each company project. There could be hundreds of company projects.

3. Binary serialize the collection and save it to the location for the company project(usually on a networked drive).

4. Serialize the user options and save it (usually on the local machine).

The persisted data would be de-serialized when the program starts (user options) and when the company information is loaded.




Answer this question

Need Help Simplifying

  • Gabyx

    Is there a reason for not using a database instead of your random access files

  • m.m.b.

    Scott,

    Thank you very much for your suggestion. I have used settings in VB6 but this way is much better. I have marked both your suggestion and the one about using XML as answers.



  • gafrank

    Phantom208 wrote:
    Not really. The database would be much more difficult than serializing the collection. Each of the files contains only one record which is very long and consists of strings and numeric arrays. I wrote the original program when I was just learning VB6 after years of programming in FORTRAN. Databases were pretty foreign to me then and I did not know how to handle the different types of structures in one file.

    I'd suggest that, at the very least, you look into storing this data as XML which can be validated with an appropriate schema. This gives you a lot more flexibility in terms of making changes to the "reader" code, allows you to import the data directly with the appropriate type, and allows you to manually edit the files if you absolutely must. Binary data files are a huge pain, and they're nearly always incomprehensible to anybody who isn't the developer.



  • harley_8006

    Scott,

    Thanks for pointing out the settings designer. I think it will do the settings quite nicely and will use it. Do you have an opinion you are willing to share about the company files



  • SnowJim

    I solved the problem of serialization by moving the structures outside the class (e.g., immediately below the imports statements) and adding <Serializable> attribute. An error occurs when the structure is inside the class. I also found the reference to the SOAP formatter. All that works now.

    I will implement both suggestions: Use XML and using the built-in settings for application and user. I want to accept both suggestions as the answer but am not sure how.

    Many thanks to both of you for your excellent suggestions.



  • gudel

    For storing user settings I would take a look at the settings designer.

    It makes reading and writing user scoped configuration data very easy. In particular, with the settings designer the IDE will auotmatically generate the class that stores the settings values along with all the logic to read and write the values to and from your program. All you have to do is tell the deigner what you want your settings to be named and what type of data you are storing and it will handle the rest (make sure that you tell the settings designer to use "User Scope" settings as opposed to "Application Scope" settings).

    You can access it by bringup your project's property dialog (right click on the project in the solution explorer and select properties) and clicking on the settings tab. You can then read and write these settings in code via My.Settings (setting "X" will be accessible via My.Settings.X). To load the settings from disk call My.Settings.Reload(). To save them call My.Settings.Save(). This will autoamtically save the settings to a an application specific file in the users "personal directory" (i.e. C:\documents and settings\Phantom208").

    - Scott Wisniewski


  • brian_tsim

    DMan1,

    Not really. The database would be much more difficult than serializing the collection. Each of the files contains only one record which is very long and consists of strings and numeric arrays. I wrote the original program when I was just learning VB6 after years of programming in FORTRAN. Databases were pretty foreign to me then and I did not know how to handle the different types of structures in one file.



  • hotaruu

    Duck Thing:

    I will surely look at XML. Since I have never done either the serializing or XML, I have to learn whichever one I use. It will take a few days to study up on it and run some tests. I'll respond to this thread about my choice and why. Thanks for your thoughtful response.



  • Earl Hood

    Duck Thing:

    Here is my feeble attempt which has led to an error I cannot resolve. The easiest thing to do is create a hash table of structures. the following code has two structures which I put into a hash table, clear the structures, read the structures from the hash table and print to a message box to confirm the hash table and then try to persist the table via a binary serialization. (I used binary because I could not get the SOAP formatter to appear in my VB 2005 Express. Maybe when the professional version comes in a few days I can use SOAP. Oddly enough, the Word Frequencies project in Mastering Visual Basic 2005 uses SOAP and it worked fine. I can't figure out what the difference is. Maybe in a few days.)

    The error appears in the attempt to serialize the hash table. I think it means that structures cannot be serialized. If that is so, I'm stuck. I would hate to have to use the individual elements of all the structures. The code followed by the error detail is:

    ****************************Code**********************************

    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary


    Public Class TestHashTable
    Dim hTable As New Hashtable
    Public Structure CompanyInformation
    <VBFixedString(40)> Dim CompanyName As String
    <VBFixedString(16)> Dim IntAudNbr As String
    <VBFixedString(30)> Dim TypeAuditFile As String
    Dim RecNo As Short
    <VBFixedString(100)> Dim DataPath As String
    End Structure
    Public Structure AuditorInformation
    Dim AuditorName As String
    Dim AuditorPhone As String
    Dim AuditorEMail As String
    End Structure

    Dim CompanyInfo As New CompanyInformation
    Dim AuditorInfo As New AuditorInformation

    Private Sub btnProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcess.Click
    With CompanyInfo 'store values in the hash table
    .CompanyName = txtInputCompanyName.Text
    .IntAudNbr = txtInputAuditNumber.Text
    .RecNo = txtInputRecordNbr.Text
    .TypeAuditFile = txtInputAuditType.Text
    .DataPath = txtInputDataPath.Text
    End With
    hTable.Add("CompanyInfo", CompanyInfo)
    With AuditorInfo
    .AuditorName = txtInputAuditorName.Text
    .AuditorPhone = txtInputAuditorPhone.Text
    .AuditorEMail = txtInputAuditorEMail.Text
    End With
    hTable.Add("AuditorInfo", AuditorInfo)
    'Clear the structures
    With CompanyInfo
    .CompanyName = "Cleared"
    .IntAudNbr = "Cleared"
    .RecNo = 0
    .TypeAuditFile = "Cleared"
    .DataPath = "Cleared"

    End With
    With AuditorInfo
    .AuditorName = "Cleared"
    .AuditorPhone = "Cleared"
    .AuditorEMail = "Cleared"
    End With
    ShowHashTableContents(hTable)

    Dim savefile As FileStream
    SaveFileDialog1.DefaultExt = "XML;"
    If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
    savefile = File.OpenWrite(SaveFileDialog1.FileName)
    savefile.Seek(0, SeekOrigin.End)

    Dim Formatter As BinaryFormatter = New BinaryFormatter

    Formatter.Serialize(savefile, hTable) '******************Here is the error******************
    savefile.Close()
    MsgBox("File saved.")
    End If

    End Sub

    Private Sub btnRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRead.Click
    Dim readFile As FileStream
    OpenFileDialog1.DefaultExt = "BIN"
    If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
    readFile = File.OpenRead(OpenFileDialog1.FileName)
    Dim de As DictionaryEntry
    Dim hTable2 As New Hashtable
    Dim BFormatter As New BinaryFormatter
    hTable2 = CType(BFormatter.Deserialize(readFile), Hashtable)
    readFile.Close()
    For Each de In hTable2
    Select Case de.Key
    Case "CompanyInfo"
    CompanyInfo = de.Value
    Case "AuditorInfo"
    AuditorInfo = de.Value
    End Select
    Next
    txtOutputCompanyName.Text = CompanyInfo.CompanyName
    txtOutputAuditNbr.Text = CompanyInfo.IntAudNbr
    txtOutputRecordNbr.Text = CompanyInfo.RecNo
    txtOutputAuditType.Text = CompanyInfo.TypeAuditFile
    txtOutputDataPath.Text = CompanyInfo.DataPath
    txtOutputAuditorName.Text = AuditorInfo.AuditorName
    txtOutputAuditorPhone.Text = AuditorInfo.AuditorPhone
    txtOutputAuditorEmail.Text = AuditorInfo.AuditorEMail
    End If
    End Sub
    Private Sub ShowHashTableContents(ByVal table As Hashtable)
    Dim key As Object
    Dim MsgLine As String = "hTable contains " & hTable.Count.ToString & " elements." & vbCrLf
    For Each key In table.Keys
    Select Case key
    Case "CompanyInfo"
    CompanyInfo = table.Item(key)
    MsgLine = MsgLine & key.ToString & vbCrLf
    MsgLine = MsgLine & CompanyInfo.CompanyName & vbCrLf
    MsgLine = MsgLine & CompanyInfo.IntAudNbr & vbCrLf
    MsgLine = MsgLine & CompanyInfo.RecNo.ToString & vbCrLf
    MsgLine = MsgLine & CompanyInfo.TypeAuditFile & vbCrLf
    Case "AuditorInfo"
    AuditorInfo = table.Item(key)
    MsgLine = MsgLine & key.ToString & vbCrLf
    MsgLine = MsgLine & AuditorInfo.AuditorName & vbCrLf
    MsgLine = MsgLine & AuditorInfo.AuditorPhone & vbCrLf
    MsgLine = MsgLine & AuditorInfo.AuditorEMail & vbCrLf
    End Select
    Next
    MsgBox(MsgLine)
    End Sub
    End Class
    *********************Error Message*******************
    System.Runtime.Serialization.SerializationException was unhandled
    Message="Type 'TestHashTableXML.TestHashTable+AuditorInformation' in Assembly 'TestHashTableXML, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable."
    Source="mscorlib"
    StackTrace:
    at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
    at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
    at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
    at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
    at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
    at TestHashTableXML.TestHashTable.btnProcess_Click(Object sender, EventArgs e) in D:\VB2005 Testing Programs\TestHashTableXML\TestHashTable.vb:line 61
    at System.Windows.Forms.Control.OnClick(EventArgs e)
    at System.Windows.Forms.Button.OnClick(EventArgs e)
    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.ButtonBase.WndProc(Message& m)
    at System.Windows.Forms.Button.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.Run(ApplicationContext context)
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    at TestHashTableXML.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
    at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()

    **************************End of Code and Detail*****************************

    I have tried to mark the structure as serializable but that causes a compiler error.

    I appreciate your help.



  • Need Help Simplifying