Centralizing Code for Form Buttons in a Module (1 Viewer)

Isaac

Lifelong Learner
Local time
Today, 02:33
Joined
Mar 14, 2017
Messages
8,738
I'd agree, but if someone has given you a form class to to just that, I'd be more than happy to use it.?
I have started using @MajP 's FAYT classes. I do not need to know how they work, just that they do work, and work very well.
What I would call 'black box' routines.?

If arnelgp has created a Form class for the o/p that they can just use, then that is going to save them a lot ot time, as it will just work.?

I must admit, this is one of those times, that just handing out a fish works. :D
I respect your positions and respectfully disagree. #1 I never deploy code that I don't personally understand, and could explain and troubleshoot if something goes wrong. #2 I know he likes classes and the more advanced stuff, and I greatly respect his skill, second to none--but that is HUUUUGE overkill in this instance, and I personally feel that deploying such a thing to someone less experienced is not doing them any favors. I guess we are different - I hate the idea of having any black box routine in my toolset, it seems dangerous to deploy something I cannot truly own. But mostly because it's an extreme form of overkill just for a few common and routine form commands...
I will stop now because I sense myself going into overdrive on this and truly, I respect your position. Carry on, I've said my piece. The OP will decide if they want something simple or more complex.
 

Isaac

Lifelong Learner
Local time
Today, 02:33
Joined
Mar 14, 2017
Messages
8,738
I would say that 99.99% of the time, it is because the member does not know better.?
However that should not stop them being 'advised' of cross posting.?

Another member on that other forum is already trying to help?
As you have stated that, I agree.
 

Gasman

Enthusiastic Amateur
Local time
Today, 09:33
Joined
Sep 21, 2011
Messages
14,037
I respect your positions and respectfully disagree. #1 I never deploy code that I don't personally understand, and could explain and troubleshoot if something goes wrong. #2 I know he likes classes and the more advanced stuff, and I greatly respect his skill, second to none--but that is HUUUUGE overkill in this instance, and I personally feel that deploying such a thing to someone less experienced is not doing them any favors. I guess we are different - I hate the idea of having any black box routine in my toolset, it seems dangerous to deploy something I cannot truly own. But mostly because it's an extreme form of overkill just for a few common and routine form commands...
I will stop now because I sense myself going into overdrive on this and truly, I respect your position. Carry on, I've said my piece. The OP will decide if they want something simple or more complex.
Isaac,
I know where you are coming from. :)

I spent a good deal of time for me and messages, yesterday pushing a member to amend the code themselves, rather than just hand over amended code for that reason. That to me was not a 'black box' situation, and certainly assistance would be unlikely from whoever created it, it was that old. It It did however show some neat techniques. :D

I have noticed that if one does hand over a piece of code and the o/p uses it, they do tend to come back and ask for something else, rather than try and do it themselves. After all that is the easiest path?

I have seen on here where a memeber has been on the forum for over 3 years with over 500 posts and just comes back and asks what I believe to be a simple question, that could so be easily answered via Google, which is where I get a lot of the answers I supply to members if I do not know the answer offhand, which tends to be alot of the time. :) Just asking here however, is so much easier?

Perhaps one of the moderators (new or otherwise) might want to lock this soon? :)
 

Gasman

