SQL insert of '' is neither null or empty in Access - ms-access

I have a function that essentially copies records and inserts them with new IDs. The code works and everything copies fine.
The SQL that occurs is essentially:
INSERT INTO myTable (ID, field, select) VALUES ('newID','stuff','')
Notice the last value is blank,empty,null, whatever. Sometimes it has something in it, sometimes it doesn't.
I have a check against that value in an access form and it uses isNull or isEmpty and both come up false, with only records that are inserted in this manner.
So what is being inserted, if nothing is being inserted? it's neither null nor empty and there is nothing in there, so I'm completely baffled. If I enter something and wipe it out, it'll be fine.

The IsEmpty() Function is generally only of use to check to see if a variable of type variant has not been initialised.
A database field can be said to be empty which is not the same as if it was Null.
For example if you have a field called Gender which was not a required field on a new record the value could be Null, then if a user typed in Female obviously it would a contain value. If they were then to delete the word Female then the field would now be empty (Not Null).
The most useful function to use when dealing with Nulls in Microsoft Access is the following:
Nz()
This function has two arguments, the first one being the variable you wish to check and the second one being the value you wish to return if the variable is Null. For example the following will return an empty string:
Dim variantName As Variant
variantName = Null
Debug.Print Nz(variantName,"")
Also please note if you try to join a variable that contains Null with a String using the plus character (+) then this will result in Null which is probably where you're having problems.
A try typing the following into the immediate window results are also shown here:
? len(null)
Null
? len(null + "abc")
Null
? len(null & "abc")
3

could be a \r or \n or any other non printable character,
you may want to select such a row and cast it as varbinary to see the content

Related

Entry with NULL in combobox

I have a combobox that I use for filtering entries in the column below. The code reads the entries of the column and adds what it finds into the combobox (SELECT DISTINCT).
This works fine if the columns don't have entries that are NULL. If they do, a blank field will show in the combobox (which is good, I want to be able to filter for empty entries). However, if I click on this field in the combobox, all entries are shown, not just the NULL ones. Does anyone know why this could be? Does Access convert NULL to an empty string? If so, can I circumvent this somehow?
You are looking for the NZ function
Syntax
Nz ( variant [, valueifnull ] )
The Nz function syntax has these arguments:
variant
Required. A variable of data type Variant.
valueifnull
Optional (unless used in a query). A Variant that supplies a value to be returned if the variant argument is Null. This argument enables you to return a value other than zero or a zero-length string.
Note: If you use the Nz function in an expression in a query without using the valueifnull argument, the results will be a zero-length string in the fields that contain null values.
MS DOC:
https://support.office.com/en-ie/article/nz-function-8ef85549-cc9c-438b-860a-7fd9f4c69b6c

Sum Values not equal to a space from a Control Source in MS Access

As the subject expresses, I'm trying to sum the values of a string field where spaces may exist. It must be done this way, unfortunately.
The database is very old. The original developer chose to make all fields Text fields; to get over the null value problems, a function was written in VB6 to replace any null value with a space. This cannot be changed.
Fast forward to now, I'm trying to create a report that sums the length field without changing spaces to nulls first, and it should be done entirely through the control source property of the report.
I've added some of what I've tried below, but every time the report is run, I receive:
Data Type Mismatch
...and I'm not sure how to get around it.
Ideally, I'd like to keep the users out of the database completely, and just add a combo box that lists the reports created in the database so they can be opened by name without having to run any additional update queries first.
=Sum(IIf([MY_LEN]<>" ",DCount("[MY_LEN]","MY_TABLE"),0))
=Sum(Nz(Iif(Trim([MY_LEN])='',Null,[MY_LEN]),0))
=DSum("[MY_LEN]","[MY_TABLE]","[MY_LEN]<>' '")
=Sum(Iif(Val([MY_LEN])>0,[MY_LEN],0))
=(SELECT Sum([MY_LEN]) AS MyLen FROM MY_TABLE WHERE (((MY_TABLE.[MY_LEN])<>' ')))
Is this possible?
Can't compare anything to Null. Can't say If x = Null Then because Null is undefined. So you can't test if undefined = undefined. Use If IsNull(x) Then in VBA and Is Null in query criteria. Don't really need IIf() for Sum() aggregate, other aggregates such as Count or Avg would.
To handle possible space, empty string, or Null for a text field holding numeric data.
=Sum(Val([MY_LEN] & ""))

MS Access Null Not Working as Query Parameter

