I import data from an Access database just fine. However, I want to make the DB a runtime (.accdr instead of .accde). The Runtime works fine, too, on its own, but I cannot import data from a runtime application when in Excel (it does not permit it).
How can I contact my database and have a Runtime mode?
Nothing on the web I have found even mentions this problem. I have no problem with opening an ADODB connection with VBA if it is required.
Since ACCDR databases are not displayed among the choices offered by Excel's Data>From Access option, you can open a recordset to retrieve your Access data and then use Excel's CopyFromRecordset Method to save those data into a worksheet.
This code uses a DAO recordset loaded from an ACCDR database file and saves the data in the active worksheet ...
Const cstrDbPath As String = "C:\share\Access\Database2.accdr"
Const cstrDao = "DAO.DBEngine.120"
Dim dbe As Object ' DAO.DBEngine
Dim db As Object ' DAO.Database
Dim rs As Object ' DAO.Recordset
Dim strSql As String
strSql = "SELECT 'Hello World' AS greet_world;"
Set dbe = CreateObject(cstrDao)
Set db = dbe.OpenDatabase(cstrDbPath, True)
Set rs = db.OpenRecordset(strSql)
Range("A2").CopyFromRecordset rs
rs.Close
db.Close
That code uses DAO with late binding. If you prefer early binding, add "Microsoft Office <version> Access database engine Object Library" to your project's references.
Or if you prefer ADO, CopyFromRecordset will also work with an ADO recordset.
Related
I'm struggling opening a database from excel.
I'm want to retrieve some information and populate comboboxes.
I tried pasting the code in a standard module, and running it inside the userform module.
I run the code when the userform initializes.
First the code:
Dim dbe As DAO.DBEngine
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qry As String
On Error GoTo ERR_BBDD
'This is the line where the error is thrown.
Set db = dbe.OpenDatabase("E:\myDB.mdb")
I get error 91 "variable or with block not defined blah blah".
I checked if the .mdb file path is ok and it is.
The code is really simple but I must be missing something and can't find a reason for it to be failing, since as I read in all the docs and the internet, my code should work fine.
It looks like you're trying to open Access (for DAO) as you would from inside of an Access application instance, but you're in Excel. I don't think Excel has a DBEngine for you to call. You could open Access as a new Access.Application instance, then do your operations, but it will literally open an Access instance in the background which is not really efficient for a few lookups.
Instead I would suggest creating an ADODB connection, load your lookups, then close it.
Set objCnn = CreateObject("ADODB.Connection")
objCnn.Provider = "Microsoft.Jet.OLEDB.4.0"
objCnn.Open strDir & "\MyDatabase.mdb"
Set rst = CreateObject("ADODB.Recordset")
rst.Open strSQL, objCnn, adOpenStatic
Do Until rst.EOF
... do some lookup loading stuff here
rst.MoveNext
Loop
rst.Close
Hope that works!
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
I have a macro in Excel to delete tables in Access.
Is there is a way to do this without opening the Access database?
Set AppAcc = Nothing
Set AppAcc = New Access.Application
AppAcc.Visible = True
AppAcc.OpenCurrentDatabase "C:\MyStuff\MyDataBase.mdb"
AppAcc.DoCmd.SetWarnings False
With AppAcc
.DoCmd.OpenQuery "Delete_Query1"
.DoCmd.OpenQuery "Delete_Query2"
.DoCmd.OpenQuery "Delete_Query3"
End With
AppAcc.DoCmd.SetWarnings True
AppAcc.Quit acQuitSaveNone
Set AppAcc = Nothing
Absolutely, there is a way. Since MS Access is a database it can connect via a backend like all major RDBMS's (Oracle, SQL Server, Postgres, etc.). Below demonstrates ODBC/OLEDB connections using ADO. Then, further below is an alternative version with DAO which you are currently running but can do so without Access.Application and DoCmd calls.
Both should even work without having MS Access GUI (the MS Office app) installed. Each use late binding. For early binding, add VBA references Microsoft ActiveX Data Objects #.# Library or Microsoft DAO #.# Object Library, then modify Dim and Set statements.
ADO
Dim conn As Object
Set conn = CreateObject("ADODB.Connection")
' WITH ODBC DRIVER
conn.Open "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C:\MyStuff\MyDataBase.mdb;"
' WITH ODBC DSN
'conn.Open "DSN=MS Access Database;DBQ=C:\MyStuff\MyDataBase.mdb;"
' WITH OLEDB PROVIDER
'conn.Open "PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyStuff\MyDataBase.mdb;"
' THREE WAYS TO CALL ACTION QUERIES
conn.Execute "{CALL Delete_Query1}"
conn.Execute "EXEC Delete_Query2"
conn.Execute "Delete_Query3"
Set conn = Nothing
DAO
Dim conn As Object, db As Object
Set conn = CreateObject("DAO.DBEngine.120")
Set db = conn.OpenDatabase("C:\MyStuff\MyDataBase.mdb")
db.Execute "Delete_Query1"
db.Execute "Delete_Query2"
db.Execute "Delete_Query3"
Set db = Nothing
Set conn = Nothing
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 Have a database that many people across my workplace have excel files with linked tables etc.
There are times where it is critical I have exclusive access to the DB and it is not feasible to track down hundreds of possible excel files with links that do not properly break and revamp them; especially when people are makign new files all the time.
I found the following code that allows me to see whether someone is connected o the front end of the database:
Sub ShowUserRosterMultipleUsers()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i, j As Long
Set cn = CurrentProject.Connection
' The user roster is exposed as a provider-specific schema rowset
' in the Jet 4.0 OLE DB provider. You have to use a GUID to
' reference the schema, as provider-specific schemas are not
' listed in ADO's type library for schema rowsets
Set rs = cn.OpenSchema(adSchemaProviderSpecific, _
, "{947bb102-5d43-11d1-bdbf-00c04fb92675}")
'Output the list of all users in the current database.
Debug.Print rs.Fields(0).Name, "", rs.Fields(1).Name, _
"", rs.Fields(2).Name, rs.Fields(3).Name
While Not rs.EOF
Debug.Print rs.Fields(0), rs.Fields(1), _
rs.Fields(2), rs.Fields(3)
rs.MoveNext
Wend
End Sub
is there any code that will do the same thing as this to give me back end connections? As in who has an open excel file that is linked and locking the DB to Read- Only?
1) You can open a connection to any database. You've used "CurrentProject.Connection", but you can use:
set cn=Server.CreateObject("ADODB.Connection")
cn.Provider="Microsoft.Jet.OLEDB.4.0"
cn.Open "c:/webdata/northwind.mdb"
2) If method (1) is not suitable, you can use ODBC to query WMI and get a list of everyone connected to any particular file.