I have just started to do some coding with Access and trying to create a function that adds a row to a table but this would not work.
I have created a simple table (Table1) with two columns "FirstName" and "LastName" and a button that fires off the following code:
Private Sub Command0_Click()
AppendRow "Table1", "John", "Doe"
End Sub
Where AppendRow is:
Function AppendRow(toTableName As String, firstName As String, lastName As String) As Boolean
' Returns True on success, false otherwise
' USAGE: AppendRow "toTableName", "firstName", "lastName"
On Error GoTo errhandler
Dim strSql As String
'Create the SQL string
strSql = "INSERT INTO " & toTableName & " (FirstName, LastName) " & _
"VALUES ('" & firstName & "', '" & lastName & "');"
'Print the SQL so we can paste into the query build if there are errors
Debug.Print strSql
MsgBox strSql
'Run the SQL Query
CurrentDb.Execute strSql
'If no errors return true
AppendRow = True
ExitHere:
Exit Function
errhandler:
'There is an error return false
AppendRow = False
With Err
MsgBox "Error " & .Number & vbCrLf & .Description, vbOKOnly Or vbCritical, "AppendTable"
End With
Resume ExitHere
End Function
The SQL string looks like this
INSERT INTO Table1 (FirstName, LastName) VALUES ('John', 'Doe')
EDIT: Added missing quotes.
You reported that you are now quoting the text values you attempt to insert, but that you do not get the row inserted and apparently no error message. I don't understand why that is so, and offer this simple procedure simply to see whether you can get something to work.
Public Sub AppendRow(ByVal toTableName As String, _
ByVal pFirstName As String, _
ByVal pLastName As String)
Dim db As DAO.Database
Dim rs As DAO.Recordset
'* ensure SetWarnings is not off *'
DoCmd.SetWarnings True
Set db = CurrentDb
Set rs = db.OpenRecordset(toTableName, dbOpenTable, dbAppendOnly)
With rs
.AddNew
!firstName = pFirstName
!lastName = pLastName
.Update
.Close
End With
Set rs = Nothing
Set db = Nothing
End Sub
I didn't include error handling because this is intended only for testing. I made it a subroutine instead of a function because I noticed you weren't using the function's return value in your code which called the function.
If this doesn't work for you, please tell us the error message you receive and which line in that procedure triggers the error.
HansUp's code didnt work for me until I removed the dbAppendOnly option from the OpenRecordSet function call. MS Help documentation implies that it is only valid for Dynaset RecordSets, not TableSet Recordsets. Changed it to "Set rs = db.OpenRecordset(toTableName, dbOpenTable)" and it worked.
But his code was extremely helpful and I am very grateful. I had been going around and around unable to make my .Execute "INSERT "...-type code work either. I have no idea what was going on with that. It worked once and I made a minor change... Maybe my blood pressure peaking from my aggravation had something to do with it.
btw, #ymail.com is a valid email domain despite what your automated eddress checker says.
Related
I just started studying VBA for Access. I am therefore using some examples of site "https://learn.microsoft.com/en-us/office/client-developer/access/access-home".
When the code contains "EnumFiels" its execution generates the error "Sub or Function not defined".
I can't understand the reason for it and, above all, I don't know how to eliminate it.
For instance:
Sub WhereX()
Dim dbs As Database, rst As Recordset
Set dbs = OpenDatabase("Northwind.mdb")
Set rst = dbs.OpenRecordset("SELECT LastName, " _
& "FirstName FROM Employees " _
& "WHERE LastName = 'King';")
rst.MoveLast
EnumFields rst, 12
dbs.Close
End Sub
Alright, short background, I have a form, on which I have 3 Comboboxes.
Two of these comboboxes are tied to the same exact table, an accounts table. They use slightly different queries between them, see below.
In one box, cmb_GA I have set the box property "On Not in List" to the following code segment :
Private Sub cmb_GA_NotInList(NewData As String, Response As Integer)
Dim cnn As New ADODB.Connection
Dim strSQL As String
Dim password As String
Dim bytUpdate As Byte
On Error GoTo ErrHandler
Set cnn = CurrentProject.Connection
bytUpdate = MsgBox("Do you want to add " & NewData & " to the Accounts list?", vbYesNo, "Not in list of Accounts!")
If bytUpdate = vbYes Then
password = InputBox("Enter New Account Password")
strSQL = "INSERT INTO tbl_Accounts(Login, PW) " & "VALUES
('" & NewData & "#mcsnet.org' , '" & password & "')"
Debug.Print strSQL
cnn.Execute strSQL
Response = acDataErrAdded
Call AuditLogs("txt_DN", "New")
ElseIf bytUpdate = vbNo Then
Response = acDataErrContinue
Me!cmb_GA.Undo
End If
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description, vbOKOnly, "Error"
End Sub
Note that for formatting here I put in an extra CR after "VALUES" that doesn't exist in the actual code, other than that, and some deleted comments, WYSIWIG.
This code works perfectly. 100% Does what I want.
I have another combobox, cmb_IA
I am using the same code for it (Yeah I probably should have done this as a module in retrospect, but I didn't yet.)
The problem is that it throws an error. "The text you entered isn't an item in the list. Select an Item from the list, or enter text that matches one of the listed items."
I've looked at the properties and can not find a difference between the two boxes on the property sheets: Here's a look at both boxes Data tab:
And here is the relevant SQL from the two queries:
SELECT *
FROM tbl_Accounts
WHERE tbl_Accounts.Association LIKE "*Device*";
and
SELECT *
FROM tbl_Accounts
WHERE tbl_Accounts.Association LIKE "*Intune*";
I would assume the question is obvious, but let me state this outright, what is happening here? Is there a way to suppress this error? Both comboboxes must let the user add new information to them, as the point of this form is to register new devices, cellphones and tablets, and the security accounts and corporate accounts that each device uses. What's puzzling me the most is that this error is only showing up on the one combobox.
Edited to add the code from the section that is throwing the error:
Private Sub cmb_IA_NotInList(NewData As String, Response As Integer)
Dim cnn As New ADODB.Connection
Dim strSQL As String
Dim password As String
Dim bytUpdate As Byte
On Error GoTo ErrHandler
Set cnn = CurrentProject.Connection
bytUpdate = MsgBox("Do you want to add " & NewData & " to the Accounts list?", vbYesNo, "Not in list of Accounts!")
If bytUpdate = vbYes Then
password = InputBox("Enter New Account Password")
strSQL = "INSERT INTO tbl_Accounts(Login, PW) " & "VALUES ('" & NewData & "#mcsnet.org' , '" & password & "')"
Debug.Print strSQL
cnn.Execute strSQL
Response = acDataErrAdded
Call AuditLogs("txt_DN", "New")
ElseIf bytUpdate = vbNo Then
Response = acDataErrContinue
Me!cmb_IA.Undo
End If
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description, vbOKOnly, "Error"
End Sub
It was suggested I show the RowSource SQL generated by Access so here it is Working:
SELECT qry_DeviceAccounts.AccountIDKey, qry_DeviceAccounts.Login, qry_DeviceAccounts.PW
FROM qry_DeviceAccounts
ORDER BY qry_DeviceAccounts.[Login];
Not Working:
SELECT qry_SecurityAccounts.AccountIDKey, qry_SecurityAccounts.Login, qry_SecurityAccounts.PW
FROM qry_SecurityAccounts
ORDER BY qry_SecurityAccounts.[Login];
I can't believe I didn't see it earlier. This was the result of the difference between the two queries, and the way they filtered for the account information. I needed to set the new account information to be filtered for during the INSERT statement, which hadn't been done. Since the other one worked on the default value of one of the fields in the table, it wasn't relevant to that one's INSERT statement.
Moral of the story, check your fields, and make sure you carefully read what each is doing. I was so busy looking for an error in my VBA, I forgot to check my SQL.
In my code, I am trying to use an input box to hold a user inputted value as a string, then use SQL to then update a field based on that.
My code is:
Dim strinput
Dim strsql
Call CreateRevisions
strinput = InputBox(prompt:="Name of revision")
If Not IsNull(strinput) Then
'DoCmd.SetWarnings False
strsql = " UPDATE tblJobDetails.RevisionName"
strsql = strsql & " SET tblJobDetails.RevisionName = '" & strinput & "'"
strsql = strsql & " WHERE (((tblJobDetails.JobID)=[Forms]![JobQuote]![JobID]));"
'DoCmd.RunSQL strsql
CurrentDb.Execute strsql
'docmd.setwarnings true
End If
End Sub
When it runs, I get the prompt that fields are about to be updated, then the input box appears and allows me to enter something. I checked the value of strinput and it is holding the value correctly, but when I try to actually execute the SQL statement I can an interesting error I haven't run into before.
The error is :
Run-time error '3024':
Could not find file 'C\....
I have run various statements like this before with no problem. This is the first time I have tried using the input box however. What is causing that error?
I have tried changing it to docmd as well as adding in debug.print, but it still results in the same error.
I use Access quite a bit but only dabble in VBA code. I have some code that works, but I tried to compile the code and get the following error.
Private Sub Report_Open(Cancel As Integer)
Dim RS As Date
Set RS = CurrentDb.OpenRecordset("tblDate")
MsgBox ("The month and year are: " & RS)
DoCmd.OutputTo acOutputReport, "LP Completions", "PDFFormat(*.pdf)", Chr(34) & "\\sharepoint.xx.yyyy.zzz\Reports\" & Format(RS.Fields(0), "yyyy-mm") & Chr(32) & " - LP Completions - Exec Report.pdf" & Chr(34), False
End Sub
I get a Compile Error: Object Required. In the code view the RS = is highlighted.
I have no clue why this is coming up. Can someone provide some guidance as to how to fix this? Thanks so much!
If you're opening a recordset the variable should be a recordset. You then reference the field in the table you're after in the messagebox.
If you have more than one record in the table it will return the first value - so either create a temporary query to return the value you're after, or search the recordset and go to the correct record.
Private Sub Test()
Dim RS As dao.Recordset
Set RS = CurrentDb.OpenRecordset("tblDate")
MsgBox "The month and year are: " & Format(RS.Fields("MyDateField"), "yyyy-mm")
End Sub
Edit:
If you're using a query to get the record:
Private Sub Test2()
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("", "SELECT MAX(MyDateField) AS MaxDateField FROM tblDate")
Set rs = qdf.OpenRecordset
MsgBox "The month and year are: " & Format(rs.Fields("MaxDateField"), "yyyy-mm")
End Sub
In VBA, Set is only to be used when assigning to object variables. A variable of type Date is not an object variable, so you just say
RS = CurrentDb.OpenRecordset("tblDate")
(note that you can, if you really want to, put a Let in front, but pretty much no one ever does).
I am having trouble getting this to compile, it keeps giving an undefined variable error during compile at 'Incdntno.Value'. I tried to Dim Incdntno as Integer but then was getting Invalid qualifier. I have a similar code that works (see second code block). I didn't need a lot of what was going in the working code part so I removed it. I would be so grateful if someone can point out where I am going wrong in the first code block? Thank you, very much
Private Sub Incdntno_AfterUpdate()
Dim conn As ADODB.Connection
Dim sSQL As String
Set conn = CurrentProject.Connection
If IsNull([Incdntno]) Then
Me.Dirty = False
End If
Dim Incident As String
Incident = Incdntno.Value
sSQL = "INSERT INTO tblFieldIncident_Complaint_InspHist ( Incdntno, InspectID, Dt_Inspect ) SELECT " & [Incdntno] & ", " & [InspectID] & ", " & [InspDate] & " FROM tblInspect WHERE Incdntno='" & Incident & "';"
conn.Execute sSQL
'Me.Requery
frmInspectItemsSub.Requery
ProcExit:
Exit Sub
End Sub
Code that works:
Private Sub InspectType_AfterUpdate()
Dim conn As ADODB.Connection
Dim sSQL As String
Dim wYesNo As Integer
On Error GoTo ProcErr
If Not mbNewRecord Then
wYesNo = MsgBox("Changing the inspection type will erase the current entries and insert items specific to the new inspection. Proceed?", vbYesNo, "Inspection item update")
If wYesNo <> vbYes Then GoTo ProcExit
End If
Set conn = CurrentProject.Connection
If Not mbNewRecord Then
conn.Execute "DELETE FROM tblInspectItems WHERE InspectID=" & InspectID
End If
If IsNull([InspectID]) Then
Me.Dirty = False
End If
Dim inspType As String
inspType = InspectType.Value
sSQL = "INSERT INTO tblInspectItems ( ItemID, InspectID ) SELECT ItemID, " & [InspectID] & " FROM tblRefInspectItemCodes WHERE InspectType='" & inspType & "';"
conn.Execute sSQL
'Me.Requery
frmInspectItemsSub.Requery
ProcExit:
Exit Sub
ProcErr:
ErrMsg ("frmInspect.InspectType_AfterUpdate")
Resume ProcExit
End Sub
This sounds like what happens if you duplicate event code. Take a close look at your control names and make sure they match. Also, you'll want to make sure that [Event Procedure] appears in the event properties. That link may not appear automatically if you change control names.