Kill the hidden form trick (1 Viewer)

Moniker

VBA Pro
Local time
Today, 00:47
Joined
Dec 21, 2006
Messages
1,567
I've seen a lot of people here describe the use of a hidden form with information stored on it that can be accessed by other forms. While it's functional, it's clumsy and referencing it from various other areas can become a syntactical test for the best of us.

In that light, I'm offering what I think is a better solution.

Create a table called t_SystemSettings (or something similar). In this table, you are going to store whatever data elements you will need throughout the life of the DB. This can be a user ID, start date, stop date, version number, or whatever else you need to carry. This is an especially useful method for passing values to other forms or reports. There's only going to be one record in here, so make your field names specific to their function.

To get information from this table, make a simple function like this:

Code:
Function GetSettings (settingname As String) As String

    GetSettings = DLookUp(settingname,"t_SystemSettings")

End Function

Now, depending on what you've stored there, you can easily identify this code in your program because it will be obvious things like GetSettings("UserID") or GetSettings("Start_Date"). In the long run, this makes maintenance very easy, and it's much cleaner than something like UserID = Forms!Form("your_hidden_form_name").FieldName.

To write to the table, make another one line subroutine like this:

Code:
Sub SetSettings(settingname as String, settingvalue as String)

    CurrentDb.Execute "UPDATE t_SystemSettings SET " & settingname & "='" & settingvalue & "';"

End Sub

Note that using CurrentDb.Execute automatically disables and then reenables the warning messages (I.e., you won't get the "You are about to update 1 row in t_SystemSettings. Are you sure?"). It's the equivalent of SetWarnings Off, run query, SetWarnings On.

Now, to write a setting, just code it like SetSettings("UserID", environ("username")).

I believe you'll find that a method like this is cleaner and simpler to use than the hidden form method. I am, of course, open to suggestions or revisions to this method, so feel free to tear it apart or utilize it or whatever else you'd like to do. :)
 
Last edited:

pbaldy

Wino Moderator
Staff member
Local time
Yesterday, 22:47
Joined
Aug 30, 2003
Messages
36,133
Won't that UPDATE query fall over on a date field? Might handle a numeric value, even with the single quotes, but I'm not so sure about a date.
 

pbaldy

Wino Moderator
Staff member
Local time
Yesterday, 22:47
Joined
Aug 30, 2003
Messages
36,133
Never mind; I tested and it seems to work okay.

Mental note; test, THEN reply. :rolleyes:
 

Moniker

VBA Pro
Local time
Today, 00:47
Joined
Dec 21, 2006
Messages
1,567
lol... ;)

I've been using the method I described for a few years now. It's pretty well tested. Still though, I'm not proclaiming it as the best method, just as a cleaner alternative to the hidden form.

Also note that you can alter SetSettings easily to handle various data types if you do run into issues:

Code:
Sub SetSettings(settingname as String, settingvalue as String, settingtype as String)

    Select Case settingtype
        Case "text" 
            CurrentDb.Execute "UPDATE t_SystemSettings SET " & settingname & "='" & settingvalue & "';"
        Case "number"
            CurrentDb.Execute "UPDATE t_SystemSettings SET " & settingname & " =  & settingvalue & ";"
        Case "date"
            CurrentDb.Execute "UPDATE t_SystemSettings SET " & settingname & " = "#" & settingvalue & "#;"
        Case Else
    End Select

End Sub
 
Last edited:

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 00:47
Joined
Feb 28, 2001
Messages
27,321
For a multi-user FE/BE environment in which these hypothetical multiple users are on different platforms, if any of the table settings would differ from one platform to another, the last user thereof would win. Therefore, a careful eye to design is important.

If the "hidden table" happens to be in the FE, no problem. It is just a little trickier to keep one table in a FE and the rest in a BE. One nice thing about having such data in a table is persistence across activations.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 06:47
Joined
Sep 12, 2006
Messages
15,710
why not store what you need for a session in global variables?

There seems to be a presumption against using them, but i don't see the difference between global vars and a local table - except that the syntax is easier with the variables.

i sometimes save vars in the registry between sessions, which also works great.
 

Moniker

VBA Pro
Local time
Today, 00:47
Joined
Dec 21, 2006
Messages
1,567
Global variables are okay in some situations, but using a local table stores the information from session to session.

For example, If you're trying to run an ad-hoc quarterly report, you may enter 10/1/06 as your start date and 12/31/06 as your end date to get the fourth quarter of 2006. By storing that information in a local table, the start date and end date variables stay the same and are there each time you go to run the reports. If you store the information in a global variable, the data is lost each time the DB is closed and reopened.

This is also good for when you are storing options. For example, you may have a form dialog where a user can check various options by using checkboxes. When stored in a local table, these variables are stored and remain constant until changed. With global variables, the user would have to go check/uncheck the options he wants each time the DB was closed and reopened (usually a daily thing).

I do agree that some have really come out against the use of global variables, but they are useful in certain situations and I do use them. I just wouldn't use them in this situation because of things like the examples I provided.
 

MarkK

bit cruncher
Local time
Yesterday, 22:47
Joined
Mar 17, 2004
Messages
8,187
For system settings I use a class module with custome Property Get and Let procedures that read from and write to a settings table. Instantiating the class offers intellisense on all the properties so I don't have to remember any names. I find this very handy when coming back to a system I haven't worked on in a while.
Code looks like...
Code:
  Dim csts As New cSetting
  MsgBox csts.
...and as soon as you hit the period intellisense lists the setting names.
 

MarkK

bit cruncher
Local time
Yesterday, 22:47
Joined
Mar 17, 2004
Messages
8,187
What I don't like about globals is you can't be sure what processes produce or consume their values. I inheritted a system that used globals profusely and following the code was ridiculous. Everything was so ad-hoc. That said, I do expose one important global property...
Code:
Private m_dbs As DAO.Database

Public Property Get dbs As DAO.Database
  If m_dbs Is Nothing Then Set m_dbs = CurrentDb
  Set dbs = m_dbs
End Property
This provides a system-wide, always-on reference to the CurrentDb. If I use globals I only use properties, which, when debugging allows you to set a breakpoint and figure out who's consuming the data.
 

Users who are viewing this thread

Top Bottom