Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating/ Using custom defined types 1

Status
Not open for further replies.

claudebo

Programmer
May 17, 2002
8
US
I have created a type called :
Type userDefaults
userID as Integer
useraddress as string
userpermissions as string
End type

There is a login screen called frmlogin
in there is a function call to : Call getUserDefaults(Me!UserID)



The Module getUserDefaults looks like this:

Public Function getUserDefaults (UserID)
Dim dbs As Database
Dim rstUserIndex As Recordset
Dim CurrentuserDefault As userDefaults

Set dbs = currentdb
Set rstUserIndex= dbs.OpenRecordset(" SELECT * _
& "FROM tlbUserIndex " _
& " WHERE (tlbUserIndex.[UserID]=" & UserID & ");")

'User Defaults
CurrentuserDefault.userID = rstTownIndex!userID
CurrentuserDefault.useraddress = rstTownIndex!useraddress
CurrentuserDefault.userpermissions = rstTownIndex!userpermissions
rstTownIndex.close
end Function
'____________________________________________________
Ok, now the problem I want to be able to refer to the defined types in any form or module. It does not!

For example if I open the form : frmNewInvoice with the openevent :

Private Sub Form_Open(Cancel As Integer)
Dim UserStuff As userDefaults

Me!User = UserStuff.userID

Then Me!User has no value, why is it not pulling the userID value??

Does it have something to do with Private v. Public variables.

I'm stumbed!


Thanks in advance



 
If this is to work, you need a public udt - for instance declare it in the same module as you have your function to retrieve the information - AND - rename the module so it doesn't have the same name a s the funtion.

I e - in stead of declaring the type within the function, declare it at the top of the module

Public CurrentuserDefault As userDefaults

Then refer to your global CurrentuserDefault whenever you need the information.

I think I would consider the function to return the userdefaults in stead, which might also give you the possibility of making it "self-healing", should something occur that clears the content (unhandled error?).

Roy-Vidar
 
Here's an attempt at "self-healing" code, which in my eyes are better than globals, cause they will be reset on next usage. Should probably add some errorhandling etc.

You need to call it wherever it's needed, say with

[tt] Dim ud as UserDefaults

ud = getUserDefaults(42) ' a variable, I presume?
debug.print ud.userID, ud.userAddress, ud.userPermissions[/tt]

Using static on the udt, so it will retain the value.

[tt]Public Function getUserDefaults(ByVal lUserID As Long) As UserDefaults

Static CurrentUserDefault As UserDefaults
Dim rs As DAO.Recordset

If CurrentUserDefault.userID <> lUserID Then
Set rs = CurrentDb.OpenRecordset("SELECT * " & _
"FROM tblUserIndex " & _
"WHERE [UserID] = " & lUserID)
If rs.RecordCount Then
With CurrentUserDefault
.userID = rs.Fields("UserID").Value
.userAddress = rs.Fields("userAddress").Value
.userPermissions = rs.Fields("userPermissions").Value
End With
End If
rs.Close
Set rs = Nothing
End If
getUserDefaults = CurrentUserDefault

End Function[/tt]

BTW in the original code, you declare and open a recordset called rstUserIndex, but the one you try to assign from, is rstTownIndex.

Roy-Vidar
 
Thank you for the assistance!

I presume your statement "self-healing" mean that each time the a form needs one of these variables then the function “CurrentUserDefault.userID” gets used/updated.

I wanted to get away from pulling the data out of the tables each time a variable is because this program is
used most times on a server with multiple users. On
the assumption that this slows down the program and taxes
the network, maybe I’m wrong about that.

I tried:

Type userDefaults
userid As String
useraddress As String
userpermissions As String
End Type

Public CurrentuserDefault As userDefaults

Function getUserDefaults(userid2)
Dim dbs As Database
Dim rstUserIndex As Recordset


Set dbs = currentdb

Set rstUserIndex = dbs.OpenRecordset(" SELECT * " _
& " FROM tlbUserIndex" _
& " WHERE autoNum = " & userid2)

