MS Access Parameter Query inside Subform Won't Print - ms-access

Here's what I've done:
I created a Parameter Query in which one of the crtiterias is Between [Start Date] and [End Date]. I then put that Parameter Query along with other bound fields and created a subform. So far, no problems and it works great.
But I'm having issues when it comes to printing or trying to convert the form into a PDF. As soon as I ask it to print, for example, the pop-ups from the parameter query will pop up asking me the dates again and even after I enter them in (again), it keeps asking me multiple times and cancels the print job.
How do I keep the query from essentially running when I'm trying to print what's on the screen? The same thing happens if I'm trying to create a PDF.

In my not so humble opinion, parameters are handled badly in MS Access.
I think having to enter the values in the query whenever it is run (unless it is a one off experimental query) is just wrong headed. It would be so much easier to automate reports like that if you could just pass the parameters.
Typically, I create a report without the parameters in the where clause of the query, and then pass in your own where condition which gets added on Remou's answer here
You could also alter the query in the report before you call it, but that's pretty hackey.
-- Edit --
I see the confusion. I interpreted what you were doing as a report (not a form).
What's likely happening is you that when it tries to render/format the print job, it's having to make multiple calls to form's record source. And that why it keeps asking you for that data.
From what I understand in your question, you have a query that looks like this:
select foo
from bar
where
yaddah_date between [Start Date] and [End Date]
And then you've used that query as the record source for a form that you are trying to latter print as a PDF. First of all you should probably create a report that is an analogue of the form. And then open the report for printing with a filter on it:
DoCmd.OpenReport "myReport", , , , _
"yaddah_date between " & txtStartDate & _
" and " & txtEndDate
(the last part is basically the filter/where clause that report will apply to the results of the query that's generating its data).
If you MUST print the form, you can do something similar
DoCmd.OpenForm "foo", acNormal, , _
"yaddah_date between " & txtStartDate & _
" and " & txtEndDate
Or you can set the filter property of the form/subform.

Related

Detecting the invoking object from within a report

Is there some way I can detect, from within a report, which form invoked the report?
I have a form for selecting several criteria which are used to build the WhereCondition for various reports. In the report On Load, I test for the calling form being open. If it is open, I grab the selection criteria for display in the report header. If it isn't open, I display things like "Species: All" instead of, for example "Species: Blue-tailed damselfly". That works ok in this particular case but it feels a bit flaky. I would prefer to know what it was that invoked the report, in case in some future more complex system, a report could be invoked from different places. I know that a parent form is available from within a subform but that doesn't apply in this situation.
You have a form where the user selects the criteria used to build the WhereCondition which is used to filter the report. Do not ask the report to re-examine the form criteria in order to generate the appropriate header for itself. Build your header string in the same form procedure which builds the WhereCondition. Then pass that string as OpenArgs when you call OpenReport.
For example, if no restriction is placed on species:
strHeader = "Species: All"
Or for the selected species:
strHeader = "Species: Blue-tailed damselfly"
Then pass strHeader when you open the report:
DoCmd.OpenReport ReportName:="YourReport", _
View:=acViewReport, _
WhereCondition:=strWhere, _
OpenArgs:=strHeader
And in the report's load event you can check whether you got something in OpenArgs and use it:
If Len(Me.OpenArgs) > 0 Then
' do what you want with it '
End If
This approach makes the report independent from any particular form. The strategy does not break if you rename the current form or create a different form for report selection criteria.
You could even designate an appropriate header when report criteria are standardized in advance. For example, a command button captioned "View Yesterday's Additions":
strWhere = "[Date_Added] >= (Date() - 1) AND [Date_Added] < Date()"
strHeader = "Species Added Yesterday"
DoCmd.OpenReport ReportName:="YourReport", _
View:=acViewReport, _
WhereCondition:=strWhere, _
OpenArgs:=strHeader

Access Main Form 'Enter Parameter Value'

Sorry, I’m pretty new at Access so I might not be using some terms correctly (or might not know some terms at all).
I’m encountering an ‘Enter Parameter Value’ error when I put my subform1 into my mainform. On subform1 I have a button that runs query1, query2, query3. These 3 queries query tables and also calculated fields that are located on subform1. Subform1’s data source is query4. When I press the button (with 3 queries), everything works.
Once I place that subform1 onto my mainform (so that my user can press the button to run the queries without entering the subform1) I receive an ‘Enter Parameter Value’ error. Query1, query2, query3 are unable to find those calculated fields located on subform1. For example the ‘enter parameter value’ error is as follows: Forms!subform1!calculatedfield1. I’ve tried changing the ‘location’ to things like: Me.subform1!calculatedfield or Form!mainform1!subform1!calculatedfield but I still receive that same parameter error. I could move the calculated fields to mainform1, which makes the queries work fine. But I would like to keep all of the calculated fields on the subform. Does anyone have any suggestions?
I always name subform container control different from the object it holds, such as ctrDetails. Then this works for me:
Forms!Main!ctrDetails!fieldname
However, my preference would be to run SQL statement in VBA. So code behind button could be like:
CurrentDb.Execute "UPDATE table1 SET table1field = " & Me.subform1calculatedfield & _
" WHERE table1field Between " & Me.subform1calculatedfield & " And " & me.subform1calculatedfield2
Why do you need to save calculated data?

Can I use criteria from any current form in a single query in Access 2003

I have a report (ReportX) that I wish to open from two different forms (FormA and FormB) in my database. I wish to do this because FormA and FormB address different aspects of my data, even if they ultimately get to the same output. ReportX is based on data from QueryX.
The problem I have is that QueryX would ideally filter the data based on the current RecordID in the current form. But I don't know how to accomplish this. I'd like to design QueryX so that the criteria for RecordID is essentially CurrentForm!RecordID, but research suggests that I cannot do this. Must I make separate but otherwise identical queries and reports for each form? Or is there a way to use VBA to define the query criteria when I click on the OpenReportX command button?
I already tried using the WHERE condition in the OpenReport command:
DoCmd.OpenReport "ReportX", acViewPreview, ,"RecordID = " & RecordID
but that did not display the results I wished. I need the report header to display/print for each RecordID and the page count in the page footer to reflect only the current/total pages of the RecordID in question. (In other words, if record 1 is one page, record 2 is two pages and record 3 is three pages, then ReportX, when displaying the first page of record 2, should say "Page 1 of 2" and not "Page 2 of 6.") So being able to display and print a single record properly using record filters would also solve my problem.
Which is the least cumbersome/most possible solution?
You should be able to accomplish this using the WHERE condition argument when you open a report:
DoCmd.OpenReport "rptName", acViewPreview, ,"RecordID = " & Me!RecordID
In the case where a I need more control over a Report's recordsource than what the Where condition argument can do for me, I will set the Reports RecordSource to be blank (after designing the report). Next I write code create the correct SQL statement in the Open Report button's Click event, followed by code to open the report and pass in the SQL as an opening argument for the report.
Private Sub cmdOpenReport_Click()
Dim sSQL as string
sSQL = "SELECT * FROM tblWhatever WHERE RecordID = " & Me!RecordID
DoCmd.OpenReport "rptReportName", acViewPreview, , , ,sSQL
End Sub
Then in the report's Open event I write code to set the recordsource:
Private Sub Report_Open(Cancel As Integer)
If IsNull(Me.OpenArgs) = False Then
Me.RecordSource = Me.OpenArgs
End If
End Sub
If neither of those accomplish what you want then you have an issue of a different sort. It's a little difficult for me to understand why you need All Records to show up in the header but only one record in the detail area. And how you expect to accomplish this. You might be best off trying to write a query first that gives you the exact results that your looking for so you know that it can be done.
As a side note, I actually use very few saved queries in my designs. It's not that there's anything wrong with using them, as the option is there for your convenience. I frequently use raw SQL on both forms and reports and set the RecordSource to the SQL on the Form or Reports Open or Load events.
Yes you can point to form data items in a query, and subsequently use that query in a report. The forms need to be open before the report runs. As far as having a header for each record, that is controlled in the settings of the report and how it displays the data.
In the Field, or Critera you can use the format:
[Forms]![frm_Process_Candidates]![QuestionTemplate]
Where frm_Process_Candidates would be the name assigned to your form, and QuestionTemplate is either the name of a control on your form, or a field from the data source of your form.
If you have a sub-form, there will be another [Form] call in the middle there.
[Forms]![frm_Dropdown_Admin]![frm_Dropdown_Admin_Detail].[Form]![text22]
Access should figure it out from there.

Fill report with VBA

I got a form associated with a report. Depending on the fields filled in the form the report has to add some extra things, ej.: if the user chooses "A" in some field, let's say [options] field of the form, the report has to show "you choose A this time" in the [options] report's field, and "it's a good choice" in other field in the report, let's say [explanation] field.
I've used the openreport method in vba and playing around with the where statement or the openargs
docmd.openreport "myreport", acViewPreview, , "[options] = " & "you choose " + [forms!].[options!] + " this time"
But i don't need to do a query to fill the report, so the where condition doesn't fit my need. Also with openargs nothing happens, maybe i'm getting something wrong.. Does someone has an idea of how to make it work with openargs or with another method?
There may be a simpler solution, but you can insert your user's choices into a 1 row table. Then use that table as a recordsource for your report.
An advantage of this approach is that, since your report will have a stable data source (table), it's a little easier to develop.

Best way to prompt for report parameters in microsoft access

Lets say you are designing a sales report in microsoft access. You have 2 parameters: Startdate and EndDate.
I can think of 3 ways to prompt the end user for these parameters when the report is run.
Create a form with 2 Text Boxes and a button. The Button runs the report, and the report refers back to the form by name to get the start date and end date.
Create a form with 2 text boxes and a button. The button runs the report but sets the appropriate filter via the docmd.openreport command.
Base the report on a Query and define query parameters. Access will automatically prompt for those parameters one by one.
Which is the best way to go?
Which is best depends on a number of factors. First off, if you want to run the report without parameters, you don't want to define them in the recordsource of the report. This is also the problem with your first suggestion, which would tie the report to the form (from Access/Jet's point of view, there is little difference between a PARAMETER declared in the SQL of the recordsource and a form control reference; indeed, if you're doing it right, any time you use a form control reference, you will define it as a parameter!).
Of the three, the most flexible is your second suggestion, which means the report can be run without needing to open the form and without needing to supply the parameters at runtime.
You've left out one possibility that's somewhat in between the two, and that's to use the Form's OnOpen event to set the recordsource at runtime. To do that, you'd open the form where you're collecting your dates using the acDialog argument, hide the form after filling it out, and then write the recordsource on the fly. Something like this:
Private Sub Report_Open(Cancel As Integer)
Dim dteStart as Date
Dim dteEnd As Date
DoCmd.OpenForm "dlgGetDates", , , , , acDialog
If IsLoaded("dlgGetDates") Then
With Forms!dlgGetDates
dteStart = !StartDate
dteEnd = !EndDate
End With
Me.Recordsource = "SELECT * FROM MyTable WHERE DateField Between #" _
& dteStart & "# AND #" & dteEnd & "#;"
DoCmd.Close acForm, "dlgGetDates"
End If
End Sub
[Edit: IsLoaded() is a function provided by MS. It's so basic to all my Access coding I forget it's not a built-in function. The code:]
Function IsLoaded(ByVal strFormName As String) As Boolean
' Returns True if the specified form is open in Form view or Datasheet view.
Const conObjStateClosed = 0
Const conDesignView = 0
If SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> conObjStateClosed Then
If Forms(strFormName).CurrentView <> conDesignView Then
IsLoaded = True
End If
End If
End Function
Now, there are certain advantages to this approach:
you can pre-fill the dates such that the user would have to click only OK.
you can re-use the form in multiple locations to collect date values for multiple forms, since the form doesn't care what report it's being used in.
However, there is no conditional way to choose whether to open the form or not.
Because of that, I often use a class module to store filtering criteria for reports, and then check if the relevant class module instance has filter values set at the time the OnOpen event fires. If the criteria are set, then I write the SQL for the recordsource on the fly, if they aren't set, I just use the default recordsource (and any filter passed in the OpenReport argument). In this setup, you would run the report only after you've collected the criteria and set up the class module instance. The advantage of this approach is that the report can be run in either of the two contexts, and none of the parts need to know anything about each other -- the report simply needs to understand the class module's interface.
I used to use the Docmd.Openreport Where clause, your option 2. But I've switched to using report filters in the reports Open event, your option 1, as it supports creating PDF files which the Where clause does not. See Microsoft Access Report Printing Criteria Selection Form at my website.
As far as the dates go in SQL strings I use the Format statement as at Return Dates in US #mm/dd/yyyy# format
Also your option three can be handled by putting in the following example in the criteria in the reports record source SQL query. Forms!Form_Name!Control_Name. This is generally simpler for folks who don't want to get into VBA.