Hi Ray,
My suggestion (which I used in an application I built last week) is as
follows:
Set up a table, with every field as a text field, into which the Excel data
is imported via the TransferSpreadsheet command. When you use this command,
with HasFieldNames set to false, you get the contents of the spreadsheet
imported with every field as a text field. You then set up a query on this
table which tests each field to determine if the text representation of the
entry can be interpreted as an entry of your desired datatype.
For example, consider a spreadsheet such as this, where column A has no
specific formatting applied, Column B has a date/time format applied, and
column C has a number format, with 2 decimal places (and numbers may be
entered to greater precision):
Text Date Number
sample1 13/05/2007 9:25 123.45
sample2 4/07/2011 17:25 78.00
sample3 23/02/2004 14:42 not a number
sample4 not a date 456.79
[Note: the alignment of these columns in this posting will almost certainly
be dreadful!!!]
I use the following statement to import this into tblImportRaw, which is a
table containing three text fields (F1, F2, F3):
DoCmd.TransferSpreadsheet acImport, , "tblImportRaw", "c:\book1.xls",
False, "!a:c"
(As I said in my original post, the Range parameter will prevent an error if
the spreadsheet has data in any other column.)
tblImportRaw now contains the following data, all as text strings:
Text Date Number
sample1 39215.392361 123.45
sample2 40728.725694 78
sample3 38040.6125 not a number
sample4 not a date 456.79
The following query converts valid dates (which are now shown as numbers, in
the Microsoft standard format (days since 30-Dec-1899 as the integer
portion, time as the decimal portion) because the spreadsheet has that
column formatted as a date/time) in F2 into date/time entries, and valid
numbers in F3 into double entries:
SELECT F1 AS F1Text,
IIf(IsNumeric([F2]),CDate(CDbl([F2])),Null) AS F2Date,
IIf(IsNumeric([F3]),CDbl([F3]),Null) AS F3Number
FROM tblImportRaw;
The Isnumeric function is a boolean function; I use it to test whether the
string can be interpreted as a number. If so, I convert it to a number,
using the CDbl function, otherwise, I return a null. For the date/time
field, I first test for numeric, then convert from the double value to the
Date/Time datatype using CDate. Attempting to do this without the
intermediate conversion gives a type conversion error, which show in the
query as #error, and cannot be trapped by the IsError function (I think
because it's a run-time error).
The output of this query is:
Text
sample1 13/05/2007 9:25:00 AM 123.45
sample2 4/07/2011 5:25:00 PM 78
sample3 23/02/2004 2:42:00 PM
sample4 456.78901234
This query can be converted into an append query to append the converted
data into a table with three fields, with types of Text, Date/Time, and
Double, with no data conversion errors.
HTH,
Rob
Ray S. said:
Thanks Rob,
I'm studying Bill's code...could you explain your alternative with a
little
more detail? I did try to use the TransferSpreadsheet method...importing
into
a pre-existing table with the field data-types defined...I played with
designating the field names parameter as false, but that created another
problem because one of the fields is a date field with a long date format
(with several items separated by spaces). This required a dump file with
more
fields than the original...would I then query that dump file to
concatenate
the date field back to it's original? I'm not sure how you're suggesting
to
use IsNumeric. Does that convert a numeric data type to a string? I
certainly
don't want the text entries to be converted to null values. I'll try to
play
with it.
Rob Parker said:
Hi Ray,
A possible alternative to the code Bill Edwards posted in a separate
thread
would be to use the TransferSpreadsheet method to import everything in
the
spreadsheet into a (different) pre-existing table, with every field
(named
F1 to Fn, where n is the number of columns you want to import) set as
Text
datatype. Set the HasFieldNames parameter to False, and limit the Range
imported to a fixed number of columns, to prevent errors if there is data
in
more columns than you have in your (new) import-dump table - use an entry
such as "!a:g" to import the seven left columns. Set up a query on this
table which converts valid data (eg. use an expression such as
ValidF1:iif(IsNumeric([F1]),[F1],Null) in the fields of interest), and
run
it as an append command into your existing table (which has the desired
datatypes).
HTH,
Rob
I've read a lot of posts regarding trouble importing data from Excel
into
an
Access table, but nothing seems to work.
The offending data is text. I have formatted the cells in Excel as
text.
I'm importing it into a pre-existing table in Access where I have made
the
field tata type text.
Most of the data looks like numbers, but it is not. Occasionally a bit
of
data will be obviously text, but Access ignores both the data type of
the
Excel cells and the data type of the Access field and just gives me a
type
conversion error and doesn't import the offending data.
The only solution I have found is to cut the entire range of cells from
Excel and paste them into Notepad, then re-copy them back into Excel.
Isn't
there a less cumbersome way to avoid the data errors and get the data
transferred?