MS Access: Use variables instead of text.SetFocus method to query - vba

I have two parameters form a FROM and THRU textbox. The code object is txtFROM and txtTHRU. Now I tried to open the query and reports with a txtFROM.SetFocus and txtTHRU.SetFocus and used in the query criteria: Between [FORMS]![ReportName]![txtFROM].[Text] and [FORMS]![ReportName]![txtTHRU].[Text]. However nothing turns up when I link a button to the query and report to show the data with those two parameters. I think it may be due to the fact that the .SetFocus method will only work on one parameter, so I think writing VBA variables to pass into a query might work if possible. The thing is I do not know if it is possible to call a VBA variable while running to a query as it were an object. The variables would otherwise read .SetFocus to ready the parameter to be passed to the Access query.
DoCmd.SetWarnings False
If IsNull(txtFROM.Value) = False And IsNull(txtTHRU.Value) = False Then
dataFROM = CDate(txtFROM.Value)
dataTHRU = CDate(txtTHRU.Value)
End If
DoCmd.OpenQuery ("Expiring")
DoCmd.OpenReport ("Expirees"), acViewPreview
DoCmd.SetWarnings True
The above variables dataFROM and dataTHRU would be what I would like to fit in the query criteria to reference the Form which displays reports.

You might need to script the query "on the fly" by using CreateQueryDef. Sort of like:
Dim db as Database
Dim qdf as QueryDef
Set db = CurrentDB
Set qdf = db.CreateQueryDef("Expiring", "SELECT * FROM MyTable WHERE " &_
"MyDate >= #" & CDate(txtFROM.Value) & "# and MyDate =< #" CDate(txtTHRU.Value) & "#")
DoCmd.OpenReport "Expirees", acViewPreview
Of course, you'll probably need to add some code at the beginning to delete that query if it already exists. Definitely inside an If/Then because if the code happens to burp and doesn't create the query one time, it'll crash the next time you run it.
Edit
As suggested by HansUp, another option is simply to alter the query's SQL statement, which you can do in code.
Set myquery = db.OpenQueryDef("Expiring")
strsql = "SELECT * FROM MyTable WHERE " &_
"MyDate >= #" & CDate(txtFROM.Value) & "# and MyDate =< #" CDate(txtTHRU.Value) & "#"
myquery.SQL = strsql
myquery.Close

It looks like there was a mixup in my query code, the FROM was duplicated, FROM FROM, not FROM THRU. The code works as it should have with the reference to the Reports and Form which the text controls. Keep with the usual method then.

Related

Setting two rowsources in same procedure is terrible slow - Access 2010

I have two Listboxes which are filled via vba on a click event. The table 'Project' is a odbc datasource with 250 records.
List1.RowSource = "SELECT Name FROM Project WHERE ProjectID = " & ProjectID.Caption & " AND Year = " & ActualYear.Caption & " ORDER BY Name"
List2.RowSource = "SELECT ProjectShare FROM Project WHERE ProjectID = " & ProjectID.Caption & " AND Year = " & ActualYear.Caption & " ORDER BY Name"
So far so good. But when I run this code, it takes everytime up to 30sec to complete. I thought, okay it's because of odbc and so on. But when I run only one line of this code (no matter which), it is fast as lightning (0,1sec).
How can it be, that one query takes 0,1sec and two querys 30sec? May I could make a break between these two lines? Btw. without odbc everything works like a charm, no matter how many lines
You can bind both listboxes to the same recordset by manually creating the recordset. This allows Access to only query the table once instead of twice at the same time, avoiding any locking conflicts, and tends to avoid other problems as well.
This also allows you to use parameters, fixing any errors introduced by string concatenation.
Dim rs As DAO.Recordset
With CurrentDb.CreateQueryDef("", "SELECT Name, ProjectShare FROM Project WHERE ProjectID = p1 AND Year = p2 ORDER BY Name")
.Parameters(0).Value= ProjectID.Caption
.Parameters(1).Value = ActualYear.Caption
Set rs = .OpenRecordset(dbOpenSnapshot) 'Snapshot because it won't be updated
End With
Set list1.Recordset = rs
Set list2.Recordset = rs
Note that I have had errors occur when an object bound to a recordset with parameters was requeried, so you might want to use string concatenation if that's happening.

