So I've been trying to put together this last piece of this VBA script and the connection to the database is giving me problems. The database opens but right after I get and error could not find installable isam I tried to register the DLL, no luck, I tried different versions in the connection, no luck.
At this point I am at a loss. All this is trying to do is import a range in an Excel sheet to the Access database. If anyone has a reason why it is giving me this error, please help.
Sub Open_Database()
Dim appAccess As Object
Dim pathToDatabase As String
pathToDatabase = Environ("USERPROFILE") + "\Desktop\FuturesDemandScheduling - Copy.mdb"
Set appAccess = CreateObject("Access.Application")
appAccess.OpenCurrentDatabase pathToDatabase, True, "password"
Windows("FuturesFIle-2014.xlsx").Activate
appAccess.DoCmd.TransferSpreadsheet acImport, _
acSpreadsheetTypeExcel3, _
"futuresData", _
Application.ActiveWorkbook.FullName, _
False, _
"A2:G491"
appAccess.CloseCurrentDatabase
appAccess.Quit
Set appAccess = Nothing
End Sub
I suspect the problem is the way you are importing the excel data into the table
Since you said the version of excel is 2010 and you are using .xlsx file extension in the code
Try
acSpreadsheetTypeExcel12Xml instead of acSpreadsheetTypeExcel3
acSpreadsheetTypeExcel3 supports Excel 3.0 Format
acSpreadsheetTypeExcel12Xml supports Excel 2010
Complete list here
Related
I am using an Excel macro to define a data range in Excel and then call "objAccess.DoCmd.TransferSpreadsheet" to import the data from this range into an Access table. This import does not work all of the time.
I have come to the conclusion that the macro works fine when there is only one instance of Excel open. However, the data import fails when another instance is already open. In the latter case the Access database opens up and the Excel file from which I run the macro is being reopened (in read-only mode) in the other Excel instance. There is no actual error but the desired import is not being carried out. Why does this happen?
Sub Excel_2_Access()
Dim strPath As String
Dim strwbPath As String
Dim strRange As String
Dim objAccess As Access.Application
Dim wbActive As Workbook
'get database path
strPath = Worksheets("error").Range("Access_DB_Path").Value & "\" & Worksheets("error").Range("Access_DB").Value
'open database
Set objAccess = New Access.Application
Call objAccess.OpenCurrentDatabase(strPath)
objAccess.Visible = True
'access import
Worksheets("error").Columns("P:P").Calculate
Set wbActive = ActiveWorkbook
strwbPath = Application.ActiveWorkbook.FullName
strRange = "error!M2:M" & (Worksheets("error").Range("WKN_count").Value + 2)
Call objAccess.DoCmd.TransferSpreadsheet(acImport, 8, "WKN_Mapping", strwbPath, True, strRange)
objAccess.Forms("MX_Import").Refresh
End Sub
As the macro is fairly short I have included the entire code for your reference. However, I don't think the way the range is specified or names are provided is really relevant to the question.
The desired outcome would be to have an Excel macro in place that carries out the transfer from Excel to Access no matter if there are other instances of Excel open or not.
Is there such a thing as the primary instance of Excel (the first one that was opened) which has a special status? Is there a way to provide the specific Excel instance the workbook is in when calling the Access function from Excel? Or is there a more reliable way to transfer the data which generally avoids this problem with multiple instances?
I tested approach that opens Access db and runs TransferSreadsheet. Don't need to set a workbook object (your code sets but then doesn't even utilize). It ran without error every time. I tried setting the Access object Visible but the database appears and immediately closes anyway, although the data import does happen. Set reference libarary: Microsoft Access x.x Object Library.
Sub test()
Dim ac As Access.Application, strRange As String
Set ac = New Access.Application
strRange = "Sheet1!A1:E3"
ac.OpenCurrentDatabase "C:\Users\June\LL\Umpires.accdb"
ac.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "Rates", ThisWorkbook.FullName, True, strRange
End Sub
Example Excel VBA code that exports all rows of worksheet to existing table in Access without opening Access file. Setting an ADODB connection makes the Execute method available. This approach runs faster. Set reference library: Microsoft ActiveX Data Objects x.x Library.
Sub test()
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 8.0"
cn.Execute "INSERT INTO Rates(RateLevel, Rate, Pos, EffDate) IN 'C:\Users\June\LL\Umpires.accdb' " & _
"SELECT RateLevel,Rate,Pos,EffDate FROM [Sheet1$];"
cn.Close
Set cn = Nothing
End Sub
So after searching through numerous other pages im still having difficulty and admittedly its due to self teaching myself VBA, so forgive me :(
I have created a simple Phone call counter Access form with a table. My goal is to press a button and it exports the table to a specified directory to an existing XLSM (the data exported would open a new worksheet with the current date as the worksheet name and then save it.
database location is here:
L:\Reports\TestCalltoolmetric.accdb
existing Excel file is here:
L:\Reports\Callcounterreports\MonthlyCallCounter.xlsm
What i have tried so far...
1.
Dim strTable As String
Dim strWorksheetPath As String
strWorksheetPath = "L:\Reports\Callcounterreports"
strWorksheetPath = strWorksheetPath & Format(Date, "ddmmmyy") & "Callreport.xlsx"
This exports my database to a new file with the name of the file as the date+callreport. It works but i dont know if i can use this command to accomplish my goal above (filename isnt really important but at the end of the month i need to provide call metrics so i need every days export all in one workbook so i can create totals).
2.
I tried using this:
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "Table1", "L:\Reports\Callcounterreports\MonthlyCallCounter.xlsm"
But it errors out saying that Access database engine could not find the object 'Table1'
3.
I also found through some furious googling a similar request but it was based off exporting a query...in an less than educated mannor i tried adapting it but never really was able to get it to work..
Dim appXL As Object
Dim wb As Object
Dim wks As Object
Dim xlf As String
Dim rs As DAO.Recordset
xlf = "L:\Reports\Callcounterreports\MonthlyCallCounter.xlsm" 'Full path to Excel file
Set rs = CurrentDb.OpenRecordset("Query1") 'Replace Query1 with real query name
Set appXL = CreateObject("Excel.Application")
Set wb = appXL.Workbooks.Open(xlf)
Set wks = wb.Sheets & Format (Date, "ddmmmyy") ' Sheet name
wb.Save
wb.Close
appXL.Quit
Set wb = Nothing
rs.Close
Set rs = Nothing
I know i am by far not the first person to probably ask about how to do this, but any help would be fantastic!
SO....after futher digging i figured out what i was doing wrong with at least using
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "Table1", "L:\Reports\Callcounterreports\MonthlyCallCounter.xlsm"
I first had to rename the table from "Table1" to another name, which i chose "DataTable".
Second i made a mistake on the filepath portion of the command, the location was a networked location which showed up a drive letter. after putting the full and correct file path the form worked like a charm.
https://msdn.microsoft.com/en-us/vba/access-vba/articles/docmd-transferspreadsheet-method-access
i used this website to verify my commands, which now i feel silly that i hadnt found it before.
Big thank you to #dbmitch i think frustration got the better of me instead of really reading the error info..
Is there any way to link tables in an Access database to Excel without importing the entire table? I need to reference/lookup cells in the Access table but don't want to import the whole table into the excel workbook (tables are too big).
My second option is to export the Access tables into a separate excel workbook, then just reference this new workbook instead of the Access database itself. When I try to do this only around 65,000 rows of data from any Access table actually export to Excel, as the rest 'couldn't be copied to the clipboard'. Is there a simple way around this? (I want to actually have a connection between the excel/access files, so the data can be refreshed, not just copy and paste the rows over)
See this ancient article, which should help you get the data you actually need rather than everything:
http://dailydoseofexcel.com/archives/2004/12/13/parameters-in-excel-external-data-queries/
You can work with Access database tables from Excel without importing the table into an Excel worksheet:
Dim cnn As ADODB.Connection ' Needs a reference to the Microsoft ActiveX
Dim rs As ADODB.Recordset ' Data Objects Library
Set cnn = CreateObject("ADODB.Connection")
cnn.Open "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=database-path\Data.accdb;"
Set rs = cnn.Execute("SELECT * FROM MyTable")
While Not rs.EOF
Debug.Print rs(1)
rs.MoveNext
Wend
You may need the Microsoft Access Database Engine 2010 Redistributable which you should install with the /passive option if you are using a x86 Access version on a x64 OS.
Try the following script. This should give you what you want.
Option Compare Database
Private Sub Command0_Click()
Dim InputFile As String
Dim InputPath As String
InputPath = "C:\your_path_here\Desktop\"
InputFile = Dir(InputPath & "*.xlsx")
Do While InputFile <> ""
DoCmd.TransferSpreadsheet acLink, , InputFile, InputPath & InputFile, True '< The true is for column headers
InputFile = Dir
Loop
End Sub
I'm following the instructions here http://software-solutions-online.com/excel-vba-export-worksheet-to-existing-access-table/ to transfer data from an Excel spreadsheet to an Access database. The script I have adapted is:
Sub MailMerge2()
Dim strPath As String
Dim objAccess As Access.Application
Dim strExcelPath As String
strPath = "C:...Documents\MailMerge2"
strExcelPath = Application.ActiveWorkbook.FullName
Set objAccess = New Access.Application
Call objAccess.OpenCurrentDatabase(strPath)
objAccess.Visible = True
Call objAccess.DoCmd.TransferSpreadsheet(acImport, _
acSpreadsheetTypeExcel8, "MyTable1", strExcelPath, _
True, "A1:D11")
End Sub
However, running this gives me an error saying:
Run-time error: 7866, Microsoft Access can't open the database
because it is missing, or opened exclusively by another user, or it is
not an ADP file.
Any suggestions on which of these the problem is? I'm fairly new to Access, and haven't quite got the hang of the terminology yet.
Found the problem. I left out .accdb in my Access db file names.
RESOLVED: I've accepted an answer below from Siddharth. I greatly appreciate everyone's help and I am amazed at the swift responses. I always learn something new when coming to this community for help, you guys are awesome.
Thanks for taking a moment to look at my message. I've put together a script (thanks in no small part to the great help here on SO) that takes an excel workbook and imports each worksheet to a separate table in an Access 2007 database. The script used to work fine on my PC but since a recent recovery from a hardware failure I haven't been able to get the script to run. To top it off, my client is getting different error messages than my own.
A large part of the issue has to do with my object references, when I have the Microsoft Excel 14 Object Library added as a reference from the tools menu, all works fine. However, the client has a different version of Office on their systems and wishes this app to be distributed to others who may have other versions of office installed. I've tried to implement some form of late binding, but I may not be approaching this correctly. Code is below:
edit: current code updated again, related to the accepted post from Siddharth below
Private Sub Command101_Click()
On Error GoTo Err_Command101_Click
' Set up excel object
Dim excelApp As Object
Set excelApp = CreateObject("Excel.Application")
' Set up workbook object
Dim excelbook As Object
' Set up file selection objects with parameters
Dim fileSelection As Object
Dim intNoOfSheets As Integer, intCounter As Integer
Dim strFilePath As String, strLastDataColumn As String
Dim strLastDataRow As String, strLastDataCell As String
' Prompt user with file open dialog
Set fileSelection = Application.FileDialog(1)
fileSelection.AllowMultiSelect = False
fileSelection.Show
' Get the selected file path
strFilePath = fileSelection.SelectedItems.Item(1)
' Open the workbook using the file path
Set excelbook = excelApp.Workbooks.Open(strFilePath)
' Get the number of worksheets
intNoOfSheets = excelbook.Worksheets.Count
' Set up object for current sheet name
Dim CurrSheetName As String
' Disable errors
DoCmd.SetWarnings False
' Loop through each sheet, adding data to the named table that matches the sheet
For intCounter = 1 To intNoOfSheets
excelbook.Worksheets(intCounter).Activate
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _
excelbook.Worksheets(intCounter).Name, strFilePath, True, _
excelbook.Worksheets(intCounter).Name & "!" & _
Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")
Next
' Close Excel objects
excelbook.Close
excelApp.Quit
Set excelApp = Nothing
' Confirmation message
MsgBox "Data import Complete!", vbOKOnly, ""
DoCmd.SetWarnings True
Err_Command101_Click:
MsgBox Err.Description
End Sub
The failure seems to occur for the client on the line Set excelbook = excelApp.Workbooks.Add with this message:
My question is somewhat twofold:
a) Have I implemented late binding properly? and
b) How can I resolve this error while making sure to keep the script independent of a specific Office release?
Thanks for any help you can provide!
I believe the error is in this line
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, ActiveSheet.Name, _
strFilePath, True, _
excelbook.Worksheets(intCounter).Name & "!" & _
Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")
ActiveSheet.Name <+++++ This is causing the error.
Change that to excelbook.Worksheets(intCounter).Name
In Latebinding the code will not understand what Activesheet is
FOLLOWUP
You are getting a compile error because you did not add " _" at the end of the first line in DoCmd.TransferSpreadsheet
Copy the below code and paste it as it is in your code.
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, _
excelbook.Worksheets(intCounter).Name, _
strFilePath, True, _
excelbook.Worksheets(intCounter).Name & "!" & _
Replace(excelbook.Worksheets(intCounter).UsedRange.Address, "$", "")
The Workbooks.Add method creates a new workbook. I don't understand why you're using that. Seems so me you want the user to select an existing workbook and open that, so you should use Workbooks.Open instead.
As to whether you have implemented late binding correctly, make sure your code module includes Option Explicit in its Declarations section (see Gord's answer for useful details), and then run Debug->Compile from the VB Editor's main menu. That effort will alert you to anything in your code (objects, properties, methods, constants) for which you need further work to make them compatible with late binding.
This is a big red flag:
DoCmd.SetWarnings False
Turning SetWarnings off can suppress error information which you need to help understand why your code isn't doing what you want. If you feel you must turn off SetWarnings in your production code, at least leave it on during development and debugging.
I'll add this just for reference... In the VBA IDE Window choose Tools > Options... and ensure that the "Require Variable Declaration" box has a check mark in it:
Then, check all of your existing modules to make sure that the very first two lines are
Option Compare Database
Option Explicit
The Option Explicit statement will be added to any new Modules that you create, but you'll need to add it yourself for any existing Modules.