UtterAccess.com
X   Site Message
(Message will auto close in 2 seconds)

Welcome to UtterAccess! Please ( Login   or   Register )

Custom Search
2 Pages V  1 2 >  (Go to first unread post)
   Reply to this topicStart new topic
> Global Declaring Issue, Access 2013    
 
   
gint32
post Apr 4 2019, 09:24 PM
Post#1



Posts: 368
Joined: 8-May 09
From: Australia


Seems like a silly question, so don't laugh I am trying to make a variable global which seems straight enough to most

I want the logged on user to remain the logged on user throughout the entire "ACCDB" or ACCDR, so I have read from heaps of sources that you just need to call it

so, I have tried inserting the below declaring but I get error when compiling and have no idea why!
CODE
Public loggedonuser As String = Environ("UserName")'''

or
CODE
Constant loggedonuser = Environ("UserName")


So my question ..is : where does the above need to reside (meaning where can I place this) so its available everywhere throughout the DB, or do I have to copy this into every form at the top of the code within "Microsofts Access Class Headers" or does it have to go into each header within each "Module", surely and hopefuly not and theirs a far simpler way that I can just insert it in one place.

Currently, I have to keep calling Call a Mod that I created from the code within each form. which I think is just not right!

thanks for reading smile.gif
This post has been edited by gint32: Apr 4 2019, 09:25 PM
Go to the top of the page
 
sumosoftware
post Apr 4 2019, 09:41 PM
Post#2



Posts: 33
Joined: 3-April 19



This is a basic example, please edit as required.

Global gUserName As String

Public Function setGlobalUserName()
gUserName = Environ("UserName")
End Function

You can place this in a separate module, maybe call it GlobalUtils and use where required.

This will allow you to access gUserName from anywhere, for example textbox0.value = gUserName, or perhaps make a function that returns gUserName which can also be used in other MS Access Objects.

Public Function getGlobalUserName()
getGlobalUserName = gUserName
End Function

Apologies for beginning method names with lower case, today I'm in javascript land.


Cheers.
This post has been edited by sumosoftware: Apr 4 2019, 09:48 PM
Go to the top of the page
 
gint32
post Apr 4 2019, 09:43 PM
Post#3



Posts: 368
Joined: 8-May 09
From: Australia


great where does it go to make avail to all forms..thanks
This post has been edited by gint32: Apr 4 2019, 09:43 PM
Go to the top of the page
 
sumosoftware
post Apr 4 2019, 09:49 PM
Post#4



Posts: 33
Joined: 3-April 19



just pop the code in a new code module, I like to place global declarations in a separate module just to be organized.
Go to the top of the page
 
gint32
post Apr 4 2019, 10:25 PM
Post#5



Posts: 368
Joined: 8-May 09
From: Australia


So back to my OP, do I have to call this from each form? or like I asked can this be placed just once and set at login or on opening of the accdb and remain a constant somehow.thanks
This post has been edited by gint32: Apr 4 2019, 10:27 PM
Go to the top of the page
 
sumosoftware
post Apr 4 2019, 10:33 PM
Post#6



Posts: 33
Joined: 3-April 19



Yep set gUserName once and this works across the whole app.

1. Set gUserName on login form or main form load event.

2. On another form load event, you could set a text box value. eg txtUserName = gUserName.

I hope that makes sense.

cheers.
This post has been edited by sumosoftware: Apr 4 2019, 10:37 PM
Go to the top of the page
 
gint32
post Apr 4 2019, 10:36 PM
Post#7



Posts: 368
Joined: 8-May 09
From: Australia


Will do and thanks, for the quick response.
Go to the top of the page
 
theDBguy
post Apr 4 2019, 10:36 PM
Post#8


UA Moderator
Posts: 76,820
Joined: 19-June 07
From: SunnySandyEggo


Hi. Pardon me for jumping in but if you’re using Environ(“Username”), then I don’t really see the need to use a variable other than maybe to save on typing more characters.

--------------------
Just my 2 cents... "And if I claim to be a wise man, it surely means that I don't know" - Kansas
Access Website | Access Blog | Email
Go to the top of the page
 
sumosoftware
post Apr 4 2019, 10:56 PM
Post#9



Posts: 33
Joined: 3-April 19



very true theDBguy as the username is very simple to evaluate and gint32 may be better of just calling Environ("UserName") where needed, but its also good to know how to declare something global for next time.
Go to the top of the page
 
gint32
post Apr 4 2019, 11:06 PM
Post#10



Posts: 368
Joined: 8-May 09
From: Australia


Sorry to be a pest, but after inserting as you suggested into a new module, I now get an error "ambiguous name detected" everywhere I use the variable such as the following:
CODE
MsgBox " User, " & loggedonuser & " Hey" , vbCritical, "SECURITY BREACH! Attempted by " & loggedonuser

This post has been edited by gint32: Apr 4 2019, 11:10 PM
Go to the top of the page
 
MadPiet
post Apr 4 2019, 11:13 PM
Post#11



Posts: 3,364
Joined: 27-February 09



Did you declare it somewhere else too? A global variable is visible EVERYWHERE in your application, so if you have another variable with the same name somewhere in your code, the compiler would flag it as an error. I suspect that you tried to declare the variable somewhere else and forgot to remove that code. I would open a code module and then search all the modules for that variable name. If you find that the variable has been declared elsewhere, delete the other instances of it.
Go to the top of the page
 
gint32
post Apr 4 2019, 11:18 PM
Post#12



Posts: 368
Joined: 8-May 09
From: Australia


thanks very much for your help, I do a search and get back..
Go to the top of the page
 
gint32
post Apr 4 2019, 11:27 PM
Post#13



Posts: 368
Joined: 8-May 09
From: Australia


I done a find and replace for all instances of :

CODE
loggedonuser = Environ("UserName")

and replaced with
CODE
' loggedonuser = Environ("UserName")

and same with
CODE
dim loggedonuser as string

with
CODE
'dim loggedonuser as string


I still get the same error message, any other reasons this maybe happening

Go to the top of the page
 
gint32
post Apr 5 2019, 12:05 AM
Post#14



Posts: 368
Joined: 8-May 09
From: Australia


QUOTE
re-dbguy.. using Environ(“Username”),


You can imagine I have heaps of variable I wish to be global, so I wish to put these in just one time, but by the looks of it, I can't even get that one sorted. So, so far if I cant resolve one then I don't have much chance of the getting the rest if I cant get this one sorted.

so I need suggestions as to why I get this error ambiguous, especially if it not declared elsewhere as tis is the case here.
Thanks
This post has been edited by gint32: Apr 5 2019, 12:06 AM
Go to the top of the page
 
sumosoftware
post Apr 5 2019, 12:46 AM
Post#15



Posts: 33
Joined: 3-April 19



Try from the vba window menu clicking Debug > Compile. This will usually tell you where you have code issues throughout your vba.

I'm sure you'll work it out, good luck.
Go to the top of the page
 
gint32
post Apr 5 2019, 01:07 AM
Post#16



Posts: 368
Joined: 8-May 09
From: Australia


QUOTE
try VBA Compile.

thanks this is what I have done and it stops at and highlights "loggedonuser" on the line below : with ambiguous error
CODE
MsgBox " User, " & loggedonuser & " Hey" , vbCritical, "SECURITY BREACH! Attempted by " & loggedonuser
Go to the top of the page
 
isladogs
post Apr 5 2019, 04:05 AM
Post#17


UtterAccess VIP
Posts: 1,879
Joined: 4-June 18
From: Somerset, UK


Suggest you make a backup then do a global search for all existing variations of username as listed in your last post...then delete them.
Then you need to save your global variable/constant in the declarations section of a standard module.
Do a debug compile as a final check

As your loggedonuser will be a text string, you need text delimiters in your message box code

--------------------
Colin (Mendip Data Systems)
Website, email
Go to the top of the page
 
AlbertKallal
post Apr 5 2019, 10:54 AM
Post#18


UtterAccess VIP
Posts: 2,898
Joined: 12-April 07
From: Edmonton, Alberta Canada


Ok,

Your global declare is to be placed in a standard code module (not a forms or report code module, but a standard code module).

You code module like will have this:

CODE
Option Compare Database
Option Explicit

Public loggedonuser     As String


The above is all you need. However, on application start-up, your code will now have to set the variable to some text. And again, you in general only need to do this one time at startup (perhaps in your first form that is set to load on startup).

Now, in any form that you are having that ambiguous error? Well, this means + suggests you by accident declared the variable again.

So, to help track down this error, then when you do the debug->compile in the VBA editor, and get that erorr? I now strong suggest you go to the top of that module (you are likely in a forms code module), and check the settings:

You have either this:

CODE
Option Compare Database

+ a whole bunch  more code follows



Or

This:

CODE
Option Compare Database
Option Explicit

+ a whole bunch more code follows


The use of Option explicit is VERY (but I mean very very very) recommend here. This option forces you as you write code to ALWAYS declare your variables that you use. If you don’t do this, then at any point in code you can simply type

Myzoozoo = "Hello"


What access will do is NOW create on the fly that variable for you, and it has now been created. Needless to say, this can be BEYOND confusing, since you can by accident create many variables at any and all times. And THEN you don’t know if the variable you are about to use has been already created and used elsewhere. (it becomes a un-mitigated mess).

So it becomes rather hard to know if a variable you are using or about to use was already created + used in some other place by accident.

So, without option explicit in ALL of your code modules, then you lose complete control of when Access can and will create variables for you.

The default in Access is to NOT insert an option Explicit at the top of each code module for you automatic. You can change this default behaviour when in the VBA editor going

Tools->options.

On the Editor tab, check this box:

[x] Require Variable Declaration


Note that this setting DOES NOT touch or change existing code modules, but is only a “convenience” setting for WHEN you create new forms, or reports or code modules, it will simply insert that extra line of code for you.

It is a BEYOND good habit.

One other thing to check:

Ensure that you added a standard code module, and NOT a class module to place your global variable declare (and perhaps a few functions also can over time be placed in that code module.

You can NOT use a forms code module for this, it MUST be a standard code module (and not a class module).

In fact, once you fix your issue, then I would suggest you add this to your code module above:

CODE
Option Compare Database
Option Explicit

Public loggedonuser     As String


Public Function MyUser() As String

   MyUser = loggedonuser
  
End Function


The reason why I suggest adding the above “helper” function is that you can ONLY use + show a VBA variable by using code. So if say on each form at the top, you wanted to display the logged on user variable (name), then you have two choices:

In the forms on-load event, your code has to stuff (set) the value of some un-bound text box in code.

A text box cannot DIRECTLY display the value of a VBA variable, you MUST use code.

However, a textbox can be set DIRECTLY to use a VBA function!

What this means, in place having to write code in every single form, or every single report, you can simply place a text box on that form, and for the data control source set it to that helper function.

Normally a text box is “bound” to the underlying record source but you can also choose to bind a text box to a function (a global function).


So, for the data source of the text box, you can type in this:


=MyUser()

Now, you can cut + paste this text box from that form into any other form (or report), and you don’t need to write code. And you can place this text box even on reports, and again no code required.

Because your plan + goal is to display this global variable in “many many” places, then writing that helper function will allow you to display the logged on user without having to write any code for each new form or report that you create.

If this was just to display some variable ONE time in one place,then you would not go to all that trouble to build that helper function.

However before you build and adopt the helper function, I STONG suggest you fix and hunt down your duplicate variable name issue(s).

When you do a debug.compile and get that error, then go to the top of the form, and add the option explicit to that form’s code (or standard code module), and then try compiling again.

Use of option explicit will help you by leaps and bounds find this error, and I willing to be you never create another application without using Option Explicit to save you all this hassle and time you are having.

Regards,
Albert D. Kallal (Access MVP 2003-2017)
Edmonton, Alberta Canada
Go to the top of the page
 
gint32
post Apr 5 2019, 06:35 PM
Post#19



Posts: 368
Joined: 8-May 09
From: Australia


QUOTE
Your global declare is to be placed in a standard code module (not a forms or report code module, but a standard code module).


Perfectly detailed explanation and now it all makes sense, so thank you very much I will get to work on it asap..(and thanks to all )
Go to the top of the page
 
TenaciousCoder
post Apr 7 2019, 05:09 PM
Post#20



Posts: 6
Joined: 25-October 13



I just skim-read this thread and I’m blown away with the level of knowledge in the responses. So I’m somewhat reluctant to share what I discovered a long time ago about using global variables, but on the off chance that it may help here, or perhaps help someone else wrestling with global variables, I’ll risk looking dumb and share the tip I picked up.

For some long ago forgotten reason, I read that storing values in global variables can be risky under certain conditions and that it is better to create a dedicated, always-loaded form, with fields to hold globally available values. The form is loaded when the db is opened and hidden permanently from view. I’ve been using this method for years now to work around using global variables. While I’ve created some fairly complex apps over the years, I still consider my code to be somewhat spaghetti-like and no way near professional grade, but solid enough to get the job done.

Here is what I use in the On Load event of whatever main form I open first:

Private Sub Form_Load()
On Error GoTo Err_Form_Load

'Open the form to hold global variables in lieu of using system global variables
DoCmd.OpenForm "gvars", , , , , acHidden

I know it is crude, but effective!
Go to the top of the page
 
2 Pages V  1 2 >


Custom Search


RSSSearch   Top   Lo-Fi    7th December 2019 - 07:14 AM