Access 2007 ReportEvents class is not firing events - ms-access

I'm having an issue with report events that I haven't
encountered before in Access prior to Access 2007.
I'm using using Access 2007 for a Front-end to a SQL Back-end.
I have a Class, ReportEvents, that I use for the reports.
In a report's Report_Open event I instantiate and then use this class to
handle events like activate, Close, NoData and I also put common code
such as exporting data to excel instead of a report.
This code was working fine in a previous Access 2003 application (mdb) I was using,
but it isn't working as expected in 2007 (accdb). In my tests the call to a non event public sub, ProvideXLOption works like a charm, but none of the events are being fired
from the ReportEvents class. I didn't change the code I just imported it into the
project. I set up break points but they aren't being hit. I changed all of them to
public events and then called them within the test reports event and they worked fine.
I set up another report in Access 2007 with the same results. I've checked
the startup settings in Access and they are fine. I even removed and re-added
the database location from the trusted locations without any luck.
Has Microsoft modified the Events Code or is this just a simple code error on my part that I'm not seeing? It's gotta be something simple. My brain is just toast (my son decided to stay awake after last night's feeding).
Class ReportEvents Code:
Option Compare Database
Option Explicit
Private WithEvents rpt As Access.Report
Const strEventKey As String = "[Event Procedure]"
Public Property Set Report(Rept As Access.Report)
Set rpt = Rept
With rpt
.OnActivate = strEventKey
.OnClose = strEventKey
If LenB(.OnNoData) = 0 Then
.OnNoData = strEventKey
End If
End With
End Property
Public Sub Terminate()
On Error Resume Next
Set rpt = Nothing
End Sub
Private Sub rpt_Activate()
LoadPrintRibbon
End Sub
Private Sub rpt_Close()
Me.Terminate
End Sub
Private Sub rpt_NoData(Cancel As Integer)
Dim strMsg As String
strMsg = "No Records were found that match your criteria."
MsgBox strMsg, vbInformation, rpt.Name & _
": No Match. Report Cancelled"
Cancel = True
End Sub
Private Sub LoadPrintRibbon()
#If AccessVersion >= 12 Then
If rpt.RibbonName <> "PrintPreview" Then
rpt.RibbonName = "PrintPreview"
End If
#End If
End Sub
';;Provides user with option to send data to Excel instead of a report
Public Sub ProvideXLOption(Cancel As Integer)
'... some XLOption Code
End Sub
In the Test Report Code:
Private Sub Report_Open(Cancel As Integer)
Dim rptEvts As ReportEvents
Set rptEvts = New ReportEvents
Set rptEvts.Report = Me
';;Let User User Choose to Export Data to Excel or Display the report
rptEvts.ProvideXLOption Cancel
End Sub

I figured it out. It was a scope issue The ReportEvents class variable rptEvts, was inside the Report_Open sub. Because of this it wouldn't exist when the other events happened. It should be at the module level and not within the procedure.
Dim rptEvts As ReportEvents
Private Sub Report_Open(Cancel As Integer)
Set rptEvts = New ReportEvents
Set rptEvts.Report = Me
';;Let User User Choose to Export Data to Excel or Display the report
rptEvts.ProvideXLOption Cancel End Sub
End Sub
It's amazing what a little rest will do for you.

Related

Button to turn change AllowEdits to true in Access using VB

I am trying create a button which changes the value of AllowEdits to False and another for true for a subform. I am using the below code. I get a Runtime error 424 each time I run it.
Option Compare Database
Private Sub Toggle_Edit_Click()
Dim strForm As String
strFormName = Me.Name
Call ToggleEdit(Me)
End Sub
and
Option Compare Database
Public strFormName As String
Sub ToggleEdit(myForm As Form)
Call Message
ctrlControl.AllowEdits = True
End Sub
and if you were interested
Sub Message()
MsgBox "Remember not to overwrite incorrect records"
End Sub
Please add Option Explicit at top of your modules!
I think AllowEdits is a Form property, not a Control property.
Option Explicit
Sub ToggleEdit(myForm As Form)
myForm.AllowEdits = Not myForm.AllowEdits
End Sub
If the code is behind the form itself, you can use Me.
Sub ToggleEdit() 'no parameter
Me.AllowEdits = Not Me.AllowEdits
End Sub
If you want to act at control level, use Locked or Enabled properties.

MS Access 2016 VBA Code Reuse in Buttons

I have an Access database frontend that houses 16 different forms. All of them have three buttons in common namely Show All, Clear and Refresh, that perform that exact same function using their respective subforms. For instance, for viewing data from a table named tbl_Students the 'On Click' event of these buttons on the Students Form have the following code:
Option Explicit
'Show all records button
Private Sub cmdShowAll_Click()
Dim task As String
task = "SELECT * FROM tbl_Students"
Me.frm_Students_subform.Form.RecordSource = task
Me.frm_Students_subform.Form.Requery
End Sub
'Clear displayed records button
Private Sub cmdClear_Click()
Dim task As String
task = "SELECT * FROM tbl_Students WHERE (StudentID) is null"
Me.frm_Students_subform.Form.RecordSource = task
Me.frm_Students_subform.Form.Requery
End Sub
'Refresh records button
Private Sub cmdRefresh_Click()
Me.frm_Students_subform.Form.Requery
End Sub
Currently, I'm using the exact same code, but with different respective subform names, in all my 16 forms. Is there a better, more efficient way to do it, with code reuse? Thanks.
Consider creating one generalized subroutine in a standard module that all 16 forms call passing needed parameters. Specifically use CurrentProject and Controls to reference objects dynamically by string.
Module save in a named standard module (not behind any form)
Option Explicit
Public Sub ProcessForms(task As String, mainform As String, subform As String)
On Error GoTo ErrHandle
CurrentProject.AllForms(mainform).Controls(subform).Form.RecordSource = task
CurrentProject.AllForms(mainform).Controls(subform).Requery
Exit Sub
ErrHandle:
Msgbox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Exit Sub
End Sub
Example Form single line calls
Option Explicit
'Show all records button
Private Sub cmdShowAll_Click()
Call ProcessForms("SELECT * FROM tbl_Students", _
"frm_students", "frm_Students_subform")
End Sub
'Clear displayed records button
Private Sub cmdClear_Click()
Call ProcessForms("SELECT * FROM tbl_Students WHERE (StudentID) IS NULL", _
"frm_students", "frm_Students_subform")
End Sub
'Refresh records button
Private Sub cmdRefresh_Click()
' Re-assigns same recordsource in line with others
Call ProcessForms(Me.Controls("frm_Students_subform").Form.RecordSource, _
"frm_students", "frm_Students_subform")
End Sub

Access Listbox AfterUpdate Not Firing when Selected = True

I have an Access form with a listbox and a combo box.
Private Sub Form_Open(Cancel As Integer)
'... misc code
me.comboBox.RowSource = "sql statement"
call comboBox_AfterUpdate
End Sub
Private Sub comboBox_AfterUpdate()
listbox.Selected(0) = true
End Sub
Private Sub listbox_AFterUpdate()
'.... important code that updates the form
End Sub
On the form load/open, the the code runs as
Form_Open > comboBox_AfterUpdate > listbox_AfterUpdate
However after the form has already loaded, when the combo box is changed and the comboBox_AfterUpdate is triggered, the listbox_AfterUpdate() is NOT triggered.
I would move the code in the listbox_AfterUpdate() to a separate sub-routine, but that would call the code to run twice when the form loads. Any ideas on why this happens?
Similar issue here:
http://www.tek-tips.com/viewthread.cfm?qid=1395160
You could use two custom functions and use optional parameters to know the context in which it is called. That way you have full control over when which function does which.
E.g.
Public Sub MyFunc1 (Optional CalledFromLoad As Boolean)
Public Sub MyFunc2 (Optional CalledFromLoad As Boolean)
Private Sub comboBox_AfterUpdate()
Call MyFunc1 False
End Sub
Private Sub listbox_AFterUpdate()
Call MyFunc2 False
End Sub
Private Sub Form_Open(Cancel As Integer)
Call MyFunc1 True
End Sub
Moving all your code gives you a greater degree of customization, and can help you avoid calling the same code twice.
You could possibly set a global variable in MyFunc1, then trigger MyFunc2 by changing the listbox, and then reset that global variable again. Numerous solutions are possible.

get Access VBA have a Sender

In Access I have a form that has about 200 text boxes on it. I Know that in C# on every on click event there is textbox1_Click(object sender).
how can I in VBA have reference the current sender without saying Me.txt_Whatever?
this is what I have so far
Private Sub txtHotMix_DblClick(Cancel As Integer, sender As Object)
Dim txt As TextBox
Set txt = sender
MsgBox txt.Name
End Sub
I think the ActiveControl property of the Screen object is what you're after (https://msdn.microsoft.com/en-us/library/bb225491(v=office.12).aspx):
In a module:
Option Compare Database
Option Explicit
Public Sub ctrl_Print(objCtrl As Control)
MsgBox objCtrl.Value, vbOKOnly, "Control Value"
End Sub
You would still have to add a click event to every control to call this sub, like this:
Option Compare Database
Option Explicit
Private Sub Text0_Click()
Call ctrl_Print(Screen.ActiveControl)
End Sub

Access VBA - TreeView Control - AfterLabelEdit Event

I've got a treeview control in my form. I would like to be able to edit the node in the tree and push the change to Access DB. However, I'm having trouble finding an appropriate event. MSDN treeview events reference page advices AfterLabelEdit, but I am not able to get it to work. Is anyone aware of any workaround/solution?
Snippet of the code I use (I've added onClick and onDblClick for comparison, as they work):
Private Sub xMyTreeview_Click() 'OK
testit
End Sub
Private Sub xMyTreeview_DblClick() 'OK
EditLabel
End Sub
Private Sub xMyTreeview_AfterLabelEdit() 'Problem
AfterLabel
End Sub
Sub EditLabel()
Me.xMyTreeview.StartLabelEdit
End Sub
Sub AfterLabel()
MsgBox prompt, vbOKOnly, "afterlabel"
End Sub
Sub testit()
Dim nodSelected As MSComctlLib.Node ' a variable for the currently selected node
Set nodSelected = Me.xMyTreeview.SelectedItem ' get the currently selected node
NodesStrLength = Len(nodSelected.Key)
Dim NodeStr As String
Dim StrToChange As String
StrToChange = nodSelected.Key
NodeStr = Mid(StrToChange, 2, NodesStrLength - 1)
Me.txtNodeID = NodeStr
Me.sfrmDOCNODE.Visible = True
End Sub
Your link is to the .net Windows Form Treeview but MSComctlLib is the older Visual Basic Common Controls: http://msdn.microsoft.com/en-us/library/aa443023(v=vs.60).aspx
Note the event prototype is different; if you don't declare it with the correct arguments it will never get raised;
Private Sub object_AfterLabelEdit(cancel As Integer, newstring As String)