CALL ANOTHER CODE

rainbows

Registered User.
Local time
Yesterday, 18:32
Joined
Apr 21, 2017
Messages
428
at the bottom on the first screen shot there are 3 buttons i use to open acknowlegement , send it to a file , and send it to the customer i am now trying to adda button to carry out all these tasks in one go but i dont know how to call them up having tried a few ways. the code at the bottom is a part of one of the codes that i was trying to call up.

thanks steve


1708957130845.png


1708957388518.png

yhanks
 

Attachments

  • 1708957085779.png
    1708957085779.png
    218.9 KB · Views: 61
You can call each event procedure
just call it by its name
cmdEmail_Click()

You do not have a procedure called
subCmdEmail_Click()
 
What is the error you are getting?

It will probably work if you just remove the "Call" from each line, since you are just running Sub procedures.
 
That would seem to work if you could get the names correct?
What have you tried and what was the result.?
Have you walked through your code line by line?
 
It is cleaner to pull the procedure code out of the event procedure and put into its own standard procedure. Then the event procedure calls the procedure. Then other events procedures can call the same procedure.

Code:
Private CmdEmail_Click()
   'remove code and put in its own sub
   SendEmail
end sub

Private Sub SendEmail()
  'code to send email
end sub

Now from another event or another button

Code:
Private SomeOtherButtonOrEvent()
  SendEmail
  OpenInvoice
  SavePDF 
end sub
 
maybe add a flag to test if the other process is already done before proceeding to the next Click event:
Code:
Dim bolDone As Boolean

Private Sub allack_Click()
    bolDone = False
    call syscmd(acSysCmdSetStatus,"stage (1) sending email...")
    Call SubcmdEmail_Click
    Do While bolDone = False
        DoEvents
    Loop
    bolDone=False
    call syscmd(acSysCmdSetStatus,"stage (2) creating pdf....")
    Call SubcmdPDF_Click
    Do While bolDone = False
        DoEvents
    Loop
    bolDone = False
    call syscmd(acSysCmdSetStatus,"stage (3) open invoices...")
    Call SubcmdOpenInvoice_Click
    Do While bolDone = False
        DoEvents
    Loop
    call syscmd(acSysCmdClearStatus)
End Sub

'on each sub before the End Sub, set bolDone=True
 
Last edited:
I agree with Maj, if you have code that you want to reuse, CALL it from the event procedure rather than putting it in one procedure and calling it from another.

WHY? - event procedures execute when a specific event happens. Somebody clicks on a button, the form opens, the form loads, etc. Most developers will not expect the event procedure code to be executed at any other time. Therefore, once the initial developer moves on, subsequent developers are likely to introduce errors into the code by adding logic to the event procedure that should NOT be executed during the alternative uses of the code. If you ever wonder how a mature code base like Access "breaks", this is how. Sloppy programming techniques. Do not be sloppy with your coding.
 
at the bottom on the first screen shot there are 3 buttons i use to open acknowlegement , send it to a file , and send it to the customer i am now trying to adda button to carry out all these tasks in one go but i dont know how to call them up having tried a few ways. the code at the bottom is a part of one of the codes that i was trying to call up.

thanks steve


View attachment 112779

View attachment 112780
yhanks
The Private Subs are NOT SubcmdEMail_Click etc.
They are cmdEMail_Click, cmdPDF_Click, cmdOpenInvoice_Click
You don't use Sub as a prefix that I know of.
 
WHY? - event procedures execute when a specific event happens.

Yes as Pat and majP say, it's not a good idea to call command button code from elsewhere... There's another post about it here, which basically says the same as what Pat already said!

 
In addition to what the others have said, if I were going to run a lot of lines of code all at one time I would just create a Public Function, put all the code there, and call the Public Function from a single command button or other form Event Procedure. You only have one place to change anything you need and one place to trap errors. Easy.
 
They are cmdEMail_Click, cmdPDF_Click, cmdOpenInvoice_Click

Regarding:-
cmdEMail_Click, cmdPDF_Click, cmdOpenInvoice_Click

There is an alternative:-
btnEMail_Click, btnPDF_Click, btnOpenInvoice_Click


The prefix "btn" for command buttons comes from the Leszynski naming convention. Stan's convention has been widely adopted. However, it's worth noting that you don't have to follow Stan Leszynski's naming convention, you are free to use your own prefixes, or as some prefer suffixes. Whatever you use you must stick to one system in your project.

I mention it because I prefer the prefix "btn" for command buttons. It just has a feeling of rightness about it. I always felt that "cmd" represented "command" which is not unambiguously associated with a button "btn".

In other words there's no ambiguity in "btn", whereas in what is an unlikely case, but something you might come across, is code which uses command, for instance, if you were using a command line interface within your MS Access database.
 
Last edited:
I don't always recognize as I am writing a procedure that I might have to use it in multiple places so it gets coded where ever I need to use it. If later, I find myself repeating the code, I stop and refactor the original code to be reusable. Once code is used more than once, it needs to be actually reusable to minimize future maintenance. Stop, take the 3 minutes to refactor the original code. It really isn't much effort. When it is form related and I now want to use the code from multiple forms, I pass in a form reference. That way, as long as the control names are consistent, the code is very easy to reuse. Instead of Me.ControlName, the reference becomes frm.ControlName and the frm reference is passed as the procedure is called. I avoid like the plague having any table updated by multiple forms. But sometimes, the client wants it and so I even turn the BeforeUpdate event into a called procedure in a standard module. In a current app, there is a subform that needs to be a concise list so it doesn't include any of the optional columns. I created a called procedure that did the validation for the common fields and the popup form which includes all the fields, calls the common sub and then also validates the optional fields. It allows me to reuse part of the validation code but not all of it.
 
