I am creating a user interface based off of one internal and two linked (external) Access datasheets in Access 2013.
Two of the fields on my UI are combo boxes that read from the linked datasheets and display the options. This is so that the entries for suppliers and material types are called-out consistently and typos are avoided. However, I would like to add the following functionality:
-If a new value is entered into the combo box the user will be prompted to fill out the necessary information on the new value. This information will subsequently be saved to the appropriate linked datasheet.
How would I go about setting up the prompt from the combo boxes themselves? It would require Access to open a form or sub-form that will, in turn, save to the linked datasheet.
I'd prefer it to be automatic, instead of end-user prompted so that it isn't skipped. It's been years since I played around with VB, so I would like to avoid that if possible and use Access' built-in functions (even if it requires a little more time). Thank you in advance!
Alright, so I was able to do it after researching the "OnNotInList" function and a little VB code.
In the OnNotInList section of the 'Event' properties sheet, I chose 'Code Builder' and entered the following:
Private Sub Supplier_NotInList(NewData As String, Response As Integer)
Dim ctl As Control
Dim dbsCustomerDatabase As Database
On Error GoTo Supplier_NotInList_Err
Dim intAnswer As Integer
Dim strSQL As String
intAnswer = MsgBox("The supplier " & Chr(34) & NewData & _
Chr(34) & " is not currently listed." & vbCrLf & _
"Would you like to add it to the list now?" _
, vbQuestion + vbYesNo, "Spire Manufacturing Solutions")
' Adding the new entry to the list:
If intAnswer = vbYes Then
strSQL = "INSERT INTO CustomerList([CustomerName]) " & _
"VALUES ('" & NewData & "');"
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
MsgBox "The new supplier has been added to the list." _
, vbInformation, "Spire Manufacturing Solutions"
Response = acDataErrAdded
' Opening the Supplier datasheet to add details
' to the new entry:
MsgBox "Opening Supplier database for new entry..."
DoCmd.OpenTable "CustomerList", acViewNormal, acEdit
End If
Supplier_NotInList_Exit:
Exit Sub
Supplier_NotInList_Err:
MsgBox Err.Description, vbCritical, "Error"
Resume Supplier_NotInList_Exit
End Sub
This allowed me to automatically prompt the user to add the details for a new supplier if they enter a new supplier name. Or, cancel the entry if they simply misspelled it. I'd quite forgotten how versatile VB was. Thank you all for your assistance in getting me headed in the right direction!
Related
I'm having issues with my Microsoft Access project.
The project comprises of two forms called, InfoForm and SearchBox.
InfoForm form
The InfoForm form is the primary-form, and has the following:
Custom navigation buttons, which are; Next and Prev
A custom Search button, which opens up the SearchBox form.
SearchBox form
The SearchBox form is used to browse and open individual records, and has the following:
List of available individual records
Open button
Individual records
The individual records open into the InfoForm form.
I use this code on the Open' button of theSearchBox` form, as follows:
Private Sub Command1_Click()
Dim strLN As String
strLN = Me.SearchResults.Column(0)
Dim strGN As String
strGN = Me.SearchResults.Column(1)
Dim strMN As String
strMN = Me.SearchResults.Column(2)
DoCmd.OpenForm "InfoForm", acNormal, , _
"[Last Name] = '" & strLN & "' And " & _
"[Given Name] = '" & strGN & "' And " & _
"[Middle Name] = '" & strMN & "'"
DoCmd.Close acForm, "SearchBox"
End Sub
This code works perfectly when the InfoForm form is first opened, right up until an individual record is opened.
At this point, the navigation buttons "Next" and "Prev" on the 'InfoForm' form stop working.
Please help. Thank you.
As #Andre noted, if the form is filtered to a single record then there are no succeeding or previous records to navigate to. Does your filter criteria result in a single record dataset?
An alternative is to open the form unfiltered (or with a filter that returns a restricted dataset but will usually still have multiple records) and 'go to' the desired record, then there will be succeeding and preceding records to navigate. Example from my code:
To open form:
DoCmd.OpenForm "Samples", , , , , acDialog, strLabNum
Then code behind the opened form:
Private Sub Form_Open(Cancel As Integer)
Me.RecordsetClone.FindFirst "LabNum='" & Me.OpenArgs & "'"
Me.Bookmark = Me.RecordsetClone.Bookmark
End Sub
I have a form control (address) that uses Dlookup to call info from a table "database" but the form is bound to table "Tracker". The dlookup is based on another control on the same form - "Name" I need the form to record this dlookup control, along with other controls that are bound to "tracker" as new recordto the table "tracker."
My failed attempts:
Using the default value property to assign the recalled data from the dlookup to another text box which would be bound to "tracker" This simply does not work for some reason. Perhaps I am missing something that tells this control "Address" to update upon selecting the correct "name?"
Code:
Private Sub SubmitReferral_Click()
On Error GoTo Err_SubmitReferral_Click
DoCmd.GoToRecord , , acNewRec
Exit_SubmitReferral_Click:
Exit Sub
Err_SubmitReferral_Click:
MsgBox Err.Description
Resume Exit_SubmitReferral_Click
End Sub
I also tried this - to assign the data - but the data from the dlookup in control "Address1" is not transferring/copying to control "Address2"
Private Sub Combo276_OnUpdate()
OnUpdate ([Address2].Value = [Address1].Value)
End Sub
Help or suggestions?
PS - I have tried to Edit per request to be as specific as possible, and to follow proper board etiquette.
Still unsure of your field names, etc., but the following is an example you can modify. Change 'tblEmployee' to 'database'.
I must state that if you are just starting out with developing in Access (or VBA) that you should never use names that are reserved words, or that can be misleading. Your table named 'database' is ok if named 'tblDatabase'.
Option Compare Database
option Explicit
Private Sub cmdInsert_Click()
Dim strSQL As String
Dim i As Integer
Debug.Print "cmdInsert; "
i = MsgBox("Do you want to add 1 row for Employee ID: " & Me.EmpID & " to table 'tracker'?", vbYesNo, "Confirm Add")
If i = vbNo Then
Exit Sub
End If
DoCmd.SetWarnings True
strSQL = "INSERT INTO tracker ( FirstName, LastName, Add1, City, St, Zip ) " & _
"SELECT tblEmployee.FirstName, tblEmployee.LastName, tblEmployee.Add1, tblEmployee.City, tblEmployee.St, tblEmployee.Zip " & _
"FROM tblEmployee " & _
"WHERE (((tblEmployee.EmpID)=" & Me.EmpID & "));"
DoCmd.RunSQL strSQL
End Sub
Thanks for the help - I solved my concern by hiding the fields that contain the dlookup, and putting code behind a button that copies the information to fields that are bound and therefore will record to the table "tracker"
Recently started learning Access and I'm a bit stuck on deleting records within a form. I have a list with the following code:
Private Sub lstPickList_AfterUpdate()
Dim rst As DAO.Recordset
Set rst = Me.RecordsetClone
rst.FindFirst "OrderID=" & lstPickList.Column(0) & ""
If rst.NoMatch Then
MsgBox "The selected record can not be displayed." _
& "To display this record, you must first turn off record filtering.", _
vbInformation
Else
Me.Bookmark = rst.Bookmark
End If
Set rst = Nothing
End Sub
And a button that I would like to use to delete whatever Order is currently selected on the list. The "DeleteRecord" macro just gives me a "The command or action 'DeleteRecord' isn't available now." error. Searching has given me a bunch of code that hasn't worked for me at all.
You can delete directly from the clone:
If rst.NoMatch Then
MsgBox "The selected record can not be displayed." _
& "To display this record, you must first turn off record filtering.", _
vbInformation
Else
rst.Delete
End If
I am trying to set the value of a text box based on the value I select in a combo box and a pre-existing value in another text box. Both the controls are in a continuous subform within a form. One key was to save the record OnDirty for Combo1, then execute the code to update TextBox1 AfterUpdate. Everything works, except that I get the following error message every time I change a value in Combo1:
Run-time error '2115':
The macro or function set to the BeforeUpdate or ValidationRule property for this field is preventing Database from saving the data in the field.
If I click 'End' on the error message, I'm fine. I have no validation rules on any elements on any of the tables connected to these forms. I am not using either the BeforeUpdate or ValidationRule properties on either the form or subform.
The code now looks like this:
Private Sub Combo1_Dirty(Cancel As Integer)
DoCmd.RunCommand acCmdSaveRecord
End Sub
Private Sub Combo1_AfterUpdate()
DoCmd.RunCommand acCmdSaveRecord
Dim con As ADODB.Connection
Set con = Application.CurrentProject.Connection
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
ssql = "(SELECT TABLE1.DESCRIPTION As d1 " & _
"FROM TABLE1 " & _
"INNER JOIN TABLE2 ON " & _
"(TABLE1.CATEGORY = TABLE2.CATEGORY) " & _
"AND (TABLE1.LEVEL = TABLE2.LEVEL) " & _
"WHERE " & _
"(((TABLE1.LEVEL)= " & [Forms]![MainForm].[Subform].Form.Combo1.Value & ") " & _
"AND ((TABLE2.CATEGORY)= '" & [Forms]![MainForm].[Subform].Form.[CATEGORY].Value & "'));)"
rs.Open ssql, con
Do Until rs.EOF = True
[Forms]![MainForm].[Subform].Form.TextBox1.SetFocus
[Forms]![MainForm].[Subform].Form.TextBox1.Text = rs.Fields!d1
rs.MoveNext
Loop
End Sub
When I click 'Debug', it highlights this line of code:
[Forms]![MainForm].[Subform].Form.TextBox1.Text = rs.Fields!d1
Again, neither the TextBox1 control or the data element underneath it have any Validation rules set, and my code is not using any BeforeUpdate (actually, not using that anywhere in the database). Any ideas why I'm getting an error, even though it's working otherwise?
Any help is greatly appreciated. Thanks!
Firstly, Dirty is called before BeforeUpdate, which is called before AfterUpdate,
so you don't need to save the record in Dirty and in AfterUpdate, I would just ditch the code for Dirty altogether since it's not really adding anything.
Try:
[Forms]![MainForm].[Subform].Form.TextBox1.Value = rs!d1
instead of
[Forms]![MainForm].[Subform].Form.TextBox1.SetFocus
[Forms]![MainForm].[Subform].Form.TextBox1.Text = rs.Fields!d1
Also, is there a particular reason you're looping through the whole recordset just to set one textbox? Does the textbox have a control source?
Wouldn't it be easier to change the subform's recordsource to rs?
Hello I just want to know on how to make a continuously questionnaire form in access that will update all the table once all the question have been filled. but before it reached end of the page, the user will be able to edited back and forth from forms to forms.
so it will be like this:
Total 30 forms
One form only update 1-3 fields in the table
Once the user finished with one form, the form will close and open another form.
The user will be able to back to previous form and edit it.
The buttons that it available only 2 buttons back arrow and next arrow(save data and move to another form and close current form)
The last form will save all the data.
When user finished all the question, the form will allows to be reopened from the first one and it will insert entirely new line of user data in table.
The one that i have done is
I create a form, with a box and tag, connected directly to the table, so it will updated in real time. so user can back and forth to edit it
"Next" button, using macro to close and open new form.
Final form using the folowing VB code to update the table:
Private Sub Close_Click()
CurrentDb.Execute "INSERT INTO Demographics(vid, cid, dobd, gend, heght, heght2, wgt, wgt2, lschool, secschl, qualify, hqlify, army, abranch )" & _
"VALUES('" & vid1 & "','" & cid1 & "','" & dobd1 & "','" & gend1 & "','" & heght1 & "','" & heght21 & "','" & wgt1 & "','" & wgt21 & "','" & lschool & "','" & secschl1 & "','" & qualify1 & "','" & hqilfy1 & "','" & army1 & "','" & abranch1 & "')"
cmdClear_Click
cmdClose_Click
End Sub
Private Sub cmdClose_Click()
DoCmd.Close
End Sub
Private Sub cmdClear_Click()
vid1 = ""
cid1 = ""
dobd1 = ""
gend1 = ""
heght1 = ""
heght21 = ""
wgt1 = ""
wgt21 = ""
lschool1 = ""
secschl = ""
qualify = ""
hqlify = ""
army = ""
abranch = ""
End Sub
Private Sub Form_Current()
End Sub
Problem:
Final page script above wouldnt insert the data into the table at all.
It can insert data into table, if i indexed the column in the table, but it will end up messy if i did a lot of updates
My Questions:
Can anyone suggest me the correct VB script to do this continuously form activity, instead of update entire table per-form.
How do I create a form like in access 2003 on which i can create switchboard with login for user only, and special login access to the database only for administrator, so it will like an application. (im using Access 2010 .accdb file)
sorry for the long post, just want to make sure everything is clear, any answer would be greatly appreciated.
Thank you in advance
Regarding your first question:
This is one of those cases where a bound form could prove to be handy.
You can use INSERT INTO, but you'd need to generate a different query for each form in order to avoid errors. If you set all of your forms to bind to the same table, though, the form fields can interact directly with the table without requiring a lot of code.
Try the following example, using 3 forms (though you can easily extend this out to 30 forms).
Each form has:
A hidden field, ctlID (bound to the table's ID field)
Any number of other fields, bound to matching fields in the table
A 'Next' button, cmdNext (or in the case of the last form, cmdFinish)
You can use the WhereCondition argument of DoCmd.OpenForm to keep referring to the same record across multiple forms.
Here's the code:
' Form1 code:
Private Sub Form_Load()
DoCmd.GoToRecord , , acNewRec
End Sub
Private Sub cmdNext_Click()
Dim iID As Long
iID = Me.ctlID.Value
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "Form2", , , "ID = " & iID
End Sub
' Form2 code:
Private Sub cmdNext_Click()
Dim iID As Long
iID = Me.ctlID.Value
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "Form3", , , "ID = " & iID
End Sub
' Form3 code:
Private Sub cmdFinish_Click()
DoCmd.Close acForm, Me.Name
End Sub