MS Access Forum / New Users / May 2008
Help!! I having problems with Null Values!
|
|
Thread rating:  |
WLBrandibur - 11 May 2008 02:07 GMT I am trying to build a report to look like a statement. I have two fields.. One is this months data and the other is the previous data. Since I only have room for one number, I went back to the query to build the iif formula to tell it to look at either one field or another and give me the one that has numbers in it. Since some of the fields are null (obviously) it keeps giving me problems. My mom says I need to build a null program, but she can't remember how and I cannot find anything on it. And due to the null problem, the report is not showing that field. It will show the other fields, even ones that are depending on the field input to calculate the answer. I am building this report in 2007, but need it to continue to work as if it is in 2003. Please help.. I am getting very frustrated.
 Signature Wendy
Ken Snell (MVP) - 11 May 2008 03:12 GMT You didn't show us the expression that you've tried to use, but perhaps this will give you a starting point:
=Nz([FieldName1], [FieldName2])
 Signature Ken Snell <MS ACCESS MVP>
>I am trying to build a report to look like a statement. I have two >fields.. [quoted text clipped - 13 lines] > in > 2003. Please help.. I am getting very frustrated. Tom Wickerath - 11 May 2008 03:31 GMT Hi Wendy,
Perhaps you need to use the conditional IF function, IIF, in combination with the ISNull function. The syntax for the IIF function is this:
IIf(expr, truepart, falsepart)
The syntax for the IsNull function is this:
IsNull(expression)
So, for instance, you might have a Control Source for a text box that looks something like this:
=IIF(IsNull(Field1) = True, [Field2], [Field1])
where Field1 and Field2 are the two fields in question. Make the appropriate substitutions for your field names. You could also have this expression as the Field in a query, but you would leave out the = sign. This works in the Northwind sample database, using the Customers table in a query:
Field: CityState: IIf(IsNull([City])=True,[Region],[City])
Tom Wickerath Microsoft Access MVP http://www.accessmvp.com/TWickerath/ http://www.access.qbuilt.com/html/expert_contributors.html __________________________________________
> I am trying to build a report to look like a statement. I have two fields.. > One is this months data and the other is the previous data. Since I only have [quoted text clipped - 7 lines] > building this report in 2007, but need it to continue to work as if it is in > 2003. Please help.. I am getting very frustrated. Tom Wickerath - 11 May 2008 07:44 GMT PS. Ken's answer is more succinct than mine. Use his method instead.
Tom Wickerath Microsoft Access MVP http://www.accessmvp.com/TWickerath/ http://www.access.qbuilt.com/html/expert_contributors.html
WLBrandibur - 11 May 2008 16:49 GMT Thanks for your help!! What Ken gave me ran and gave me the desired result when there was updates, but it is still giving me the parameter response. I am dealing with amounts and some of them are a zero amount. Some are blank, waiting for the numbers to be sent in to me. We are wanting to use the number that are the most up to date. For instance if the account closed then the answer would be 0 no matter what month and I have this plugged in now. Or maybe the account didn't send in the information for April, then we would want to have the formula look at March. My mom mentioned that Access can not always discern the difference between a character=zero and an actual null value=blank.
 Signature Wendy
