VBA conditional formatting not visible in Print Preview - vba

I am trying to apply conditional formatting to a report using VBA. This works if I open the report in Report View, but does not work if I open the report in Print Preview (unless I first open in Report View).
This issue does not apply to conditional formatting added via the wizard. That displays correctly in Print Preview.
I am using Office365 with Access Version 2208
My setup uses a form to allow a user to enter a date. This date is then passed to the report as an OpenArg:
Private Sub cmd_Ok_Click()
'DoCmd.OpenReport "Component Value", acViewPreview, , , , Me.txt_Date <- Does not show conditional formatting
DoCmd.OpenReport "Component Value", acViewReport, , , , Me.txt_Date
DoCmd.Close acForm, Me.Name, acSaveNo
End Sub
Then the report adds a format condition in its OnLoad event
Dim strCondDate As String
Private Sub Report_Load()
If Not IsNull(Me.OpenArgs) Then
strCondDate = Me.OpenArgs
End If
If Not IsNull(strCondDate) Then
With Me.txt_Updated.FormatConditions
With .Add(acExpression, , "[Last Updated] < #" & strCondDate & "#")
.BackColor = vbYellow
End With
End With
End If
End Sub
I can breakpoint this code and see that it runs correctly when I open the report with acViewPreview, but the formatting is not visible.
Why does the format condition not appear in Print Preview (unless I first open the report in Report View)?
How can I get the formatting to be displayed?

Conclusion is Conditional Formatting rule cannot be programmatically added to report opened directly to Print or PrintPreview but can to ReportView. Fortunately, there is no need to use VBA. CF rule can grab OpenArgs content: Field Value Is less than CDate([OpenArgs]). Otherwise, have rule reference control on form that has user input.
Another alternative is to directly set Backcolor property in OnFormat or OnPrint event with conditional VBA structure. Drawback is these events do not execute in ReportView.

Related

Get report name from DataSource of subform ms access vba

I have a form (say form1) to navigate to another form (form2) which has a subform that opens reports based on the DataSource put into by selecting the Text box on form1.
The code looks like this
Private Sub txt_DeliveryItemsSummary_Click()
DoCmd.OpenForm "frm_viewReports", acNormal
Forms!frm_ViewReports!subrpt_ReportArea.SourceObject = "Report.rpt_DeliveryItemsSummary"
End Sub
And on form2 I have a print button to print the report
The code looks like this
DoCmd.OpenReport subrpt_ReportArea.SourceObject, acViewNormal, , , acWindowNormal
But this code gives following error
Runtime Error 2103
The report name 'Report.rpt_DeliveryItemsSummary' you entered in either the property sheet or macro is misspelled or refers to a report that doesn't exist.
Any help how can I fix this issue.
Thanks a lot in advance.
Just figured it out myself. I knew i need to skip a piece of text but how! There I was getting trouble.
Here is the working code
DoCmd.OpenReport Right(subrpt_ReportArea.SourceObject, Len(subrpt_ReportArea.SourceObject) - 7), , acViewNormal, , , acWindowNormal
Thanks #Gustav for reaching out again.

Why form object doesn't load RecordSource attribute in VBA for Ms Access

I need to read programmatically the RecordSource attribute of a form, to know what table or query is the form depending on.
After some research, it seems that the form object needs to be actually open in a window (or hidden, but open) so that certain attributes can be accessed. I've put together the following code snippet:
Application.DoCmd.OpenForm "Form1", view:=acDesign, windowMode:=acWindowNormal
Dim frm as Access.Form
Set frm = Forms("Form1").Form
Debug.print frm.Name 'works ok
Debug.print frm.RecordSource 'prints an empty string
Application.DoCmd.Close AcForm, "Form1"
I can see that the form is correctly open, but the RecordSource attribute is empty, eventhough the form is fed from a table.
What could be going on? I'm using .accdb Ms Access database files. And have compacted the database, just in case the db were corrupted, but the issue remains.
Edit: The form is very minimal, and I realize that actually has no RecordSource at all; it only has a subform which, since it is indeed fed with a table, does have a non-blank RecordSource.
So VBA was right returning a blank RecordSource for the parent form. The script posted was correct after all. Thanks for your inputs!!
Any hints or directions would be greatly appreciated. Thank you in advance!!
Most likely, the RecordSource is assigned in code when the form is loaded, either as a table name or as SQL:
Me.RecordSource = "Select * From SomeTable Order By SomeField"
In design view you can't get RecordSource programmatically. You can see from Property window. You have to open it as normal form, may be you want it to open as hidden. You can specify WindowMode to open form hiddenly by DoCmd.OpenForm "Form1", acNormal, , , , acHidden. Try below codes.
Private Sub CmdTest_Click()
Dim frm As Access.Form
DoCmd.OpenForm "Form1", acNormal, , , , acHidden
Set frm = Forms("Form1")
Debug.Print frm.Name
Debug.Print frm.RecordSource
DoCmd.Close acForm, "Form1"
End Sub

