I have an MS Access front-end with an Oracle SQL back-end database.
I'm trying to create a pass-through query that contains a function within Access. The function is for setting the jobnumber based on what the user types into the login screen.
SELECT
CC_QAQC_SPEC_MASTER.JOBNUMBER,
CC_QAQC_SPEC_MASTER.SPECSECTION,
CC_QAQC_SPEC_MASTER.SPECDESCRIPTION,
CC_QAQC_SPEC_MASTER.ID
FROM
CC_QAQC_SPEC_MASTER
WHERE
CC_QAQC_SPEC_MASTER.JOBNUMBER=GET_QAQC_JOB()
ORDER BY
CC_QAQC_SPEC_MASTER.SPECSECTION,
CC_QAQC_SPEC_MASTER.SPECDESCRIPTION;
When I run the above I receive an error message that says:
ODBC--call failed [Oracle][ODBC][Ora]ORA-00942:table or view does not
exist(#942)
Well, since the sql is sent "raw" to Oracle, then of course the server side database has no idea what to do with a VBA function.
So, one possible solution would be to re-create the VBA function as a scaler oracle function.
However, because that given function has no paramters, then we can assume that the function returns a given value - darn near close to a static, or a value that you wish/want to pass to oracle.
The approach then means we have to resolve the function client side BEFORE we attempt to use or execute that PT query.
So, I recommend that you take the above PT query, and copy it. (access side). You now have two PT queries.
Now, in code, we grab the sql, modify it, shove it into the 2nd query, and now you are free to launch + use that pass-though query (for a report, recordsets, forms or whatever)
So, your code will look like this:
Sub MyOraclePT()
Dim strSQL As String
strSQL = CurrentDb.QueryDefs("PT1").SQL ' <-- this change
strSQL = Replace(strSQL, "GET_QAQC_JOB()", GET_QAQC_JOB())
CurrentDb.QueryDefs("PT2").SQL = strSQL
' now you can open or use this query.
'
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("PT2")
' or open a report/form based on that PT2 query
' such as
DoCmd.OpenReport "MyReport", acViewPreview
End Sub
So, we used two PT query, because the first one is the sql you have as a above. We then modify the 2nd PT query to replace the function value with the actual value of the function.
The above assumes the function is a number (not a string). If the column CC_QAQC_SPEC_MASTER.JOBNUMBER was a string, then you would could/would place single quotes around the function name in the first PT query.
I also note a bug/syntax error, as you have:
WHERE
CC_QAQC_SPEC_MASTER.JOBNUMBER)=GET_QAQC_JOB()
In above, I see a stray ")" in above - you want to fix that.
Assuming the function is a function written in VBA in Access, you can't call it from the query. I believe the DML in the query is sent in its entirety to the source system, Oracle in this case. Oracle has no idea what the function is and errors.
Option-1: Submit the Query via ADO.NET in VBA
Abandon the pass-thru query objects in Access. Execute the query from VBA connecting to Oracle via ADO or something like it. There are lots of resources on how to use ADO to pull data from external data sources such as How To Open ADO Connection and Recordset Objects. Here is an example using DAO.
Option-2: Wrap the Pass-thru Query in Another Query
Access lets you create queries that call other queries. Create the pass-thru query without the WHERE predicate. This is the pass-thru query. Create another access query that calls the pass-thru query. This is the wrapping query. The wrapping query (since its native Access SQL) should have the parameter you use to filter the result set.
Complete disclosure. I didn't try this with Oracle.
Now, if the pass-thru query is grabbing a lot of data. This option won't perform well.
Option-3: Dynamically Create the Pass-Thru Query
You have an event (button click or whatever) call a VBA sub-procedure, which dynamically creates and assigns the SQL for the query:
Public Sub foo()
Let qaqc_job_number = GET_QAQC_JOB()
Set Query = CurrentDb.QueryDefs("<your-pass-thru-function-name>")
Let sql_job_data = "SELECT" & _
"CC_QAQC_SPEC_MASTER.JOBNUMBER, " & _
"CC_QAQC_SPEC_MASTER.SPECSECTION, " & _
"CC_QAQC_SPEC_MASTER.SPECDESCRIPTION, " & _
"CC_QAQC_SPEC_MASTER.ID " & _
"FROM " & _
"CC_QAQC_SPEC_MASTER " & _
"WHERE " & _
"CC_QAQC_SPEC_MASTER.JOBNUMBER)= " & qaqc_job_number & " " & _
"Order BY " & _
"CC_QAQC_SPEC_MASTER.SPECSECTION, " & _
"CC_QAQC_SPEC_MASTER.SPECDESCRIPTION; "
Let Query.Sql = sql_job_data
End Sub
Then you run the query.
Everything in the SQL you stick in this Access query object has to exist in Oracle and ONLY in Oracle.
Related
I'm attempting to have a user search through a table in Microsoft Access 2010, but the SQL command isn't working. The command that loads and refreshes the table is this:
SELECT Equipment.equipmentID, Equipment.equipmentName, Equipment.model,
Equipment.make, Equipment.equipmentLocation FROM Equipment ORDER BY Equipment.equipmentName;
This works, but when I try to use a variable (or any normal criteria):
searchItem = Me.searchBox.Value
Me.List64.RowSource = "SELECT Equipment.equipmentID, Equipment.equipmentName,
Equipment.model, Equipment.make, Equipment.equipmentLocation FROM Equipment
WHERE Equipment.equipmentName LIKE '%searchItem%' ORDER BY Equipment.equipmentName;"
I've also tried something like "%10%" instead of the searchItem variable, but the command has the table come up blank with no errors. I suspect the problem is with the Equipment.eqiupmentName as the column name, but I can't quite figure out what's wrong here.
Here's a quick look at what the table looks like:
Try this:
Me.List64.RowSource = & _
"SELECT Equipment.equipmentID, Equipment.equipmentName," & _
" Equipment.model, Equipment.make, Equipment.equipmentLocation FROM Equipment" & _
" WHERE Equipment.equipmentName LIKE '*" & searchItem & "*'" & _
" ORDER BY Equipment.equipmentName;"
User rjt011000 has a valid solution, but I recommend using & for string concatenation in VBA (and Access). For an explanation of + and & see this thread.
Access will not recognize or substitute VBA variables inside an SQL statement. Furthermore, the LIKE operator is fed an SQL string value in this case (inside single quotes... which are inside the double quotes), so even if a VBA variable could be referenced directly inside SQL, Access does not interpret any such thing inside a string value.
Regarding the Access SQL LIKE operator, the multi-character matching pattern is * rather than %. Access also recognizes the operator ALIKE which does indeed honor the ANSI pattern %. See LIKE operator docs and this thread regarding ALIKE.
To be more thorough, the string delimiters and LIKE pattern-matching character should be escaped if you don't want the user inadvertently injecting invalid characters that cause errors in the SQL. Following is an example of escaping a couple of them. There are more elegant ways to handle this for all special characters, but the code and technique are beyond the scope of this answer.
...'" & Replace(Replace(searchItem, "*", "[*]"), "'", "''") & "'...
For the record, although Access SQL will not substitute a VBA variable, it will recognize and call a public VBA function. Normally such a public function must be defined in a normal module, but in context of a form's Record Source query, a form-module method can sometimes be called.
One last technique... It is possible to reference a form control's value directly in SQL. This can be very convenient and reduce extra code, but there are a couple caveats:
The form must of course be open, otherwise Access will interpret the reference as an unknown parameter and display a prompt. This will of course not be a problem if the SQL is always in context of the same form.
Access will sometimes automatically refresh the query when such a referenced control is changed, but it is not always guaranteed. The "timing" of automatic refreshes might not be immediately intuitive. You can call the Refresh method on the control or subform from various form events to force the query to refresh after the value is changed.
Notice that in the following example, the string concatenation is inside the VBA string, so that the concatenation actually happens in context of SQL and not beforehand like in the first code snippet. There is no problem with this, just something to consider since this entire answer revolves around proper string interpretation and concatenation.
But really, the same concern exists for un-escaped pattern-matching characters in the user text. Rather than making the SQL text long and ugly with calls to Replace(), instead create a custom function (e.g. EscapePattern()) that does this for any text and then wrap the control reference with that function. The example does this, although I don't include the code for the special function. Such a function could also be used in the first VBA code snippet to simplify building the SQL text.
Me.List64.RowSource = & _
"SELECT Equipment.equipmentID, Equipment.equipmentName," & _
" Equipment.model, Equipment.make, Equipment.equipmentLocation FROM Equipment" & _
" WHERE Equipment.equipmentName LIKE ('*' & EscapePattern(Forms![Form Name]![Control Name]) & '*')" & _
" ORDER BY Equipment.equipmentName;"
There is always more! Did you see the VBA line continuation in my example? It makes the SQL text much easier to view within VBA editor.
I suspect you are not setting your searchItem variable correctly in the SQL string. I am not too familiar with access string concatenation but try separate the searchItem out of the SQL string and then checking if your RowSource has the value you suspect.
Me.List64.RowSource = "SELECT Equipment.equipmentID, Equipment.equipmentName,
Equipment.model, Equipment.make, Equipment.equipmentLocation FROM Equipment
WHERE Equipment.equipmentName LIKE '%" + searchItem + "%' ORDER BY Equipment.equipmentName;"
I'm using Access 2010. Right now I have a function called SetQuerySource:
Private Sub SetQuerySource()
Dim sql As String
sql = DLookup("QueryText", "tblQuery", "QueryName ='qselDailyMilkYield'")
CurrentDb.QueryDefs("qselDailyMilkYield").sql = sql
sql = sql & vbCrLf & "where pt.DLVDate between '" & Me.txtDate
& "' AND '" & Me.txtEndDate & "' and pb.ITEMID like '%pm%' and pjb.ITEMID
like '%pm%' group by pt.ITEMID, pb.ITEMID, pt.NAME, pt.DLVDATE"
CurrentDb.QueryDefs("qselDailyMilkYield").sql = sql
End Sub
I use this to run a query located in a table named tblQuery in my Access database. I then append the Where clause to the query using VBA in case (as shown above) I need to point to a named control which holds a value based on user input.
I came into this setup. By that I mean I didn't create this function I just began using it. My question is how do I point to a different database on a different server? The query I need to run has tables (connected via ODBC) already linked to this Access database but my search of OpenDatabase proved futile as I didn't understand how to use it in my environment.
I receive this error:
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name 'dbo.MilkReceived'. (#208)
Private Sub cmdTruckDeliveries_Click()
SetQuerySource
DoCmd.OpenReport "rptTruckDeliveries", acViewPreview
End Sub
This is my code for the button click event jic.
Thank you,
To make a longer story shorter:
I'm an Access noob, doing a quick-and-dirty conversion of a massive Excel spreadsheet into an Access database. Part of the requirements are to mimic some of the functionality of Excel, specifically, pulling data from a certain table and doing some basic calculations on it (sums, averages, etc.).
I've written a chain of queries to pull the data, count/sum it, etc., and have been testing them by using a manually-entered Parameter (i.e., the kind where the input box pops up and asks you to type a response). Now that I'm ready to drop these queries into a (sub)form, though, I have no idea how to automatically pass that parameter from a box in the form into the subform into the query.
Every query I've written uses a manually-entered Parameter named "MATCHNAME," which holds the name of an individual. In manual testing, if I enter this parameter on one query, all the queries it calls also get that value. So, I think I just need to figure out how to tell the top query what MATCHNAME actually is, and that'll take care of it.
Problem is, I don't know how to do that in Access. If it was any other programming language, I'd do something like "queryXYZ(MATCHNAME);", but I don't think I can do that in Access. Plus, since the values queryXYZ returns are all calculated, I'm not sure how to add an extra MATCHNAME field, nor how to actually make sure that gets read by the queries, nor how to make sure it gets passed down the chain. I've even tried creating a Parameter in design view, then trying to set up Link Master Fields, but the Parameter doesn't appear in that window.
I'd also like to re-run these queries whenever a new record is pulled up, but I'm not sure how to do that either--i.e., the numbers should be current for whatever record I'm looking at.
And, before we go there--I feel like a Relationship is out of the question, as the data itself is auto-generated, and is in rough enough shape to where I can't guarantee that any given key is wholly unique, and large enough (20k+) that, outside of writing a magical script, I can't assign a numerical key. However, I don't know much about Relationships in Access, so please prove me wrong.
(Is this all making sense?)
Do you have any suggestions for me--for how to make a subform read a field on the main form to run its queries on? Alternately, is there an easier way to do this, i.e., to bed SQL calls inside a form?
Thanks very much for your help...
You can use SQL as the recordsource of the subform in the property tab and use the afterupdate event of your matchname field to change yourform.recordsource = "Select * from table where filteredfieldname = & me.matchname & ";" . You can also use sql as the control source of form fields. To pass criteria to filter the subform using the whole table as the recordsource, add an event procedure to your field's after update event like this
`In the declarataions at the top
Global mtchnmfltr as string
Private Sub MATCHNAME_AfterUpdate()
'use the same procedure for Private Sub yourmainform_Current()
mtchnmfltr = "[yourfilterfield] = " & Chr(34) & me.matchname & Chr(34)
'if matchname is not text then just = "[yourfilterfield] = " & me.matchname
with me.subformname.form
.filter = mtchnmfltr
.filteron = true
end with
'Build your sql as a string for your sum avg fields etc. using mtchnmfltr in the where clause
me.yoursumfield.controlsource = "Select...where " & mtchnmfltr & ";"
'etc.
end sub
Or you could throw Matchname into a sql recordsource of the subform and add the function fields to the subform on the same on current and after update events
if me.newrecord = true then
me.dirty = false
end if
me.subform.form.recordsource = "Select Table.Matchname, sum(yourfield) as sumalias, _
(etc.) from yourtable where table.matchname = " & chr(34) & me.matchname & _
chr(34) & Group By table.matchname"
If you are storing your sums etc in a table you need to do it a bit different, since your controls controlsource are bound to fields.
dim strsqlsumfld as string
dim rs as dao.recordset
strsqlsumfld= "Select SUM.....AS sumfldalias where " & mtchnmfltr & ";"
set rs = currentdb.openrecordset(strsqlsumfld)
me.yoursumfield = rs("sumfldalias")
rs.close
I use a DAO Data component to data bind control elements on a form. The query I create dynamically in a recordset which I bind to the Data component. This works pretty well. However, when I run Data.Refresh and the SQL Where statement contains references to the same table via different aliasses then an error shown.
Note: the sql queries below run fine in the MS Access query designer
Global gDB As DataBase
Set Data1.Recordset = GetData(select, from, where, order)
Data1.Refresh
Public Function GetData(select As String, from As String, where As String, order As String) As Recordset
Dim sql As String
sql = "SELECT " & select & " FROM " & from & " WHERE " & where & " ORDER BY " & order
Set GetData = gDB.OpenRecordset(sql, dbOpenDynaset)
End Function
The following will work:
SELECT
WIZ_APPL.*,
TRANS_PRI.Text AS LocalizedText
FROM
TRANSLATIONS AS TRANS_PRI,
WIZ
WHERE
TRANS_PRI.Tag="prog" & WIZ_APPL.Id AND
TRANS_PRI.LanguageId=1 AND
WIZ_APPL.Enabled <> 0
ORDER BY
WIZ_APPL.Id;
Until I try this:
SELECT
WIZ_APPL.*,
TRANS_PRI.Text AS LocalizedText,
TRANS_ALT.Text As AlternativeText
FROM
TRANSLATIONS AS TRANS_PRI,
TRANSLATIONS AS TRANS_ALT,
WIZ_APPL
WHERE
TRANS_PRI.tag="prog" & WIZ_APPL.Id AND
TRANS_ALT.tag="prog" & WIZ_APPL.Id AND
TRANS_PRI.LanguageId=1 AND
TRANS_ALT.LanguageId=2 AND
WIZ_APPL.Enabled <> 0
ORDER BY
WIZ_APPL.Id;
I get a Run-time error '3061':
Too few parameters. Expected 1.
With a slightly different query, which includes an INNER JOIN on another table I get a Run-time error '3075':
Syntax error (missing operator) in query expression 'TRANS_PRI.tag = "prog'.
SELECT
WIZ_APPL.*,
TRANS_PRI.Text AS LocalizedText,
TRANS_ALT.Text As AlternativeText
FROM
TRANSLATIONS AS TRANS_PRI,
TRANSLATIONS AS TRANS_ALT,
WIZ_APPL
INNER JOIN
WIZ_COUNTRY_APPL ON WIZ_APPL.Id = WIZ_COUNTRY_APPL.APPL
WHERE
TRANS_PRI.tag="prog" & WIZ_APPL.Id AND
TRANS_ALT.tag="prog" & WIZ_APPL.Id AND
TRANS_PRI.LanguageId=1 AND
TRANS_ALT.LanguageId=2 AND
WIZ_COUNTRY_APPL.Country=1
ORDER BY
WIZ_APPL.Id;
The bizar thing is that the created recordset is fine and I can print the data. Also, the controls on the form are binding and showing data. However, as soon as I call Data1.Refresh I get the run-time error. Also, refresh() probably destroys the recordset (which is probably normal behaviour).
Set Data1.Recordset = GetData(select, from, where, order)
Do While Not Data1.Recordset.EOF
Debug.Print Data1.Recordset!LocalizedText
Debug.Print Data1.Recordset!AlternativeText
Data1.Recordset.MoveNext
Loop
Data1.Refresh
UPDATE: If I assign the SQL query as String to Data1.RecordSource then the refresh works fine. However, when I assign the SQL query to a recordset then recordset.Name contains only a part of the SQL query. After a Refresh() call Data1.RecordSource is the same as Data1.RecordSet.Name. If the Data component tries to build a query from the shortened Recordset name then it obviously would not work.
Is this a known VB6 DAO Recordset issue?
I am not entirely sure about this but I think this is a DAO recordset and Data component bug.
It looks like the recordset uses the SQL query to create its name property however, it cuts the query short. The data component seems to use this cut query to refresh its internal recordset.
Bug 1: the recordset name property cuts the query short
Bug 2: the data component probably uses the recordset name property to retrieve the SQL query from the recordset or, it uses another property/function which also cuts the query short
Workaround or perhaps the correct method of usage; don't assign the SQL query to the internal recordset, rather use the Data component recordsource property
I have a function I've written that was initially supposed to take a string field and populate an excel spreadsheet with the values. Those values continually came up null. I started tracking it back to the recordset and found that despite the query being valid and running properly through the Access query analyzer the recordset was empty or had missing fields.
To test the problem, I created a sub in which I created a query, opened a recordset, and then paged through the values (outputting them to a messagebox). The most perplexing part of the problem seems to revolve around the "WHERE" clause of the query. If I don't put a "WHERE" clause on the query, the recordset always has data and the values for "DESCRIPTION" are normal.
If I put anything in for the WHERE clause the recordset comes back either totally empty (rs.EOF = true) or the Description field is totally blank where the other fields have values. I want to stress again that if I debug.print the query, I can copy/paste it into the query analyzer and get a valid and returned values that I expect.
I'd sure appreciate some help with this. Thank you!
Private Sub NewTest()
' Dimension Variables
'----------------------------------------------------------
Dim rsNewTest As ADODB.Recordset
Dim sqlNewTest As String
Dim Counter As Integer
' Set variables
'----------------------------------------------------------
Set rsNewTest = New ADODB.Recordset
sqlNewTest = "SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, " & _
"dbo_part.partdescription as Description, dbo_partmtl.qtyper as [Qty Per] " & _
"FROM dbo_partmtl " & _
"LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum " & _
"WHERE dbo_partmtl.mtlpartnum=" & Chr(34) & "3C16470" & Chr(34)
' Open recordset
rsNewTest.Open sqlNewTest, CurrentProject.Connection, adOpenDynamic, adLockOptimistic
Do Until rsNewTest.EOF
For Counter = 0 To rsNewTest.Fields.Count - 1
MsgBox rsNewTest.Fields(Counter).Name
Next
MsgBox rsNewTest.Fields("Description")
rsNewTest.MoveNext
Loop
' close the recordset
rsNewTest.Close
Set rsNewTest = Nothing
End Sub
EDIT: Someone requested that I post the DEBUG.PRINT of the query. Here it is:
SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, dbo_part.partdescription as [Description], dbo_partmtl.qtyper as [Qty Per] FROM dbo_partmtl LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum WHERE dbo_partmtl.mtlpartnum='3C16470'
I have tried double and single quotes using ASCII characters and implicitly.
For example:
"WHERE dbo_partmtl.mtlpartnum='3C16470'"
I even tried your suggestion with chr(39):
"WHERE dbo_partmtl.mtlpartnum=" & Chr(39) & "3C16470" & Chr(39)
Both return a null value for description. However, if I debug.print the query and paste it into the Access query analyzer, it displays just fine. Again (as a side note), if I do a LIKE statement in the WHERE clause, it will give me a completely empty recordset. Something is really wonky here.
Here is an interesting tidbit. The tables are linked to a SQL Server. If I copy the tables (data and structure) locally, the ADO code above worked flawlessly. If I use DAO it works fine. I've tried this code on Windows XP, Access 2003, and various versions of ADO (2.5, 2.6, 2.8). ADO will not work if the tables are linked.
There is some flaw in ADO that causes the issue.
Absolutely I do. Remember, the DEBUG.PRINT query you see runs perfectly in the query analyzer. It returns the following:
Job/Sub Rev Description Qty Per
36511C01 A MAIN ELECTRICAL ENCLOSURE 1
36515C0V A VISION SYSTEM 1
36529C01 A MAIN ELECTRICAL ENCLOSURE 1
However, the same query returns empty values for Description (everything else is the same) when run through the recordset (messagebox errors because of "Null" value).
I tried renaming the "description" field to "testdep", but it's still empty. The only way to make it display data is to remove the WHERE section of the query. I'm starting to believe this is a problem with ADO. Maybe I'll rewriting it with DAO and seeing what results i get.
EDIT: I also tried compacting and repairing a couple of times. No dice.
When using ADO LIKE searches must use % instead of *. I know * works in Access but for some stupid reason ADO won't work unless you use % instead.
I had the same problem and ran accoss this forum while trying to fix it. Replacing *'s with %'s worked for me.
Description is a reserved word - put some [] brackets around it in the SELECT statement
EDIT
Try naming the column something besides Description
Also are you sure you are using the same values in the where clause - because it is a left join so the Description field will be blank if there is no corresponding record in dbo_part
EDIT AGAIN
If you are getting funny results - try a Compact/Repair Database - It might be corrupted
Well, what I feared is the case. It works FINE with DAO but not ADO.
Here is the working code:
Private Sub AltTest()
' Dimension Variables
'----------------------------------------------------------
Dim rsNewTest As DAO.Recordset
Dim dbl As DAO.Database
Dim sqlNewTest As String
Dim Counter As Integer
' Set variables
'----------------------------------------------------------
sqlNewTest = "SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, " & _
"dbo_part.partdescription as [TestDep], dbo_partmtl.qtyper as [Qty Per] " & _
"FROM dbo_partmtl " & _
"LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum " & _
"WHERE dbo_partmtl.mtlpartnum=" & Chr(39) & "3C16470" & Chr(39)
Debug.Print "sqlNewTest: " & sqlNewTest
Set dbl = CurrentDb()
Set rsNewTest = dbl.OpenRecordset(sqlNewTest, dbOpenDynaset)
' rsnewtest.OpenRecordset
Do Until rsNewTest.EOF
For Counter = 0 To rsNewTest.Fields.Count - 1
MsgBox rsNewTest.Fields(Counter).Name
Next
MsgBox rsNewTest.Fields("TestDep")
rsNewTest.MoveNext
Loop
' close the recordset
dbl.Close
Set rsNewTest = Nothing
End Sub
I don't use DAO anywhere in this database and would prefer not to start. Where do we go from here?
I know some time has passed since this thread started, but just in case you're wondering, I have found out some curious about Access 2003 and the bug may have carried over to 2007 (as I can see it has).
I've had a similar problem with a WHERE clause because I needed records from a date field that also contained time, so the entire field contents would look like #6/14/2011 11:50:25 AM# (#'s added for formatting purposes).
Same issue as above, query works fine with the "WHERE ((tblTransactions.TransactionDate) Like '" & QueryDate & "*');" in the query design view, but it won't work in the VBA code using ADO.
So I resorted to using "WHERE ((tblTransactions.TransactionDate) Like '" & QueryDate & " %%:%%:%% %M');" in the VBA code, with ADO and it works just fine. Displays the record I was looking for, the trick is not to use "*" in the Like clause; or at least that was the issue in my case.
I put brackets around the word "Description" in the SELECT statement, but it's behavior remains. It works fine as long as I don't put anything in the WHERE clause. I've found if I put anything in the where clause, the description is blank (despite showing up in the Query analyzer). If I use a LIKE statement in the WHERE clause, the entire recordset is empty but it still works properly in the Query Analyzer.
Ultimately I think it's a problem with running ADO 2.8 on Vista 64
Personally I have always used DAO in Access projects.