> PS. Ken's answer is more succinct than mine. Use his method instead. > [quoted text clipped - 3 lines] > http://www.accessmvp.com/TWickerath/ > http://www.access.qbuilt.com/html/expert_contributors.html Ken Sheridan - 11 May 2008 19:09 GMT Wendy:
Before we look at your specific problem it might help if we examine a few general concepts. Firstly what do we mean by NULL? Well, the first thing to understand is that NULL is not a value, so to talk of a NULL value is really a contradiction in terms, although, just to muddy the waters, its true that the Value property of an object can be NULL. A NULL is really the absence of a value. About the nearest we can get to saying what its means is that its an 'unknown'. Zero on the other hand is most definitely a value.
Because a NULL is not a value it behaves rather strangely. We say that NULL 'propagates' for instance. This means that any arithmetical expression invoving a NULL will always result in NULL whatever the other value are, so 10 + NULL = NULL, 100 + NULL = NULL, 25 * NULL = NULL and so on. Often we want to use another value if something is NULL, which is where the Nz function comes in. This returns a value in place of a NULL or the actual value if something is not NULL, e.g. if MyField is NULL then Nz([MyField],0) returns 0, but if MyField is 42 then Nz([MyField],0) returns 42.
NULLs also behave a little strangely in comparative operations if we have a criterion of MyField < 123 say and MyField is NULL then the answer is not True or False, but, you've guessed it, NULL. This makes sense oif you think about it because, if NULL is an 'unknown', then the answer if we compare NULL with any value must also be 'unknown', i.e. NULL. The field which is NULL could be less than 123, more than 123 or it could equal 123; we just don't know. This does mean we need to be careful with NULLS. What would a NULL credit limit for a customer mean? Zero credit? Unlimited credit? There is no way of knowing. With currency data its more often than not best not to allow NULLs and to give fields a DefaultValue of 0.
So much for NULLs. Turning to table design in a relational database like Access, your statement: "I have two fields.. One is this months data and the other is the previous data." does set my antennae twitching a bit. It sounds to me that you might, by having separate columns for each month, be doing what's known as 'encoding data as column headings'. This is against a fundamental principle of relational database design which requires that data only be stored as values at column positions in rows in tables. Having columns for each month is storing two data values 'this month' and 'last month' as the column headings. A correctly design table would have the values for each month in separate rows, with columns to indicate the month and the amount. I'll come back to this below.
In a relational database tables rep[resent 'entity types' and their columns represent 'attributes types' of the entity type. FirstName and LastName might be attribute types of a Customers entity type for instance. The columns in a table should represent attribute types specific to that entity type, so as to avoid any redundancy. OrderNumber would not be an attribute type of a Customers entity type for example, as you'd have to have separate rows in the Customers table for every order placed by that customer, so there would be a lot of repetition of FirstName, LastName etc. and the possibility of inconsistencies. Instead you'd have an Orders table with a CustomerID foreign key column which references the primary key of Customers. This is a one-to-may relationship type but sometimes relationship types can be many-to-many, e.g. Orders to products as each order can be for more than one product, and ech product can be included in more than one order. In a case like this the relationship type is represented by another table, OrderDetails with columns OrderID, and ProductID, these being foreign keys referencing the primary keys of Orders and Products, along with columns such as UnitPrice, Quantity etc which are specific to each order detail.
Applying these general principles to your scenario, lets assume a simple hypothetical situation where you have accounts identified by unique AccountID values and columns such as AccountName, Closed (a Yes/No column to indicate when an account is closed etc. So you'd have an Accounts table with columns for these attribute types. Each month an amount is returned in relation to each account, so the attribute types for this are the year, the month and the amount so you'd have an AccountReturns table with columns ReturnYear, ReturnMonth and Amount, all numbers (the last as currency) as this makes it easy to work with the months and it’s a simple matter to get the name of the month from the number if required. Accounts and AccountReturns.
When a return is made a new row for the account is inserted into the AccountsReturned table. One things this means of course is that there will never be a NULL amount as no row will exist until an amount is returned.
To list all returns for each account is simple a matter of joining the two tables in a query like so:
SELECT Accounts.AccountID, AccountName, Closed, ReturnYear, ReturnMonth, Amount FROM Acounts INNER JOIN AccountReturns ON AccountReturns.AccoutID = Accounts.AccountID;
However, you want to return the latest returns per account only, and to return a zero if the account is closed. To do this you need to restrict the rows returned to those where the ReturnYear and ReturnMonth values represent the latest return for each account. This done by means of a subquery, which is 'correlated' to the main 'outer' query on the AccountID values. It would go something like this:
SELECT Accounts.AccountID, AccountName, Closed, FORMAT(ReturnYear & "-" & ReturnMonth& "-" & 1,"mmm yyyy") As MonthReturned, IIF(Closed,0,Amount) AS AmountReturned FROM Acounts INNER JOIN AccountReturns AS AR1 ON AR1.AccoutID = Accounts.AccountID WHERE AR1.ReturnYear & FORMAT(AR1.ReturnMonth,"00") = (SELECT MAX(AR2.ReturnYear & FORMAT(AR2.ReturnMonth,"00")) FROM AccountReturns AS AR2 WHERE AR2.AccountID = AR1.AccountID);
To explain this:
1. FORMAT(ReturnYear & "-" & ReturnMonth& "-" & 1,"mmm yyyy") As MonthReturned shows the year/month in a format such as May 2008.
2. IIF(Closed,0,Amount) AS AmountReturned shows a zero if an account is closed.
3. AR1.ReturnYear & FORMAT(AR1.ReturnMonth,"00") tacks the year and month values together in a format like 200805.
4. MAX(AR2.ReturnYear & FORMAT(AR2.ReturnMonth,"00")) finds the highest value of the year/month in the same format as above, i.e. the latest month.
5. WHERE AR2.AccountID = AR1.AccountID correlates the subquery with the outer query on AccountID. Note how the AccountReports table is given aliases of AR1 and AR2 to distinguish between the two instances of the table in the outer and subquery.
The query should consequently give the latest amounts returned per account, regardless of when the latest return was. In the case of closed accounts the amount will be given as zero.
I realize this won't match your scenario exactly, or maybe not even closely, but I hope it will give you some insight into how this sort of situation can be handled.
Ken Sheridan Stafford, England
> Thanks for your help!! What Ken gave me ran and gave me the desired result > when there was updates, but it is still giving me the parameter response. I [quoted text clipped - 14 lines] > > http://www.accessmvp.com/TWickerath/ > > http://www.access.qbuilt.com/html/expert_contributors.html Tom Wickerath - 11 May 2008 22:19 GMT Hi Wendy,
Ken Sheridan gave you quite an impressive reply; I do hope you spend the time to try to understand the points he made. To add some to his reply, take a look at some of the articles on database normalization, available here:
http://www.accessmvp.com/JConrad/accessjunkie/resources.html#DatabaseDesign101
The first two articles, written by database design expert Michael Hernandez, should be considered "must read" articles; one of them in only four pages in length. If you have similar data stored in two or more fields in the same table, then you have a multi-valued table design, which is not a good thing.
> ...always discern the difference between a character=zero and an actual > null value=blank. I'm assuming your fields are numeric, but just in case you are using a text field, you should know the difference between a zero length string and null (unknown). Access MVP Allen Browne covers this topic here:
Problem properties ---> See "Fields: Allow Zero Length" http://allenbrowne.com/bug-09.html
Ken's reply also delved into the subject of subqueries. Allen Browne also has some excellent pages that discuss using subqueries:
Subquery basics http://allenbrowne.com/subquery-01.html
Surviving Subqueries http://allenbrowne.com/subquery-02.html
Tom Wickerath Microsoft Access MVP http://www.accessmvp.com/TWickerath/ http://www.access.qbuilt.com/html/expert_contributors.html __________________________________________
> Thanks for your help!! What Ken gave me ran and gave me the desired result > when there was updates, but it is still giving me the parameter response. I [quoted text clipped - 6 lines] > always discern the difference between a character=zero and an actual null > value=blank. WLBrandibur - 15 May 2008 15:50 GMT Ken & Tom,
Thanks so much. I am trying to apply what you told me and I think we are not communicating well. Or maybe I cannot understand what you are telling me!! Since I am a great believer in reiterating until I understand, I am going to explain in greater detail what I am trying to accomplish and maybe this will help.. (Since from what I understand null is nothing which is what I want it to understand and if the space is null, then go to the previous cell... Hmm that is exactly what I am needing!!! and I will tell you why and if I am right:
There are a list of the Prime keys for my database. Each prime key is a company of ours. We get monthly bank statements in for each of these companies (and sometimes multiple statements for each company) and this is where I am having the problems. This database is accessed by our acturials (who are not very access savy at all) using it to import into a database built in the 1960's or early 70's. It cannot handle the yes/no at all (since I have it in the database for those of us who know how to use the database and they have called to ask me to change the no to zeros) and we have to show what the balance is (even if zero) since the other tables that have additional information imported from seperate sources. Each of these tables have infromation that will need to subtracted from the zero or other values.. This table is only one of many variables for these companies. So.. I have the key values on the right. and the months are the fields across. For instance.. code 999 has a field for each month's balance so that we can track the interest and such for each account and so on. The acturials ONLY need this information and it is on it's own table that was originally imported from an excel spreadsheet. Currently we are manually calculating and inputting all this data into a word document to produce a statement along with other information. They have asked me to automate this since I have every piece of the puzzle in the database and we have been generating reports with this information in it. BUT... I cannot get a formula to work (that subtracts the statement balance from the required ammount in the account) and have slowly removed each aspect of the formula to find that it is not liking the balance problem that I have been asking about. Since we have about 350 companies and some have multiple accounts and we are adding about 300 companies in the next couple of months, you can see why we are wanting to automate this.
I REALLY appreciate your help with this. My divsion is begininng to undertand what databasing can do for it and has me running around helping everyone. (That is why I could not get back to this sooner. too many hotspots!!) This is the first time I am using the report feature. We are a numbers based company and most of the reports are required in excel and so I have not had any problems until now. (using the office tools feature and sending everything out to excel) I am teaching myself how to do a report and this formula is erasing some of the numbers in the statement. I could not get it to work in the report and have it in the query that the report is based on. It gives me the answer, but removes all the factors shoing this in the report. It is very frustrating and everyone is of course wanting this done this month. They have tried to give it to outside companies to do, and they all point their fingers back at me syaing they cannot do it but she has all the infromation and can do it.
Again.. I REALLY appreciate all the help. They are paying forme to go to SQL class, but I cannot go until later..
 Signature Wendy
> Hi Wendy, > [quoted text clipped - 44 lines] > > always discern the difference between a character=zero and an actual null > > value=blank. Tom Wickerath - 22 May 2008 05:45 GMT Hi Wendy,
> ...(Since from what I understand null is nothing... Null is undefined. It's not zero, it's not nothing, it is undefined, just like any number X divided by zero is undefined in mathematics.
> ...and if the space is null, then go to the previous cell... The solution Ken Snell offered, which uses the built in Nz function, should work for this purpose.
> So.. I have the key values on the right. and the months are the fields across. Stop. Having separate fields for each month is not good database design. This is known as a multi-valued field design. Go back and read the database design papers, written by Michael Hernandez, which I told you about in a previous reply. It sounds to me like you have an "Access spreadsheet" with this design. Multi-valued field designs are always much harder to work with.
Tom Wickerath Microsoft Access MVP http://www.accessmvp.com/TWickerath/ http://www.access.qbuilt.com/html/expert_contributors.html __________________________________________
> Ken & Tom, > [quoted text clipped - 52 lines] > Again.. I REALLY appreciate all the help. They are paying forme to go to > SQL class, but I cannot go until later..
|
|
|