I know it is possible to call query by name as follow:
DoCmd.OpenQuery "yourQueryName", acViewNormal, acEdit
OR
CurrentDb.OpenRecordset("yourQueryName")
But is it possible to call them with numbers like Sheets in Excel?
Something like:
CurrentDb.OpenRecordset Queries(1)
or any other way possible?
Note: I want to do that because my queries are in Japanese and I would like to avoid the hard way to read them in VBA.
You can certainly execute queries using the QueryDefs collection. However, referring to them by position is a dangerous thing to do, since the position may change and you might be opening the wrong query.
To do so, you can use CurrentDb.QueryDefs(1).OpenRecordset
Note that Access also makes temporary/internal queries available to the QueryDefs collection. Their name starts with ~, and there are often many on a large database.
(in my general development database, the first real query is currently QueryDefs(20))
Related
I'm trying to write some VBA code that will export an MS Access query.
I'd like it to be run it all from within Excel to source from a database I don't understand and don't want to tamper with. I just know I have to run a query and export it.
That's easy enough if the query doesn't rely on a user-input value to run (EG beginning/end dates) but if it needs input I can't find a good way to make that be set automatically.
I've seen some clever options here:
https://bytes.com/topic/access/answers/466248-can-i-pass-parameters-macro-query
A) Putting the SQL underlying the query within the VBA, but that can get very unwieldy, especially with big queries that I'm unfamiliar with. And TBH I don't quite understand the coding behind it- but that's just me being lazy...
B) Use a form on which to record the desired value- again unwieldy and also I can't change the query code.
But I'd rather something along the lines of: cmdRun(QueryX,PARAM1,PARAM2). Is that wishful thinking?
I have a large MS Access database, and I want to get rid of all the records that aren't relevant to my city. I could make a series of queries, but that would be tedious. And I don't know an efficient way to get just the data from the queries into another database, or into Excel. I only know tedious ways.
In addition to tedious queries, you can write tedious VBA code.
Loop the recordset and validate each record. If it fails, delete the record and move to the next.
Even though tedious, it is more fun than writing SQL.
For example, say I'm creating a table which stores promo codes for a shipping site. I want to have the table match a promo code with the code's validator, e.g.
PROMO1: Order must have 3 items
PROMO2: Order subtotal must be greater than $50
I would like to store the query and/or routine in a column in the table, and be able to use the content to validate, in the sense of
SELECT * FROM Orders
WHERE Promo.ID = 2 AND Promo.Validation = True
Or something to that effect. Any ideas?
I wouldn't save the query in the database, there are far better possibilities.
You have to decide, which best fits your needs (it's not clear for me based on your question). You can use
Views
or
Prepared Statements
or
Stored Procedures
There's probably a better way to solve the issue, but the answer to your question is to write stored procedures that return the results you want. Where I work (and I hate this design), they actually store all queries and dml used by the application in stored procedures.
You can also dynamically build your queries using dynamic sql. For MySql, see the post below which might be of some help to you.
How To have Dynamic SQL in MySQL Stored Procedure
Otherwise, you can also store your queries in a string format in the database, and retrieve them and execute them using the EXECUTE statement, such as that post points out.
I'd personally keep away from designs like that though. Storing queries in XML isn't a bad alternative, and have your app be written to be extensible and configurable from XML, so you don't need to make code changes to add new validation logic, and instead just have to configure it in XML.
I needed to find minimum revenue from a table tbl_Revenue. I found out two methods to do that:
Method 1
Dim MinRevenueSQL As String
Dim rsMinRev As DAO.Recordset
MinRevenueSQL = "SELECT Min(tbl_Revenue.Revenue_Value)As MinRevenue FROM tbl_Revenue WHERE (((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'));"
Set rsMinRev = CurrentDb.OpenRecordset(MinRevenueSQL)
MinRev = rsMinRev!MinRevenue
Method 2
MinRev2 = DMin("Revenue_Value", "tbl_Revenue", "(((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'))")
I have following questions:
which one of them is computationally more efficient? Is there a lot of difference in computational efficiency if instead of tbl_Revenue table there is a select statment using joins?
Is there a problem with accuracy of DMin fundtion? (By accuracy I mean are there any loopholes that I need to be aware of before using DMin.)
I suspect that the answer may vary depending on your situation.
In a single user situation, #transistor1 testing method will give you a good answer for an isolated lookup.
But on a db that's shared on a network, IF you already Set db = CurrentDb, then the SELECT method should be faster, since it does not require opening a second connection to the db, which is slow.
The same way, it is more efficient to Set db = CurrentDb and reuse that db everywhere.
In situations where I want to make sure I have the best speed, I use Public db as DAO.Database when opening the app. Then in every module where it is required, I use
If db is Nothing Then set db = CurrentDb.
In your specific code, you are running it once so it doesn't make much of a difference. If it's in a loop or a query and you are combining hundreds or thousands of iterations, then you will run into issues.
If performance over thousands of iterations is important to you, I would write something like the following:
Sub runDMin()
x = Timer
For i = 1 To 10000
MinRev2 = DMin("Revenue_Value", "tbl_Revenue", "(((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'))")
Next
Debug.Print "Total runtime seconds:" & Timer - x
End Sub
Then implement the same for the DAO query, replacing the MinRev2 part. Run them both several times and take an average. Try your best to simulate the conditions it will be run under; for example if you will be changing the parameters within each query, do the same, because that will most likely have an effect on the performance of both methods. I have done something similar with DAO and ADO in Access and was surprised to find out that under my conditions, DAO was running faster (this was a few years ago, so perhaps things have changed since then).
There is definitely a difference when it comes to using DMin in a query to get a minimum from a foreign table. From the Access docs:
Tip: Although you can use the DMin function to find the minimum value
from a field in a foreign table, it may be more efficient to create a
query that contains the fields that you need from both tables, and
base your form or report on that query.
However, this is slightly different than your situation, in which you are running both from a VBA method.
I have tended to believe (maybe erroneously because I don't have any evidence) that the domain functions (DMin, DMax, etc.) are slower than using SQL. Perhaps if you run the code above you could let us know how it turns out.
If you write the DMin call correctly, there are no accuracy issues that I am aware of. Have you heard that there were? Essentially, the call should be: DMin("<Field Name>", "<Table Name>", "<Where Clause>")
Good luck!
Hallo all.
I need to run the 'replace([column], [new], [old])' in a query executing on n Access 2003 DB. I know of all the equivalent stuff i could use in SQL, and believe me I would love to, but i don't have this option now. I'm trying to do a query where all the alpha chars are stripped out of a column ie. '(111) 111-1111' simply becomes '1111111111'. I can also write an awsum custom VBA function and execute the query using this, but once again, can't use these functions through JET. Any ideas?
Thanx for the replies guys. Ok let me clarify the situation. I'm running an .NET web application. This app uses an Access 2003 db. Im trying to do an upgrade where I incorporate a type of search page. This page executes a query like: SELECT * FROM [table] WHERE replace([telnumber], '-', '') LIKE '1234567890'. The problem is that there are many records in the [telnumber] column that has alpha chars in, for instance '(123) 123-1234'. This i need to filter out before i do the comparison. So the query using a built in VBA function executes fine when i run the query in a testing environment IN ACCESS, but when i run the query from my web app, it throws an exception stating something like "Replace function not found". Any ideas?
Based on the sample query from your comment, I wonder if it could be "good enough" to rewrite your match pattern using wildcards to account for the possible non-digit characters?
SELECT * FROM [table] WHERE telnumber LIKE '*123*456*7890'
Your question is a little unclear, but Access does allow you to use VBA functions in Queries. It is perfectly legal in Access to do this:
SELECT replace(mycolumn,'x','y') FROM myTable
It may not perform as well as a query without such functions embedded, but it will work.
Also, if it is a one off query and you don't have concerns about locking a bunch of rows from other users who are working in the system, you can also get away with just opening the table and doing a find and replace with Control-H.
As JohnFx already said, using VBA functions (no matter if built in or written by yourself) should work.
If you can't get it to work with the VBA function in the query (for whatever reason), maybe doing it all per code would be an option?
If it's a one-time action and/or not performance critical, you could just load the whole table in a Recordset, loop through it and do your replacing separately for each row.
EDIT:
Okay, it's a completely different thing when you query an Access database from a .net application.
In this case it's not possible to use any built-in or self-written VBA functions, because .net doesn't know them. No way.
So, what other options do we have?
If I understood you correctly, this is not a one-time action...you need to do this replacing stuff every time someone uses your search page, correct?
In this case I would do something completely different.
Even if doing the replace in the query would work, performance wise it's not the best option because it will likely slow down your database.
If you don't write that often to your database, but do a lot of reads (which seems to be the case according to your description), I would do the following:
Add a column "TelNumberSearch" to your table
Every time when you save a record, you save the phone number in the "TelNumber" column, and you do the replacing on the phone number and save the stripped number in the "TelNumberSearch" column
--> When you do a search, you already have the TelNumberSearch column with all the stripped numbers...no need to strip them again for every single search. And you still have the column with the original number (with alpha chars) for displaying purposes.
Of course you need to fill the new column once, but this is a one-time action, so looping through the records and doing a separate replace for each one would be okay in this case.