Pass Through Query Won't Run From Command Line

I created a pass through query in Access.
All it says is .
sp_Submit ''
If I click on it directly it runs the SSMS stored procedure which just changes some test tables.
However if I run it in VBA it does not work. It doesn't error out or anything, it just does not work.
I have tried
sSQL = "sp_Submit '" & Me.cboNumber & "'"
and
sSQL = "sp_Submit '"
Please not the stored procedure isn't doing anything much at this point. I have it testing some stuff. It just deletes everything in one table and inserts it in another.
What am I doing wrong? I've used this in the past and it has worked so I'm not sure why it doesn't work this time. The stored procedure itself is set up to accept one variable but it doesn't actually do anything with it (yet.).
Thank you.
Given what you have to far, then you should be able to edit the saved pass though query with
Sp_Submit 'test'
Assuming the 1 paramter is text. If the parameter is to be a number, then
Sp_Submit 123
At this point, you have to save that query. Now click on it, does it run correctly?
And in place of clicking on the query, you can certainly do
CurrentDB.execute "name of saved query goes here"
However, keep in mind that a PT query is raw T-SQL. What executes runs 100% on the server. This means that such query(s) cannot contain references to any form, or anything else. So you have to “pre-process” or create the value you wish to pass and modify the PT query. So your code of creating the SQL you have looks correct, but you then have to take that sql string and "set" the PT query.
The most easy way to do this is with code like this:
With CurrentDb.QueryDefs("MyPass")
.SQL = "sp_Submit '" & Me.cboNumber & "'"
.Execute
End With
Of course if the PT query returns records, then you would go:
Dim rstRecords As DAO.Recordset
With CurrentDb.QueryDefs("MyPass")
.SQL = "sp_Submit '" & Me.cboNumber & "'"
.ReturnsRecords = True
Set rstRecords = .OpenRecordset
End With
And to be fair, you likely should set “returns” records = false in the first example. You can do this in the property sheet of the save query, or in code like this:
With CurrentDb.QueryDefs("MyPass")
.SQL = "sp_Submit '" & Me.cboNumber & "'"
.ReturnsRecords = False
.Execute
End With
Note that you can use the one PT query over and over in your code. So once you ceated that one PT query, then you can use it to pass any new sql you wish, such as:
Dim rstRecords As DAO.Recordset
With CurrentDb.QueryDefs("MyPass")
.SQL = "select * from tblHotels"
.ReturnsRecords = True
Set rstRecords = .OpenRecordset
End With
So you can "stuff" in any sql you want for that one PT query - and use it throughout your application.

Run-time Error 2498 for Append and Make Table Queries Created in VBA

I'm getting a 2498 error and really don't understand why. I'm building a string in VBA and am getting the error with the following line of code...
DoCmd.OpenQuery qdfNew, acNormal
It happened with a very long string created to create the query so I simplified the code as much as possible and am still getting the error.
Here's the code...
Option Compare Database
Option Explicit
Dim dbsFootball As Database
Dim strInsertSQL, strSelectSQL, strIntoSQL, strFromSQL, strOrderSQL, strSQL As String
Dim qdfNew As QueryDef
Sub CreateFormattedData()
Set dbsFootball = CurrentDb()
strSelectSQL = ""
strIntoSQL = ""
strFromSQL = ""
strOrderSQL = ""
strSQL = ""
strSelectSQL = "SELECT [tbl_Raw_League_Data].[Season]"
strIntoSQL = "INTO [tbl_Manip Data]"
strFromSQL = "FROM [tbl_Raw_League_Data]" _
+ "LEFT JOIN Referees ON [tbl_Raw_League_Data].[Referee] = Referees.[Referee from Source Data]"
strSQL = strSelectSQL + " " + strIntoSQL + " " + strFromSQL + " " + strOrderSQL
On Error Resume Next ' If query doesn't exist, error won't stop execution
DoCmd.DeleteObject acQuery, "pgmqry_Create Table tbl_Manip"
On Error GoTo 0 ' Reset error handler
Set qdfNew = dbsFootball.CreateQueryDef("pgmqry_Create Table tbl_Manip", strSQL)
DoCmd.OpenQuery qdfNew, acNormal
End Sub
The source field, [tbl_Raw_League_Data].[Season], is a "Short Text" data type (field size = 7).
If I terminate the VBA code and run the query that was created by the code, it works fine with no apparent errors. However, it will never run the query from within the VBA code.
I was originally getting the error 2498 when using "INSERT INTO" for an append query, but realized that the table could as easily be recreated at code execution time.
I'm lost and would sure appreciate some ideas!
Thanks in advance,
Jason
You are passing the querydef object to DoCmd.OpenQuery when it expects a string referencing name of a stored query object. Consider using the querydef's Name property:
DoCmd.OpenQuery qdfNew.Name, acNormal
Alternatively, use .Execute command from database object using the SQL string variable, bypassing any need for querydef:
dbsFootball.Execute strSQL, dbFailOnError
Or with querydef object, as #HansUp suggests, where you simply execute directly since it is an action query:
qdfNew.Execute dbFailOnError
Do note above two options bring up the regular MS Access discussion, of using stored vs VBA string query. While the former is precompiled and runs through query optimizer caching best plan, the latter can have sql dynamically created (structural components that is like SELECT, FROM and JOIN clauses as both can use passed in parameters). From your code snippet consider saving SQL query beforehand without needing to build it in VBA on the fly, and call it with DoCmd.OpenQuery.

