I have an Access frontend with a lot of tables linked through ODBC to a MySQL backend. I have a VB.net application that sometimes adds columns to the tables in the backend, and when that happens, I need to refresh the link to the table in the frontend from the VB.net app to show the new columns.
I'll consider just about any solution as long as it doesn't require restarting MySQL or Access, and will allow me to refresh only the links I need to refresh (which I know in advance) as there are hundreds of links and tables in the frontend.
This should get you started:
Dim Con As New ADODB.Connection
Dim Cat As New ADOX.Catalog
Dim tbl As New ADOX.Table
Con.Open(m_sAccessDbPath)
Cat.ActiveConnection = Con
' Name the new Table and set its ParentCatalog property
' to the open Catalog to allow access to the Properties
' collection.
tbl.Name = m_sAccessDbTableName
tbl.ParentCatalog = Cat
' Set the properties to create the link.
tbl.Properties("Jet OLEDB:Create Link").Value = True
tbl.Properties("Jet OLEDB:Link Provider String").Value = RemoteDbPath
tbl.Properties("Jet OLEDB:Remote Table Name").Value = RemoteTableName
' Append the table to the Tables collection.
Cat.Tables.Append(tbl)
Source: http://bytes.com/topic/visual-basic-net/answers/370859-create-linked-table-access
Related
I am trying to change the links in an Access 2016 database, but the method I've used in the past is not working as required.
I am using the
t.connect="new connection"
t.refreshlink
method, where t is a the table.
I have seen in the linked table manager that the tables are now grouped by a data source. I can create the new source and link it to the desired table, but I have many as migrating, so would like to do this in code.
I get no errors the current way, but immediately after the .refreshlink the table's .connect is still the same.
Is this still possible?
I currently populate a dictionary with the table name and it's existing connection, but only if non ODBC.
I am then looping through this dictionary, getting the table and changing its connection
CurrentDb.TableDefs(strTableName).Connect = strNewConnection
CurrentDb.TableDefs(strTableName).RefreshLink
Debug.Print CurrentDb.TableDefs(strTableName).Connect
Existing connection = ;DATABASE=\\app01\Access\CRM_Data.mdb
New connection =;DATABASE=C:\CRM_TEST\CRM_DATA_BE_2016.accdb
Many thanks
You should not use CurrentDb.TableDefs when changing tables, as that changes between calls and makes the reference to the tabledef where you change the connection string be a different one than the one where you refresh the link.
Dim d As DAO.Database
Set d = CurrentDb
d.TableDefs(strTableName).Connect = strNewConnection
d.TableDefs(strTableName).RefreshLink
AFAIK this behaviour is not version-dependent, so the code you provided should never have worked.
I am using this code in Access 2016 and it works just fine:
Public Function RelinkTables(environment As Integer)
On Error Resume Next
Dim tblDef As DAO.TableDef
For Each tblDef In CurrentDb.TableDefs
If tblDef.Connect <> "" Then
tblDef.Connect = GetConnectionString(environment)
tblDef.RefreshLink
End If
Next
End Function
Public Function GetConnectionString(environment As Integer) As String
Select Case environment
Case 1 ' connection to Test db
GetConnectionString = "your connection string to Test"
Case 2 ' connection to Prod db
GetConnectionString = "your connection string to Production"
End Select
End Function
If this would not work with your db than may be the path is wrong.
I am building a somewhat complex Excel sheet for a bank, that uses an Access Database.
This sheet loads a ton of data to prebuilt sheets.
After that, they can run a few macros and add some inputs
In the end, I open a new connection to insert these inputs in different tables from the ones that where queried in the beginning
My problem is that when loading the information to the workbook, this action can only be performed by one user at a time.
When this process is running in one user computer other users get the error
The Microsoft Office Access database engine cannot open or write to
the file ''. It is already opened exclusively by another user, or you
need permission to view and write its data.
I know the users have permission because once the process is done on user 1, user 2 has no problem.
I am using ADODB (connection, recordset and command) and this is the code I use about four different times for four different stored queries in access:
Dim cnn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd_apoio As New ADODB.Command
Set cnn = New ADODB.Connection
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = " & PV.dbpath
With cmd_apoio
.ActiveConnection = cnn
.CommandType = adCmdStoredProc
.CommandText = "tabela_apoio_entidades"
.Parameters.Append .CreateParameter("nip", adNumeric, adParamInput, 20)
.Parameters.Append .CreateParameter("anomes", adNumeric, adParamInput, 20)
.Parameters(0) = PV.nip_grupo
.Parameters(1) = PV.ano_mes
End With
Set rs = cmd_apoio.Execute()
(the PV. variables are public variables declared in another module(PV))
Using this method is there a way to allow multiple connections at once?
Especially as this is only to retrieve information (read-only) and not to update any records in tables.
I am using Excel 2013 and Access 2013, the database is .accdb
EDIT: The tables are linked tables to txt files (i think this might be important)
Try using rs.Open instead of cmd.Execute, and specify the lock type:
After your End With:
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open cmd_apoio, cnn, adOpenStatic, adLockOptimistic
You need to set your connection mode explicitly:
Set cnn = New ADODB.Connection
cnn.Mode = 16 + 3 'adModeShareDenyNone + adModeShareReadWrite '
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = " & PV.dbpath
See here: https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/connectmodeenum
I can only contribute the comments that I've always considered excel not to be multi user.
And in linking Excel to Access - which I've done a lot - the excel must always be closed when working from the Access side. There cannot be a user directly in the Excel - it's role to Access is to behave like a table.
You are in the other direction in using Excel as the front end with Access tables linked - - but in terms of multi user I wonder if the situation is the same.
I am in the same situation as you do, having excel as front-end connecting to data stored in Access.
I kind of solved this multi-user issue by establishing and closing connection on every single action taken by user.
It drags down performance a lot, but I guess it enables concurrent uses.
cnn.Close
Set cnn = Nothing
I have Access database project connected with Ms SQL Server. Data (tables) is stored in the Ms SQL server and Forms and Reports are stored in the Access .ADP file. It is not possible to create Queries, Tables, Views using Design view but Tables and Views can be created using SQL queries and stored on the server. I don't have Ms SQL Server Management Studio and I can't install it in my computer in my office.
So, what I want is to get a dynamically generated Datasheet of a SELECT SQL query to see results temporarily for data analysis. I have placed a textbox and a button in a form and want to display a datasheet containing the result of the SQL query written in the textbox when the button is clicked.
I tried this but it is not working for me and doesn't seems what I want:
MS Access VBA - display dynamically built SQL results in datasheet subform
I also tried by assigning query to Recordsource property of a form. It is showing blank datasheet, but the navigation pane below the datasheet is showing the actual number of records retrieved. So, it is working but not showing the data.
I tried (from http://www.pcreview.co.uk/forums/create-query-dynamically-vba-t3146896.html):
Dim db As DAO.Database
Dim qd As DAO.QueryDef
Dim strSQL As String
Set db = CurrentDb
strSQL = "select * from analysts"
Set qd = db.CreateQueryDef("NewQueryName", strSQL)
DoCmd.OpenQuery "db.NewQueryName"
It is showing run-time error 91, Object variable or With block variable not set on the line Set qd = db....
And also (from the same page):
Dim strSql As String
strSql = "select * from analysts"
CurrentDb.QueryDefs("qryExport").SQL = strSql
DoCmd.OpenQuery "qryExport"
Returning same error on the line CurrentDb.QueryDefs.....
Any idea or workaround?
This doesn't seems efficient, but it is working and a bit satisfactory:
DoCmd.RunSQL "IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS " & _
"WHERE TABLE_NAME = 'tv') DROP VIEW tv"
DoCmd.RunSQL "create view tv as " & txtQry
DoCmd.OpenView "tv"
Here I am creating a temporary VIEW (tv) in a button's click event. Before creating the view, I am checking that if a view with the same name exist or not; and if it exist then delete it so that a new view can be created with the same name with different query.
Access ADPs are a whole different beast than the normal MDB that you are probably used to working with. DAO isn't generally used in ADPs, you probably had to add a reference to DAO to get any part of the code above to work. ADPs are designed around using ADO to interact with the source database. If you just want to open a recordset to your data, use something along these lines.
Dim strSql As String
Dim rs as ADODB.Recordset
strSql = "select * from analysts"
set rs = New ADODB.Recordset
Set rs.ActiveConnection = CurrentProject.Connection
rs.Source = strsql
rs.Open
You can then interact with that recordset. If you want to bind that recordset to a form so that you can view the data, you can use:
Set Me.Recordset = rs
This is working how I want:
Dim frm As Form ' create a form dynamically
Set frm = CreateForm
Dim rs As New ADODB.Recordset
rs.Open Replace(txtQry, vbCrLf, " "), CurrentProject.Connection ' replace "enters" (vbCrLf) with space because it was throwing error while executing query!
Dim c As Control
For Each f In rs.Fields
Set c = CreateControl(frm.Name, IIf(f.Type = 11, acCheckBox, acTextBox)) ' if field type is "bit", add checkbox; for other datatypes, add textbox
c.ControlSource = f.Name
c.Name = f.Name ' sets column header to the same name as of field's name
Next
rs.Close
frm.RecordSource = txtQry
DoCmd.OpenForm frm.Name, acFormDS ' open form in "DataSheet" view otherwise it will be in "Form" view
This code is placed in a button's click event.
Other possible datatypes for rs.Fields(x).Type (here, f.Type) are (3 = int, 200 = varchar)
I am creating a Lotus Notes application which has to have dynamic combo boxes. The choices for the combo boxes need to be retrieved by selecting from a SQL database.
I am new to Lotus Notes / Domino, I would love to know how to connect my SQL database for use in the domino designer. Thanks.
Edit: this is the client, not the web
Sub Initialize
On Error GoTo e
Dim pw As String,user As String,odbc As String
Dim i As Integer
Dim conn As ODBCConnection,query As ODBCQuery,rs As ODBCResultSet
Dim db As NotesDatabase
Dim session As NotesSession
Dim view As NotesView
Dim doc As NotesDocument
Dim newDoc As NotesDocument
Set session = New NotesSession
Set db = session.CurrentDatabase
Set view = db.GetView("Reports")
Set doc = view.GetFirstDocument
Set conn = New ODBCConnection
Set query = New ODBCQuery
Set rs = New ODBCResultSet
Set query.Connection = conn
Set rs.Query = query
odbc = "server"
user = "user"
pw = "pass"
Call conn.ConnectTo( odbc , user , pw )
i = 0
query.SQL = "SELECT * FROM table"
rs.Execute
rs.FirstRow
Do While Not rs.IsEndOfData
i = i + 1
rs.NextRow
Loop
conn.Disconnect
Exit Sub
e :
MessageBox "Error " & Err & " line " & Erl & ": " & _
Error
Exit Sub
End Sub
The questions is tagged Lotusscript so I assume that this is Lotusscript related (and not XPages related).
Have a look at the ODBCConnection, ODBCQuery, and ODBCResultSet Lotusscript classes in the Domino Designer Help database.
If you're not able to use any XPages components, you could try the ODBC variant of #DBLookup in the 'Use formula for choices' part of your combobox.
The code you have added to the question is going to cause an infinite loop due to the while/wend
Depending on how often the choices for the dropdown boxes change you could also create a scheduled agent that connections to the SQL server. I do this a lot for some of my own internal applications as it cuts down on unnecessary traffic to the SQL server if the values being returned are always the same.
Your scheduled agent would need to use the LSXLC extensions by adding UseLSX "*lsxlc" to the options section of the Lotusscript agent.
The LSXLC has a LOT of options which would be beyond the scope of this question so I would recommend looking at the Domino Designer Help files and searching for lsxlc. There are lots of examples in the help files.
Have a look at extlib on OpenNTF. It has an XPages component that allows you to connect to make SQL calls.
http://extlib.openntf.org
if you are using an xpages application, you can use a managed bean or static java method to get the data you want and bind it to the select values of the of combobox control.
Connect to a linked table with code.
I have some linked tables from a SQL-server; they are linked with an ODBC connection. The password is not saved with the connection. When I am double clicking on the table in Access table-view I get a prompt for username and password. After entering the password I can view the data in the table.
My problem is when I try to access the table with code before having opened it in this way. What I try to do is to use ADODB to open a recordset with data from the linked table, like:
Dim rst as new ADODB.Recordset
Dim sql as string
Sql = “SELECT * FROM LinkedTable”
rst.Open sql, CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly
Running this code without having access the table before will generate this error: Error# -2147467259, ODBC: connection to dns-name failed.
So, my question is, are there any way to connect to the database with code that can be run when the database is opened? This would also help the users as they would not have to remember a password to the SQL-server.
It seems that you are mixing 2 technologies that might not work together, ie linked tables through ODBC and ADODB recordsets. Have you tried to open DAO recordsets on your linked tables?
Dim rst as DAO.Recordset
Dim sql as string
Sql = “SELECT * FROM LinkedTable”
set rst = currentDb.openRecordset(sql,<your parameters>)
You could of course use ADODB recordsets through 2 ADODB connections, one to your access file, the other one to your SQL server:
Dim rsSQL as ADODB.recordset, _
rsACCESS as ADODB.recordset, _
connectionSQL as ADODB.connection, _
connectionACCESS as ADODB.connection
set connectionSQL = New ADODB.connection
set connectionACCESS = New ADODB.connection
connectionSQL.properties(...) = enumerate your SQL parameters
connectionACCESS.properties(...) = enumerate your ACCESS parameters (use currentproject.accessConnection if your access tables are local tables only)
set rsSQl = New ADODB.recordset
set rsACCESS = New ADODB.recordset
rsSQL.open "SELECT * FROM ...", connectionSQL, <other parameters>
rsACCESS.open "SELECT * FROM ...", connectionACCESS, <other parameters>
Linking ADO recordsets to forms and comboboxes in Access is possible. But, when creating forms, this technology has to be mainly managed through VBA code (you will have to write 'on open' events such as set me.recorset = ...), while the standard "linked tables" technology can be easily used through the user-friendly 'form-design' interface.
You can use a connection string in your code, it is easy enough, seeing you are already using ADO: http://www.connectionstrings.com/
You will need to find out which version of SQL Server you are linking to.