?
Solved

saving configs into a text file then reloading?

Posted on 2006-04-13
10
Medium Priority
?
236 Views
Last Modified: 2013-11-18
Hi,

Please kindly assist how can we store the configs to a text file and reload then?

all objects are combo boxes. saving what the user selected into a text file and so that next time he runs the application
changes are save.

cmbLateTimeInHrs.AddItem "--", 0
cmbLateTimeInHrs.AddItem "1h", 1
cmbLateTimeInHrs.AddItem "2h", 2
cmbLateTimeInHrs.AddItem "3h", 3

Thanks.
0
Comment
Question by:RyanBank
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 28

Accepted Solution

by:
vinnyd79 earned 800 total points
ID: 16445266
Something like this?



Private Sub Command1_Click()
Call SaveComboBoxes("C:\Cfg.txt")
End Sub

Private Sub Command2_Click()
Call LoadComboBoxes("C:\Cfg.txt")
End Sub

Private Sub SaveComboBoxes(CfgFile As String)
Dim Ctl As Control, ff As Integer, i As Long
ff = FreeFile
Open CfgFile For Output As #ff
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        Print #ff, "~" & Ctl.Name
            Print #ff, "  " & Ctl.Text
    End If
Next
End Sub

Private Sub LoadComboBoxes(CfgFile As String)
Dim Ctl As Control, ff As Integer, i As Long, Ln As String, CtlName As String
ff = FreeFile
Open CfgFile For Input As #ff
Do Until EOF(ff)
Line Input #ff, Ln
If Left$(Ln, 1) = "~" Then
    CtlName = Trim$(Mid$(Ln, 2))
    GoTo GetNext
End If
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        If CtlName = Ctl.Name Then
           Ctl.Text = Trim$(Ln)
        End If
    End If
Next
GetNext:
DoEvents
Loop
Close #ff
End Sub
0
 
LVL 28

Expert Comment

by:vinnyd79
ID: 16445296
Forgot to close the file in the Save routine. It should be:

Private Sub SaveComboBoxes(CfgFile As String)
Dim Ctl As Control, ff As Integer, i As Long
ff = FreeFile
Open CfgFile For Output As #ff
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        Print #ff, "~" & Ctl.Name
            Print #ff, "  " & Ctl.Text
    End If
Next
Close #ff
End Sub
0
 
LVL 28

Expert Comment

by:vinnyd79
ID: 16445348

Here is an example that uses a "|" as a delimiter in the file and then uses the split function in the load routine:

Private Sub Command1_Click()
Call SaveComboBoxes("C:\Cfg.txt")
End Sub

Private Sub Command2_Click()
Call LoadComboBoxes("C:\Cfg.txt")
End Sub

Private Sub SaveComboBoxes(CfgFile As String)
Dim Ctl As Control, ff As Integer, i As Long
ff = FreeFile
Open CfgFile For Output As #ff
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        Print #ff, Ctl.Name & "|" & Ctl.Text
    End If
Next
Close #ff
End Sub

Private Sub LoadComboBoxes(CfgFile As String)
Dim Ctl As Control, ff As Integer, Ln As String
Dim arrLn() As String, CtlName As String
ff = FreeFile
Open CfgFile For Input As #ff
Do Until EOF(ff)
Line Input #ff, Ln
If InStr(Ln, "|") Then
arrLn = Split(Ln, "|")
CtlName = arrLn(0)
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        If CtlName = Ctl.Name Then
           Ctl.Text = arrLn(1)
        End If
    End If
Next
End If
DoEvents
Loop
Close #ff
End Sub
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:RyanBank
ID: 16445610
vinnyd79,

Amazing, how do we load into the combo box? how do load for each combo box?

cmbLateTimeInHrs.AddItem "--", 0
cmbLateTimeInHrs.AddItem "1h", 1
cmbLateTimeInHrs.AddItem "2h", 2
cmbLateTimeInHrs.AddItem "3h", 3


Thanks
0
 
LVL 28

Expert Comment

