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.
Related
I have sub that runs when the database is opened to a specific form and I'm trying to get it to add information in a table.
The table name is UnAuthorizedAccess and the columns in table are ID(auto number), NAME(text), COMPUTERNAME(text), ATTEMPTDATE(date/time).
What commands do I need to use to add a new record to this table? I have a VBA that if they're login information Isn't there is will force close access all together. I'm trying to gather information on the user as well before kicking them out.
I figured this is the easiest way as outlook won't let you send a hidden email from the user unless they first see it.
You can add records to a recordset with the following code, but I am unsure whether you have a field called COMPUTERNAME. You shouldn't need to add the ID value as its an autonumber.
dim Rst as recordset
Set Rst = CurrentDb.OpenRecordset(Name:="UnauthorizedAccess", Type:=RecordsetTypeEnum.dbOpenDynaset)
With Rst
.AddNew
![NAME] = Me.Name.Value
![COMPUTERNAME] = Me.COMPUTERNAME.Value
![ATEMPTDATE] = date()
.Update
End With
As for sending hidden emails, see this question I asked not so long ago. It sends an email via outlook, but remember to reference the Microsoft Outlook Object library in the VBA Editor.
CurrentDB.Execute is the method for executing SQL statements, and INSERT INTO is the SQL statement for adding records to a DB table.
CurrentDB.Execute "INSERT INTO UnAuthorizedAccess (NAME, COMPUTERNAME, ATTEMPTDATE) " & _
"VALUES (" & Your_NAME_Variable & ", " & Your_COMPUTERNAME_Variable & ", " & Now() & ")
Replace Your_NAME_Variable and Your_COMPUTERNAME_Variable with the variables in your code containing these values.
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
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 have a question with my converting in VBA. I made a button in a form and when I press it, it should make an update in my database table, but I get an ERROR:
arithmetic overflow error converting numeric to data type numeric
How can solve this problem? Here is my code:
Private Sub Inserare_Click()
Dim strSQL As String
Dim rst As New ADODB.Recordset
strSQL = "UPDATE dbo.Soferi_test SET number= '" &
Me![subform_soferi].Form!certificat_cipti & _
"',drivers= '" & Me![subform_soferi].Form!categorii_permis & _
"' WHERE IDNO = " & Forms!Forma_redactare_soferi!IDNO
Call AttServ(strSQL, rst)
MsgBox ("Datele au fost introduse cu success")
End Sub
number is a reserved word. Bracket that name in your UPDATE statement so the db engine knows it's supposed to be a field name.
strSQL = "UPDATE dbo.Soferi_test SET [number]= '" &
If that change doesn't resolve the problem, inspect the completed SQL statement. Insert this line after you store the string to strSQL.
Debug.Print strSQL
You can view that output in the Immediate window (go there with Ctrl+g). You can then copy that statement text into SQL View of a new Access query for testing. Add the statement to your question if you can't get it to work properly and tell us whether you get the same or different error message.
It may also help to show us the code from your AttServ procedure which uses strSQL.
I think the problem is in the field type of the table you are trying to update.
Example: If you try to set the value of a small integer field to a long integer, value, Access will throw an error.
Check the type of your fields and set them to the appropriate type.
Other think that can be wrong is the value of the text boxes. Just to be sure, try to convert the values.
Example: Cdbl(Me![subform_soferi].Form!certificat_cipti) will convert the string in your text field to a double value.
Also, I recommend you use the value attribute of your text boxes:
Me![subform_soferi].Form!certificat_cipti.Value
or
CDbl(Me![subform_soferi].Form!certificat_cipti.Value)
Notice that if you use the "conversion" functions (CDbl, CInt, CDate, etc.) an error will be thrown if the conversion fails (for example, trying to convert 12abc to an integer will fail)
I'm not sure if this is the right site to post this question, but here it goes...
In Access 2007 I get the error "Runtime Error '3061': Too few parameters. Expected 1" on this piece of VBA code:
Private Sub btnCheck_Click()
Dim rs As Recordset
Dim db As Database
Dim id As String
Dim query As String
MsgBox ("one")
Set db = CurrentDb()
id = Me.UniqueID.Value
query = "SELECT [Unique_ID] from tblPatients WHERE [Unique_ID] =" & id
MsgBox (id)
Set rs = db.OpenRecordset(query) <<<<<HIGHLIGHTED LINE
If IsNull(rs) Then
Me.lblCheck.Caption = "NEW"
Else
Me.lblCheck.Caption = "EXISTS"
End If
End Sub
The data source is a table, not a query. Any help would be much appreciated!
There is no field named Unique_ID in your table tblPatients. If you posted all of your code then that is the only possible explanation.
EDIT: Your comment confirmed my suspicions:
I just triple checked :P Table name: tblPatients Column name: Unique ID
You added an underscore in your code that did not exist in your field name. You are correct in using square brackets, but the correct code should be:
query = "SELECT [Unique ID] from tblPatients WHERE [Unique ID] =" & id
Please note the removed underscores. Alternatively (and I'd say preferably if you are in the early stages of design), you can rename the field in the table to either Unique_ID or UniqueID and save yourself a good deal of hassle.
A Few things can cause this error. A common error is misspelled table names and field names.
I would check tblPatients is spelled correctly or that there is no prior suffix like dbo.tblPatients required if the table is linked to a Server Connection.
As well we are assuming the id is a number and isn't a text field which would cause an error if you do not have the correct quotes. ie.
it would instead read
query = "SELECT [Unique_ID] from tblPatients WHERE [Unique_ID] = '" & id & "';"
Lastly, try to place ";" like I did in the line above.
I suggest you add a Debug.Print statement to your code like this:
query = "SELECT [Unique_ID] from tblPatients WHERE [Unique_ID] =" & id
Debug.Print "query: " & query
The reason for that suggestion is Debug.Print will print your SQL statement to the Immediate Window. (You can use the Ctrl+g keyboard shortcut to get to the Immediate Window.) Then you can view the completed string you're asking OpenRecordset to use. Often just seeing that string (rather than trying to imagine what it should look like) will let you spot the problem. If not, you can copy the string from the Immediate Window and paste it into SQL View of a new query ... the query designer can help you pinpoint syntax errors ... or in this case, I think it may alert you to which item in your query the database engine doesn't recognize and suspects must therefore be a parameter. And if that step still doesn't resolve the problem, you can paste the string into your question on Stack Overflow.
Finally, I think you may have a logic error with IsNull(rs) ... because rs has been declared a recordset, it will never be Null. In the following example, the SELECT statement returns no records. And the Debug.Print statement says IsNull(rs): False both before and after OpenRecordset.
Public Sub RecordsetIsNeverNull()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSql As String
strSql = "SELECT * FROM tblFoo WHERE 1 = 2;"
Set db = CurrentDb
Debug.Print "IsNull(rs): " & IsNull(rs)
Set rs = db.OpenRecordset(strSql)
Debug.Print "IsNull(rs): " & IsNull(rs)
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Edit: According to Problem names and reserved words in Access, query is an Access reserved word. I don't actually think that is the cause of your problem, but suggest you change it anyway ... perhaps strQuery.