From: mp on

"Larry Serflaten" <serflaten(a)gmail.com> wrote in message
news:hvktq3$kv8$1(a)news.eternal-september.org...
>
> "mp" <nospam(a)Thanks.com> wrote
>
>> a very nice technique Thanks.
>> What i'm struggling with now is how to put the function in a utility.bas
>> module so i can use in all projects, then call it from any form. so
>> different forms can declare their own settings type and send them to the
>> same function in the utility module to read and save.
>> If i declare the settings type Private in the form, I cant' pass it to a
>> public module.
>> If I declare it Public I get the error can't do public type in private
>> module.
>> i remember seeing discussions here, but since i wasn't using udts I
>> didn't
>> pay attention
>> searching google now but if any one has the solution I"d appreciate it.
>> Thanks
>> Mark
>
>
> It seems to me each app would have its own options and user settings,
> based on the task the program performs.

yes, that's exactly the case, thank you!
so what's the solution for that...seems i have to duplicate the read/write
code in each project since i can't pass a udt from a form to a bas module

But there are some common
> values that could be saved (such as window placement) which would
> be common to many applications.

exactly - for that, the solutions offered work perfect - however, i'm trying
to solve the app specific data requirements...sounds' like there's no way
around duplication of code which goes against what i've learned from reading
(code in one place and one place only)

so every project needs a bas module which reads/writes the appspecific udt
which is hardcoded into that particular bas module - but the read write code
is the same, just the name of the udt is hardcoded??? is that the only
solution?
thanks
mark


> snip


From: Larry Serflaten on

"mp" <nospam(a)Thanks.com> wrote


> then all forms would just call that one universal read/write function in a
> utility.bas that is common to all projects.
>
> guess i can't do it like that....so i have to reproduce the read/write code
> in all projects that want to use that technique? or am i still missing
> something?

Where that method fails is that you cannot convert a private UDT to a
Variant or Object or any other generic type of variable. The read and
write code needs to know exactly what UDT is being written so it can
load and save the data correctly.

If many of your apps require settings such that you want some form
of reusable code, I would suggest you look at wrapping the settings
up in a class module. The read and write code would be in the class
module, but all the settings would be user definable
(Variants for ease of use).

You could then create one object for each form and the form itself
would define the setting names and values. Some of that code might
look like:

' In the form module ...
Private FormSettings As SettingsClass
Private Enum eSettings
FormLeft
FormTop
FormWidth
FormHeight
' ...
End Enum

' Upon loading the form....
Set FormSettings = New SettingsClass
FormSettings.ReadFile(Filename)
Me.Left = FormSettings.Values(FormLeft)
Me.Top = FormSettings.Values(FormTop)
.... etc.

'Upon Unloading the form
FormSettings.Values(FormLeft) = Me.Left
FormSettings.Values(FormTop) = Me.Top
' ...
FormSettings.SaveFile


The class code would just expose a Values property that is backed by
a dynamic array of Variants. Something like:

Private Data() as Variant

Private Sub Class_Initialize()
ReDim Data(0)
End Sub

Public Property Get Values(ByVal Index as Long) as Variant
If Index <= UBound(Data) Then
Values = Data(Index)
End If
End Property

Public Property Let Values(ByVal Index as Long, Value as Variant)
If Index > UBound(Data) Then
ReDim Preserve Data(Index)
End If
Data(Index) = Value
End Property


Using an Enum in the form makes for easier use and puts all the data
at specific indexes. The class could then just write the data out to the
file, one item per line (or some such method). The read method would
just be the reverse of the write method, all wrapped up in the class....

HTH
LFS


From: Mayayana on
| > Why would you have different instances of the
| > same settings UDT?
|
| because different projects have different forms with different things it
| might want to save
| (other than size and position which i realize are common to any form)
|

I mistakenly assumed that by form you
meant a single form in a multi-form project.
It sounds like you're using form and project
as synonyms -- dealing with multiple single-
form projects.

I use a .dat file myself because I have a lot of
settings to save, in several data types, in programs
with mulitple forms, and usually not per-user.

Since Vista/7 I've started designing my installer
to set permissions on a program folder subfolder
that I create during install.
I keep settings there, where everyone can read/
write. That way I can save all-user settings without
special permission requirements and at the same
time there's no compromise of system security.
It's turned out to be a good, extensible solution
for all Windows versions.

But it sounds like you have a less involved
requirement if you're looking to reuse the exact
same .bas module in all projects, with the exact
same UDT, and the projects are all similar 1-form
programs. If that's all you need, and if you don't
mind saving the data per-user, then why bother
with all the UDT rigmarole? I'd just use the
VB SaveSetting and GetSetting, and name each
seting "1", "2", etc.