Word VBA: Static Status dialog window

I've created a form that works well with macros running in the background to validate data and then print the document to a specific printer on the network.
The key element of this process is a production number value which I would like to keep a running log of and display in a static status dialog window. In other words, a popup window similar to a MsgBox that would not interfere with other actions on the form, but float on top of the document.
Visual concept of this would be...
User could shift the window away from their work if needed. Close the window if they desired, but pragmatically I want to re-pop/refresh the data in the window each time the background macro completes.
I can't use MsgBox, because it forces a closure of the window before the user can continue working on the document. I just want this visible to the user so they know what was last worked on and the few prior to that.
Any idea what control I might be able to use, or switch to MsgBox that would allow the user to continue working?
Ken...
PS: I found this and am trying to find a way to make this work for me. So far I have managed to get to function in the manner I want, but the lingering issue is how to call this PS script and include the information I need to display.
Alternatives to MsgBox in VBScript - StackOverflow
PPS: I opted to go a slightly different route and release the form with a MsgBox that is displayed at the end of the macro. I describe this in the solution noted below.
Instead of using a MsgBox, please consider using a VBA Userform. They're not much more complicated to use than a MegBox, but you can set them to be Modeless. Modeless dialogs remain open on-screen while you work on the Word document. Here'is Microsoft's page on setting dialogs as Modal or Modeless: Show method
If you search on VBA modeless dialog, you'll find many other helpful pages on the subject.
After doing much research, I've come back to revising my macro to incorporate static variables and a MsgBox at the end to report the last 5 production numbers that have been printed.
To provide a means of bringing up this MsgBox for reference, between printing runs, I created an OnlyNum variable as string and replaced the MsgBox I had for letting the users know they were only to use numbers in this field with that message. The end of that trap diverted the flow to the bottom of the macro (where the MsgBox that displayed the last five print jobs has been placed).
So, when the status MsgBox is displayed as a result of printing it only shows the last five events. If the trap captures it, it shows the message letting the user know to only use numerals and then displays the last five events.
Code reference:
Private Sub CommandButton1_Click()
Dim Prod As String
Dim Temp As String
Dim OnlyNum As String
Static ProdNum1 As String
Static ProdNum2 As String
Static ProdNum3 As String
Static ProdNum4 As String
Static ProdNum5 As String
'Check for only numeric value of TextBox1.Text
If Not IsNumeric(TextBox1.Value) Then
OnlyNum = "only numbers allowed" & vbCrLf & vbCrLf
Cancel = True
GoTo NotToday
End If
'Remove any spaces from TextBox1.Text
Prod = Replace(TextBox1.Text, " ", "")
'If the resulting lenght is equal to 7 Print it.
If Len(Prod) = 7 Then
ActiveDocument.PrintOut
'Update recent production numbers (5 in total)
ProdNum5 = ProdNum4
ProdNum4 = ProdNum3
ProdNum3 = ProdNum2
ProdNum2 = ProdNum1
ProdNum1 = Prod & " - " & Now() ' Insert a new production number with timestamp
TextBox1.Text = "" 'Clear the value of TextBox1.Text to prepare for the next Production number
Else
MsgBox ("Production Numbers must be 7 digits and contain only numerials.")
End If
NotToday:
Application.ActivePrinter = Temp
MsgBox (OnlyNum & ProdNum1 & vbCrLf & ProdNum2 & vbCrLf & ProdNum3 & vbCrLf & ProdNum4 & vbCrLf & ProdNum5)
OnlyNum = "" 'Reset value of OnlyNum
End Sub