by:vinnyd79
ID: 16446221
The above should handle all comboboxes on the form. If you want to load specific comboboxes only you can add an optional argument to the load routine to supply the Comboname.Maybe something like this:


Private Sub Command1_Click()
Call SaveComboBoxes("C:\Cfg.txt")
End Sub

Private Sub Command2_Click()
Call LoadComboBoxes("C:\Cfg.txt")  ' to load all the combo's on form
Call LoadComboBoxes("C:\Cfg.txt", "Combo1")  ' to just load combo1
End Sub

Private Sub SaveComboBoxes(CfgFile As String)
Dim Ctl As Control, ff As Integer, i As Long
ff = FreeFile
Open CfgFile For Output As #ff
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        Print #ff, Ctl.Name & "|" & Ctl.Text
    End If
Next
Close #ff
End Sub

Private Sub LoadComboBoxes(CfgFile As String, Optional ComboName As String)
Dim Ctl As Control, ff As Integer, Ln As String
Dim arrLn() As String, CtlName As String
ff = FreeFile
Open CfgFile For Input As #ff
Do Until EOF(ff)
Line Input #ff, Ln
If Trim$(ComboName) = "" Then
If InStr(Ln, "|") Then
arrLn = Split(Ln, "|")
CtlName = arrLn(0)
For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        If CtlName = Ctl.Name Then
           Ctl.Text = arrLn(1)
        End If
    End If
Next
End If
Else
CtlName = Trim$(Left$(Ln, InStr(Ln, "|") - 1))
If Trim$(ComboName) = CtlName Then
    For Each Ctl In Me.Controls
    If TypeOf Ctl Is ComboBox Then
        If Ctl.Name = Trim$(ComboName) Then
           Ctl.Text = Trim$(Mid$(Ln, InStr(Ln, "|") + 1))
        End If
    End If
    Next
End If
End If

DoEvents
Loop
Close #ff
End Sub
0
 
LVL 9

Assisted Solution

by:dancebert
dancebert earned 800 total points
ID: 16447289
I have a class that does what you want, except that it saves the vaues in a PropertyBag (a binary file, it's a built in part of VB).  Call it at form_unload to save the settings, call it at form_load to reset controls from saved values.  If there are no saved values, it does nothing.  

It works with the following controls: ComboBox, TextBox, OptionButton, DriveListBox, DirListBox, CheckBox, ListBox.  It's easy to modify the code to save just the controls you want, or to add other control types.

Intro to PropertyBags at http://www.developer.com/net/vb/article.php/10926_1537081_5  Scroll down to the heading "PropertyBag Objects"

=====  form code ====

Private Sub Form_Load()
   <put any control initialization here>
   
    Dim o As New cControlSettings
    o.LoadSettings Me, "c:\settings.pb"   ' .pb is the usual extension for a PropertyBag
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Dim o As New cControlSettings
    o.SaveSettings Me, "c:\settings.pb"
End Sub


=== cControlSetings.cls ===

Option Explicit

'' Save control contents to a PropertyBag, reload from there.
'' Works with: TextBox,OptionButton,DriveListBox,DirListBox,CheckBox,ListBox,ComboBox
'' Sample calling code at bottom


Private Declare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hwnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Long, _
    lParam As Any) As Long

Private Const LB_GETSELITEMS = &H191
Private Const cnIGNORE_KEY As String = "SETTINGS"
Private Const cnIGNORE_VALUE As String = "NO"


