MS Access queries with inline functions can't be exposed - sql

I have an MS Access 2003 database that contains the following query:
SELECT Replace(Trim(TABLE_A.Field_01), "XXX", "YYY") AS FLD01 FROM TABLE_A
If I do an "Import Data" with Excel from this Access database, I can't find the name of this query that is defined in the database.
If I change the query by removing the Trim function, then I can see the query in Excel.
SELECT RTrim(LTrim(TABLE_A.Field_01)) AS FLD01 FROM TABLE_A
Has anyone had a similar experience? I think there's a limitation on what kind of function one can apply to a query in MS Access.
It looks like there is a problem with MS Jet SQL, which doesn't support the Replace() function - searching the key words "Jet Sql Replace Function" in google gives a lot of references with various issues with the same root cause, but I haven't found a decent solution yet...

Trim() function is not a part of SQL (resides in VBA.Strings library) so couldn't be called outside MS Access.
So you can use any SQL function but none of "external".

For what it's worth, the Replace() function is supported by the Access Database Engine 2010 (a.k.a. "ACE", the successor to "Jet"), available here. To verify that I created a table named [SomeTable] in an Access 2003 database file:
ID s
-- ----------------------------
1 Everybody loves tofu!
2 Nobody really liked Raymond.
...and I created a saved query named [stockReplaceQuery]:
SELECT ID, Replace([s],"tofu","bacon") AS s1
FROM SomeTable;
When I tested a Jet ODBC connection using the following VBScript
Option Explicit
Dim con, rst
Set con = CreateObject("ADODB.Connection")
con.Open "Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\Users\Public\2003test.mdb;"
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT s1 FROM stockReplaceQuery WHERE ID = 1", con
WScript.Echo rst(0).Value
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
...I got
C:\__tmp>cscript /nologo repl.vbs
C:\__tmp\repl.vbs(6, 1) Microsoft OLE DB Provider for ODBC Drivers: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression.
When I tested an ACE ODBC connection by changing the con.Open line to
con.Open "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\Users\Public\2003test.mdb;"
...I got
C:\__tmp>cscript /nologo repl.vbs
Everybody loves bacon!
It might be worth a try to install the ACE engine/drivers and see if that helps any.

Related

Open a Table in a Form using VBA

In the "old" days, in order for me to search a "Table" for specific data in a vba statement in a "Form"/"Event" in MS Access 2003, that I chose. I would use the following code:
Set Table_ID = New ADODB.Recordset
Table_ID.CursorLocation = adUseClient
Table_ID.Open "Select * From Table_ID", _
CurrentProject.Connection, adOpenDynamic, adLockOptimistic
The above code gives me the following message when I ran it MS Access 2019:
Microsoft Visual Basic for Application Compile error: User-defined type not defined
I changed the "ADODB" with the database I'm using in MS Access 2019 as follows:
Set Table_ID = New DB002.Recordset
When I ran it again in MS Access 2019, the same message appeared.
Please advise.

Microsoft Access Append VBA

I am trying to automate records from a query to append to a table if the ID does not exist. While running into issues, I have even tried to use VBA from some other databases I know this is working on and put it into the targeted database. Still, I am receiving the same error. It is highlighting "dbs as Database" when the error appears.
Error- "Compile Error: User-defined type not defined"
Function HistoricTable()
Dim dbs As Database
Dim qdf As QueryDef
Set dbs = CurrentDb
dbs.Execute "insert into [Destination_Table] SELECT * FROM [Query Name] "
End Function
Thank you!
I believe it should be something like this.
INSERT INTO target [(field1[, field2[, …]])]
VALUES (value1[, value2[, …]])
See the link below for more info.
http://www.fmsinc.com/microsoftaccess/query/snytax/append-query.html
You have to add a reference to the DAO library in the VBA editor. In my old Access it's in the menu Tools > References...
You can also remove the ADODB library (the other database access technology).

SQL Query in Excel gives "undefined function name" error

