this is more conceptual. I have a query I currently run in SQLServer that I'd like to make into a passthrough query in Access. However, it's a monster query that must be limited by a WHERE clause with the ID#s I want (there are too many ID#s to not have the WHERE clause; it'll freeze up). The ID#s I need change everyday, so I can't set this passthrough up once and be done.
So I don't really know how to get it so the user either 1. imports a table with the ID#s for that day and that table links to the passthrough, or 2. the user pastes in the ID#s into an input box and those become the WHERE clause conditions.
As far as I can see I can't JOIN the table in Access with the ID#s to the Passthrough, and I can't use WHERE ID# = [table].[ID#] in the WHERE part of my passthrough. Taking out the WHERE in the passthrough and then making a simple select query where it is joined with the access table doesn't work either, because the query just takes so long it times out.
Is this even possible or should I explore completely different strategies?
I use another technique when i have strange pass through queries
First i create a dummy pass through query where everything that is subjective are represented by dummy constants
e.g if i have changing of year i have a dummy year 1900 and i use replace to change it to whatever i need
The changed SQL is then passed to another pass through which serves as the
So my code is like this
Const DummyToReplace = "1900"
Dim strSql as String
Dim qdf as QueryDef
strsql = vbnullstring
set qdf = currentdb.QueryDefs(SourceDummyPassThroughQry)
strsql = qdf.SQL
set qdf = nothing
strsql = replace(strSql,DummyToReplace ,TheCriteriaYouwantToPass)
set qdf = currentdb.QueryDefs(ModifiedPassThrough)
qdf.SQL = strsql
set qdf=nothing
At this point you can either execute the ModifiedPassThrough or use it as a RecordSource.
In the case of WHERE you can use string splitting to split the SQL to 2 parts
1st part up to WHERE e.g
strSql = SELECT * from my TABLE WHERE
2nd part just put the Where Criteria
WhereCriteria = " ID IN (Various IDs)"
so you concatenate then and feed them to the modified Pass Through
qdf.SQL = strsql & " " & WhereCriteria
The rest are easy
Build the query in SqlServer as a stored procedure that returns data and accepts paramenters. Build a form in which you request the ID from the users, or build a function that get those IDs if possible. Have the paramenters in the stored procedure be the IDs you need in the WHERE clause.
You can dinamically redefine the SQL of a query by using querydefs like
CurrentDb.QueryDefs("myAccessQueryPassT").sql =
"EXEC mySqlServerStoredProc (" & par1 & ", " & par2 & ")"
where par1, par2, ... par(n) are the IDs you want to filter.
Then you can run a msAccess query as usual:
SELECT * FROM myAccessQueryPassT
Note that you can also define an unfiltered view in SqlServer (mySqlServerView) and then in the passthrough (in the example I include only one parameter, you can include more of course):
CurrentDb.QueryDefs("myAccessQueryPassT").sql =
"SELECT *
FROM mySqlServerView
WHERE ID = " & par1 & ")"
Or course you can always build the entire query dinamically, in that case it will be like:
CurrentDb.QueryDefs("myAccessQueryPassT").sql = "SELECT ... FROM ... WHERE..."
Same as before you can query the passthrough:
SELECT * FROM myAccessQueryPassT
Related
I have an AccessDB app where I need to grab the ItemIDs for the current user-applied filter into a new table to use downstream. Using the subform datasheet .recordsetclone property I can see the desired recordset, .recordcount reports the correct number of records. Otherwise, the following does not produce the desired temp table and AccessVBA does not complain.
Dim db As DAO.Database
Dim rstItemIDs As DAO.Recordset
Dim strSQL as String
Set db = CurrentDb
set rstItemIDs = Forms!Mainform![Data subform].Form.RecordsetClone
msgbox rstItemIDs.recordcount 'reports the correct result
strSQL = "SELECT rstItemIDs.ItemID INTO tempTable FROM rstItemIDs;"
db.Execute strSQL
Is it possible to construct a SQL Select query against a dao.recordset?
Thanks for any pointers you can provide.
Access SQL will not accept either a DAO or ADODB Recordset as the data source for a query.
However, I'm puzzled that Access does not complain when you try. With every attempt I made to reproduce your sample code, I got error #3078, "The Microsoft Access database engine cannot find the input table or query 'rstItemIDs'. Make sure it exists and that its name is spelled correctly."
Even DoCmd.SetWarnings False did not suppress that error message.
If you're interested in alternatives, you could persist tempTable (instead of creating a new version each time), then delete its contents and move through rstItemIDs adding each value to the second recordset. Although that is a RBAR (row by agonizing row) method, it may not be too painful with a small recordset.
A set-based approach could be to create a query based on your form's .RecordSource and .Filter properties. For example, with my form's .RecordSource as SELECT * FROM foo and the current form .Filter as id>10, this would give me a SELECT which returns the form's filtered records:
Replace(Me.RecordSource, ";", "") & vbcrlf & "AND " & Me.Filter
I am using VBA macro to make a table. First, I am inputting a date "PeriodEnd", this date filters a base table using a query. Then, I am making a second table and populating that table with (a) the results of the query, and (b) about 30 calculated fields based on the records of the query and other related tables.
My problem is that I am trying to put the PeriodEnd date in the table name and I can't seem to get the Syntax right. I am a VBA beginner, so thanks for the help. My VBA looks like as follows:
....
Dim db as DAO.Database
Dim PeriodEnd as Date
Dim PerStr as String
Set db = CurrentDb()
PeriodEnd = #12/31/2013#
PerStr = Format(PeriodEnd, "yyyy-mm-dd")
db.Execute "CREATE TABLE TblName_" & PerStr _
& " (Field1 as LONG)
I've run this with syntax where the table name is static and I don't get any errors. When I run with the variable table name I get "Run-time error '3290': Syntax error in CREATE TABLE statement."
Also, is there a better way to structure this? The only difference in these table will be the period end date--and the impact that a different period end date has on the underlying calculations I am forming in the VBA (functions not supported within the SQL).
Any advice on whether this should be structured instead as a query or a report (no experience yet with reports)?
You're attempting to create a table whose name includes dashes (because of the date format). You will need to bracket that name.
db.Execute "CREATE TABLE [TblName_" & PerStr _
& "] (Field1 as LONG)"
Also make sure to include the quotation mark at the end of the statement as I did above.
But consider using a variable to hold your CREATE statement. Then you can Debug.Print the variable to inspect the statement you're asking the db engine to execute.
Dim strDdl As String
strDdl = "CREATE TABLE [TblName_" & PerStr & "] (Field1 as LONG)"
Debug.Print strDdl
db.Execute strDdl
I've got a subform (RegistrationFsub) based on table Registration. It's purpose is to create a one-to-many relationship between a person and the year(s) they have enrolled in the group.
When a mom enrolls in a new year, I have a command button that is supposed to add a new line to the table Registration with MomID (from the parent form: MomsFsub) and the start date of the current enrollment year (YearStart, from table Year). Since the current enrollment period is represented by the latest date, I want to use the Max() command to retrieve it from YearT. I tried the following code:
Dim db As DAO.Database
Dim sqlSTR As String
Dim IDvar As String
'new code added since question posted
Set db = CurrentDb
Call MsgBox (Max(YearT!YearStart), vbOKonly)
'MsgBox checks value returned for Max(YearStart)
'end new code
IDvar = CStr(MomID)
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM YearT;"
'new: debug statement
Debug.Print sqlSTR
db.Execute sqlSTR
And I got an "Object variable or With block variable not set" error. What am I doing wrong?
Edit: Setting the db to Currentdb fixes the Object variable error, but now returns a "Too few parameters" error. The original table name "Year" has been changed to "YearT," since I only reference it in this one bit of code anyway.
Update
Now that I've fixed RegistrationFsub, it seems that the button also inserts data currently displayed in other controls on the form. So if the 2012 entry has RID = 1 and Leader = True, the above code creates an entry in Registration that also has RID = 1 and Leader = True. How can I keep those other fields blank?
The object variable error is because you didn't Set db to anything before you attempted db.Execute. Do this first ...
Set db = CurrentDb
If you later get an error with Execute, it may be because Year is a reserved word. Enclose that table name in square brackets to avoid confusing the db engine.
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM [Year];"
If you are adding a new record based on the Mom's current new entry, you need to take the current time: Now() and parse the year off of it..
Year(Now())
Looking for Max(YearStart) could be looking for a record that happened 5 years ago..
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM Year;"
I think you need to update the code to two different operations:
sqlSTR = "INSERT INTO Registration(Year(Now()), MomID)"
run your code..
Then do a..
sqlSTR= "SELECT Year(Now()), " & IDvar & " AS expr1 FROM [Year];"
The most relevant answer was deleted before it could be selected, so I shall paste the content here:
The object variable error is because you didn't Set db to anything before you attempted db.Execute. Do this first ...
Set db = CurrentDb
If you later get an error with Execute, it may be because Year is a reserved word. Enclose that table name in square brackets to avoid confusing the db engine.
sqlSTR = "INSERT INTO Registration(YearStart, MomID) SELECT Max(YearStart), "_
& IDvar & " AS expr1 FROM [Year];"
For "too few parameters", add Debug.Print sqlSTR after the sqlSTR = ... line.
But before the Execute command
Run the code and go to the Immediate window (Ctrl+g). Copy the SQL text, create a new query in the query designer, switch to SQL View, and paste in the SQL text. When you run that query, Access will pop up an input box asking you to supply a value for the parameter. That box also include the name of whatever Access thinks is the parameter.
The trouble here is that YearStart had a different field name in table Year.
Many thanks for the clear and helpful answer.
I more or less need to add this as a filter option of a calculated field. It's on a form with a search function that runs a query. I'm attempting to consolidate all the queries from the previous creator into one query. This is the only step I'm missing.
If I made that control a combo box and put as the row source
<5;<15;<30
Ideally, I'd like it to be <5; 15>x>5; 30>x>15 but I'm not sure how I can write that where the query can see if it's like that control.
Criteria Like "*" & [Forms]![FRM_SearchMulti]![txtClosing] & "*"
I reckon you can build the string in VBA for speed, or use a UDF if you do not care about related queries failing or speed.
Dim qdf As queryDef
Set qdf = CurrentDB.QueryDefs("TempQuery") ''TempQuery must exist
sSQL = "SELECT * FROM Table WHERE ANumber " & Me.MyCombo
qdf.SQL = sSQL
DoCmd.OpenQuery qdf.Name
Or there abouts.
In MS Access 2010, I am building an update query (using the Query Designer).
I would like to pass the name of the column to update as a variable, at run time.
I have tried writing the SQL and running the query in VBA. This seemed like the easiest way... however the SQL to complete the update becomes quite messy. I would prefer to do this in the query builder GUI .
Is it possible?
I have so far tried entering field names into the query builder:
expr1:[field_name]
Although Access prompts me for "Field_name" This results in "Cannot update 'field_name'; field not updateable.
Also, I tried this method:
Expr1: "'" & [field_name] & "'"
which results in "'" & [field_name] & "'" is not a valid name; check for punctuation.. etc
Below is a screen capture the query I am trying to build.
Access' db engine will not allow you to use a parameter as the name of the target field for your UPDATE statement.
If you try a user-defined function instead of a parameter to provide the field name, the result will be the same ... no joy.
It seems the db engine will not resolve object names when it executes a SQL statement. That limitation applies not just to field names, but table names as well. IOW, the following query will fail with an error message that it "cannot find the input table or query 'give me a table name'".
SELECT *
FROM [give me a table name];
While that isn't exactly the same as your situation, I suspect the reason may be. The db engine is too limited about resolving object names when it plans/executes queries.
Perhaps the best method is to use SQL, build your prompts and then assign these values to variables in VBA, then just add the variable value into your SQL.
So something along these lines. Your using Update query but same logic
Dim SQL as string
dim **FieldName** as string
SQL = "Select [table]![" & Chr(34) & **FieldName** & Chr(34) & "] from ........"
Check Here for SQL building tips
I use this method frequently - I know it's a very old post, but hope this helps someone - building on what David said:
Sub CreateQuery
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Set dbs = CurrentDb
Set qdf = dbs.CreateQueryDef("NameOfNewQuery")
strSQL = "Select " 'notice the space
strSQL = strSQL & "FROM " 'notice the sapce
strSQL = strSQL & "WHERE;"
qdf.SQL = strSQL
qdf.Close
Set qdf = Nothing
Set dbs = Nothing
End Sub