Public Sub SaveSettings(ByVal p_frm As Form _
                , ByVal p_sPathAndFileName As String)
   
    Dim pb As PropertyBag: Set pb = New PropertyBag
    Dim vContents As Variant
    Dim ii As Long
   
    With pb
        Dim o As Control
        For Each o In p_frm.Controls
           
            If InStr(ReadTag(o.Tag, cnIGNORE_KEY), cnIGNORE_VALUE) = 0 Then
   
                If TypeOf o Is TextBox Then
                    .WriteProperty o.Name, o.Text
                ElseIf TypeOf o Is OptionButton Then
                    .WriteProperty o.Name, o.Value
                ElseIf TypeOf o Is DriveListBox Then
                    .WriteProperty o.Name, o.Drive
                ElseIf TypeOf o Is DirListBox Then
                    .WriteProperty o.Name, o.Path
                ElseIf TypeOf o Is CheckBox Then
                    .WriteProperty o.Name, o.Value
                ElseIf TypeOf o Is ListBox Then
                    If o.MultiSelect <> 0 Then
                        Dim sItems As String: sItems = SelectedListboxMultiItems(o)
                        Dim v_ As Variant: v_ = Split(sItems, "|")
                        For ii = LBound(v_) To UBound(v_)
                            .WriteProperty o.Name & CStr(ii), CStr(v_(ii))
                        Next
                    Else
                        .WriteProperty o.Name, SelectedListboxItem(o)
                    End If
   
                ElseIf TypeOf o Is ComboBox Then
                    .WriteProperty o.Name, o.ListIndex
                Else
'                    Debug.Print "ElseIf TypeOf o Is  " & Left(o.Name, Len(o.Name) - 1)
                End If

            End If  '' If InStr(ReadTag(o.Tag, cnIGNORE_KEY), cnIGNORE_VALUE) = 0 Then
        Next
       
        vContents = .Contents
    End With

   
    ' Save to a text file.
    If Not Dir(p_sPathAndFileName) = "" Then
        Kill p_sPathAndFileName
    End If
   
    Dim lFree As Long: lFree = FreeFile
    Open p_sPathAndFileName For Binary As #lFree
    Put #lFree, , vContents
    Close #lFree

End Sub

Public Sub LoadSettings(p_frm As Form _
            , p_sPathAndFileName As String)

    On Error GoTo Oops
   
    If Dir(p_sPathAndFileName) = "" Then
        Exit Sub
    End If

    Dim vTemp As Variant
    Dim lFree As Long: lFree = FreeFile
    Open p_sPathAndFileName For Binary As #lFree
    Get #lFree, , vTemp
    Close #lFree

    Dim byteAry() As Byte
    byteAry = vTemp
    Dim pb As PropertyBag
    Set pb = New PropertyBag
    pb.Contents = byteAry
   
    On Error GoTo Bogus
   
    Dim s As String
    With pb
        Dim o As Control
        For Each o In p_frm.Controls
            If InStr(ReadTag(o.Tag, cnIGNORE_KEY), cnIGNORE_VALUE) = 0 Then
           
                If TypeOf o Is TextBox Then
                    s = pb.ReadProperty(o.Name)
                    o.Text = s
                ElseIf TypeOf o Is OptionButton Then
                    s = pb.ReadProperty(o.Name)
                    o.Value = s
                ElseIf TypeOf o Is DriveListBox Then
                    s = pb.ReadProperty(o.Name)
                    o.Drive = s
                ElseIf TypeOf o Is DirListBox Then
                    s = pb.ReadProperty(o.Name)
                    o.Path = s
                ElseIf TypeOf o Is CheckBox Then
                    s = pb.ReadProperty(o.Name)
                    o.Value = s
                ElseIf TypeOf o Is ListBox Then
                    If o.MultiSelect <> 0 Then
                        HighlightListboxMultiItems o, pb
                    Else
                        HighlightListboxItem o, pb.ReadProperty(o.Name)
                    End If
               
                ElseIf TypeOf o Is ComboBox Then
                    s = pb.ReadProperty(o.Name)
                    o.ListIndex = CLng(s)
                Else
                    'nop
                End If
            End If  '' InStr(ReadTag(o.Tag, cnIGNORE_KEY), cnIGNORE_VALUE) = 0 Then
           
            GoTo Continue
Bogus:
            ' 327 Property bag contains an element with a control name that is not on p_frm
            ' 68 Drive doesn't exist
            If Err.Number = 327 Or Err.Number = 68 Then
                Err.Clear
            Else
                GoTo Oops
            End If
