Results 1 to 11 of 11

Thread: [RESOLVED] A PropertyBag issue

  1. #1

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    397

    Resolved [RESOLVED] A PropertyBag issue

    Hi all,
    I try to store 8 strings in a small database and these strings are actually some distribution lists for email. When I have written these strings in the Distribution.dat file everything goes well and also all could be loaded properly via ReadProperty method. The issue occurs when I try to change a certain string (property) of the group already stored. Below is my code:
    Code:
     Dim objBag As PropertyBag
        Set objBag = New PropertyBag
        With objBag
            .WriteProperty "CenterTO", toList1, vbNullString
            .WriteProperty "CenterCC", ccList1, vbNullString
            .WriteProperty "NEstTO", toList2, vbNullString
            .WriteProperty "NEstCC", ccList2, vbNullString
            .WriteProperty "NVestTO", toList3, vbNullString
            .WriteProperty "NVestCC", ccList3, vbNullString
            .WriteProperty "SudTO", toList4, vbNullString
            .WriteProperty "SudCC", ccList4, vbNullString
         SaveContents .Contents, App.Path & "\Distribution.dat"
        End With
        Set objBag = Nothing
    
    Private Sub SaveContents(Contents As Variant, FilePath As String)
        Dim FileNum As Integer
             FileNum = FileSystem.FreeFile()
        Open FilePath For Binary As FileNum
             Put #FileNum, , Contents
        Close FileNum
    End Sub
    The question is : Could I modify only one property (let's say "CenterCC") without to re-write all other? Because when I try to do this each time the new string remains stored properly but all other strings stored previously disappear ...Thank you in advance.
    Last edited by Daniel Duta; Sep 23rd, 2014 at 04:55 AM.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: A PropertyBag issue

    Calling the .WriteProperty() method does not erase the rest of the values in the PropertyBag. If it did you could never store more than one property in one!

    I suspect you simply have a bug in your code, but you haven't shown us enough of it to know where you may have gone wrong.


    PropertyBags are not magical creatures though. If you create a new empty PropertyBag, set a value for one property, and write the Contents over an existing Contents file on disk then of course you wipe out everything else.

  3. #3
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: A PropertyBag issue

    Quote Originally Posted by Daniel Duta View Post
    The question is : Could I modify only one property (let's say "CenterCC") without to re-write all other? Because when I try to do this each time the new string remains stored properly but all other strings stored previously disappear ...Thank you in advance.
    No. Your property bag is a New instance; therefore, nothing pre-existing to update
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  4. #4

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    397

    Re: A PropertyBag issue

    First of all I am honored to be within this thread with two of the greatest contributors of this forum.
    Quote Originally Posted by dilettante View Post
    I suspect you simply have a bug in your code, but you haven't shown us enough of it to know where you may have gone wrong.
    I suspect also I have a bug in the Load and Save Content procedures...From this reason I attached a small example regarding what I intend to do.
    Quote Originally Posted by LaVolpe
    No. Your property bag is a New instance; therefore, nothing pre-existing to update
    My intention is to modify only one property (never more than one), overwriting an old one but keeping all other properties. Maybe a possibility would be to create a file with each specific property on a certain row. In other news, I am glad to see you again in the community though I didn't understand why you stayed away in recent years.
    Attached Files Attached Files

  5. #5
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: A PropertyBag issue

    Maybe a property bag isn't the best solution here? In order to update a single entry in the pbag. You'll have read the contents, then rewrite the pbag. Have you considered using an INI type file? APIs can update, insert, delete single entries or groups.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    397

    Re: A PropertyBag issue

    I have not considered an INI file or other methods based on API functions because I feel the solution should be a little bit easier. The first thing I have in mind is to try an approach considering the UDT arrays. I will keep you informed with my first results. Thanks.

  7. #7
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: A PropertyBag issue

    Yep, many ways to persist data. The pbag can actually be accessed, parsed, and written by hand, but that may be more work than it's worth
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: A PropertyBag issue

    I wouldn't put myself in LaVolpe's category, I've just been doing this off and on for a long time.

    Quote Originally Posted by LaVolpe View Post
    In order to update a single entry in the pbag. You'll have read the contents, then rewrite the pbag. Have you considered using an INI type file? APIs can update, insert, delete single entries or groups.
    Those APIs do things far uglier than simply loading the PropertyBag, updating it, and writing it back to disk.

    They have to lock the file because they must be atomic updates. Then they load and parse the entire file's contents carefully preserving comments, deal with potential registry mapping, then change or insert a value, and reassemble the pieces and write them back out, finally trimming the file as required and unlocking it.

    And all of that is done separately for each single value change you make.

    Why are INI files deprecated in favor of the registry? goes into some of the reasons why INI files are bad, m'kay? Note how Raymond always refers to them in the past tense there.


    I can't think of any built-in VB6 or Windows key-value store object that offers minimal-touch random access updates to its persistance format on disk. And if you are using this as some sort of "address book" surely you need more? The PB gives you a single unindexed record and once you have a second entry you need two, 100 entries you need 100 of them, and so on.

    Why not just bite the bullet and use a Jet MDB instead?

  9. #9
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: A PropertyBag issue

    A quite elegant way to handle this, would be over a Class which offers the Field-Props -
    then using an Private UDT as the 'm'-Variable for the internal state of the Properties.

    In the Class the Save and Load-Routines would become very simple then:
    Code:
    Option Explicit
    
    Private Type mT
      CenterTO As String
      CenterCC As String
      NEstTO As String
      NEstCC As String
      NVestTO As String
      NVestCC As String
      SudTO As String
      SudCC As String
    End Type
    
    Private m As mT
    
    Public Sub Load(FileName As String)
    Dim FNr As Long: FNr = FreeFile
      Open FileName For Binary As FNr
        Get FNr, , mT
      Close FNr
    End Sub
    
    Public Sub Save(FileName As String)
    Dim FNr As Long: FNr = FreeFile
      Open FileName For Binary As FNr
        Put FNr, , mT
      Close FNr
    End Sub
    And the rest is just a bit of copy&paste, to make Properties which
    in turn access the m.Variables contents (even with intellisense).

    You can then decide freely, if you want to call the Save-Routine
    directly in the Property Let (on each single change) - or if you
    perhaps could live with Saving/Loading in Class-Terminate/Initialize.

    Code:
    Public Property Get CenterTO() As String
      CenterTO = m.CenterTO
    End Property
    Public Property Let CenterTO(NewValue As String)
      m.CenterTO = NewValue
    End Property
    
    Public Property Get CenterCC() As String
      CenterCC = m.CenterCC
    End Property
    Public Property Let CenterCC(NewValue As String)
      m.CenterCC = NewValue
    End Property
    
    Public Property Get NEstTO() As String
      NEstTO = m.NEstTO
    End Property
    Public Property Let NEstTO(NewValue As String)
      m.NEstTO = NewValue
    End Property
    
    Public Property Get NEstCC() As String
      NEstCC = m.NEstCC
    End Property
    Public Property Let NEstCC(NewValue As String)
      m.NEstCC = NewValue
    End Property
    
    Public Property Get NVestTO() As String
      NVestTO = m.NVestTO
    End Property
    Public Property Let NVestTO(NewValue As String)
      m.NVestTO = NewValue
    End Property
    
    Public Property Get NVestCC() As String
      NVestCC = m.NVestCC
    End Property
    Public Property Let NVestCC(NewValue As String)
      m.NVestCC = NewValue
    End Property
    
    Public Property Get SudTO() As String
      SudTO = m.SudTO
    End Property
    Public Property Let SudTO(NewValue As String)
      m.SudTO = NewValue
    End Property
    
    Public Property Get SudCC() As String
      SudCC = m.SudCC
    End Property
    Public Property Let SudCC(NewValue As String)
      m.SudCC = NewValue
    End Property
    Olaf

  10. #10

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    397

    Re: A PropertyBag issue

    Quote Originally Posted by dilettante View Post
    Why not just bite the bullet and use a Jet MDB instead?
    In my particular case I just want to keep in control 8 strings and for this purpose to use a MDB seems to be a heavy solution. The Olaf's approach is closest to the mine and I consider - after those dedicated functions GetSetting-SaveSetting that work with registries - an UDT array remains the most straightforward approach when we need to handle (store and update) indexed entries.
    Below is my tested code that could be useful to other who have similar needs. Thank you all.
    Code:
    Option Explicit
    
    Private Type Settings
        myProperty As String
    End Type
    
    Private getSetting() As Settings
    Private myBase As String
    
    Private Sub Form_Load()
        ReDim getSetting(3) 'depending on how many entries you want
        myBase = App.Path & "\BinaryBase.dat"
        Call cmdOpen
    End Sub
    
    Private Sub cmdOpen()
        Open myBase For Binary As #1
        Get #1, , getSetting 'Fill getSetting array from file
        Close #1
        Call UpdateControls
    End Sub
    
    Private Sub UpdateControls()
        Dim i As Byte
        For i = 0 To UBound(getSetting) 'Populate controls with loaded data
            Text(i).Text = getSetting(i).myProperty
        Next i
    End Sub
    
    Private Sub cmdSave(Index As Integer)
        getSetting(Index).myProperty = Text(Index).Text
        Open myBase For Binary As #1
            Put #1, , getSetting 'Write the new property
        Close #1
    End Sub
        
    Private Sub Text_LostFocus(Index As Integer)
        Call cmdSave(Index) 'When the control lost focus we save the content
    End Sub
    Attached Files Attached Files

  11. #11
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,393

    Re: [RESOLVED] A PropertyBag issue

    After encountering this issue myself recently I also found out the hard way that the ".WriteProperty" method does not overwrite previously saved values in a property bag. However, the ".Contents" byte array can be overwritten!

    So if you only need to change the value of one or a couple of saved properties then you could look inside the byte array at the appropriate index and modify the saved values in there and then simply overwrite the whole array in the ".Contents" property.

    Hope this helps.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width