Execute VBA using SQL - sql

Ok, this may be a long shot but in MS Access, is it possible to execute VBA using SQL? I'm looking to write a query that runs either a single VBA statement or a Sub. Basically, what I'm trying to do is modify the hidden attribute of a table using SQL.
MS makes enough weird decisions with Office implementations that I'm mildly hopeful this is one of those cases.

You can create a VBA function and use the function's return value as a field expression in a query. However, you must run the query from within an Access application session. Otherwise the db engine will not be able to use your custom function.
SELECT YourFunction() AS result;

It's been a few years (thankfully) since I used Access, but to the best of my knowledge, that's simply not possible. You can use VBA to execute SQL, but not vice versa.

You can use user-defined functions within an SQL query ( http://www.sqlexamples.info/SQL/inlineudf.htm ). I doubt Excel checks what you do inside this function, so you probably can do whatever you like.

Related

Cannot view the SQL portion of a query in ACCESS?

I am currently working on a project of replacing our old access database queries, but on one of them I am not able to view the actual SQL View.
Does anyone know a way to force the view or to export it somehow?
Error causing problem:
The SQL statement could not be executed because it contains ambiguous outer joins.
Note that I can view the Design View without issue but when I right click on the tab and select SQL View is when I get the error.
I did attempt what #LeeMac mentioned below but same error occurs:
EDIT:
This question is not like Ambiguous Outer Joins?
The OP on that question can actually see and edit their SQL.
My issues is that I cannot see or edit the SQL as the SQL View wont open.
Try executing the following VBA code from the Immediate Window (accessible using Ctrl+G) in the VBA IDE (open the IDE using Alt+F11):
?CurrentDb.QueryDefs("YourQuery").SQL
Replace YourQuery with the name of your query.
This should print the SQL code which comprises your query - you can then analyse the SQL to determine the cause of the error.
It's odd this error would arise when merely viewing the SQL content of the query definition.
It makes me think that the query is perhaps referencing a crosstab subquery which is actually the cause of the error, but which needs to be evaluated in order for MS Access to determine the columns available when viewing the design of the query in question.
Try this:
hit ctrl-g, and from immediate window type in this:
saveastext acQuery,"Name of query","c:\test\mysql.txt"
Access ordinarily doesn't allow you to save invalid queries, so it's strange you somehow got into this situation in the first place.
If you can copy the query, you can easily get to the SQL by changing the query to a passthrough query, either through the GUI or through VBA:
Dim q As DAO.QueryDef
Set q = CurrentDb.QueryDefs!Query1
q.Connect = "ODBC;"
Debug.Print q.SQL
Passthrough queries are not validated, so you can freely read and write anything you want as SQL in it.
Note that this is irreversible when done through VBA. You can only change it back to a normal query once you made the SQL valid again. If you do it through the GUI, you can just not save it, though.
I had this problem and the issue was that i had a subquery that calculated fields but did not actually have a table in it. for example it would calculate first and last day of last month which is 2 calculated fields, then it was the first query in a series of queries that were built off it and the last one wouldnt resolve sql as original poster indicated also gave the ambiguous join message as well as query needs input table (which was that first subquery). i put a table with 1 record in it but didnt use the record and it worked.... so it just a needs a table in it.

Running SQL through VBA

I am trying to run the following query:
SELECT Project.* FROM Project WHERE (((Projects.[End Date (PPL)])>=DateAdd('m',-6,Date())));
It runs fine in Access (2007) however when i move it over to VBA:
strQry = "SELECT Project.* FROM Project WHERE (((Projects.[End Date (PPL)])>=DateAdd('m',-6,Date())));"
I get an error message saying 'No value given for one or more required parameters'
I can get it running with the following code but it doesn't provide the correct information:
strQry = "SELECT Project.* FROM Project WHERE Project.[End Date (PPL)] >= DateAdd('m',-6,Date());"
Any help would be great.
The definitive answer to your question is here, in StackOverflow:
VBA function in Excel ADODB query
The short answer is:
You're using a dialect of SQL called Jet-SQL, and most people call it from Microsoft Access, a database application which makes VBA functions available to the SQL engine.
If you run Jet SQL from any other platform - like an ODBC or ADODB wrapper -the VBA functions aren't available: all you have is the Jet-SQL native functions.
There's a list of the native Jet-SQL functions here: it's almost complete, and you can see that it's rather short:
MS Access: Functions - Listed by Category
...And it doesn't include NZ()
It's somewhat confusing that these functions look like the familiar VBA - and annoying that the web page listing them is labelled 'MS-Access' rather than Jet SQL.
There is an interesting item in that list: the inline 'If' function, IIF(), and you can use it as a substitute for NZ:
SELECT
IIF(
table1.[RIC] IS NOT NULL,
table1.[RIC],
table2.[ISIN] + ', CODE:ISIN'
) AS [RetrievalCode],
table3.[Value],
table3.[DateStamp]
FROM
* The rest of your Query *
Hope that helps: I suspect that it won't, because you may be calling a named query (or SQL with a named subquery in it), and all the non-native function calls in those queries are invalid unless the whole thing is called from within MS-Access.
You can, of course, make a 'schema' query and extract the SQL, parse it out, and replace all the VBA with native Jet-SQL functions. But the syntax for Jet-SQL gets arcane when you're outside it's intended environment - the Query-By-Example visual query builder inside Microsoft Access - so that suggestion may be more time and trouble than doing it some other way.

SQL Parameters - where does expansion happens

I'm getting a little confused about using parameters with SQL queries, and seeing some things that I can't immediately explain, so I'm just after some background info at this point.
First, is there a standard format for parameter names in queries, or is this database/middleware dependent ? I've seen both this:-
DELETE * FROM #tablename
and...
DELETE * FROM :tablename
Second - where (typically) does the parameter replacement happen? Are parameters replaced/expanded before the query is sent to the database, or does the database receive params and query separately, and perform the expansion itself?
Just as background, I'm using the DevArt UniDAC toolkit from a C++Builder app to connect via ODBC to an Excel spreadsheet. I know this is almost pessimal in a few ways... (I'm trying to understand why a particular command works only when it doesn't use parameters)
With such data access libraries, like UniDAC or FireDAC, you can use macros. They allow you to use special markers (called macro) in the places of a SQL command, where parameter are disallowed. I dont know UniDAC API, but will provide a sample for FireDAC:
ADQuery1.SQL.Text := 'DELETE * FROM &tablename';
ADQuery1.MacroByName('tablename').AsRaw := 'MyTab';
ADQuery1.ExecSQL;
Second - where (typically) does the parameter replacement happen?
It doesn't. That's the whole point. Data elements in your query stay data items. Code elements stay code elements. The two never intersect, and thus there is never an opportunity for malicious data to be treated as code.
connect via ODBC to an Excel spreadsheet... I'm trying to understand why a particular command works only when it doesn't use parameters
Excel isn't really a database engine, but if it were, you still can't use a parameter for the name a table.
SQL parameters are sent to the database. The database performs the expansion itself. That allows the database to set up a query plan that will work for different values of the parameters.
Microsoft always uses #parname for parameters. Oracle uses :parname. Other databases are different.
No database I know of allows you to specify the table name as a parameter. You have to expand that client side, like:
command.CommandText = string.Format("DELETE FROM {0}", tableName);
P.S. A * is not allowed after a DELETE. After all, you can only delete whole rows, not a set of columns.

What could be SQL Query of a data source that is a spreadsheet, to be returned to a seperate spreadsheet? Including UDFs in the query?

I currently have a data source of a large table, sitting in workbook1. From workbook2, which is currently empty, I wish to set up a DSN connection to workbook1, so that I can query it from workbook 2.
In the SQL query result, I wish to display extra columns which are calculated using User-Defined VBA functions, the arguments of which will be other fields from the data source.
Example:
Workbook1 is Field1, F2, F3 and F4. I wish to query this and display all records, but additionally I wish to have F5=UDF(F3,F4).
I have been advised already that the solution to this is:
SELECT UDF(F3,F4) as F5
FROM \SourceWorkBookLocation\SourceWorkBook
IN ACCESS:
The problem I am having in access is not at the top of my list right now, relates to data types and trying to determine if a number in a string is <25. But the main problem is in MS Query:
IN EXCEL/MS QUERY:
The function is just not recognized; "undefined function"
I am not sure how to get it to see the function? My end goal here is to build a front end in excel, and have vba querying appropriately using user input variables passed to the queries. The querying will be done on a separately updated workbook.
Any ideas on how to get MS Query to see my UDF and accept what I am doing? Could it be a driver issue? There are a range of excel drivers to choose from.
Thanks
Looking at the info you have provided, you have tried to use two Excel workbooks as tables to query using Excel VBA UDF. Now I assume you are going to use these workbooks as your tables but in MS Access.
All most all databases is able to read standard SQL. See the thing is that each database is able to handle functions writting in their own space. In your case please write your UDF in Access VBA. Then try to execute to the same.
This is a common issue sometimes people do face, either tyring to access MS Access UDFs from Excel or vise versa. In a nutshell, when you're running MS Access, queries can call back into VBA. But when you're going through ODBC or ADO, the JET engine doesn't have the whole VBA model to draw on because it's simply not running.
You could try to do something like this:
Dim objExcl As Object
Set objExcl = CreateObject("Excel.Application")
objExcl.OpenCurrentDatabase "ExcelFileName/Path"
objExcl.Run ("UDFName")
objExcl.CloseCurrentDatabase
Set objExcl = Nothing
Frankly I prefer moving the UDF in to Acces..
References:
Create Access UDF
http://www.sqlexamples.info/SQL/inlineudf.htm

In ClearQuest, How do I generate a query in SQL Editor that allows me to prompt the user for a value?

I generate a ClearQuest query using the Query Wizard. In the Query Editor, I am able to select a filter for a given field. However, I want to refine the query using the SQL Editor, but then I loose the ability to have a dynamic filter. How can I resolve this.
Pretty sure the answer is "you can't" since the SQL generated includes the value entered for any dynamic filters set up when you built the query, and as you say, the act of editing the SQL prevents using the Query Editor to make further changes.
Your best bet is to figure out a way to use the Query Editor to do what you need the SQL Editor for. Start another question.