Continue:
        Next
    End With
   
Exit Sub

Oops:
    Err.Raise Err.Number
End Sub

Private Function SelectedListboxMultiItems(p_lstBox As ListBox) _
                As String
   
    ' Returns pipe delimited string of selected items from a listbox
                   
    With p_lstBox
        If .MultiSelect <> 0 Then
            ' API Parameters - dont change the datatype
            Dim ItemIndexes() As Long
            Dim iNumItems As Integer: iNumItems = .SelCount
            ' end API Parameters
            Dim ii As Long
            Dim sReturn As String
       
            If iNumItems > 0 Then
                ReDim ItemIndexes(iNumItems - 1)
                SendMessage p_lstBox.hwnd, LB_GETSELITEMS, iNumItems, ItemIndexes(0)
       
                For ii = 0 To iNumItems - 1
                    sReturn = sReturn & .List(ItemIndexes(ii)) & "|"
                Next ii
       
                ' Remove trailing comma
                Dim lLenReturn As Long: lLenReturn = Len(sReturn)
                If lLenReturn > 0 Then
                    sReturn = Left(sReturn, lLenReturn - 1)
                End If
            End If
        End If
    End With

    SelectedListboxMultiItems = sReturn

End Function


Private Function SelectedListboxItem(p_lstBox As ListBox) _
                As String
   
    ' Returns item selected in a non-multiselect listbox
               
    Dim ii As Long
    Dim sReturn As String
    With p_lstBox
        For ii = 0 To .ListCount - 1
            If .Selected(ii) Then
                sReturn = .List(ii)
            End If
        Next ii
    End With
   
    SelectedListboxItem = sReturn

End Function

Private Function HighlightListboxItem(p_lstBox As ListBox _
            , ByVal p_sSelected As String)
           
    '    Compare members of listbox to p_sSelected.  Highlight (select) the matching one.
    'Works on non-multiselect listboxes

    Dim ii As Long
    For ii = 0 To p_lstBox.ListCount - 1
        If InStr(p_sSelected, p_lstBox.List(ii)) > 0 Then
            p_lstBox.Selected(ii) = True
        Else
            p_lstBox.Selected(ii) = False
        End If
    Next

End Function



Private Sub HighlightListboxMultiItems(p_lstBox As ListBox, pb As PropertyBag)

    '    Compare members of listbox to propertybag.  Highlight (select) the matching ones.
    ' Works on multi-select listboxes.
   
    With p_lstBox
        If .MultiSelect <> 0 Then
            ' for each item in the list
            On Error Resume Next
            Dim sProp As String
            Dim ii As Long, jj As Long
            For ii = 0 To .ListCount - 1
                ' for each potential property
                .Selected(ii) = False
                For jj = 0 To .ListCount - 1
                    sProp = ""
                    sProp = pb.ReadProperty(.Name & CStr(jj))
                    If .List(ii) = sProp Then
                        .Selected(ii) = True
                        Exit For
                    End If
                Next
            Next
        End If
        On Error GoTo 0
    End With

End Sub