Enthusiastic Amateur
Local time
Today, 09:33
Joined
Sep 21, 2011
Messages
14,037
Well I almost set fire to the kitchen, whilst composing that post. my memory is so bad. :(
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 05:33
Joined
Feb 19, 2002
Messages
42,970
I do this for certain events. I do not use a custom class. I use a standard module. I pass in a reference to the form to make it work.
Code:
Public Sub CommonClose(frm As Form)
On Error GoTo ErrProc
    If bForceClose = True Then
        Exit Sub        'do not run close code
    End If
    If frm.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
    If IsNull(frm.OpenArgs) Then
        DoCmd.OpenForm "Switchboard"
    Else
        DoCmd.OpenForm frm.OpenArgs
    End If
    
    bForceClose = False     'reset variable
ExitProc:
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 2102   'bad open args form name
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
    End Select
End Sub
Public Sub CommonReturn(frm As Form)
On Error GoTo ErrProc
    If frm.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
    DoCmd.Close acForm, frm.name
ExitProc:
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 3709, 3021, 2501  'caused when save is cancelled
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
    End Select
End Sub

Public Sub CommonSave(frm As Form)
On Error GoTo ErrProc
    If frm.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
ExitProc:
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 3709, 3021, 2501, 3071  'caused when save is cancelled
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
            Resume Next
    End Select
End Sub

Public Sub CommonExit(frm As Form)

On Error GoTo ErrProc
    If frm.Dirty Then
       DoCmd.RunCommand acCmdSaveRecord
    End If
    
    DoCmd.Close acForm, frm.name, acSaveNo
ExitProc:
    
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 3709, 3021, 2501, 3071, 3270  'caused when save is cancelled
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case 2046       'can't save record
            frm.Dirty = False
            DoCmd.Close acForm, frm.name, acSaveNo
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
            Resume Next
            
            
    End Select
End Sub

The code is called this way:

Code:
Private Sub Form_Close()
    Call CommonClose(Me)
End Sub
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 04:33
Joined
Feb 28, 2001
Messages
26,996
Hey, guys.... a little politeness, please. We've totally hijacked the thread.
 

Isaac

Lifelong Learner
Local time
Today, 02:33
Joined
Mar 14, 2017
Messages
8,738
Hey, guys.... a little politeness, please. We've totally hijacked the thread.
On the whole discussion of cross posting, point taken - and I apologize for having contributed to that as of late. I shouldn't have barged in.
On the discussion of whether to use a custom class to close a form - Still very relevant and instructive to the OP + the problem at hand.
I assume you were talking about the former. : )
 
Last edited:

GAK34nj

New member
Local time
Today, 05:33
Joined
Jul 28, 2020
Messages
5
I do this for certain events. I do not use a custom class. I use a standard module. I pass in a reference to the form to make it work.
Code:
Public Sub CommonClose(frm As Form)
On Error GoTo ErrProc
    If bForceClose = True Then
        Exit Sub        'do not run close code
    End If
    If frm.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
    If IsNull(frm.OpenArgs) Then
        DoCmd.OpenForm "Switchboard"
    Else
        DoCmd.OpenForm frm.OpenArgs
    End If
  
    bForceClose = False     'reset variable
ExitProc:
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 2102   'bad open args form name
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
    End Select
End Sub
Public Sub CommonReturn(frm As Form)
On Error GoTo ErrProc
    If frm.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
    DoCmd.Close acForm, frm.name
ExitProc:
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 3709, 3021, 2501  'caused when save is cancelled
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
    End Select
End Sub

Public Sub CommonSave(frm As Form)
On Error GoTo ErrProc
    If frm.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
ExitProc:
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 3709, 3021, 2501, 3071  'caused when save is cancelled
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
            Resume Next
    End Select
End Sub

Public Sub CommonExit(frm As Form)

On Error GoTo ErrProc
    If frm.Dirty Then
       DoCmd.RunCommand acCmdSaveRecord
    End If
  
    DoCmd.Close acForm, frm.name, acSaveNo
ExitProc:
  
    Exit Sub
ErrProc:
    Select Case Err.Number
        Case 3709, 3021, 2501, 3071, 3270  'caused when save is cancelled
            Resume ExitProc
        Case 2455   'happens for A2007 when unbound form references the Dirty property
            Resume Next
        Case 2046       'can't save record
            frm.Dirty = False
            DoCmd.Close acForm, frm.name, acSaveNo
        Case Else
            MsgBox Err.Number & "--" & Err.Description
            Resume ExitProc
            Resume Next
          
          
    End Select
End Sub

The code is called this way:

Code:
Private Sub Form_Close()
    Call CommonClose(Me)
End Sub
 

GAK34nj

New member
Local time
Today, 05:33
Joined
Jul 28, 2020
Messages
5
PAT -- I'm a little unclear as to how this related back to the four buttons I described in my original post.... Not sure I see how to implment those buttons.

