Importing Data from Excel file to MSAccess formatting each column in VBA - vba

I'm coding a system which import a excel file to a ms access database, but I would like to know if is possible format every column before import to the database.
For example:
EXCEL FILE (xls or xlsx): COLUMN A = DateTime; COLUMN B = Integer; COLUMN C = Char(25); COLUMN D = VARCHAR(255)...
I'm using this code right now but it's automatically.
Do While Len(strFile) > 0
strPathFile = strPath & strFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, strPathFile, blnHasFieldNames
strFile = Dir()
Loop

Yes it is possible and advisable to format the columns in excel before importing, so as to reduce risk of some data not been correctly imported.
Select the cells(s) you want to modify.
Click the drop-down arrow next to the Number Format command on the Home tab. The Number Formatting drop-down menu will appear.
Select the desired formatting option
formatting options in excel includes
A.ABC General
B. Number
C Currency
D Short date
E Long date
and some others.
You have to format the columns in excel manually, it can not be programmatically done from access

Related

Difficulty forcing VBA to parse dates in US/UK format

Thanks to all those who have helped thus far and helped me refine the problem
I'm receiving a CSV file from a third party software application with date time stamp in UK format that can be read by the VBA as a US date format
My machines "Region and Language Settings" are set to English (United Kingdom) but if I use
Application.LanguageSettings.LanguageID(msoLanguageIDUI)
The result is 1033 - ie: English, US and not fitting my machine settings.
CSV is a file with columns as follows:
| report name | value | % | date |
CSV created by a program and saved by users - a direct save of the CSV to disk by the third party app results in CSV table rows as follows:
"Report name","264","2.2 %","08 Jul 2021 11:05" (this imports correctly)
If users open the CSV and then save from Excel the file is saved as follows (note no quotation marks and amended date format:
Report name,1,0.00%,01/07/2021 12:37 (this fails to import correctly - cell read by VBA as 7th Jan 21)
My code should be able to handle both situations.
I'm importing the CSV data as follows:
Set csvWB = Workbooks.Open(my_FileName)
Set csvData = csvWB.Worksheets(1)
Dim csvReportAr() As Variant 'array of reprot names from column one of the CSV
Dim csvNumberAr() As Variant 'array of values (report results) from col 2 of the CSV
Dim csvDateAr() As Date 'array of the dates the reports were run
Do While csvData.Cells(cellRow, 1).Value <> Empty
Do While csvData.Cells(cellRow, 1).Value <> Empty
ReDim Preserve csvReportAr(cellRow)
ReDim Preserve csvNumberAr(cellRow)
ReDim Preserve csvDateAr(cellRow)
csvReportAr(cellRow - 1) = csvData.Cells(cellRow, 1).Value
csvNumberAr(cellRow - 1) = csvData.Cells(cellRow, 2).Value
Debug.Print "cell value = " & csvData.Cells(cellRow, 4).Value
Debug.Print "Month (of cell value) = " & Month(csvDateAr(cellRow - 1))
csvDateAr(cellRow - 1) = convertDateUKtoUS(csvData.Cells(cellRow, 4).Value)
Debug.Print "Date value = " & csvDateAr(cellRow - 1)
Debug.Print "Month of date = " & Month(csvDateAr(cellRow - 1))
cellRow = cellRow + 1
Loop
the debug statements print the following:
cell value = 07/01/2021 06:45:00
Month (of cell value) = 12
Date value = 07/01/2021
The difficulty is that the date I'm trying to import here is listed as 01/07/2021 06:45:00 in the CSV (1st July) based on the text editor view of the CSV. Just reading this cell value it seems that the VBA assumes this is a date and stores as a date saved in US format.
I suspect this is a locale issue? My locale settings seem incongruous and other users might have erroneous locale settings as well so we should be able to account for this
Questions:
Can I force VBA to read the date-time stamp as a string and then parse manually to ensure read as date in UK format? - OR - Can I read as a date time stamp specifying a specific format to read with?
Can you advise on the issue with locale with VBA stating locale is English US whilst machine settings seem to be English UK?
Can I change the locale with VBA temporarily? (other posts I've read suggests this is not advised!)
Is my use of cell.value inappropriate?
Rest of post deleted as probably no longer relevant
Thanks to all contributors so far!
I have partial but inelegant solution - I hope others can do better than me. I still can't work out why the UK date is being parsed to a US date automatically.
Thanks to all for their help as I could not have got my project to work without your helpful comments.
My partial solution:
Read the data from the CSV, assuming it may have been parsed incorrectly
If day(importDate) <=12 we are at risk of erroneous date import
create an alternate date with transposed days /months from the importDate
Use a vbYesNo MsgBox to get user to confirm which date is correct.
This works for my project as all dates in the single CSV file should be equal, You could use a similar solution of error checking a date for being read in US vs UK format if all dates in your CSV where recorded in the same format. However it will not help others who want to processes multiple CSVs or who may have a CSV with different date formats in it.
An alternative approach would be to read the csv file into an array using a CSV parser that lets you specify the file's date format, and then paste the array into a worksheet.
Here's such a parser (I'm the author):
https://github.com/PGS62/VBA-CSV
In this example, Data is pasted to a new worksheet.
Sub Demo()
Dim Data As Variant
Dim Target As Range
Data = CSVRead("c:\temp\datesukformat.csv", _
ConvertTypes:=True, _
Delimiter:=",", _
DateFormat:="D/M/Y")
Set Target = Application.Workbooks.Add.Worksheets(1).Cells(1, 1).Resize(UBound(Data, 1), UBound(Data, 2))
Target.value = Data
End Sub

Append data to beginning of CSV file

I'm working on an Access application and I've run into the following snag. Currently I'm writing an output file by exporting a query as a CSV file, however this file needs to be read by an older database system and will need a header row containing some identifying data.
I can construct the string for this header row in VBA without any trouble, but I'm not quite sure how to insert it in the first line of the CSV file, rather than it being appended at the end. How can I do this/achieve the desired result?
Open the file, read it, write the header, write back the data:
Dim data As String
Dim hF As Integer: hF = FreeFile()
Open "c:\path\foo.csv" For Input As #hF
data = Input$(LOF(hF), #hF)
Close #hF
Open "c:\path\foo.csv" For Output As #hF
Print #hF, "Header data here" & vbCrLf & data
Close #hF
Consider explicitly labeling your query columns with the corresponding header column as aliases. Then, export to csv with these headers using the VBA method, TransferText:
SQL
SELECT Col1 As Header1,
Col2 As Header2,
Col3 As Header3,
Col4 As Header4
...
FROM Table1
INNER JOIN Table2
ON Table1.PKID = Table2.FKID
VBA
Dim csvpath As String
csvpath = "C:\Path\To\CSVFile.csv"
DoCmd.TransferText acExportDelim, , "QueryName", csvpath, True

How to convert multiple column from text to date?

In my excel file, there are hundred columns. I want to convert some columns (eg. Column A, C,F, G..) from text to date. It really take time if manually change each column one column by one.
How can I do it ? By using VBA ?
The original text column format just like '31-Dec-2011 00:00:00'. I want to convert to 'dd/mm/yyyy' 31/12/2011
Thanks
If you actually want to chop the time off in each of the cells then this might be an approach:
If the target times are in column A of a sheet called "target" and the column header in A1 is "StartTime"
You could amend the below and add an argument so that it takes the column address. Then it could be called several times to carry out this operation on several columns.
Sub ChopOffTime()
dim mySheetName as string
mysheetname = "target" '<<<<change to your sheet name
myLstRow = Excel.ActiveWorkbook.Sheets(mysheetname ).Cells(Excel.ActiveWorkbook.Sheets(mysheetname ).Rows.Count, Excel.ActiveWorkbook.Sheets(mysheetname).Range("A2").Column).End(Excel.xlUp).Row
With Excel.ActiveWorkbook.Sheets(mysheetname)
.Columns("B:B").Insert Excel.xlToRight
.Range("B2:B" & myLstRow).FormulaR1C1 = "=TIME(HOUR(RC[-1]),MINUTE(RC[-1]), SECOND(RC[-1]))"
.Range("B1") = "StartTime" '<<<<<change to appropriate header
.Columns("B:B").Copy
.Columns("A:A").PasteSpecial Excel.xlPasteValues
.Columns("B:B").Delete Excel.xlToLeft
End With
End Sub
Thanks all.
To simplified the procedure, I just developed some macro for user to run to change the column format, and then they can import the excel the mdb without error.
Use the following for the columns in question:
Columns("A:A").Select
Selection.NumberFormat = "m/d/yyyy"

Automation 31 templates or 1 template

am producing an excel report where I bring in data for one country via a data connection and then run a macro that refesh pivots and other sheets with that data and then closes and saves the Excel report for that country. For example Germany . I have then another 31 templates for other countries where the same process happens. The differences between the 31 templates is that the database sql query for the data connection ( bring records for Germany ) and the filename that it is saved as like Report_Germany .
In SSIS, I am using a process task that calls a vbs script which simply opens an excel file and runs a macros for each country . Now I do not want to create 31 different SSIS tasks.
Anyway I could use 1 Template and produce the required 31 Excel Reports in the same directory ?
Yes, it is possible to use a single temple to create multiple reports.
All your pivot tables need to have a report filter equal to the country and all the data needs to be retrieved into one workbook.
Then you can loop through the countries setting the filters each time and saving the workbook as with a separate country name.
Listed below is some basic code to achieve this.
Sub Update_Pivot_filter()
Dim StaticArray(1 To 3) As String
Dim strName As String
Dim lCount As Long
StaticArray(1) = "Germany"
StaticArray(2) = "France"
StaticArray(3) = "Italy"
For lCount = LBound(StaticArray) To UBound(StaticArray)
ActiveWorkbook.Sheets("Sheet1").PivotTables("PivotTable1"). _
PivotFields("Name").CurrentPage = StaticArray(lCount)
' Change report filter on a pivot table
ActiveWorkbook.RefreshAll
' Refresh all pivot tables
ActiveWorkbook.SaveAs Filename:= _
"C:\Temp\Report_" & StaticArray(lCount) & ".xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
' Save the file with a name matching the filter name
MsgBox StaticArray(lCount)
Next lCount
End Sub
The downside of this approach is that each workbook contains all your data.

Excel VBA to force numeric value into time format

There are two columns copied into a workbook from a Access database.
I want to ensure that the data is formatted correctly so I added this code:
'DateTime Column
Sheets("Sheet1").Columns("A:A").Select
Selection.NumberFormat = "m/d/yyyy hh:mm"
'Time Column
Sheets("Sheet1").Columns("B:B").Select
Selection.NumberFormat = "hh:mm"
The datetime column formats correctly.
The time column is initially copied as a numeric equivalent (ie 0.595277777777778) instead of the time value (14:17).
Running the macro code does nothing to the visual display and it isn't until I hit F2 and enter on the cell that the format applies.
Is there a method (short of a loop) to force Excel to apply the formatting?
You can use VBA to accomplish the same effect as Steve Homer's answer by setting the range's value property to itself:
Dim r As Range
Set r = Sheets("Sheet1").Columns("B:B")
r.Value = r.Value
If you copy the column and paste as values (through a macro if needs be) then Excel should re-interpret the data type and the above should work correctly.
You can do this with out declare TMP as DATE:
TMP = CDate(Range("A1").Value) ' we suppose A1 value is 12:45:00
TMP = "" & TMP ' convert to char
TMP = Left(TMP, 5) ' extract the first 5 char
MsgBox TMP ' for displaying 12:45