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 TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing Variables Between Function and Sub 4

Status
Not open for further replies.

ThomasLafferty

Instructor
Mar 14, 2005
549
US
I have a disabled textbox control that I would like to enable via a command button and a password form. As the available features in the database expand, I would like to be able to use the same password form over and over and just pass expected values via a function so that I don't have to write a password routine for every feature. The problem is that my variables expire when I close the password form. Here's what I have so far:
Code:
Public Sub btn_EnableTextBoxZoom_Click()
    Call InitPassword("frmWeighDetail", "z00m", False)
    If boolenablefeature = True Then
        Me.OriginalVals.Enabled = True
    Else
        Me.OriginalVals.Enabled = False
    End If
End Sub

Public Static Function InitPassword(StrObjIdentity, StrRequiredPassword, boolenablefeature As Boolean)
    boolenablefeature = False
    DoCmd.OpenForm "frmPassword"
End Function
Public Static Function CheckPassword(StrPassword As String)
    If StrTypedPassword = StrRequiredPassword Then
        boolenablefeature = True
    Else
        boolenablefeature = False
        MsgBox "Invalid password", vbInformation, "Access Denied"
    End If
End Function

I probably don't really need two functions. What I am attempting to do is use a global boolean variable which is initialized to false: boolEnableFeature.

The functions should allow me toggle that variable between true and false based on user input in the password form. Once everything works, I can lock down the forms so that design view is not allowed, and lock down the module where my public function(s) are stored so that they require password to view.

What am I doing wrong? (other than spaghetti code...) [smile]

Born once die twice; born twice die once.
 
Oops... I forgot to post the code behind my password form:
Code:
Public Static Sub btn_frmPassword_OK_Click()
On Error GoTo Err_btn_frmPassword_OK_Click
Dim StrTypedPassword As String

Me.txtPassword.SetFocus
StrTypedPassword = Me.txtPassword.Text
CheckPassword (StrTypedPassword)

DoCmd.Close

Exit_btn_frmPassword_OK_Click:
    Exit Sub

Err_btn_frmPassword_OK_Click:
    MsgBox Err.Description
    Resume Exit_btn_frmPassword_OK_Click
    
End Sub

Born once die twice; born twice die once.
 
The problem is that my variables expire when I close the password form
Use Global variables (and Public functions) in a standard code module.

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
change
Code:
'DoCmd.OpenForm "frmPassword"
[i]DoCmd.OpenForm "FrmPassword", , , , , acDialog[/i]
and change this
Code:
Public Static Sub btn_frmPassword_OK_Click()
On Error GoTo Err_btn_frmPassword_OK_Click
Dim StrTypedPassword As String

Me.txtPassword.SetFocus
StrTypedPassword = Me.txtPassword.Text
CheckPassword (StrTypedPassword)

'DoCmd.Close
[i]me.Visible = false[/i]
Exit_btn_frmPassword_OK_Click:
    Exit Sub

Err_btn_frmPassword_OK_Click:
    MsgBox Err.Description
    Resume Exit_btn_frmPassword_OK_Click
    
End Sub

add this
Code:
Public Static Function CheckPassword(StrPassword As String)
    If StrTypedPassword = StrRequiredPassword Then
        boolenablefeature = True
    Else
        boolenablefeature = False
        MsgBox "Invalid password", vbInformation, "Access Denied"
    End If
[i]docmd.Close acForm ,"frmPassword" ,acSaveNo [/i]
End Function
 
Thanks for the replies!
The modules are public, standard code modules except for the form module. It is declared as public, but is a form module nonetheless. By using msgbox statements, I have determined that the variable [!]StrRequiredPassword[/!] passes from the initial click to the first function call and then expires when I open the password form.

I tried the suggested changes, but when the Password form opens, StrRequiredPassword is an empty string. Here's the present form of my code:

Code:
Public Sub btn_EnableTextBoxZoom_Click()
[COLOR=green]'This part works to pass the variable StrRequiredPassword[/color]

    Call InitPassword("z00m")
[!]'Both variables now empty strings![/!]
    If boolEnableFeature = True Then
        Me.OriginalVals.Enabled = True
    Else
        Me.OriginalVals.Enabled = False
    End If
End Sub

These public functions are in a standard code module, not a form module:
Code:
Public Function InitPassword(StrRequiredPassword)
    boolEnableFeature = False
    MsgBox "Public Function initPassword StrRequiredPassword: " & StrRequiredPassword
[COLOR=green]'StrRequiredPassword carries over[/color]
    DoCmd.OpenForm "frmPassword", , , , , acDialog
End Function


Public Function CheckPassword(StrTypedPassword)
MsgBox "Public Function CheckPassword StrTypedPassword: " & StrTypedPassword
[COLOR=green]'Typed password carries over
MsgBox "Public Function CheckPassword StrRequiredPassword: " & StrRequiredPassword
[!]'StrRequiredPassword is an empty string![/!]
    If StrTypedPassword = StrRequiredPassword Then
        boolEnableFeature = True
    Else
        boolEnableFeature = False
        MsgBox "Invalid password", vbInformation, "Access Denied"
    End If