ARNELGP / MAJP -- By the way - I am marvelling at the two posts about those buttons - because it's amazing to me that they trigger action even though they contain no events - never seen that before. Fascinating stuff -- I think I need some help since I'm in deeper than I can afford to be on a fairly major system that my team is depending on me to deliver - and soon. This issue of erasing the duplication of code among forms has a lot to do with me being a purist and looking for optimized, efficient processes (the curse of being a GE-trained Six Sigma!) I LOVE the database stuff - but the coding - very hard for me.

I see a lot of people on here prodding about not making it to easy for the O/P (original poster, I assume) to just have things handed to them. Let me just say that you reach a wall, where the next step is beyond my grasp - at that point getting help is immensely valuable - and being given code solutions is invaluable to me - please accept my gratitude. At least then I can explore, adapt, reverse engineer, etc. etc. -- but in all candor - sometimes the language invoked is at a level of complexity which transcends my core understanding.

So am I in over my head? Maybe. If you want to see the system I've built and weigh in, I'll be happy to share. We also have a budget to hire someone to help me get it across the finish line. Not a big budget, but a budget. And I want it to be BULLETPROOF.

One last thing - this is running on Access '19 64 Bit - which is what my company has installed. Ihope that this doesn't create an issue.

MANY thanks to all.

GK
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 05:33
Joined
Feb 19, 2002
Messages
42,970
Having common code for certain buttons is a good idea.

Rather than write custom code for you when I don't even know exactly what you want each button to do, I posted code I use in form events. The concept is the same. In my case the common code was for form events that exist in all forms such as Open and Close. The code in each different event is identical for all forms. So, I might have 20 forms with this line of code in the Close event:

CallCommonClose(me)

In your case, you would create code that you wanted to execute from each button click event. Passing in the form reference (me) allows the common code to work with form objects and events. You will need to use consistent naming if you want the common code to reference form fields.
 

Isaac

Lifelong Learner
Local time
Today, 02:33
Joined
Mar 14, 2017
Messages
8,738
I see a lot of people on here prodding about not making it to easy for the O/P (original poster, I assume) to just have things handed to them.
I for one definitely didn't mean that. PM'ed.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 05:33
Joined
May 21, 2018
Messages
8,463
@Gasman
Try this version. I just imported into a new DB, but I do not think there is a 2007 specific version. There is 2002-2003 then 2007-2016 AFAIK. I slightly modified the code to be more a "sub form" implementation. Basically I put event procedures for the buttons. I also added an additional button so you can see the roll back without having to close the code. The code provided by @arnelgp is very interesting because it uses transactions which few people realize can be done in Access. It is a good technique to have in your quiver.
To see this in action, add multiple records. Then rollback.

@GAK34nj and others
Lost in all the noise are three methods demonstrated to centralize your code.
1. Place your common code in a Standard Module. Most likely the procedures in the standard module need to be passed a reference to the form when they are called so that they know what procedure called it. This is demonstrated by @Pat Hartman in the reply 45. This is probably the approach you want to start off with as you begin to write more complex code.
2. Place your common code in a Class Module. As mentioned this is a more advanced skill, but a far more powerful skill set to have. Any real complex coding likely needs a class module. Here you can pass in references to the buttons and capture those events without having to rewrite and code when creating a new form. This was demonstrated by @arnelgp
3. Place your common code in a Sub Form. This is in truth extremely similar to what Arnelgp did, I made very few modifications. A lot of people do not get that form's module is a class module. This technique may seem more intuitive than number 2 for many people because of familiarity with form events.

IMO a good Access coder needs to understand all three of these techniques. Most people start with using standard modules, but each technique has its time and place.
 

Attachments

  • MajP_SubFormButtons.accdb
    544 KB · Views: 162

Gasman

Enthusiastic Amateur
Local time
Today, 09:33
Joined
Sep 21, 2011
Messages
14,037
Thank you MajP
However I still get Unrecognised database format. :(

Let's call it quits, I do not want anyone wasting their time when if is merely for me to take a peek. It will not be something I would likely implement, as I am not really working anymore.

Thanks for trying.
 

Users who are viewing this thread

Top Bottom