Access 2007 VBA DoCmd.SetParameter replacement? - vba

I've inherited an Access Database that has a lot of tables, forms, and queries in it. However, I'm a PHP programmer and VBA is pretty foreign to me. I was asked to make some changes, which over the course of a few days I was able to get working (with a lot of help from old random SO posts).
After passing the database back to the users, the code that works on my computer is not working on theirs. It seems I have Access 2010 and they have 2007. As best I can tell, the function DoCmd.SetParameter doesn't exist in VBA in Access 2007.
Here's a snippet of the code :
DoCmd.SetParameter "ReportYear", Year.Value
DoCmd.SetParameter "ReportMonth", Month.Value
DoCmd.OpenQuery "doFillData"
doFillData is a query inside of Access that inserts in to another table automatically, requiring 2 parameters (year and month) before running.
The obvious answer is, make them upgrade to 2010, but I don't have that power. I assume I'll be able to create conditional code to do something different in 2007, but I can't find a similar function to use. Anyone have any ideas?

Instead of using DoCmd.OpenQuery, you want to manipulate the querydef object's named parameters and then execute it. You can use Execute options like acFailOnError when executing this way (not available with OpenQuery) and you can detect the number of records affected.
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.QueryDefs("doFillData")
qdf.Parameter("ReportYear") = Year.Value
qdf.Parameter("ReportMonth") = Month.Value
qdf.Execute
MsgBox qdf.RecordsAffected & " records were affected."

Related

MS Access keeps on breaking my queries

I wrote a query in MS Access which I was able to run successfully. However whenever I head back to Design View in MS Access 2010, it kindly corrects it for me into SQL that doesn't even work!
Here is my original SQL (which I ran successfully):
SELECT [AssetTypeCounts].DELIVERED_IDENTIFIER,
[AssetTypeCounts].DELIVERED_SOURCE,
Switch([AssetTypeCounts].TYPES<1,"Missing",
[AssetTypeCounts].TYPES=1,"Correct",[AssetTypeCounts].TYPES>1,"Conflicting") AS STATUS
FROM (
SELECT DELIVERED_IDENTIFIER, DELIVERED_SOURCE, Sum(IIf(Len(PRODUCTTYPE)>0,1,0)) AS TYPES
FROM (
SELECT DISTINCT DELIVERED_IDENTIFIER, PRODUCTTYPE, BILLINGCODE, DELIVERED_SOURCE
FROM AprilUsageFile) AS "DisctinctAssetIdBySource"
GROUP BY DELIVERED_IDENTIFIER, DELIVERED_SOURCE
) AS AssetTypeCounts;
After I go back to Design View I get an error:
The field is too small to accept the amount of data you attempted to add. Try inserting or pasting less data.
I didn't even get a chance to edit the query.
Why does Access keep changing my query?
Can I disable features where MS Access is changing my queries?
try to create a new query by printing in immediate window:
Dim qDef As DAO.QueryDef
Set qDef = CurrentDb.QueryDefs("NameOfBrokenQuery")
Debug.Print qDef.SQL
As a general rule never open SQL queries in designer mode, because access will always change parts of it and then it will be harder for your to change it.

What is the difference between these statements, and which do most prefer?

I have noticed that a lot of code I have found on the internet will have variables defined and set that I would simply avoid...such as:
Dim db as Database
Dim rs as Recordset
Set db = CurrentDB
Set rs = db.OpenRecordset
I would write this as:
Dim rs as Recordset
Set rs = CurrentDB.OpenRecordset
I save 2 lines of code at the top plus one to Set db = Nothing at the end. Which, over hundreds of subs and functions can really add up...
But is one more preferred over another by most coders? Is there an actual reason to use one or the other? Is there an advantage to actually defining and spelling out the whole thing?? Is there any real savings in doing it my way, other than staving off carpel tunnel for a few more minutes?
In terms of execution, there is no real difference between the two VBA methods. However, the first is a more generic version as the db object can be set to either the local DAO database or an external DAO database using the Workspace.OpenDatabase method. The second is a more shortcut version as usually needed recordsets, querydefs, etc. derive from the working, local database. Below are examples of referencing external databases.
Short cut version:
Set db = OpenDatabase ("C:\Path\ToExternalDB\someotherdb.accdb")
Full generic version:
Set db = DBEngine.Workspaces(0).OpenDatabase("C:\Path\ToExternalDB\someotherdb.accdb")
Therefore, should a developer change database environments (i.e., transition from local to external database source) and even workspaces, they can easily change the set db = ... line instead of adding this line to the code if developer had originally used only the CurrentDb namespace.
This is a good example of the trade-off decision between efficiency (less scripted lines) and scalability (translatable lines).
"The CurrentDb method creates another instance of the current database... The CurrentDb method enables you to create more than one variable of type Database that refers to the current database" from https://msdn.microsoft.com/en-us/library/office/aa221178%28v=office.11%29.aspx?f=255&MSPPError=-2147217396.
So if you use CurrentDB just once in your code than its fine not to declare it, however using it multiple times it won't be the same instance but always created a new one which may create strange bugs for you.