End Function
It didn't seem to matter if I merely hid the pasword form (Me.Visible = False) and then closed in another spot as suggested, but when I did that, I also got a message that I was referring to a form that was closed or didn't exist.

Gotta be close now... Thanks again!

Tom

Born once die twice; born twice die once.
 
Again, use global (ie Public) variables defined in the declarations section of the standard code module.
Tip: use the Option Explicit instruction

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
Hi PHV! I did declare my variables in the declarations section of the module, so maybe the problem is referencing them like this in the opening line of my functions

Public Function DoSomething([!]myVariable[/!])

End Function


Even though I delcared the variable in the declarations section of the module? I probably misunderstand what placing the variable in parenthesis on the same line as my Public Function statement does. I thought it meant that I was required to feed the function a value of some sort. By doing this, am I essentially redeclaring the variable?

I will try removing those references. Thanks!

Tom

Born once die twice; born twice die once.
 
Got it! Will post solution tomorrow. Thanks!

Born once die twice; born twice die once.
 
I think you are getting the concept of variable mixed up with that of parameter.

It seems you think that having a parameter with the same name as a global variable makes them the same thing. That is not the case (unless you passed in the global variable by reference to the subroutine - which you didn't do here).

I assume you have a module that has a declaration something like:
Code:
Public [COLOR=green]StrRequiredPassword[/color] As String

This is not the same thing as the parameter in the following:
Code:
Public Static Function InitPassword(StrObjIdentity, [COLOR=red]StrRequiredPassword[/color], boolenablefeature As Boolean)

A parameter in a subroutine or function is in essence a local variable. If a local variable happens to have the exact same name as a global variable (i.e. StrRequiredPassword), VB assumes you mean the local variable (StrRequiredPassword).

There is no where in your code that you are actually setting the global StrRequiredPassword variable.

For the sake of clarity, I would use a naming convention to distinguish global variable from others. I would make changes such as follows:
Code:
Public g_StrRequiredPassword As String
Public g_boolenablefeature As Boolean
Code:
[COLOR=green]'Note - I removed the parameter StrObjIdentity since it wasn't being used in the function[/color]
Public Static Function InitPassword(StrRequiredPassword As String, boolenablefeature As Boolean)
    g_StrRequiredPassword = StrRequiredPassword
    g_boolenablefeature = boolenablefeature
    DoCmd.OpenForm "frmPassword"
End Function

You would need to also change other code that uses the global variables.

 
How are ya ThomasLafferty
TheAceMan1 said:
[blue]One of the things I've noticed is that your changing event procedures from [purple]Private to Public![/purple] and using [purple]Static![/purple] . . . This is a very bad Idea! [purple]Immediately go back and change them to private, and remove static before you do anything else![/purple][/blue]
[green]Now that were back to normal (whew!) . . .[/green] I've read this thread several times and I keep seeing a bit of [blue]overkill[/blue]. Try this simpler solution.
[ol][li]In the [blue]declarations section[/blue] of a [blue]module[/blue] in the [blue]modules window[/blue] copy/paste the following:
Code:
[blue]Public flgPWD As Boolean[/blue]
[/li]
[li]In the [blue]same module[/blue] copy/paste the following function (this is the [green]main function[/green] you'll use to access the password form):
Code:
[blue]Public Function PWDOK([purple][b]pwdRef[/b][/purple] As String)
   DoCmd.OpenForm "frmPassword", , , , , acDialog, [purple][b]pwdRef[/b][/purple]
   [green][b]'Code stops here until frmPassword is closed!
   'flgPWD is set by frmPassword.[/b][/green]
   PWDOK = flgPWD
   flgPWD = False [green]'Reset[/green]
End Function[/blue]
[/li]
[li]Next, for the [blue]btn_frmPassword_OK[/blue] click event of frmPassword overwrite the code with:
Code:
[blue]   Dim Msg As String, Style As Integer, Title As String
   Dim DL As String, valComp
   
   DL = vbNewLine & vbNewLine
   
   [green]'Note: vbBinaryCompare below enables [b]Case Sensitivity[/b][/green].
   If StrComp(Me!txtPassword, Me.OpenArgs, vbBinaryCompare) = 0 Then
      flgPWD = True
      DoCmd.Close
   Else
      Msg = "PassWord is No Good!" & DL & _
            "Try again or close the form to continue . . ."
      Style = vbInformation + vbOKOnly
      Title = "You Tried But Couldn't Do It! . . ."
      MsgBox Msg, Style, Title
      Me.txtPassword.SetFocus
   End If[/blue]
[/li][/ol]
As an example of using the function:
Code:
[blue]Private Sub btn_EnableTextBoxZoom_Click()
   Me.OriginalVals.Enabled = PWDOK("z00m")
End Sub[/blue]

[blue]Your Thoughts? . . .[/blue]

Calvin.gif
See Ya! . . . . . .
 
AceMan - you always come through. I had managed to cobble together something which was working, but due to not checking the case of the password text, it would eventually been compromised. Also, being able to call the function with an elegant single line is sooo much better than what I was doing and right on the mark. Thanks again for weighing in with such good advice. [medal]

Tom

Born once die twice; born twice die once.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top