How to Dynamically Change the Rowsource of an Access Chart

I would like to know if there is any way I can set the rowsource property of a chart in my report at run time.
I intend to have a chart in my report's group header section. The rowsource of this chart should be updated according to the group header's value.
I got the error 2455 - invalid reference to the property RowSource when I tried to do this in VBA.
I am using Access 2003.
Thank you.
I just got an inspiration after searching over the internet for some time. Here is the solution I currently implement.
Firstly, it is true that the rowsource property of a chart cannot be changed programmatically at run time. However, what we can do is to set the rowsource property to be a Query object and later update this query object in VBA.
Here is part of my code.
CurrentDb.QueryDefs("myQuery").SQL = "a new query"
Me.myChart.Requery
I have set my chart's row source to a query object named "myQuery". I placed the above code in the Format event of my group header, so every time when the group header is loaded I can use the value of my group header to update the Query object.
Another approach would be to open the form or report the chart is embedded in two steps. In the example below I am using a report, but it works just as fine with forms:
First step: open report in design view but hidden mode. Now the chart
row source can be edited (because you are in design view) but the
process is invisible (because you are in hidden mode).
Second step: save and close hidden report and re-open it now in a
"visible" mode
'report name
strReportmName = "SomeReportName"
'open report in design view but hidden
DoCmd.OpenReport strReportmName , acViewDesign, , , , acHidden
'edit chart RowSource
strSQL = "TRANSFORM Sum(Cabecas) AS SomaDeCabecas " & _
"SELECT Data "
...etc...
"PIVOT Categoria In (" & Chr(34) & strTitColunas & Chr(34) & ")"
'update chart RowSource
Reports![SomeReportName].Controls![SomeChartName].RowSource = strSQL
'Save report with edited RowSource
DoCmd.Close acReport, strReportmName , acSaveYes
're-open it in normal, visible mode
DoCmd.OpenReport strReportmName , acViewPreview

MS Access - "phantom" process created by canceling report

I have encountered a problem in Access 2010 for Windows:
Launch a report using doCmd.OpenReport
Set "Cancel = True" in an event associated with the report
Close Access
Access continues to run as a "phantom" process and must be killed in Task Manager. Access cannot open another database until this process is killed. The task initially shows some CPU utilization but quiets down to 0%.
I discovered this while using doCmd.OpenReport to launch a report. The report opens a form in the Report_Open event. The form prompts the user for report parameters and allows them to press "OK" to display the report or press "Cancel". The On Click event for "Cancel" sets "Cancel = True".
It appears that OpenReport() is not responding gracefully to the cancel. This seems like a frequently used technique so I hesitate to call it a bug and am wondering if I am doing something wrong. Actually... the more I explain this, it does sound like a bug. At this point, I am hoping somebody has a workaround or that I am missing something obvious.
This is just a simplified example I created to illustrate the problem:
form
Private Sub Form_Open(Cancel As Integer)
On Error GoTo errHandler
DoCmd.OpenReport "Test Report", acViewPreview, , , acDialog
Exit Sub
errHandler:
Select Case Err.Number
Case 2501 ' Cancelled by user, or by NoData event.
MsgBox "Report cancelled, or no matching data.", vbInformation, "Information"
Case Else
MsgBox "Error " & Err & ": " & Error$, vbInformation, "Form_Open()"
End Select
Resume Next
End Sub
report
Private Sub Report_Open(Cancel As Integer)
Cancel = True
End Sub
The reason for the problem in this case is acDialog:
DoCmd.OpenReport "Test Report", acViewPreview, , , acDialog
I think you will find:
DoCmd.OpenReport "Test Report", acViewPreview
Works without problems.
Edit re Comment
You should not need to cancel the report. For the most part, it is better to avoid errors than to trap them, so check for data and get parameters before opening the form. Move the form from the report open event to step of its own and use DLookUp or a query to check for data before launching the form.
I'm not in a position to test this problem, so I'll just offer a generic solution: Remove the data/recordset/recordsource from the report definition.
You can apply the recordsource to the report after you have determined the parameters. If the report is canceled, it is canceled without ever having a data connection.