I have a form with a subform linked by the field DataType, which displays all the data for that DataType and has been working well for years.
The DataType can be further filtered by several dropdown fields, the fields are parameters in the underlying query for the sub-form, but if these fields are blank it will return all the data for that DataType, and I have a 'Clear all' button that runs code to make all the filter values null/blank except when all the fields are blank all the data is not being returned. I have narrowed the issue down to one field DataFilterC. For some reason the query is no longer treating the field as null/blank even when it is, it will work if I choose an option for it's drop down, this is the criteria for that field;
Like IIf(IsNull([Forms]![Form]![SubForm1].[Form]![DataFilterC]),"*",[Forms]! [Form]![SubForm1].[Form]![ DataFilterC]) Or Is Null
The query skips the first IsNull and goes straight to the final Or Is Null what could be causing this?
Deal with possibility of either Null or empty string with:
IIf([Forms]![Form]![SubForm1].[Form]![DataFilterC] & "" = "", "*", ...

Access VBA - Returning some sort of blank/null for function declared as long

Question: I want to use a VBA function in Access that is declared as type Long. I want to return an integer between 0 and 35 some of the time, but I also want to be able to return a blank or null or something like that most of the time. Is there a way to do this? What I have tried (variable = "" or Set variable = Nothing) just calls an error. This will be used in a query and will give the value for one column. I want that column to be type Long. If such a thing is not possible, I guess that is all I need to know, as I already have a different but less desirable solution. Thanks for any help.
Update: Of course, right after asking the question, I figured out a good solution. If I just do Range("whatever").Value = Range("whatever").Value in Excel, then it changes a left aligned 20 to a right aligned 20, at which time it is recognized by the pivot table as a number (though when I just convert the cell type to a number in Excel, it is not recognized as a number in the pivot table). So, I am deleting the background because it is not necessary. I am still interested to know if you can return some sort of blank or null for a function declared as long. Thanks
Null can only be returned from a Variant function.
Nothing can only be returned from an Object function.
All others, you are restricted to returning a variable of the type defined as the return value of your function.
If you do not set a value, then it returns the default value
A numeric variable is initialized to zero
A variable length string is initialized to a zero-length string ("")
A fixed length string is filled with the ASCII code 0.
A date/time variable is initialized to zero
Since an unitialized long has a value of 0, the answer is "no." A function declared as long cannot return null or blank. If zero wasn't a valid return value for your function, you could use it a "null" equivalent, but you already knew that :)

Problem evaluating NULL in an IIF statement (Access)

Item in the recordset rstImportData("Flat Size") is = Null
With that, given the following statement:
IIF(IsNull(rstImportData("Flat Size")), Null, cstr(rstImportData("Flat Size")))
Result: Throws error 94: Invalid use of Null
If I change the statement by removing the type conversion upon a false comparison:
IIF(IsNull(rstImportData("Flat Size")), Null, 0)
Result: Null
It returns Null as it should have the first time. It appears that I cannot do a type conversion in an IIF if the value passed in should ever be null even if it passes an IIF test, it still attempts to evaluate it at both the true and false answer. The only reason I'm using IIF like this is because I have a 25 line comparison to compare data from an Import against a matching record in a database to see if I need to append the prior to history.
Any thoughts? The way data is imported there will be null dates and where the spreadsheet import is in a string format I must convert either side to the other to compare the values properly but if either side is null this exception occurs :(
EDIT
Example of why I was using IIF (and considering using a universal function)
If master("one") <> import("one") Or _
master("two") <> import("two") Or _
master("date") <> import("date") Or _ //import("date") comes from a spreadsheet, it comes in as string, CAN be a null value
master("qty") <> import("qty") Or _ //import("qty") comes from spreadsheet, comes in as a string can CAN be null
master("etc") <> import("etc") Then
....stuff....
End If
This code expands for roughly 20 columns to compare in the database. I would prefer to check as part of the statement. I can think of a bunch of solutions but they involve adding much more code. If that is the case power to it, however I'm not one to give in so easily.
Options I see are
Creating temp vars to do the work prior to comparing and using these new vars instead of the recordset
Creating an object to pass the record into to preformat and work with, though extra work would provide this functionality to each import type since there are different files with similar fields
I'm here for ideas, and I'm open to any interesting pieces that can be thrown my way as I get to decide how to do it I'm looking for the most reusable approach.
The simple expedient of changing the value to a string helps tremendously. The trick is that trimming a string which is NULL will get a null string. Which can then be operated on as if it wasn't a database null.
I frequently use the form:
CInt("0" & Trim(SomeVariant & " "))
To get a valid number without having to go through a bunch of hijinks. The null is a nonentity for this problem.
The behavior you described is the standard way IIf operates under VBA. This is part of what Access 2003 Help says about it:
"IIf always evaluates both truepart and falsepart, even though it returns only one of them. Because of this, you should watch for undesirable side effects. For example, if evaluating falsepart results in a division by zero error, an error occurs even if expr is True."
However, if you use an IIf statement in a query, evaluation short circuits after truepart when expr is True --- falsepart is not evaluated in that case. Unfortunately this information is not useful for you ... unless you can incorporate a query into your comparison.
I don't know of any other way to avoid your error with IIf. I would try appending the Excel data into a table whose structure matches that of the table you will compare against, thereby eliminating the need to do a string conversion at the same time you do the comparison.