You need a different technique to create totals based on calculated controls. If you try the simple method from the previous lesson, Access pops up a parameter dialog asking for a value for the calculated control that you are trying to total. This kind of glitch can drive you crazy when you don't know where the problem is coming from!
Example: Report with calculated control Savings in Detail section.
Totals over each group. Savings = [Retail Price] - [Actual Cost]
Using data from Christmas Ornaments database
You cannot use the simple method from the previous lesson for totaling values that come from a calculated control. There are ways, however, to get around this limitation!
Method 1: Repeat the calculation in the control source for the total
(Can not use an
aggregate function in the calculation, like Sum, Avg, Max, or Min.)
You have a calculated control in Detail section:
The control source is an
expression that calculates the control's value. The calculation does NOT use an aggregate function (Sum, Avg, Count, Max, Min, etc.).
In the example report, the control named Savings is in the Detail section and is calculated with the expression =[Retail Price]-[Actual Cost] The fields Retail Price and Actual Cost must be in the Report Source, of course. In this example the record source is a query which filters the records.
Other aggregate expressions would also work, like
=Max([Retail Price]-[Actual Price]) or
=Avg([Retail Price]-[Actual Price])
Error: Parameter dialog appears
It seems logical to use the
expression =Sum([Savings]) to total the Savings values. This syntax worked to total the fields Retail Price and Actual
Cost. However, if you try it with Savings, a parameter dialog
will ask you to
enter a value for Savings. Since Savings was a calculated control, Access cannot see its value to put in a
header or footer.
Method 2: Calculate field in query
Make the report's source a query which includes a calculated field.
In the example you could add a column to the source query like:
Difference:[Retail Price]-[Actual Price]
Method 3: SUM by collecting a running sum
(Can use an aggregate function in the calculated control)
This method is required when the calculation includes an aggregate function (Sum, Avg, Max, Min, etc.) but will also work for simpler calculations. A Running Sum adds up the values. (Duh!) There is no way to do a running average, or any other aggregate function. Just adding up the calculated values.
To see both Running Sum and
current value:
Use two controls. One with Running Sum = No to show the record's
value and one with Running Sum = Over Group or Over All.
Invisible control: If all you
want to see is a grand total for the group or report, you don't need to
see the accumulating values for each record. Set the Visible property
for the control in the Detail section to No.
You can make the control width teeny tiny if you need the space for other controls.
Method 4: Create a function - If you used VBA code to calculate a
control's value, you must create your own function to get a total.
Example from Microsoft
Problem:
Totals are not accumulating as expected
![]() |
Step-by-Step: Totals with Calculated Values |
![]() |
What you will learn: | to plan the report first to use Query Builder to create a Record Source to add controls and labels to create a group and edit the layout to create a calculated control to create a total of calculated values for group and whole report with: Method 1: Repeating calculation in Total control Method 2: Query with calculated field Method 3: Running Sum property |
Start with: , resource files, worldtravel-Lastname-Firstname.accdb from folder databases project4 as updated in the previous lesson
You will create a report that shows the total price of the trips sold by each travel agent, after including any discounts that were applied. The discount is a complicating factor. The Trips table has a Price field and a DiscountID field but does not have a field for the cost of the trip after taking the discount. In Access 2010, 2013, and 2016 you could have a calculated field in the table design for this CostAfterDiscount.
The Summary Options in the Report Wizard can only use fields from a table. The Group, Sort, and Total pane cannot see anything but fields in the table either. But there is a way!
You will create a new query to use as the Report Source for the report. We will do this in stages. If you get complicated to start with and there are errors, it is difficult to figure out what is causing the problems.
The query must contain the fields that you want to show on the report and any fields that you need to group or sort the records. It can also contain calculated values.
Plan the report's organization before designing the query:
The report is going show the final cost of the trips sold by each travel agent and also a total for each agent. You will need to show at least the agent's name and the final cost of the trip. For this report we will show the client's name.
For this first attempt, we will not try to calculate anything in the query itself.
Where is the information that you need?
The Trips table for sure! But that table has only ID numbers for the agent and the client and the discount. So you need to add tables/queries that have the names (Staff and Clients), the original price (Trips), and the discount percentages (Discount). These tables already have relationships, so Access can match up records from the different tables neatly. You won't have to add all of the fields to the query grid. Another benefit of a relational database!
What fields do you need for grouping and sorting?
You will group the records by agent name and sort the agents and clients alphabetically.
You can create a query that is saved as part of the report using Query Builder, which looks almost exactly like Query Design View. Such a query cannot be used by another report or form since it does not show in the Navigation Pane. This also means that it cannot be messed up because you made changes to the query for a different purpose. This is a BIG advantage of using Query Builder.
Add the following fields in this order:
Staff: LastName, FirstName, MiddleName, Suffix
Clients: LastName, FirstName, MiddleName, Suffix
Discounts: Discount %
Trips: Price
Sort Ascending the LastName, FirstName, MiddleName columns for the names from the Staff table first and then the Clients table.
The order of the columns is important! But there can be other columns in between the ones that are sorted.
Below the field name in the grid is the name of the table that the field is in. When field names are duplicated in different tables, you must be very careful!
Run the query and check the alphabetizing.
The agents are in alphabetical order. Each agent's clients are in alphabetical order.
Click the Close button on the ribbon tab.
A message appears that asks if you want to save changes to the SQL and update the property.
The property is RecordSource. So, this just means saving your changes and updating the report to use the new query.
Click on Yes.
You are back in Design View with an SQL expression in the Record Source property.
The report is still blank.
Save the report as Trips by Agents.
Now you can add fields to the report's Design View.
Drag all of the fields to the Detail section.
They neatly line up vertically.
The controls for duplicated field names include the table name with a period between the table and field names. This is the only way Access can keep track of what goes where.
Switch to Report View and scroll to see how this initial version of the report looks.
Access 2010, 2013, and 2016 look just alike. In Access 2007 the controls do not have borders.
Check the alphabetizing.
That is working, but the rest is not good at all!
The names are hard to read when separated into separate controls like this.
The layout wastes a lot of space to the right and below the record controls. That bottom space is easy to fix!
Drag the bottom edge of the Detail section up below the last control, Price.
Switch to Report View.
That fixed one space issue.
Next you will change the layout of controls to use the blank horizontal space.
Save.
[Trips by Agents]
Next you will create the group on the agent's name and rearrange the report.
Drag the control Staff.LastName to the group header.
The label and control move together.
Switch to Report View.
Access 2007 still does not show borders on the controls.
Right click on a section bar and in the context menu click on Report Header/Footer.
A blank Report Header and Report Footer appear.
Now that you have the report under better control, you can add a control that will calculate the price of the trips after any discount.
We want to show the price after taking off the discount. What we have is the original price and the percentage discount, not the dollar amount of the discount. There are several expressions that will give the same result. This one has simple syntax. It could be much more complex. Really!
Switch to to Report View.
Your report shows the discount percentage, the trip's price, and calculates the Final Price. Notice that not everyone got a discount.
Now you are ready to add some totals, which is the whole point of this report.
First, try using the Group, Sort, and Total pane again to get group and report totals for Final Price.
Expand the list of fields for Total On.
The new calculated control Final Price is not there!
FAILED METHOD: You cannot use the Group, Sort, and Total pane to total a calculated control.
Let's try adding the total control manually.
Switch to to Report View.
Whoops. A parameter dialog appears asking you to enter a value for Final Price. That means that Access does not see a field with that name. That's right! It is a calculated control. Access cannot do the calculation you want this way.
Click on Cancel.
You are back in Design View.
FAILED METHOD: You cannot total a calculated control on the report.
Instead of asking Access to do a Sum with the calculated control, you can tell it what the calculation is, right in the expression for the control.
Switch to to Report View.
In Access 2010, 2013, and 2016 the group footer has a background color. Some formatting and some lines could help make the totals easier to see.
Problem: #Error for Grand Total
You placed the control in the Page Footer instead of the Report Footer.
Solution: Move the control to the Report Footer.
Add a dividing line above the control for the total in the group footer and above the total in the report footer.
Line width: The default width is 1" for a line and for a control. So the default size is OK for now.
You must make some adjustments. The controls for the totals need to be wider. Best Fit for controls will change the height hold the current font size but won't change the width. Access does not know what the values are until they are calculated.
Select the line above the control.
Selecting this line can be tough. Drag from the right side of the total control to the left and up. You will likely select both the line and the control. Hold the SHIFT key down and click on the control to deselect it.
Alternate method: Select from the drop list. The line will have a name like Line18. The first line is the group footer line and the second one is the report footer line (if you created these according to the directions).
Design choices make it easy to see:
What's still missing?
Time period covered by the report!
When you plan to run a report at different times, you need to show what time period the report covers. Even a one-time report probably needs the time period stated somewhere.
In this case, the report includes all records in the database.
Switch to Report View.
Notice how a short expression =Now() returned a long date and a long expression returned a short "Page 1 of 1".
Pages in Report View: You will ALWAYS see Page 1 of 1 when in Report View, no matter how many pages it will really take to print.
Doing calculations with the report's query is usually faster than doing them in a control as the report is formatted. Have you noticed a time lag when displaying the report before the totals show? The calculated controls are calculated after the formatting is done. The more records there are and the more calculated controls there are in the report, the more important it is to consider such speed issues.
You will now revise the report to calculate the Final Price in the source query.
Run the query to be sure it works.
The datasheet looks good.
Problem: Only 10 of the 11 trips show in the datasheet
You did not revise the record in the Trips table earlier that had the default value for the ClientID. The joins between tables for this query require
that there be values on both sides of the join. That may or
may not be what you want to happen.
Solution:
There are two easy fixes, depending
on what you want to see. You can change the join to show the trip
anyway, or (better) you can open the Trips table and enter a ClientID. But, with the Query
Builder window open, you cannot open another Access object to edit the
data. You will have to wait to fix this.
Close the Query Builder window and save the changes when prompted.
The query is saved as part of the report's design. It will not show in the Navigation pane.
There are times when you would like to see the total as it accumulates and not just a final total. That is done using the Running Sum property, but it only works for SUM, not for averages, maximum, minimum, etc.
Move the label and controls closer together and over to the left so that there is room for a new control and label to the right of Final Price.
Don't forget the dividing lines!
Verify that your report is still 8" wide.
If it is not, fix it. You may need to move controls, labels, or lines first.
For this lesson you created several versions of a report:
Fixing missing record, if necessary
Now the report shows a new record for a trip sold by Hector Chavez. The totals for Chavez and the report updated. Hurrah!