The truth is that few organizations can analyze their raw data at face value. More often than not, some preliminary analysis with calculations and dates must be carried out before a big-picture analysis can be performed. Again, Excel is the preferred platform for working with calculations and dates. However, as you will learn in this chapter, Access provides a wide array of tools and built-in functions that make working with calculations and dates possible.
If you are an Excel user trying to familiarize yourself with Access, one of the questions you undoubtedly have is "Where do the formulas go?" In Excel, you have the flexibility to enter a calculation via a formula directly into the dataset you are analyzing. You do not have this ability in Access. So where do you store calculations in Access?
As you have already learned, things work differently in Access. The natural structure of an Access database forces you to keep your data separate from your analysis. In this light, you will not be able to store a calculation (a formula) in your dataset. Now, it is true that you can store the calculated results as hard data, but using tables to store calculated results is problematic for several reasons:
Stored calculations take up valuable storage space.
Stored calculations require constant maintenance as the data in your table changes.
Stored calculations generally tie your data to one analytical path.
Instead of storing the calculated results as hard data, it is a better practice to perform calculations in "real-time," at the precise moment when they are required. This ensures the most current and accurate results and does not tie your data to one particular analysis.
In Access, calculations are performed using expressions. An expression is a combination of values, operators, or functions evaluated to return a separate value to be used in a subsequent process. For example, 2+2 is an expression that returns the integer 4, which can be used in a subsequent analysis. Expressions can be used almost anywhere in Access to accomplish various tasks: in queries, forms, reports, data access pages, and even tables to a certain degree. In this section, you learn how to expand your analysis by building real-time calculations using expressions.
Most calculations typically consist of hard-coded numbers or constants. A constant is a static value that does not change. For example, in the expression [List
_Price]*1.1, 1.1
is a constant; the value of 1.1
will never change. Figure 5-1 demonstrates how a constant can be used in an expression within a query.
In this example, you are building a query that will analyze how the current price for each product compares to the same price with a 10 percent increase. The expression, entered under the alias "Increase," will multiply the List_Price field of each record with a constant value of 1.1
, calculating a price that is 10 percent over the original value in the List_Price field.
Not all your calculations require you to specify a constant. In fact, many of the mathematical operations you will carry out are performed on data that already resides in fields within your dataset. You can perform calculations using any fields formatted as numbers or currency.
For instance, in the query shown in Figure 5-2, you are not using any constants. Instead, your calculation is executed using the values in each record of the dataset. This is similar to referencing cell values in an Excel formula.
Using the result of an aggregation as an expression in a calculation allows you to perform multiple analytical steps in one query. In the example in Figure 5-3, you are running an aggregate query. This query executes in the following order.
The query firsts group your records by market.
The query calculates the count of orders and the sum of revenue for each market.
The query assigns the aliases you have defined respectively ("OrderCount" and "Rev").
The query then uses the aggregation results for each branch as expressions in your "AvgDollarPerOrder" calculation.
Keep in mind that you are not limited to one calculation per query. In fact, you can use the results of one calculation as an expression in another calculation. Figure 5-4 illustrates this concept.
Figure 5.3. In this query, you are using the aggregation results for each market as expressions in your calculation.
In this query, you are first calculating an adjusted forecast and then using the results of that calculation in another calculation that returns the variance of Actual versus Adjusted Forecast.
Look at the query in Figure 5-5. The calculation in this query returns a number with a fractional part. That is, it returns a number that contains a decimal point followed by many trailing digits. You want to return a round number, however, making the resulting dataset easier to read.
To force the results of your calculation into an integer, you can use the Int
function. Int
is a mathematical function that removes the fractional part of a number and returns the resulting integer. This function takes one argument, a number. However, instead of hard-coding a number into this function, you can use your calculation as the argument. Figure 5-6 demonstrates this concept.
You can use calculations that result in a number value in any function where a number value is accepted as an argument.
If you are not yet comfortable manually creating complex expressions with functions and calculations, Access provides the Expression Builder. The Expression Builder guides you through constructing an expression with a few clicks of the mouse. Avid Excel users may relate the Expression Builder to the Insert Function wizard found in Excel. The idea is that you build your expression by simply selecting the necessary functions and data fields.
To activate the Expression Builder, right-click inside the cell that contains your expression and select Build, as shown in Figure 5-7.
In fact, you can activate the Expression Builder by right-clicking anywhere you would write expressions, including: control properties in forms, control properties in reports, field properties in tables, as well as in the query design grid.
Figure 5.7. Activate the Expression Builder by right-clicking inside the Field row of the query grid and selecting Build.
As you can see in Figure 5-8, the Expression Builder has four panes to work in. The upper pane is where you enter the expression. The lower panes show the different objects available to you. In the lower-left pane, you can see the five main database objects: tables, queries, forms, reports, and functions.
Double-click any of the five main database objects to drill down to the next level of objects. By double-clicking the Functions
object, for example, you can drill into the Built-In Functions folder, where you will see all the functions available to you in Access. Figure 5-9 shows the Expression Builder set to display all the available math functions.
If you are using Access 2007, your Expression Builder will look slightly different from the one shown in Figure 5-9. However, the basic functionality remains the same. Thus, you can use the concepts illustrated in this section even with Access 2007.
Figure 5.8. The Expression Builder displays all the database objects you can use in your expression.
Figure 5.9. Similar to the Insert Function wizard in Excel, the Expression Builder displays all the functions available to you.
The idea is that you double-click the function you need and Access automatically enters the function in the upper pane of the Expression Builder. In the example shown in Figure 5-10, the selected function is Round
. As you can see, the function is immediately placed in the upper pane of the Expression Builder, and Access shows you the arguments needed to make the function work. In this case, you need a Number argument and a Precision argument.
If you don't know what an argument means, simply highlight the argument in question and click the Help button. Access will activate a help window that provides an explanation of the function. As shown in Figure 5-11, for example, the Round
function requires a number to be rounded and an optional numdecimalplaces
argument, which, in this case, indicates the number of decimal places used in the rounding operation.
As you can see in Figure 5-12, instead of using a hard-coded number in the Round
function, an expression returns a dynamic value. This calculation divides the sum of [TransactionMaster]![Line_Total]
by 13. Since the numdecimalplaces
argument is optional, that argument is omitted.
Figure 5.12. The function here rounds the results of the calculation, ([TransactionMaster]![ Line _ Total])/13
.
When you are satisfied with your newly created expression, click the OK button to insert it in the query grid. Figure 5-13 shows that the new expression has been added as a field. Note that the new field has a default alias of Expr1; you can rename this something more meaningful.
No matter what platform you use to analyze your data, you always run the risk of generating errors when you work with calculations. No magic function in Access can help you prevent errors in your analysis. However, you can take a few fundamental actions to avoid some of the most common calculation errors.
You might remember from your algebra days that when working with a complex equation executing multiple mathematical operations, the equation does not necessarily evaluate left to right. Some operations have precedence over others and therefore must occur first. The Access environment has similar rules regarding the order of operator precedence. When you are using expressions and calculations that involve several operations, each operation is evaluated and resolved in a predetermined order. It is important to know the order of operator precedence in Access. An incorrectly built expression may cause errors in your analysis.
The order of operations for Access is as follows:
Evaluate items in parentheses.
Perform exponentiation (^
calculates exponents).
Perform negation (-
converts to negative).
Perform multiplication (*
multiplies) and division (/
divides) at equal precedence.
Perform addition (+
adds) and subtraction (-
Subtract) at equal precedence.
Evaluate string concatenation (&
).
Evaluate comparison and pattern matching operators (>, <, =, <>, >=, <=
, Like, Between, Is) at equal precedence.
Evaluate logical operators in the following order: Not, And, Or.
Operations equal in precedence are performed from left to right.
How can understanding the order of operations ensure that you avoid analytical errors? Consider this basic example: The correct answer to the calculation (20+30)*4
is 200. However, if you leave off the parentheses (as in 20+30*4
), Access will perform the calculation like this: 30*4 = 120 + 20 = 140
. The order of operator precedence mandates that Access perform multiplication before subtraction. Therefore, entering 20+30*4
gives you the wrong answer. Because the order of operator precedence in Access mandates that all operations in parentheses be evaluated first, placing 20+30
inside parentheses ensures the correct answer.
A Null value represents the absence of any value. When you see a data item in an Access table that is empty or has no information in it, it is considered Null.
The concept of a Null value causing errors in a calculation might initially seem strange to Excel power users. In Excel, if there is a Null value within a column of numbers, the column can still be properly evaluated because Excel simply reads the Null value as zero. This is not the case in Access. If Access encounters a Null value, it does not assume that the Null value represents zero. Instead, it immediately returns a Null value as the answer. To illustrate this behavior, build the query shown in Figure 5-14.
Figure 5.14. To demonstrate how Null values can cause calculation errors, build this query in Design view.
Run the query, and you will see the results shown in Figure 5-15. Notice that the Variance calculation for the first record does not show the expected results; instead, it shows a Null value. This is because the forecast value for that record is a Null value.
Looking at Figure 5-15, you can imagine how a Null calculation error can wreak havoc on your analysis, especially if you have an involved analytical process. Furthermore, Null calculation errors can be difficult to identify and fix. This is a good place to remind you that you should rarely use Null values in your tables. Instead, you should use a logical value that represents "no data" (for example, 0, "NA," or "Undefined").
That being said, you can avoid Null calculation errors by using the Nz
function, which enables you to convert any Null value to a value you specify.
Figure 5.15. As you can see, when any variable in your calculation is Null, the resulting answer is a Null value.
Armed with this new information, you can adjust the query in Figure 5-14 to utilize the Nz
function. Since the problem field is Forecast, pass the Forecast field through the Nz
function. Figure 5-16 shows the adjusted query.
As you can see in Figure 5-17, the first five records now show a Variance value even though the values in the Forecast field are Null. Note that the NZ
function does not physically place a zero in the Null values. The NZ
function merely tells access to treat the Nulls as zeros when calculating the Variance field.
Basic syntax mistakes in your calculation expressions can also lead to errors. Follow these guidelines to avoid slip-ups:
If you are using fields in your calculations, enclose their names in square brackets ([ ]).
Make sure you spell the names of the fields correctly.
When assigning an alias to your calculated field, be sure you don't use a name that currently exists in the table(s) being calculated.
Do not use illegal characters—period (.
), exclamation mark (!
), square brackets ([ ]
) or an ampersand (&
)—in your aliases.
In Access, every possible date starting from December 31, 1899 is stored as a serial number. For example, December 31, 1899 is stored as 1; January 1, 1900 is stored as 2; and so on. This system of storing dates as serial numbers, commonly called the 1900 system, is the default date system for all Microsoft Office applications. You can take advantage of this system to perform calculations with dates.
Figure 5-18 shows one of the simplest calculations you can perform on a date. In this query, you are adding 30 to each ship date. This effectively returns the order date plus 30 days, giving you a new date.
Figure 5.18. You are adding 30 to each ship date, effectively creating a date equal to the ship date plus 30 days.
To be calculated correctly, dates must reside in a field formatted as a Date/Time field. If you enter a date into a Text field, the date will continue to look like a date, but Access will treat it like a string. The result is that any calculation performed on dates in this Text formatted field will fail. Ensure that all dates are stored in fields formatted as Date/Time.
You can also calculate the number of days between two dates. The calculation in Figure 5-19, for example, subtracts the serial number of one date from the serial number of another date, leaving you the number of days between the two dates.
As of Access 2010, 25 built-in Date/Time functions are available. Some of these are functions you will very rarely encounter, whereas you'll use others routinely in your analyses. This section discusses a few of the basic Date/Time functions that come in handy in your day-to-day analysis.
Date
is a built-in Access function that returns the current system date—in other words, today's date. With this versatile function, you never have to hard-code today's date in your calculations. That is to say, you can create dynamic calculations that use the current system date as a variable, giving you a different result every day. In this section, you look at some of the ways you can leverage the Date
function to enhance your analysis.
Imagine that you have to calculate aged receivables. You need to know the current date to determine how overdue the receivables are. Of course, you can type the current date by hand, but that can be cumbersome and prone to error.
To demonstrate how to use the Date
function, create the query shown in Figure 5-20.
You can use the Date
function to filter out records by including the function in a criteria expression. For example, the query shown in Figure 5-21 returns all records with an order date older than 90 days.
Imagine that you have been asked to provide a list of account managers, along with the number of years they have been employed by the company. To accomplish this task, you must calculate the difference between today's date and each manager's hire date.
The first step is to build the query shown in Figure 5-22.
When you look at the query results, shown in Figure 5-23, you realize that the calculation results in the number of days between the two dates, not the number of years.
To fix this, switch back to Design view and divide your calculation by 365.25. Why 365.25? That is the average number of days in a year when you account for leap years. Figure 5-24 demonstrates this change. Note that your original calculation is now wrapped in parentheses to avoid errors due to order of operator precedence.
A look at the results, shown in Figure 5-25, proves that you are now returning the number of years. All that is left to do is to strip away the fractional portion of the date using the Int
function. Why the Int
function? The Int
function does not round the year up or down; it merely converts the number to a readable integer.
Want to actually round the number of years? You can simply wrap your date calculation in the Round
function. The Round
function is highlighted in Appendix A of this book.
Wrapping your calculation in the Int
function ensures that your answer is a clean year without fractions (see Figure 5-26).
Figure 5.25. Your query now returns years, but you must strip away the fractional portion of your answer.
Figure 5.26. Running this query returns the number of years each employee has been with the company.
You can calculate a person's age by using the same method. Simply replace the hire date with the date of birth.
The Year, Month, Day
, and Weekday
functions are used to return an integer that represents their respective parts of a date. These functions require a valid date as an argument. For example:
Year(#12/31/1997#)
returns 1997.
Month(#12/31/1997#)
returns 12.
Day(#12/31/1997#)
returns 31.
Weekday(#12/31/1997#)
returns 4.
The Weekday
function returns the day of the week from a date. In Access, weekdays are numbered from 1 to 7, starting with Sunday. Therefore, if the Weekday
function returns 4, the day of the week represented is Wednesday.
Figure 5-27 demonstrates how you use these functions in a query environment.
A common analysis for many organizations is to determine on which date a certain benchmark is reached. For example, most businesses want to know on what date an order becomes 30 days past due. Furthermore, on what date should the customer receive a warning letter? An easy way to perform these types of analyses is to use the DateAdd
function. The DateAdd
function returns a date to which a specified interval has been added.
The query shown in Figure 5-30 illustrates how the DateAdd
function determines the exact date a specific benchmark is reached. You are creating two new fields with this query: Warning and Overdue. The DateAdd
function in the Warning field returns the date that is three weeks from the original order date. The DateAdd
function in the Overdue field returns the date that is one month from the original order date.
Why would you need to group your dates into quarters? Most databases store dates rather than quarter designations. Therefore, if you want to analyze data on a quarter-over-quarter basis, you have to convert dates into quarters. Surprisingly, there is no Date/Time
function that allows you to group dates into quarters. There is, however, the Format
function.
The Format
function belongs to the Text category of functions and allows you to convert a variant into a string based on formatting instructions. From the perspective of analyzing dates, you can pass several valid instructions to a Format
function.
Format(#01/31/2004#, "yyyy")
returns 2004.
Format(#01/31/2004#, "yy")
returns 04.
Format(#01/31/2004#, "q")
returns 1.
Format(#01/31/2004#, "mmm")
returns Jan.
Format(#01/31/2004#, "mm")
returns 01.
Format(#01/31/2004#, "d")
returns 31.
Format(#01/31/2004#, "w")
returns 7.
Format(#01/31/2004#, "ww")
returns 5.
Keep in mind that the value returned when passing a date through a Format
function is a string that cannot be used in subsequent calculations.
The query in Figure 5-31 shows how you group all the order dates into quarters and then group the quarters to get a sum of revenue for each quarter.
If you want to get fancy, you can insert the Format
function in a crosstab query, using Quarter as the column (see Figure 5-32).
As you can see in Figure 5-33, the resulting dataset is a clean look at revenue by product, by quarter.
The DateSerial
function allows you to construct a date value by combining given year, month, and day components. This function is perfect for converting disparate strings (that together represent a date) into an actual date.
The wonderful thing about the DateSerial
function is that you can pass other date expressions as arguments. For example, pretend that the system date on your PC is August 1, 2005. For those of you who have been paying attention, this means that the Date
function would return August 1, 2005. That being the case, the following expression would return August 1, 2005:
DateSerial ( Year(Date()), Month(Date()), Day(Date()) )
Year(Date())
returns the current year, Month(Date())
returns the current month, and Day(Date())
returns the current day.
So how is this helpful? Well, now you can put a few twists on this by performing calculations on the expressions within the DateSerial
function. Consider some of the possibilities:
Get the first day of last month by subtracting 1
from the current month and using 1
as the Day
argument.
DateSerial(Year(Date()), Month(Date()) - 1, 1)
Get the first day of next month by adding 1
to the current month and using 1
as the Day
argument.
DateSerial(Year(Date()), Month(Date()) + 1, 1)
Get the last day of the previous month by using 0
as the Day
argument.
DateSerial(Year(Date()), Month(Date()), 0)
Get the last day of the current month by adding 1
to the current month and using 0
as the Day
argument.
DateSerial(Year(Date()), Month(Date()) +1, 0)
Passing a 0
to the Day
argument automatically gets you the last day of the month specified in the DateSerial
function. This is because Access will interpret the 0 as bleeding into the previous month. That is to say from an Access point of view, if 1 is the first day of the month, then 0 means you want to go into the previous month.
With Access 2010, Microsoft introduced a new data type called Calculated. This new data type allows you to embed calculations directly inside your tables. That is to say, you can create a field that holds no real data, only a predefined calculation—similar to using a formula in a cell in Excel.
Database purists are sure to shun this new functionality because it goes against the rule that calculations should never be stored. Stored calculations require constant maintenance as the data in your table changes. Not to mention that stored calculations generally tie your data to one analytical path.
So why would Microsoft tweak such a long-standing database rule? The reason has to do with the Internet. In the near future, Access databases will have the ability to work on the Web. That is to say, users can interact with Access databases, forms, and reports online. Calculated data types are the first step in giving Access developers a way to employ calculations online without resorting to background queries and code (which may not be available to a user while connected through the Internet).
That being said, offline scenarios that have a calculated data type can save you time because they perform relatively simple operations that won't unduly lock down or hinder your table architecture.
Take a moment to go through a simple scenario where you can use the Calculated data type. Follow these steps:
In your sample database, you'll find a table called 2009_Projections. Right-click 2009_Projections and select Design view. Notice that one of the fields in the table is Percent Increase (see Figure 5-34). You could calculate a 2009 Target field that shows a real-time calculation of the projection for each market.
Add the new field and select the Calculated data type, as shown here in Figure 5-35. The Expression Builder will immediately activate.
The idea is to enter your calculation in the upper pane, as demonstrated in Figure 5-36. In this example, you are performing a simple operation that adds the Percent Increase to the 2008 Actual.
Once your expression is set, you can format the calculated field as needed. In Figure 5-37, the 2009 Projection field is formatted to show as a currency.
If all went well, you'll have a new calculated field. As you can see in Figure 5-38, the new 2009 Projection field looks and feels like a standard field. However, this field will recalculate on-the-fly if any of the linked variables are changed. To test this, change any of the values under Percent Increase. Once you change a value, the associated 2009 projection will change.
Figure 5.38. Although your newly created calculated field looks and feels like a standard field, it will recalculate on-the-fly.
Be aware the Calculated data types will only work in Access 2010 databases. They are not backward compatible. That means that Access 2007 or prior versions cannot use any field designated as a Calculate data type.
Not many Excel analysts know that Access has the ability to perform calculations. In fact, the most common question asked about Access is "Where do the formulas go?" The reality is that Access provides a wide array of tools and built-in functions that make performing calculations possible.
The first thing to remember is that calculations are typically not stored in Access tables as formulas are stored in Excel. There are several reasons for this:
Stored calculations take up valuable storage space.
Stored calculations require constant maintenance as the data in your table changes.
Stored calculations generally tie your data to one analytical path.
Instead of storing the calculated results as hard data, calculations in Access are typically performed in "real-time" with the use of various types of queries.
Microsoft has introduced a change to this long-standing rule with the Calculated data type. This new data type allows you to embed calculations directly inside your tables. Although this is generally shunned, you can use the Calculated data type to perform simple operations that won't unduly lock down or hinder your table architecture.
In addition to performing mathematical calculations, Access can perform calculations with dates. This is because Access stores all dates as serial numbers with December 31, 1899 being day 1. You can take advantage of this system to perform queries using date calculations. For example, you can find all orders over 90 days old, you can calculate the seniority of each employee, you can calculate the due date of an order, and the list goes on.
3.145.47.130