these are the 3 codes i use should they be put them into one of which i would struggle to do or just call up the 3

Code:
Private Sub cmdEmail_Click()
Dim strTo As String
    Dim strSubject As String
    Dim strMessageText As String
   
    Me.Dirty = False
     strTo = [Order Details subform].[Form]![EMailaddress]

    strSubject = " Acknowledgement Number " & Me.orderID
    strMessageText = Me.Firstname & "," & _
        vbNewLine & vbNewLine & _
        "Your latest Acknowledgement is attached." & _
        vbNewLine & vbNewLine & _
        ""


    DoCmd.SendObject ObjectType:=acSendReport, _
        ObjectName:="order acknowledgement", _
        OutputFormat:=acFormatPDF, _
        TO:=strTo, _
        Subject:=strSubject, _
        messageText:=strMessageText, _
        EditMessage:=True
       
       
End Sub





Private Sub cmdOpenInvoice_Click()


On Error GoTo Err_Handler
   
    Const MESSAGE_TEXT = "No current ack number."

    If Not IsNull(Me.orderID) Then
        ' ensure current record is saved
        Me.Dirty = False
        ' open report in print preview
        DoCmd.OpenReport "order acknowledgement", View:=acViewPreview
       
       
    Else
        MsgBox MESSAGE_TEXT, vbExclamation, "Invalid Operation"
   
    End If
Exit_Here:


    Exit Sub
   
Err_Handler:
    MsgBox Err.Description
    Resume Exit_Here

End Sub




Private Sub cmdPDF_Click()
On Error GoTo Err_Handler

    Const FOLDER_EXISTS = 75
    Const MESSAGE_TEXT1 = "No current invoice."
    Const MESSAGE_TEXT2 = "No folder set for storing PDF files."
    Dim strFullPath As String
    Dim varfolder As Variant

   If Not IsNull(Me.orderID) Then
       
        varfolder = DLookup("Folderpath", "pdfFolder")
        If IsNull(varfolder) Then
            MsgBox MESSAGE_TEXT2, vbExclamation, "Invalid Operation"
        Else
            ' create folder if does not exist
                                 
             varfolder = varfolder & "\" & Year(date) & "\" & [Order Details subform]![CustomerName] & "\" & "NCO" & Format(Me.NCO_No, "0000")
            Call subUNCFolder(varfolder)
            'strFullPath = varFolder & "\" & ME.CustomerName & " " & Me.Invoicenumber & ".pdf"
          strFullPath = varfolder & "\" & "NCO Number " & " " & Me.NCO_No & ".pdf"
            ' ensure current record is saved before creating PDF file
            Me.Dirty = False
          DoCmd.OutputTo acOutputReport, "order acknowledgement", acFormatPDF, strFullPath
        End If
    Else
        MsgBox MESSAGE_TEXT1, vbExclamation, "Invalid Operation"
    End If
'End If
Exit_Here:
    Exit Sub

Err_Handler:
    Select Case Err.Number
        Case FOLDER_EXISTS
        Resume Next
        Case Else
        MsgBox Err.Description
        Resume Exit_Here
    End Select

End Sub
Code:
Private Sub allack_Click()

Call cmdOpenInvoice_Click

Call cmdPDF_Click
Call cmdEmail_Click

End Sub
 
Last edited:
these are the 3 codes i use should they be put them into one
NO! Absolutely not. The idea is to make code streamlined, understandable, and maintainable. That would defeat all of those. Most coders write procedures to do one and only one thing. Then you can debug and test individually. Lots of small encapsulated procedures is better than big multi function procedures.
Some basic principles
 
these are the 3 codes i use should they be put them into one of which i would struggle to do or just call up the 3
its a YES for me.
those subs are a member of the Same form, so Calling them is not an issue (members calling each other).
 
@rainbows I interpreted the question different than arnelgp. I interpreted this to mean if you should put all of your code into a single procedure. If that is what you mean then no. If you want one procedure to call three other procedures then yes.
 
"if you want one procedure to call three other procedures then yes."



ok , i have done the above
today i see it could go wrong for me if for some reason the report was wrong yet i have put it to the file and sent it to the customer
could the code for the "cmdOpenInvoice_Click" be modified to stop until i have checked it and when i say ok it carries on or stops all the code .if i say no

i am not sure how to stop the other events as this on stops this sub





Code:
Private Sub cmdOpenInvoice_Click()


On Error GoTo Err_Handler
    
    Const MESSAGE_TEXT = "No current ack number."

    If Not IsNull(Me.orderID) Then
        ' ensure current record is saved
        Me.Dirty = False
        
        ' open report in print preview
        DoCmd.OpenReport "order acknowledgement", View:=acViewPreview
       ' DoCmd.Maximize
        DoCmd.RunCommand acCmdZoom75
        
           If MsgBox("pleazse confirm report is ok" & vbCrLf & vbCrLf _
   , vbYesNo) = vbNo Then Exit Sub
    Else
 
    
        MsgBox MESSAGE_TEXT, vbExclamation, "Invalid Operation"
        
       End If
              
    
    
    
    
 
Exit_Here:

 
    Exit Sub
    
Err_Handler:
    MsgBox Err.Description
    Resume Exit_Here

or just use the first code separaetly and a button just for the other 2

thanks steve
 
Last edited:

Users who are viewing this thread

Back
Top Bottom