I'd like to import all Excel files (with different data and columns) from some directory into MS Access 2010 database, creating new table for each file. I've found the code to import files into one table:
Option Compare Database
Option Explicit
Function DoImport()
Dim strPathFile As String, strFile As String, strPath As String
Dim strTable As String
Dim blnHasFieldNames As Boolean
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = True
' Replace C:\Documents\ with the real path to the folder that
' contains the EXCEL files
strPath = "C:\Documents and Settings\myName\My Documents\Access Test\"
' Replace tablename with the real name of the table into which
' the data are to be imported
strTable = "tablename"
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, strPathFile, blnHasFieldNames
' Uncomment out the next code step if you want to delete the
' EXCEL file after it's been imported
' Kill strPathFile
strFile = Dir()
Loop
End Function
But I need to create new table each time. Is it possible in VBA?
I think all you need to do is change the destination table name (the value of strTable) each time before you do DoCmd.TransferSpreadsheet.
In a comment you said you want the table name to be derived from the workbook file name. And, each time through your loop, another variable (strFile) contains the file name. So I think you could strip the file extension from that file name and use it as the Access table name.
Here is an Immediate window example which demonstrate how that can be done ...
strFile = "foo.xls"
strTable = Left(strFile, Len(strFile) - 4)
? strTable
foo
If that approach is suitable, revise the loop in your VBA code like this (untested) code snippet ...
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
strTable = Left(strFile, Len(strFile) - 4)
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, strPathFile, blnHasFieldNames
strFile = Dir()
Loop
I used to be a MOS Access 2003. Now everyone is using 2010 but many things have not changed.
When you do a manual import or export, you can save the layout as a specification.
This process can be automated by a macro.
Check out the link below for more details and steps.
http://office.microsoft.com/en-us/access-help/run-a-saved-import-or-export-operation-HA001226020.aspx?CTT=5&origin=HA001226307
As for the other stuff, buttons, modules, etc, please read the on line help / documentation first.
We are here to help but not do the work for you.
J
Okay, I do not know if it is an issue with my computer not being on the current office CU.
http://msdn.microsoft.com/en-us/library/office/ff192475(v=office.14).aspx
Here is a link to how to use the ImportExport Macro. Use to be in the macro section.
I did read that you had to trust the location. So I tried both my location c:\msdn plus the default for the wizards.
Still was not able have it the option come up.
I tried creating a specification to see if one was needed for the option to show, no dice.
However, there is a DoCmd.TransferText and DoCmd.TransferSpreadSheet.
Both will allow you to import.
Create a function. Call the function from a macro (RunCode). Another way is to create a main menu form. Have a button. On the click command, run the code.
Please tell me if you ever get the ImportExportData Macro to show. I think it is a bug. I will need to bring down the latest Cumulative Updates and try again.
Related
I have created this process by lifting code from this (and some other) sites, and it worked like a charm when I tested it, but when I deployed it, it crashed hard... I am novice when it come to VBA and having trouble finding appropriate solution so thought I will ask for help.
Use Case
Accountant receives 100+ spreadsheets per day(!) from employees in the field as a form of required reporting. Before I got involved, 3 accountants would open each spreadsheet received via e-mail and copy/paste certain cell contents into a "master" spreadsheet that will be used for reconciliation at the end of the month. Needless to say, this has become, let's say, inefficient.
What I did
I created an Access DB and used TransferSpreadsheet method to import data. There are only 11 cells that we need imported from each spreadsheet, so I modified spreadsheets that field employees use to pull all this data into a hidden tab, where all data is in one row and all row goes into one table in Access. As I mentioned, when I and accountants tested the solution, it worked beautifully.
What Broke
First issue was that people in a field did not have same versions MS Office, and some used OpenOffice instead and we would get errors when trying to import some spreadsheets. However, since my simple solution was built for "prefect path" only, it was impossible to identify which spreadsheets failed, especially, when there are 2000+ of them sitting in a folder.
What I would like to be able to do
Short-term, until I have time to master VBA, I would love to add some sort of error handler. Or even if after import, "good" spreadsheets would be sent to one folder, and "bad" ones to another. From my experience,about 80% of reports import fine. Once it loops through the whole folder, accountants can check "failed imports" folder and enter these manually. My questions to you, Access VBA experts, is this doable and would be a reasonable solution? If so, can you please direct me to it?
Below is my current code that I adapted from the internets. Thank you for all your help!
Function DoImport()
Dim strPathFile As String
Dim strFile As String
Dim strPath As String
Dim blnHasFieldNames As Boolean
Dim intWorksheets As Integer
Dim strWorksheets(1 To 1) As String
' the number of worksheets to be imported
' from each EXCEL file (this code assumes that each worksheet
' with the same name is being imported into a separate table
' for that specific worksheet name)
Dim strTables(1 To 1) As String
' worksheet names ;
' add / delete code lines so that there is one code line for
' each worksheet that is to be imported from each workbook file
strWorksheets(1) = "Data"
strTables(1) = "my_table"
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = True
'update the path to where the Excel files to be imported are
strPath = "\mypathhere\"
' the number of worksheets to be imported
' from each EXCEL file
For intWorksheets = 1 To 1
strFile = Dir(strPath & "*.xlsm")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
'MsgBox strPathFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, strTables(intWorksheets), strPathFile, blnHasFieldNames, strWorksheets(intWorksheets) & "$"
strFile = Dir()
Loop
Next intWorksheets
End Function
This is off the top of my head (so there may be sytax errors) but the idea is to set the error handling to jump to code that saves the filename and then jump back into the process:
ON ERROR GOTO IMPORT_ERROR
For intWorksheets = 1 To 1
strFile = Dir(strPath & "*.xlsm")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
'MsgBox strPathFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, strTables(intWorksheets), strPathFile, blnHasFieldNames, strWorksheets(intWorksheets) & "$"
strFile = Dir()
GetNextFile:
Loop
Next intWorksheets
EXIT FUNCTION
IMPORT_ERROR:
'ADD CODE HERE TO HANDLE ERROR
ON ERROR GOTO IMPORT_ERROR
GOTO GetNextFile
End Function
I have built this simple Access DB (2010) that imports 11 fields from Excel spreadsheet into a single table. What I have not done yet is to check if record in table exists and to not import it again creating duplicates.
Business Case:
User receives hundreds of spreadsheets per day (a form is used by employees in a field). User saves all these spreadsheets in a designated folder from where, VBA code picks up only some data and inserts in a single table in Access DB. When import is complete I then ask user to move all those spreadsheets into archive folder manually. I understand this process is very prone to where same spreadsheet may be imported again. I would like add a check to my VBA code to check if record exists and ignore it. It would need to check 3 fields: employee name, date, and location as there should only be one report per employee per day per location.
I am a novice and am just learning VBA so some solutions I found online are not sufficient enough for me at this point. Would like a specific example of code that I could reuse. My current code (which I also found online and modified to work for me) is something like this.
Function DoImport()
Dim strPathFile As String
Dim strFile As String
Dim strPath As String
Dim blnHasFieldNames As Boolean
Dim intWorksheets As Integer
Dim strWorksheets(1 To 1) As String
Dim strTables(1 To 1) As String
strWorksheets(1) = "data"
strTables(1) = "my_table"
blnHasFieldNames = True
strPath = "folder path were user originally saves all reports"
For intWorksheets = 1 To 1
strFile = Dir(strPath & "*.xlsm")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
'MsgBox strPathFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, strTables(intWorksheets), strPathFile, blnHasFieldNames, strWorksheets(intWorksheets) & "$"
strFile = Dir()
Loop
Next intWorksheets
End Function
Thank you vary much.
In your table, create a Unique Index using the three fields. This example assumes the names of the fields are EmployeeName, RecordDate, and Location:
This will not allow duplicates of the three fields to be inserted.
This is directly related to the following two posts:
How do I export 2 queries to a single worksheet in excel from access
Saving a custom export from an Access 2007 script
I am using Access 2010, and I have created a command button on a form with the following VBA in its Click event. The VBA allows me to export multiple queries, into different worksheets, within the same Excel file:
VBA #1: This exports multiple queries into one Excel file
Private Sub CommandBtn_Click()
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "Query1", "test1.xlsx", True, "NameofWorksheet"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "Query2", "test1.xlsx", True, "NameofSecondWorksheet"
End Sub
Edit(4/7/2014: 11:26 AM): Clarified what I want below.
Desire
I want to add the following feature to my command button's Click event: A "Save As" dialog window that prompts the user to choose where to save the newly created Excel file (test1.xlsx).
Challenges:
I do not know what VBA code would be appropriate to use for doing so. I ran into the FileDialog(msoFileDialogSaveAs) option when doing my research on this. However, I have not been able to successfully use it to produce what I want.
I think you want to get the file selection before DoCmd.TransferSpreadsheet, because the file selection is the transfer target.
I'm not sure exactly what you want, but I think this should be a step closer ...
Private Sub CommandBtn_Click()
Dim fileSelection As Object
Dim strPath As String
Set fileSelection = Application.FileDialog(2)
With fileSelection
.AllowMultiSelect = False
If .Show = True Then
strPath = .SelectedItems(1)
' use strPath with TransferSpreadsheet ...
'DoCmd.TransferSpreadsheet
Else
MsgBox "no file selected"
End If
End With
End Sub
I want to export record set "myTableRS" from Access 2010 into .xlsx file via VBA, but its showing the error as " The expression you entered is the wrong datatype for one of its argument". If I access any field value from the record set in msgbox using Msgbox(myTableRS![Field3]) so its working fine. Even when i export Access Table so the below code is working fine but not working for myTableRS record set.
I am using the code :
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, _
myTableRS, "D:\MAS.xlsx", True
Can anyone tell how to fix it?
How do I create a saved query? I have a table from which I want to search a particular record and save that particular record only at the same time of search in xlsx
If you look at TransferSpreadsheet, you will see that table name is a string.
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, _
"myTableRS", "D:\MAS.xlsx", True
This means that you cannot export a recordset using TransferSpreadsheet, however, you can create a saved query and export that.
Create a saved query
sSQL = "SELECT * FROM MyTable WHERE Id = " & thenumber
If Not IsNull(DLookup( _
"ExportQuery", "MSysObjects", "[Name]='ExportQuery' AND Type= 5")) Then
''Query exists, overwrite the sql permanently
CurrentDb.QueryDefs("ExportQuery").SQL = sSQL
Else
CurrentDb.CreateQueryDef "ExportQuery", sSQL
End If
I have two different MDB files [with the same structure]. Is there an existing tool that can report the difference between the two files [row by row]?
I found a program called "MDBDiff" on SF, however the program is no longer available for download.
I've made an AccdbMerge utility that is able to compare data and programming objects as well. In scope of "row by row" comparison - it will show what records were added/modified/removed, for modified records it will highlight fields with updated values.
See the following page and go down a bit for a list of utilities to compare Access databases
http://www.granite.ab.ca/access/thirdparty.htm One of those might be what you're looking for.
I wanted to do the same (basically use DIFF to see differences row by row) so
1) I exported all the tables:
Option Explicit
Option Compare Database
Private Sub ExportAllTables()
Dim myDatabase As Database
Dim myTableDef As TableDef
Dim strTableName As String
Set myDatabase = CurrentDb
For Each myTableDef In myDatabase.TableDefs
DoEvents
strTableName = myTableDef.Name
DoCmd.TransferText _
acExportDelim, _
, _
strTableName, _
Environ("USERPROFILE") & "\DeskTop\dump\" & strTableName & ".CSV", _
True
Next myTableDef
MsgBox "Done"
End Sub
2) concatenated them into one file
type *.csv > all.txt
CAT will do as well if you have it
3) diff'ed them
diff all.txt all2.txt
Try using SQL Data Compare from Redgate, http://www.red-gate.com/products/SQL_Data_Compare/index.htm
and then use this trick,
http://www.red-gate.com/messageboard/viewtopic.php?p=15296#15296
I haven't tried it yet but this tool looks like it would do the job http://www.datanamic.com/download/download-datadiff-for-msaccess.html