I wrote a SQL query in MS Access that uses the MonthName function. In access it works flawlessly. I copied the exact SQL statement into an excel module that I frequently use to query databases. When I run the query, excel keeps telling me that MonthName is an undefined function name. If I remove the MonthName portion, the query runs fine.
It seems like I'm missing a reference or something... Right now, I'm referencing Microsoft ActiveX Data Objects Library 6.0. Can anyone point me in the right direction? Thanks
strSQL = "SELECT DISTINCT Customers.CustomerName, Employees.EmployeeName, [Policy data revised].EXDT, MonthName(Month([EXDT])) AS expMonth
FROM (([Service Team table]
INNER JOIN Customers
ON [Service Team table].CustID = Customers.CustID)
INNER JOIN Employees
ON [Service Team table].EmployeeID = Employees.EmployeeID)
INNER JOIN [Policy data revised]
ON Customers.CustID = [Policy data revised].CustID
WHERE ((([Service Team table].RoleExtension)='2. Underwriting Assistant')
AND (([Policy data revised].EXDT)
BETWEEN #" & minExpDt & "# AND #" & maxExpDt & "#))
ORDER BY [Policy data revised].EXDT ASC;"
The MonthName() function is only available for queries run within an Access application session. See the "The following VBA functions won't work when called from a property sheet or used in an SQL statement" bullet point at About Microsoft Jet Expression Service sandbox mode. Within an Access application session, the db engine can use the expression service to use that sandboxed function.
Since you can't use MonthName, try this Format expression instead.
Format([EXDT], 'mmmm') AS expMonth
Strange, I just tried the following code in Excel 2010 (64-bit) and it worked for me:
Sub foo()
'' Reference: "Microsoft ActiveX Data Objects 6.0 Library"
Dim con As ADODB.Connection, rst As ADODB.Recordset
Set con = New ADODB.Connection
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Gord\Desktop\Database1.accdb;"
Set rst = New ADODB.Recordset
rst.Open "SELECT MonthName(Month([BookingStart])) FROM Payment_tbl", con, adOpenStatic, adLockOptimistic
Debug.Print rst(0).Value
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
End Sub
Edit
Further to HansUp's comment, something must have changed between Office 2007 and Office 2010. I ran another test from a 32-bit machine running Office 2010 and the above code run against an Access 2000 .mdb file worked for me using both...
Provider=Microsoft.ACE.OLEDB.12.0;
...and...
Provider=Microsoft.Jet.OLEDB.4.0;
I also checked the SandBoxMode registry value under...
HKLM\Software\Microsoft\Office\14.0\Access Connectivity Engine\Engines
...and it is 3, which is the value for "Enabled" (ref: here).

Multiple databases in MS Access VBA?

This Microsoft KB article details how to run a query on another database than the current one used by the Access project. However it only states how to connect to DBase, Foxpro, Paradox, BTrieve and ODBC.
I want to be able to do something like this:
UPDATE MSSQLDatabase.Table
SET MSSQLDatabase.Table.Column = AccessDatabase.Table.Column
WHERE MSSQLDatabase.Table.Column = AccessDatabase.Table.ID
INSERT INTO AccessDatabase.Table
VALUES (AccessDatabase.Table.ID)
Can you give me any pointers of where to begin? The database I want to connect to is a SQL Server 2008 Provider Native connection. I'm using Access 2007.
To do this in VBA would be perfect.
By far the easiest way to work with SQL Server in MS Access is to use linked tables. However, you can also run pass-through queries and refer to a connection in-line:
SELECT * FROM [ODBC;FILEDSN=Z:\Docs\Test.dsn;].table_1
Or
SELECT * FROM
[ODBC;DRIVER=SQL Server;SERVER=srvr;Trusted_Connection=Yes;DATABASE=Test;].table_1
Or
SELECT * FROM [ODBC;Driver={SQL Server Native Client 11.0};Server=svr;Database=test;Trusted_Connection=yes;].table_1
see also http://www.connectionstrings.com/sql-server-2008
This solution allows to catch errors:
Private Sub Command10_Click()
On Error GoTo Err1:
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
With cn
.Provider = "SQL Native Client"
.ConnectionString = "Server=myserver\myinstance;Database=mydb;Uid=myuser;Pwd=mypass;]"
.Open
End With
MsgBox "Connection successful!"
cn.Close
Exit Sub
Err1:
MsgBox Err.DESCRIPTION
End Sub
The only thing to note, is that within the Visual Basic Editor, you must first go to Tools > References, and check Microsoft ActiveX Data Objects 2.x Library.

Connect to a linked table

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.