Edit Current Object's SQL in MS Access through VBA

I am using MS Access 2013 trying to edit the SQL of the current query that is being displayed on the screen. I can get the name of the current query using qName = Application.CurrentObjectName however the current query is not saved, nor do I want it to be saved.
I know that using something like below, I can get the SQL of a saved query and modify that query.
Dim qd As QueryDef
Set qd = CurrentDb.QueryDefs(qName)
qd.SQL = "Select Customers.ID From Customers"
However, the query that I want to modify is not saved, but rather just being worked on. What I want to do is access the SQL which is visible in SQL view, read that into a variable, and modify it. I am not sure how to proceed and would appreciate some help. (What I have tried is summarized above.)
(In case you are curious. The queries I am working on may be new or may be being modified from saved queries; saving could overwrite something which I am not yet finished with/is not working, thus causing more issues.)
If your unsaved new query is open in Datasheet View, you can retrieve its SQL like this:
MsgBox Application.Screen.ActiveDatasheet.RecordSource
However if you want to modify that SQL within its current query window, I can't help you.

query criteria based on form field

So I have a query where I select a field and set the criteria so that it only selects records based on the current value of a particular field in my form. The criteria looks like this.
[Forms]![FORMAL_CERT_REVIEW_CHECK_FORM]![REVIEW_CHECK_ID]
Pretty simple stuff. But I am running into the issue where when I run the query I get the prompt that says I need to enter a value. I know that this usually happens when you set the criteria to something that may not exist or you spelt it incorrectly, but I have checked all of this and it seems like everything looks fine.
I was curious if there is something I could be missing, like a property on the field or something that I have not thought of.
When you directly open a query which includes a reference to a form control, Access is able to retrieve the query's parameter value from that control on the open form.
However, if you attempt to use the same query as the source for a recordset, Access does not resolve the query parameter from the open form.
For example, this is my query, qryREVIEW_CHECK_ID.
SELECT f.id, f.datetime_field, f.some_text
FROM tblFoo AS f
WHERE f.id=[Forms]![FORMAL_CERT_REVIEW_CHECK_FORM]![REVIEW_CHECK_ID];
With FORMAL_CERT_REVIEW_CHECK_FORM open, everything works fine when I open the form directly ... like this for example ...
DoCmd.OpenQuery "qryREVIEW_CHECK_ID"
However, using that query as the source for a recordset triggers error 3061, "Too few parameters. Expected 1."
Dim db As DAO.database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("qryREVIEW_CHECK_ID")
The workaround is to open the recordset from the QueryDef object. And include Eval() so that Access will resolve the parameter using the parameter's name.
Dim qdf As DAO.QueryDef
Set qdf = db.QueryDefs("qryREVIEW_CHECK_ID")
qdf.Parameters(0) = Eval(qdf.Parameters(0).Name)
Set rs = qdf.OpenRecordset
Your description doesn't specify whether your form is a simple form or a sub-form. I came across the same issue and realized that I was only entering the sub-form's name in the criteria.
Assuming that you have FORMAL_CERT_REVIEW_CHECK_FORM sub-form under PARENT_FORM, your criteria should read
[Forms]![PARENT_FORM]![FORMAL_CERT_REVIEW_CHECK_FORM]![REVIEW_CHECK_ID]
I hope this helps you or others. Used in Access 2016.
I have experienced this on several occasions after making a design change to the form. There is no fault with what you have done - it is an access corruption. The solution is to copy the database to another file name, delete your forma and query, compact and repair, and then import the form and query again. This normally solves the problem. It appears importing it resets the internal references allowing the form to work as it should.
Doesn't seem like this was ever solved, and I just came up with the same issue. I solved it by deleting the form and recreating it. Like you I had, [Forms]![MyForm]![ID] and out of no where it started asking for user input for the criteria on my listbox query. Making a new form and copying over the fields seems to have fixed it.

Viewing SQL in an access database?

I have an access database which has some sql queries loaded into it. I have no experience with microsoft access and need to know how I can see the sql queries it contains. My guess is they are somewhere in r_[sql name]?
What I mean specifically is to see the query itself, for example there is a form which generates an output based on various tables, my guess is there is an SQL query (like Select * from table;) doing this and I'd like to know how I can see it
You should also note that objects in Access that return recordsets (forms, reports, combo boxes, listboxes) can also have SQL properties. These cannot be seen except by examining the objects themselves (recordsource for forms/reports, rowsource for combo boxes/listboxes). So, just looking at the SQL of the stored QueryDefs is not going to show you all the SQL statements used in the app.
Additionally, if there's VBA code, there could also be SQL embedded in the code.
For each individual query, you can go to the 'View SQL', either using the button or choosing the menu option. (I only have a German access, but it should be something like View - View SQL or so).
It you are refering to view the query names and defs from VBA, the you can try
Private Sub Command0_Click()
Dim qd As queryDef
Dim queryName As String
Dim queryText As String
For Each qd In CurrentDb.QueryDefs
queryName = qd.Name
queryText = qd.SQL
Next qd
End Sub