Onion - the missing ingredient for Sage Line 50 / Sage Instant accounts packs in Excel

Onion - the missing ingredient for Sage Line 50 / Sage Instant accounts packs in Excel
Full audit trails to underlying transactions from P&Ls, Balance Sheets, graphs, PivotTables, and departmental TBs in a stand-alone Excel file. Aged Debtors and Aged Creditor files too. Free 30 day trials. Download today at www.onionrs.co.uk
Showing posts with label ImportMixedTypes. Show all posts
Showing posts with label ImportMixedTypes. Show all posts

Tuesday, 2 August 2011

Dealing with mixed data types in Excel ODBC queries (2)

Shortly after posting the first message on this topic I had cause to use it in a real life situation.  All was fine until a cell in my text field had more than 255 (?) characters.  It broke the solution!

I haven't had time to fully investigate exact limits in all of this but I think the Excel ODBC driver will only accept up to about 255 characters in a "Text" field.  If the driver comes across more than 255 characters it interprets it as a "Memo" type content (up to 32k characters?) and the attempt to query fails at the record that contains the offending data.  How to work around?

Using the IMEX=2 approach from the previous article, firstly, I appended 256 spaces into the first rows of the field that needs to be "Memo".  This was to force the majority type interpretation of this field to be "Memo".  Once this had been done I discovered that the query no longer failed but it only returned the first 253 characters of the "Memo" field.  Why I'm getting 253 I'm not sure but it seems this is a limitation of the Excel ODBC driver when dealing with "Memo" fields.  However, I discovered that if I constructed additional calculated fields in my SQL I could bring back the entire contents of the "Memo" field in 253 character chunks.  The SQL select clause entries look as follows:

''+F1 as [Memo Field],
mid(''+F1,254,253) as [Memo Field 2],
mid(''+F1,507,253) as [Memo Field 3], ... and so on.

I'd be really interested if anyone is able to put some better flesh on these bones.

Sunday, 24 July 2011

Dealing with mixed data types in Excel ODBC queries (1)

There's a great post dealing with this at Daily Dose of Excel.  However, aware that I often don't have access to the registry on the machines I access, I was interested to find out if I could make queries work no matter what the registry contents*. 

The best situation to find yourself in is if your registry has an ImportMixedTypes value of Text.   This allows you to set IMEX=1 in the extended properties for the query.  If you set HDR=No as well, the text column headers that would be the field names if HDR=Yes, ensure that the query will return text values for every field.  Criteria can suppress the display of the record containing the column headers.  Data conversion calculations provide the output of the query in the appropriate data type on all records.  Using this methodology all the original data will be in field names F1, F2 etc.  The data conversion calculations performed in SQL can alias the field names to reflect the original field names.

Below is a select statement to demonstrate how to return each data type in the above scenario:
SELECT iif(isnumeric(F1), cdbl(F1)) as [Number],
iif(isnumeric(F2), ccur(F2),0) as [Currency], 
iif(isdate(F3),cdate(F3),#1900-01-01#) as [Date],
''+F4 as [Text],
iif(F5='TRUE',cbool(1),iif(F5='FALSE',cbool(0))) as [Boolean]


The following where clause ensures that the column header record is suppressed:
WHERE F4<>'Text' or isnull(F4)

In the above the currency column populates every record with a value, effectively converting nulls to zero.  Vital if any GROUP BY operations are to return a value other than null.  For comparison, the number column doesn't replace the nulls. Below is the QueryTable output:

NumberCurrencyDateTextBoolean
            -   01/01/1900Other fields are Text in the original data
            -   01/01/1900Other fields are empty in the original data
1234     567.89 30/05/2011-1
56       12.99 23/07/2011The line above is empty0


If you find that your ImportMixedTypes=Majority Type, then IMEX=1 has no practical effect.  If a mixed type field is determined to be a text type, all values of other types will be suppressed.  The only way to guarantee that the proper values are returned for all fields is to include at least half the number of rows specified by TypeGuess rows just below the column headers in the data.  These rows can be hidden once populated with the correct types of data.  This will ensure that the Majority Type identified is the correct type. With HDR=No, criteria can suppress the display of the record containing the column headers as well as the records contained in the now hidden data rows.  Data conversion calculations provide the output of the query in the appropriate data type on all records.  Using this methodology all the original data will be in field names F1, F2 etc.  The data conversion calculations performed in SQL can alias the field names to reflect the original field names.

Below is a select statement to demonstrate how to return each data type in the above scenario:
SELECT iif(isnumeric(F1), cdbl(F1)) as [Number],
iif(isnumeric(F2), ccur(F2),0) as [Currency], 
iif(isdate(F3),cdate(F3),#1900-01-01#) as [Date],
''+F4 as [Text],
iif(isnumeric(F5),cbool(F5)) as [Boolean]


The following where clause ensures that the column header record is suppressed in addition to the records contained in the now hidden data rows (populated with '0'):
WHERE F4 not in('Text','0') or isnull(F4) 

The QueryTable output is identical to that shown above.


* the one exception is if the registry has TypeGuessRows=0 (scan all rows) and ImportMixedTypes=Majority Type - an unlikely scenario.