Private Function ReadTag(ByVal p_sSource As String _
            , ByVal p_sKey As String) _
            As Variant
           
    '   Parse contents of control.tag, searching  for desired key and it's associated values.
    ' Expected format: <key>,<value>| ...
    '           eg  Color,black|
    '       Delimiters are hard coded.  Anyone else using .Tag better conform to these
    'conventions or we're hosed.
    '
    ' Returns comma delimited string <value>s for specified <key>
    '       Return = Empty if key not found or Key doesn't have associated <value>s
    '       Elements are one for each <value>
   
    On Error GoTo Oops
   
    Dim vReturn As Variant
   
    ' Split KeyValue pairs into array elements containing <key>,<value>[<value>,...]
    Dim vPairs_ As Variant: vPairs_ = Split(p_sSource, "|")
   
    If UBound(vPairs_) = -1 Then
        vReturn = Empty
    Else
        ' Search <key> portion for target key, if found return value(s)
        Dim i As Integer
        Dim iDelimCol As Integer
        For i = 0 To UBound(vPairs_)
            iDelimCol = InStr(vPairs_(i), ",")
            If iDelimCol = 0 Then
                vReturn = Empty
            Else
                '' The -2 in iDelimCol - 2 cuts off the + or - in the key
                If Trim(UCase(p_sKey)) = Trim(UCase(Mid$(vPairs_(i), 1, iDelimCol - 1))) Then
                    'vReturn = Mid$(vPairs_(i), iDelimCol - 1, 1) & "," & Mid$(vPairs_(i), iDelimCol + 1)
                    'vReturn = Mid$(vPairs_(i), iDelimCol + 1)
                    vReturn = Trim(Mid$(vPairs_(i), iDelimCol + 1))
                    Exit For
                End If
            End If
        Next
    End If
       
    ReadTag = vReturn
   
    Exit Function
   
Oops:

        Err.Raise Err.Number, TypeName(Me) & "::" & "ReadTag" _
                        & IIf(Erl = 0, "", ", at or after line " & CStr(Erl))
End Function

' ==== debug only
'Public Sub DebugPrintListOfControlNames(ByVal p_frm As Form)
'        Dim o As Control
'        For Each o In p_frm.Controls
'
'        Next
'End Sub
'







0
 
LVL 4

Expert Comment

by:HTorres
ID: 16532120

huh thats a lot of code.

maybe:

savesetting "myapp","config","lastvalue1", "1"
lastvalue = getsetting ("myapp","config","lastvalue1",defaultsetting)

will do the trick
0
 
LVL 4

Expert Comment

by:HTorres
ID: 16532136
save:
savesetting "myapp", "config","cbo1-lastvalue",me.combo1.listindex
savesetting "myapp", "config","cbo2-lastvalue",me.combo2.listindex
savesetting "myapp", "config","cbo3-lastvalue",me.combo3.listindex
savesetting "myapp", "config","cbo4-lastvalue",me.combo4.listindex

load:
combo1.listindex = getsetting("myapp","config","cbo1-lastvalue",-1
combo2.listindex = getsetting("myapp","config","cbo2-lastvalue",-1
combo3.listindex = getsetting("myapp","config","cbo3-lastvalue",-1
combo4.listindex = getsetting("myapp","config","cbo4-lastvalue",-1

hope this helps





0
 
LVL 9

Expert Comment

by:dancebert
ID: 16534517
>huh thats a lot of code.

Actually, thats a lot of reusable code.  No matter what form or what contents of that form, the code to save the settings is always the same:

Dim o As New cControlSettings
o.LoadSettings Me, "<filename>"

Using your method, every time one saves a setting, one has to hardcode a line of code for each control on each form.

It's obvious which one is easier to use.
0
 
LVL 4

Assisted Solution

by:HTorres
HTorres earned 400 total points
ID: 16534784
maybe if you put this in the procedure
...
...
Savedefaults()
...
...

or Getdefaults()

...

and in a module

Sub SaveDefaults()
savesetting "myapp", "config","cbo1-lastvalue",frmSome.combo1.listindex
savesetting "myapp", "config","cbo2-lastvalue",frmSome.combo2.listindex
savesetting "myapp", "config","cbo3-lastvalue",frmSome.combo3.listindex
savesetting "myapp", "config","cbo4-lastvalue",frmSome.combo4.listindex
end sub

Sub GetDefaults()
   frmSome.combo1.listindex = getsetting("myapp","config","cbo1-lastvalue",-1
   frmSome.combo2.listindex = getsetting("myapp","config","cbo2-lastvalue",-1
   frmSome.combo3.listindex = getsetting("myapp","config","cbo3-lastvalue",-1
   frmSome.combo4.listindex = getsetting("myapp","config","cbo4-lastvalue",-1
end sub

its 13 keys and some cut and paste.

hope this helps RyanBank

:)
0

Featured Post

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!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Suggested Courses

850 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