MS Access VBA issue

I'm making a report in MS Access - what I'm trying to do here is basically APPEND a query to a table that I've already created - I select the first value, change it and update the table. The issue that I'm coming across is - this report will be used by a VB6 application. So the user won't be seeing Access at all.
The thing with my append query is that it needs a USER ID to run (4 digit number). Normally when I run a report in Access I pass the parameters to a form in Access - and I use them to run queries. However, in this case, I need the user to enter a value when appending the query, additionally, when appending a query in VBA it first says "You are about to append a query, are you sure" (or something along those lines), so is there a way to automate that as well, so when I append it nothing happens?
Here is my code for appending and selecting date from the tempTable:
CurrentDb.Execute "DELETE from [tempCompanyMgmt-NOW];"
DoCmd.OpenQuery "qryCompanyMgmt-SUE" - i made this append!
Set rs1 = CurrentDb.OpenRecordset("Select * from [tempCompanyMgmt-NOW]", , dbOpenDynamic)
So as long as I press OK, YES when I get notified of the APPEND process and enter the parameter for USER ID - everything works fine.
Looks like a typo in your markdown, should the 2nd line be:
DoCmd.OpenQuery "qryCompanyMgmt-SUE - i made this append!"
You'll need to remove the reference to the form inside the qryCompanyMgmt-SUE - i made this append! query, and swap it for a parameter name. You can use the Access interface to explicitly add a parameters clause to the query, and then using ADO (or DAO) from VB6, set a parameter value before you open/execute the query.
The "You are about to append a query, are you sure" message is an Access feature (and it can be disabled), so if you want the VB6 application to provide such a warning, then you'll need to create it yourself with a MsgBox.
One option would by putting your append query into the code and filling in the parameter that way.
I don't know your exact scenario, but something like:
If not isValidUserID(me.UserID) Then
msgbox "Please enter a a valid user id"
exit sub
End If
Dim strSQL As String
strSQL = "DELETE * from [tempCompanyMgmt-NOW];"
CurrentDb.Execute strSQL, dbFailOnError
strSQL = "INSERT INTO tempCompanyMgmt-NOW ( FieldName1, FieldName2, FieldName3 ) " & _
"SELECT FieldName1, FieldName2, FieldName3 FROM tempCompanyMgmt WHERE UseriD=" & Me.UserID
CurrentDb.Execute strSQL, dbFailOnError
To validate the user id you could do something like:
If (Len(me.UserID) = 4 And IsNumeric(me.UserID)) Then
or
Public Function isValidUserID(varUserID As Variant) As Boolean
Dim blnRet As Boolean
If Len(varUserID) = 4 And IsNumeric(varUserID) Then
blnRet = True
End If
isValidUserID = blnRet
End Function
To get rid of the MsgBox telling me I'm about to append a query i included this in my module before I open my append query..
DoCmd.SetWarnings False
And I realized once I have the value passed to the form (userID), that value gets passed on as a parameter when my query gets appended. So it's all set. Thanks for all help!

Access 2007 VBA Query Shows Data in Query Analyzer But Not in VBA Coded Recordset

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.