I am using MS Access 2010. I have a form that captures a couple data items and then writes the record to a table using a function that I defined. The function is called in the click event of the Write Record command-button in the form.
Form:
Code:
> Private Sub writerecord_Click()
Rem MsgBox ("in write record click event")
Dim sqlString As String
Rem 1 - write to the kit_items table
sqlString = "INSERT INTO kit_items (item_vendorid, item_name, item_description, item_cost) VALUES (" & Me!vendorlist & ", '" & Me!item_name & "', '" & Me!item_description & "', '" & Me!item_cost & "');"
DoCmd.RunSQL sqlString
MsgBox ("done writing to table kit_items")
End Sub
records saved in table looks like this
**What is generating the duplicate record ?
If your form is bound to the table that you are writing to, the button will add a second record.
If you would like to work with data this way, you would need to make sure that the form is unbound.
Beware however that if you don't take steps to 'clear' out the data once the user clicks the button to write the record, every time they click the button you will get a new record.
Is there some reason why you need to do the inserting manually (as opposed to letting the bound form handle the inserts/edits)?
Related
I have a form (Purchase Orders) and a sub-form in it
(Purchase Order Details). The Main form contains Number of the
PO (text box), Supplier (combo-box), Employee (combo-box),
Status (combo-box) which contains 2 records (New and Done) and a date box (when the PO was created). The Sub-form (datasheet) contains Product (combo-box), Quantity and a Price field.
What I want to do is to add a button on the main form which will do
next.
When the button is pressed a VBA code should be executed and do next.
Take data from the Main form (Number of the PO, Status and the date)
and the Sub-form (Product, Quantity and Price) and put all that into
a table (StockMovements).
I managed to do that with the next code:
Private Sub cmdOrder_Click()
Dim strSQL As String
strSQL = "INSERT INTO StockMovement (ID_Product, Status, Quantity, ID_PurchaseOrder) VALUES (" & _
Me.frmPurchaseOrderDetails_Subform.Form!comboboxProduct & ", '" & _
Me!txtStatus & "', " & _
Me.frmPurchaseOrderDetails_Subform.Form!txtQuantity & ", " & _
Me!txtID_PurchaseOrder & ");"
DoCmd.RunSQL strSQL
Me.Requery
End Sub
However, there are 2 problems:
As you can see I didnt add the date field because I get an error,
cant remember which one it was exactly but I think 2075;
The code works without the date, but only adds one Product to the
table, the first one. And in a Purchase Order there are usually more
than one products.
Because Im totally new in VBA, I would kindly ask you to treat me like a newbie and explain more detailed, if possible.
(Fixed the code, forgot to change the language. I mean I pasted the wrong one, now its the right one but still not working of course :))
Thanks!
1) If you only have a problem with one specific field, I would check whats special with that one. Probably the input is formatted as a string and the field as Date/Time. In that case try to use the CDate()-Function. I could imagine, that a .Value at the end could solve the problem, too.
Dim datDate as Date
datDate = CDate(Me!txtDate.Value)
2) That your code inserts only one row is absoluterly correct. Remember that e.g. Me!txtStatus.Value is a textbox that contains only one single piece of data. The rows of data are saved in a table and depending on the row you have selected with a main-form (= one row), the corresponding value is shown in the textbox.
INSERT INTO table (field1,field2) VALUES (value1,value2)
An INSERT INTO inserts one row every time it's executed. So the SQL in the code you have mentioned needs to be repeated. You could do so using loops.
Dim strSQL As String
strSQL = ""
For Each Item In Group
strSQL = strSQL & "INSERT INTO table (field1,field2) VALUES (value1,value2)"
Next
In my opinion, copying data that way is absolutely annoying with VBA. You need to create recordsets, modify and merge them. I would try to solve as much as possible with Access Non-VBA-Solutions.
My question to you: Did you think about linking the form (and sub-form) directly to the table(s)?
The date can be inserted this way:
"INSERT INTO StockMovement ([DateField]) " & _
"VALUES (#" & Format(Me!DateField.Value, "yyyy\/mm\/dd") & "#)"
That said, your code will insert one record only. To insert multiple records you need a select query or - much faster - use DAO to open the target table as a recordset and then, as source, loop the RecordsetClone of your subform and copy the records to the target table one by one.
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.
I have found similar answers to this question, even on this site, however, the syntax has not worked for my database and I'm not sure what needs to be done. This data base is used to house audits for staff performance and accuracy. I am now in the midst of creating the forms and getting them to flow properly for the user.
When conducting an audit, the user will need to enter six specific fields into the first form. Those forms are Audit, Month, Year, Username, Location, Reviewer, and Date. The user will need to complete multiple audits, however, these six fields will always be the same.
I would like to copy these fields in the first form and carry them into the second form so the user does not have to repeat the information. Here is my current code (set to run on the click of a command button on the bottom of screen 1):
Dim strSQL As String
strSQL = "INSERT INTO [tblTripMem] (Audit, Month, Year, Username, Location, Reviewer, Date)"
strSQL = strSQL & " Values (" & Me.cboFP1Audit & "," & Me.Month & "," & Me.Year & "," & Me.Username & "," & Me.Location & "," & Me.Reviewer & "," & Me.Date & ") FROM [FPScreen1]"
strSQL = strSQL & "WHERE (currentrecord = " & Me.CurrentRecord & ")"
DoCmd.RunSQL (strSQL)
Each time I run this I receive the following error: "Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'.
I am new to Access and am unsure of what this means or how to fix it. All I know is that I'm not finding a solution. Can anyone help? I'd greatly appreciate it.
Here's a mock-up Access file illustrating a way to do what you're doing without using SQL:
With Form 1 open...
...complete the various fields:
Click the Copy to Form 2 button and this will open Form 2 and populate its fields with the data from Form 1:
Here's the VBA code on the Copy to Form 2 button's OnClick event:
Private Sub cmdCopyToFrm2_Click()
Dim frm As Form
DoCmd.OpenForm "Form2"
Set frm = Forms!Form2
With frm
!AuditRef = Me.cboFP1Audit
!AuditMonth = Me.txtAuditMonth
!AuditYear = Me.txtAuditYear
!AuditUsername = Me.txtAuditUsername
!Location = Me.txtLocation
!Reviewer = Me.txtReviewer
!AuditDate = Me.txtAuditDate
End With
End Sub
Note that when Form 2 opens, the textbox that the cursor defaults to might not seem to show any data; if you move away from that textbox it should magically show (don't know why it does this, but there you go).
INSERT INTO table (...) VALUES (...) cannot have a FROM or WHERE clause. You insert a single record with fixed values, not data from another table.
But once you delete these clauses, you will have other errors, because you need to format your string and date values correctly to get the INSERT query to work.
And then you will still be prone to SQL injection errors. It is safer to use Recordset.AddNew and .Update to add records.
See e.g. here: https://stackoverflow.com/a/34969410/3820271
(but without the loop)
What is the simplest way for me to get MS Access 2007 to autofill a form based on the entry added in the first field?
I currently have 4 tables.... Customers, Parts, Order Header, and Order Lines. I have created a form for the order header table with a subform for the orderlines.
ideally what i want is that when i add the customer number into the order header form, it autofills the rest of the form with the customer name and details etc etc....
and same principle... when i add the product number to the order lines form, it autofills the Order ID and part description and sales price, taking the info from the parts table and order header table.....
Now i know for the majority of you guys this is bread and butter, but please explain in the simplest form possible... i am by no means 100% computer literate.
Here is an example from a form I use. It uses Dlookup from a table in the same .mdb file. You enter a part number and then everything else populates after you hit tab:
Private Sub Item_Number_AfterUpdate()
PopulateFields
End Sub
Private Sub PopulateFields()
''''PopulateFields takes the Item Number to fill in all the remaining fields with regards to that Item
Me.Full_Desc = RTrim(DLookup("ITEMDESC", "GP_Parts_List_Import", "ITEMNMBR = '" & Me.Item_Number & "'"))
Me.Item_Type = RTrim(DLookup("ITEMTYPE", "GP_Parts_List_Import", "ITEMNMBR = '" & Me.Item_Number & "'"))
Me.General_Desc = RTrim(DLookup("ITMGEDSC", "GP_Parts_List_Import", "ITEMNMBR = '" & Me.Item_Number & "'"))
Me.Current_Cost = RTrim(DLookup("CURRCOST", "GP_Parts_List_Import", "ITEMNMBR = '" & Me.Item_Number & "'"))
Me.Item_Class_Code = RTrim(DLookup("ITMCLSCD", "GP_Parts_List_Import", "ITEMNMBR = '" & Me.Item_Number & "'"))
End Sub
UPDATE
To get to the VBA part of your application, you press F11 or right click on the control you want triggering the code. After right click, select 'Build Event' and then choose 'Code Builder' to open the VBA Editor window.
The drop down on the left will give you every control you can choose from in that form, and the drop down on the right will give you every event that control has available. So when my text box Item_Number is filled and a user moves on, AfterUpdate is triggered and runs the function PopulateFields.
You'll need to replace the text boxes and table names obviously, and this is only one way to do it. But hope this helps.
I'm pretty new to MS Access. I'm trying to create a simple form that will basically search for a particular record using a textbox, rather than a drop down box. Essentially a user would be able to enter an ID number and retrieve some other related Info. However, I do not want the user to be able to add any new records to the database. I've been able to get the forms to look the way I want them, but I'm not sure where to place the code (do I create a macro, insert the code into the properties of the button?) Any help is greatly appreciated!
I assume that you have bound your form to a table or a query and that you want to be able to enter the ID manually in a textbox, then press ENTER and load that record's data or display an error message if there is no such record.
As dsteele said, make sure that the form's Data property Allow Addtions is set to No to disallow users from adding records.
Then, from the AfterUpdate event of the textbox, add the following code (assuming that your textbox is named txtGoTo):
Private Sub txtGoTo_AfterUpdate()
If (txtGoTo & vbNullString) = vbNullString Then Exit Sub
Dim rs As DAO.RecordSet
Set rs = Me.RecordsetClone
rs.FindFirst "[ID]=" & txtGoTo
If rs.NoMatch Then
MsgBox "Sorry, no such record '" & txtGoTo & "' was found.", _
vbOKOnly + vbInformation
Else
Me.RecordSet.Bookmark = rs.Bookmark
End If
rs.Close
txtGoTo = Null
End Sub
Note that you will have to change the line rs.FindFirst "[ID]=" & txtGoTo to something that is adequate for your data:
"[ID]=" should be replaced by the field you want to search (it could be "[POReference]=" or something else.
if you are searching by a numeric ID, for instance because the field is an autonumber column, then the code is fine.
Otherwise, if the field you are searching on is a string (say PN12-G) then you have to change the code to:
rs.FindFirst "[ID]=""" & txtGoTo & """"
Failing to use the proper quoting (or quoting where not necessary) will result in errors of the kind Data type mismatch....
As a new user, I would recommend that you have a look at the sample NorthWind project database that is either shiped with older versions of Access or available as a template for download from Access 2007.
There a lots of techniques to learn from as a new Access developer, including other ways to implement record navigation.
Set the form property Data/'Allow Additions' to No.
Either in the AfterUpdate event of the textbox, or in the Click event of a button, you can write code or assign a macro to look up and display the record you want.