'User Defaults
CurrentuserDefault.userid = rstUserIndex!userid
CurrentuserDefault.useraddress = rstUserIndex!useraddress
CurrentuserDefault.userpermissions = rstUserIndex!userpermissions
rstUserIndex.Close
End Function


Then in the open form event

Private Sub Form_Activate()
Me!user = CurrentuserDefault.userid
Me!userper = CurrentuserDefault.useraddress
Me!useradd = CurrentuserDefault.userpermissions
End Sub
This did work, but I am using a global versus a continuous updated of Function “getUserDefaults(userid2)”


Is your suggestion about globals based on a ommm an
undocumented access feature or concern that
the “UserDefaults” values may change and therefore
the global would no longer be accurate.

One last thing what is the difference between
.”userID = rs.Fields("UserID").Value”
and
“CurrentuserDefault.useraddress = rstUserIndex!useraddress”

Great idea with the “If rs.RecordCount Then” saves
a lot of headaches and shows your experience..

your btw is right I wrote the original posting on the
fly and made a mistake.
The posting is for getting it to work, in real world
there is about 30 of these fields the are used in a
number of location in the program, hence the need to
pull then our readily versus dlookup, or query. Which
could tax the program/network needlessly.


Thanks again Claude
 
> I presume your statement "self-healing" mean that each time the a form needs one of these variables then the function "CurrentUserDefault.userID" gets used/updated.

By self healing, I mean that through the usage of a static variable to hold the information, the information is retained in this variable as long as the application is running, it will not collect this information more than once at startup.

This is mostly the same as using a public varible, but the difference is when you get an unhandled error.

This will reset any public variables, and you'll have to "start over" again, unless you've created code to handle it (i e, code to discover the loss of state/that it needs to be reinstantiated, and do that).

The beauty of a self-healing function, like the above, is that until an unhandled error occurs, it will act similar to a public variable, except you need to call it in each module or routine you need it.

Only if/when something occurs which resets the information, only then will it pull the information from the table again, but then without any fuzz, by itself, and there's no need to create any more code to test whether it still retains the value - if the information for some reason is lost, it will simply fetch them again ... self healing, no disturbance of program flow, no need to close the app and start again ;-)

You will probably not call it each time you need a variable from the udt, unless you fear a state loss inbetween two parts of the code, but dependent on whether you use module level udt variables or sub/function level udt variables, you'll call it at least once per form or sub/function.

I can't see where you're calling your function, though, but that probably has to be done at an early state (in the first form loaded?)

> One last thing what is the difference between
."userID = rs.Fields("UserID").Value"
and
"CurrentuserDefault.useraddress = rstUserIndex!useraddress"

One, I'm using a With block on the udt

[tt] With CurrentUserDefault
.userID = rs.Fields("UserID").Value
.userAddress = rs.Fields("userAddress").Value
.userPermissions = rs.Fields("userPermissions").Value
End With[/tt]

two reasons
1 - it's usually faster than using the full reference performacne wise (though I could probably have saved more using it on the recordset)
2 - it increases readability/maintainability of the code, I think

In VBE, place the cursor within the keyword "with" and hit F1 - the help file is probably better in explaining than me ;-)

The way of referencing the fields, is just preference.

Roy-Vidar
 
I agree with Roy's approach it is the same method I use most of the time. I can not imagines the following is a concern

I wanted to get away from pulling the data out of the tables each time a variable is because this program is
used most times on a server with multiple users. On
the assumption that this slows down the program and taxes
the network,

But going back to your original problem your function does not return anything but only defines a local variable to your function. If you wanted to use this you could do something like

Public Function getUserDefaults (UserID) as userDefaults
...

With getUserDefaults
.userID = ...
.userAddress = ...
.userPermissions = ...
End With

end function


Then call the function from somewhere.

dim currentDefaults as userDefaults
currentDefaults = getUserDefaults(UserID)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top