From: mp on

"Larry Serflaten" <serflaten(a)gmail.com> wrote in message
news:hvlfj8$eo0$1(a)news.eternal-september.org...
>
> "mp" <nospam(a)Thanks.com> wrote
>
>
>> then all forms would just call that one universal read/write function in
>> a
>> utility.bas that is common to all projects.
>>
>> guess i can't do it like that....so i have to reproduce the read/write
>> code
>> in all projects that want to use that technique? or am i still missing
>> something?
>
> Where that method fails is that you cannot convert a private UDT to a
> Variant or Object or any other generic type of variable. The read and
> write code needs to know exactly what UDT is being written so it can
> load and save the data correctly.
>

exactamently
:-)

> If many of your apps require settings such that you want some form
> of reusable code, I would suggest you look at wrapping the settings
> up in a class module. The read and write code would be in the class
> module, but all the settings would be user definable
> (Variants for ease of use).

but then i lose that simplicity of the get and put on a udt
that was so short and sweet
:-)

>
> You could then create one object for each form and the form itself
> would define the setting names and values. Some of that code might
> look like:
>
> ' In the form module ...
> Private FormSettings As SettingsClass
> Private Enum eSettings
> FormLeft
> FormTop
> FormWidth
> FormHeight
> ' ...
> End Enum
>
> ' Upon loading the form....
> Set FormSettings = New SettingsClass
> FormSettings.ReadFile(Filename)
> Me.Left = FormSettings.Values(FormLeft)
> Me.Top = FormSettings.Values(FormTop)
> ... etc.
>
> 'Upon Unloading the form
> FormSettings.Values(FormLeft) = Me.Left
> FormSettings.Values(FormTop) = Me.Top
> ' ...
> FormSettings.SaveFile
>
>
> The class code would just expose a Values property that is backed by
> a dynamic array of Variants. Something like:
>
> Private Data() as Variant
>
> Private Sub Class_Initialize()
> ReDim Data(0)
> End Sub
>
> Public Property Get Values(ByVal Index as Long) as Variant
> If Index <= UBound(Data) Then
> Values = Data(Index)
> End If
> End Property
>
> Public Property Let Values(ByVal Index as Long, Value as Variant)
> If Index > UBound(Data) Then
> ReDim Preserve Data(Index)
> End If
> Data(Index) = Value
> End Property
>
>
> Using an Enum in the form makes for easier use and puts all the data
> at specific indexes. The class could then just write the data out to the
> file, one item per line (or some such method). The read method would
> just be the reverse of the write method, all wrapped up in the class....
>
> HTH
> LFS
>
>

so FormSettings.ReadFile would just read a text file, parse the lines with
split
and fill Data(n) accordingly?
that means i also have to cast strings to other datatypes if
req'd(longs,doubles,etc)
lots more code than one call to a get/put function :-)

that's basically what i'm doing now, just writing to a text file - that get
and put was just so sweet it got my hopes up
:-)

so i guess i can combine any or all of the below methods as fits the
situation.

use a standardized udt in util.bas for common form properties
use a generic SettingsClass to handle 'extended' form properties (if
primarily strings)
use an app specific udt for 'extended' form properties if lots of
typecasting is requ'd

your thoughts?
thanks
mark


From: Larry Serflaten on

"mp" <nospam(a)Thanks.com> wrote

> so FormSettings.ReadFile would just read a text file, parse the lines with
> split
> and fill Data(n) accordingly?
> that means i also have to cast strings to other datatypes if
> req'd(longs,doubles,etc)
> lots more code than one call to a get/put function :-)

No extra typecasting code, Print and Line Input work with Variants.
Your form sets the value, and Print sends it to the disk. Line Input
reads it back from the disk and sets the value, just like your form does.
Once you get the code working, you don't need to touch it again,
so what if it takes half a dozen more lines???


> so i guess i can combine any or all of the below methods as fits the
> situation.
>
> use a standardized udt in util.bas for common form properties
> use a generic SettingsClass to handle 'extended' form properties (if
> primarily strings)
> use an app specific udt for 'extended' form properties if lots of
> typecasting is requ'd

It really depends on what you're after. If you want a bas module,
you'll be stuck having to adjust and tweak it for every app that
has a unique setting. (meaning, you'd have multiple copies of that
module code, one file for each unique app) If you want to write it
once and use it forever, (as is), then the class method is what you
want.

Its your option...
LFS