Attempting to import data from Excel file (vrtSelectedItem) to Access table (MAF), but receive "Type Mismatch" error on the DoCmd line.
The data is in a sheet named "For Export", but I'm not sure I indicated that correctly. Could be something else on the line, though.
Additionally, the data is in a named range, "ExportRange". Is it possible to use the name instead of specifying the cells?
Dim fd As FileDialog
Dim vrtSelectedItem As Variant
Dim xl As Object
Dim wb As Object, ws As Object
'Dim data1 As Variant
'Select Excel file
Set fd = Application.FileDialog(msoFileDialogOpen)
With fd
.AllowMultiSelect = True
.Title = "Select one or more files"
.InitialFileName = InitPath
If .Show = True Then
Set xl = CreateObject("excel.application")
For Each vrtSelectedItem In .SelectedItems
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, MAF, vrtSelectedItem("For Export"), 0, "B1:B72"
Next
End If
End With
If the data you want to import is in a named range ("ExportRange"), use that name as the Range argument. And in that case, don't even mention the sheet name.
The TableName argument should be a string value. I assumed you want to import the data into a table named "MAF", so quoted that table name.
DoCmd.TransferSpreadsheet TransferType:=acImport, _
SpreadsheetType:=acSpreadsheetTypeExcel9, _
TableName:="MAF", _
FileName:=vrtSelectedItem, _
HasFieldNames:=False, _
Range:="ExportRange"
I don't see the value of CreateObject("excel.application"). It seems you only need a straightforward TransferSpreadsheet operation so you shouldn't need to create Excel application instances.
Related
I have a macro that automatically opens a pivot table file when I press YES. And I would like it to automatically change the data source from the next and other open file. However, I get the Object Doesn't Support this Property or Method error here: And file is opening normally.
PvtKraje.ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:=wbMe.Sheets("corep"), _
Version:=6)
strPath = selectFile
If strPath = "" Then Exit Sub
Set wbMe = Workbooks.Open(strPath, UpdateLinks:=0)
Dim PvtKraje As PivotTable
Dim data_wb As Workbook
CarryOn = MsgBox("Are you would like open BHPKO_mm_yyyy_podział po krajach?", vbYesNo, "Czy kontynuować?")
If CarryOn = vbYes Then
MyFolder = "source1"
MyFile = Dir(MyFolder & "\name_file1*.xlsx")
If MyFile <> "" Then
Set data_wb = Workbooks.Open(MyFolder & "\" & MyFile, UpdateLinks:=0)
Set PvtKraje = data_wb.Sheets("PODZIAŁ_KRAJ").PivotTables("KRAJE")
PvtKraje.ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:=wbMe.Sheets("corep"), _
Version:=6)
The issue is here:
SourceData:=wbMe.Sheets("corep")
From the PivotCaches.Create docs:
The SourceData argument ... should be passed a Range object (when SourceType is either xlConsolidation or xlDatabase)
You're passing a Worksheet currently, but need a Range:
SourceData:=wbMe.Sheets("corep").UsedRange
A side note, from the following paragraph in the docs:
When passing a Range object, we recommend that you either use a string to specify the workbook, worksheet, and cell range, or set up a named range and pass the name as a string. Passing a Range object may cause "type mismatch" errors unexpectedly.
In other words, UsedRange may work, but you might also encounter an unexpected Type Mismatch. You could either use a string, or set up a named range, or cross your fingers and hope for the best with UsedRange.
This is driving me insane. I've been banging my head against importing some excel data into microsoft access. Silly me for thinking that this should be easy since they are both microsoft products.
There are three excel files of about 40MB each. Four tabs in each file, each tab has the same fields in the same order between the files. ie, tab A in file 1 has the same field names in the same order as tab A in file 2 and file 3. And the corresponding table in the access database as the exact same field names in the exact same order as in the files also. Same goes for the other tabs. There are about 90K rows and about 40 columns in each tab.
The first tab I imported directly into Access and created a new table. Even though the other files have the same layout, I just can't seem to get access to import the other files correctly. Even though the fields have the exact same names in the exact same order, it keeps screwing up the mapping.
Not grossly, I either get a type conversion error for a field or two (which I also don't get since all the fields in the access table are of type "short text" so i can just import whatever is in the data files with no processing) or a couple of the wrong source fields from the files get imported into the wrong target fields in the database.
It's almost more annoying that just a few fields get messed up because it means I have to check the whole table to figure out if things went off. And it's not consistent, it screws up differently each time I try it.
I tried importing the data from the excel files and also by saving each tab as a csv. Nothing works. WTF am I doing wrong. Happy to try using some other database (filemaker, etc). I don't care about using access, I just thought it would be easier but I don't get why this is so freaking difficult.
Import data from all worksheets in all files in a folder.
Dim blnHasFieldNames As Boolean, blnEXCEL As Boolean, blnReadOnly As Boolean
Dim intWorkbookCounter As Integer
Dim lngCount As Long
Dim objExcel As Object, objWorkbook As Object
Dim colWorksheets As Collection
Dim strPath As String, strFile As String
Dim strPassword As String
' Establish an EXCEL application object
On Error Resume Next
Set objExcel = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Set objExcel = CreateObject("Excel.Application")
blnEXCEL = True
End If
Err.Clear
On Error GoTo 0
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = False
' Replace C:\MyFolder\ with the actual path to the folder that holds the EXCEL files
strPath = "C:\MyFolder\"
' Replace passwordtext with the real password;
' if there is no password, replace it with vbNullString constant
' (e.g., strPassword = vbNullString)
strPassword = "passwordtext"
blnReadOnly = True ' open EXCEL file in read-only mode
strFile = Dir(strPath & "*.xls")
intWorkbookCounter = 0
Do While strFile <> ""
intWorkbookCounter = intWorkbookCounter + 1
Set colWorksheets = New Collection
Set objWorkbook = objExcel.Workbooks.Open(strPath & strFile, , _
blnReadOnly, , strPassword)
For lngCount = 1 To objWorkbook.Worksheets.Count
colWorksheets.Add objWorkbook.Worksheets(lngCount).Name
Next lngCount
' Close the EXCEL file without saving the file, and clean up the EXCEL objects
objWorkbook.Close False
Set objWorkbook = Nothing
' Import the data from each worksheet into a separate table
For lngCount = colWorksheets.Count To 1 Step -1
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
"tbl" & colWorksheets(lngCount) & intWorkbookCounter, _
strPath & strFile, blnHasFieldNames, _
colWorksheets(lngCount) & "$"
Next lngCount
' Delete the collection
Set colWorksheets = Nothing
' Uncomment out the next code step if you want to delete the
' EXCEL file after it's been imported
' Kill strPath & strFile
strFile = Dir()
Loop
If blnEXCEL = True Then objExcel.Quit
Set objExcel = Nothing
http://www.accessmvp.com/KDSnell/EXCEL_Import.htm#ImpAllWkshtsFilesSepTbls
So I am using VBA in Access to create linked tables between Excel and Access. Simple enough and as some online resources guided me I decided to utilize the TransferSpreadsheet command. So I ran some code to test out if I had the syntax correct and got this
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel12, _
"Link Name", "File Path", True, "Sheet Name!"
So that worked perfectly, but I wanted to automate it so someone who doesn't understand how to code can use the function. So for the file path I set up a file dialog box to come up so the user can select the excel file. Again worked great.
So now to the point, I want to create a dialog box for users to select the excel sheet to link as well. So essentially the user would select the excel file first and then select from a drop down box the sheet they want to link. Is this possible? If so how would I go about doing it. Here is my code so far:
Public Sub linksheet()
Dim fd As FileDialog
Dim strpath As String
Set fd = Application.FileDialog(msoFileDialogFilePicker)
fd.AllowMultiSelect = False
fd.Title = "Select Routing File"
'get the number of the button chosen
Dim FileChosen As Integer
FileChosen = fd.Show
If FileChosen <> -1 Then
Else
strpath = fd.SelectedItems(1)
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel12, _
"Test Link", strpath, True, "Current!"
End If
End Sub
To add to this further I was attempting to utilize this code I found to get the names but I'm unsure how to store them as variables to use.
Public Function WorkSheetNames(strwspath As String) As Boolean
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Dim strarray(25)
Set xlApp = CreateObject("Excel.application")
Set xlBook = xlApp.Workbooks.Open(strwspath, 0, True)
For Each xlSheet In xlBook.Worksheets
Debug.Print xlSheet.Name
Next xlSheet
xlBook.Close False
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
Set xlSheet = Nothing
End Function
What the above code does is list out each sheet name into the debug window, I just am finding it difficult to push those values to an array.
I don't see why you need to store the sheet names in an array. You could store them as a list in a string variable. Then you could assign that string as the RowSource property of a combo box which allows the user to select one of the available sheets.
Dim strSheets As String
' adapt your existing code to use this ...
For Each xlSheet In xlBook.Worksheets
'Debug.Print xlSheet.Name
strSheets = strSheets & ";" & xlSheet.Name
Next xlSheet
' discard leading semi-colon
strSheets = Mid(strSheets, 2)
After you have collected the sheet names, apply them as the combo box source.
' ComboName should have Value List as Row Source Type
Me.ComboName.RowSource = strSheets
Hi there and thanks for your help. I'm putting together a seemingly simple Access data management solution for use in our office here and I'm having trouble as my background in vba is minimal at best.
What I have here are two related but disconnected Access 2007 applications and I need a system for the user to easily import and export this information. I've got a script working now to export all the tables from the application into a single excel file with each table as a different worksheet, the issue is that when I go to import it only seems to find the first sheet for import.
What I'm hoping to find is a method to iterate over each worksheet, grab the sheet name, and then merge that data into the table based on the sheet name.
To clarify:
Multiple copies of App A are sent to various departments
App A: Users enter information into the tables
App A: Users press command to run export macro
Excel file is created with each table as a sheet with matching names (e.g. tblCourse, tblStudent, tblFaculty, etc.)
Users of App B receive excel spreadsheet
App B: Users press command to run import script (This is the solution I'm looking for)
User is prompted for file location
Import script opens excel workbook
Script iterates over each sheet, reads name, and imports data to table of matching name
Thanks in advance for any help you can provide, much appreciated.
Edit
Working script (Thanks greatly to grahamj42's help here):
Private Sub Command101_Click()
'Dim excelapp As New Excel.Application
Dim excelApp As Object
Set excelApp = CreateObject("Excel.Application")
'Dim excelbook As New Excel.Workbook
Dim excelbook As Object
Set excelbook = excelApp.Workbooks.Add
'Dim excelsheet As New Excel.Worksheet
'Dim excelsheet As Object
'Set excelsheet = excelbook.Sheets
Dim intNoOfSheets As Integer, intCounter As Integer
Dim strFilePath As String, strLastDataColumn As String
Dim strLastDataRow As String, strLastDataCell As String
strFilePath = "C:\Users\UserName\Documents\Export\DatabaseExport03-28-2013.xlsx"
Set excelbook = excelApp.Workbooks.Open(strFilePath)
intNoOfSheets = excelbook.worksheets.Count
Dim CurrSheetName As String
For intCounter = 1 To intNoOfSheets
excelbook.worksheets(intCounter).Activate
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, ActiveSheet.Name, _
strFilePath, True, _
excelbook.Worksheets(intCounter).Name & "!" & _
Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")
Next
excelbook.Close
excelApp.Quit
Set excelApp = Nothing
End Sub
Note that in the DoCmd.TransferSpreadsheet command there is a HasFieldNames property that is set to 'True' here because my spreadsheets export with the field names as column headers.
Your use of Selection without selecting anything will refer to the selected cell in the worksheet when it was saved. While I don't see, in your case, why this should be outside the table, you could do better like this without selecting anything by using Worksheet.UsedRange:
For intCounter = 1 To intNoOfSheets
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, Activesheet.Name, _
strFilePath, True, _
excelbook.Worksheets(intCounter).Name & "!" & _
Replace(excelbook.Worksheets(intcounter).UsedRange.Address, "$", "")
Next
I did a little combining of two different pieces of code, as I didn't want to hard code the location or file name.
Dim excelApp As Object
Dim excelbook As Object
Dim dlg As FileDialog
Dim StrFileName As String, intcounter, intNoOfSheets As Integer
Set excelApp = CreateObject("Excel.Application")
Set dlg = Application.FileDialog(msoFileDialogFilePicker)
With dlg
.Title = "Select the Excel file to import"
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Excel Files", "*.xlsx", 1
.Filters.Add "All Files", "*.*", 2
If .Show = -1 Then
StrFileName = .SelectedItems(1)
Set excelbook = excelApp.Workbooks.Open(StrFileName)
intNoOfSheets = excelbook.worksheets.Count
'DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, "COR Daily", StrFileName, True
For intcounter = 1 To intNoOfSheets
excelbook.worksheets(intcounter).Activate
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel8, excelbook.Activesheet.Name, StrFileName, True, _
excelbook.worksheets(intcounter).Name & "!" & _
Replace(excelbook.worksheets(intcounter).UsedRange.Address, "$", "")
Next
Else
Exit Function
End If
End With
End Function
I have created an excel worksheet in a such way that the user can insert some rows (max 100).
The value of some fields are chosen from a dropdown list.
I put the formula on all 100 rows.
The problem is that the data are not imported in access, if the user inserts less of 100 rows. In this case the data are imported only if I delete the formula for the dropdown list from the remaining rows.
To import excel data in access I use:
DoCmd.TransferSpreadsheet [Transfer Type], [Spreadsheet Type], [Table Name], [File Name], [Has Field Names], [Range]
How could I resolve this issue?
EDIT
After the Remou's answer, I tried with:
Private Sub import_Click()
Dim openDialog As FileDialog
Dim FileChosen As Integer
Set openDialog = Application.FileDialog(msoFileDialogFilePicker)
On Error GoTo DoNothing
With openDialog
.title = "Import"
.AllowMultiSelect = False
.Show
End With
filename = openDialog.SelectedItems.Item(1)
Dim xl As Excel.Application
Dim wb As Excel.Workbook
Dim rng As Excel.Range
Set xl = CreateObject("Excel.Application")
xl.Visible = True
Set wb = xl.Workbooks.Open(nomeFile)
c = wb.Worksheets("Sheet1").Range("1:1").end(-4161).Address
r = wb.Worksheets("Sheet1").Range("A:A").end(-4121).Row
ImportRange = "Sheet1!" & "A1:" _
& Replace(Mid(c, 1, InStrRev(c, "$")) & r, "$", "")
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _
"ImportTable", filename, True, ImportRange
DoNothing:
If Err.Number = cdlCANCEL Then
End If
End Sub
but I've a debug error on Dim xl As Excel.Application
NOTE Having tested with Excel dropdowns and validation dropdowns, I find I do not have any problems importing data with validated cells or dropdowns in unused ranges, other than those rows are imported, even though all other cells are empty. The problem may be with data types and importing into an existing table. You may have to import to a scratch table and then append.
I suggest you use automation to get the used range and add that as the range to import.
This sample code uses late binding. You can add a reference to the Microsoft Excel x.x Object Library, so I have kept the various definitions, but late binding is best if you are using the code on more than one PC.
Dim xl As Object ''Excel.Application
Dim wb As Object ''Excel.Workbook
Dim rng As Object ''Excel.Range
Set xl = CreateObject("Excel.Application")
xl.Visible = True
Set wb = xl.Workbooks.Open("z:\docs\test.xlsx")
'Choosing a column that is fully filled on sheet5
'xldown=-4121,xltoright=-4161
c = wb.Worksheets("Sheet5").Range("1:1").end(-4161).Address
r = wb.Worksheets("Sheet5").Range("A:A").end(-4121).Row
ImportRange = "Sheet5!" & "A1:" _
& Replace(Mid(c, 1, InStrRev(c, "$")) & r, "$", "")
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, _
"ImportSheet2", "Z:\Docs\csharp.xlsm", True, ImportRange