Using a form to display previous entries and add new ones - ms-access

I'm trying to design a simple wildlife tracking DB, so that when myself or my colleagues spot an animal we can enter its ear tag number via a form. That will either bring us up a list of previous dates/locations that animal was observed, or if it's not in the DB, allow us to enter the new animal and location.
I have two main data tables:
dt_Animal - which stores the ear tag info, species, and other information about that unique animal
dt_Sightings - stores info on when/where animals been seen (linked to dt_Animal in a one-to-many relationship, of course)
What I want is that when you open up the form, you get a box (text or combo) to enter the animal's ear tag ID.
If the ID already exists in the DB, it brings up all the info on that animal and its previous sightings - with the option to fill out any missing info and (of course) to add a new sighting - and it WILL NOT add a new record to dt_Animal - just to dt_Sightings
If the ID doesn't exist in the DB, it creates a new record in dt_Animal and allows you to enter any/all of the other information
Where I'm running into problems is that I don't want duplicate records in dt_Animal - each animal is unique.
So far, I've gotten it so that if the eartagID value you've entered is already present in dt_Animal, instead of just popping up a warning, the form will bring up the associated data in the 'Sightings' subform, so you can see where the animal has been previously as well as add your new sighting.
Any help would be appreciated! I had been getting some help at another forum until the person helping me was banned for a fracas on another thread...!
http://www.access-programmers.co.uk/forums/showthread.php?p=1249087
Thanks!

If you haven't tried it already, I would suggest using a Form for Animals that uses standard text boxes, combo boxes, etc., to display/edit the animals' details and uses a linked Subform control to display/edit their sightings all at once, like this:
The main form is bound to [dt_Animal], so you don't run the risk of creating duplicates in that table if [eartagID] is the Primary Key (which it should be). The "Sightings" subform is bound to [dt_Sightings] and linked to [dt_Animal] by [eartagID], so
it only shows the Sightings for the current Animal
if you add a new Sighting it will automatically link that Sighting to the current Animal (i.e., automatically insert the correct [dt_Sightings].[eartagID]).
Edit
To make searching/adding animals more "seamless", one approach would be to add a text box txtAddSearch and a command button cmdAddSearch to the form header with the following code behind the form:
Option Compare Database
Option Explicit
Private Sub cmdAddSearch_Click()
Dim rst As DAO.Recordset
If Not IsNull(Me.txtAddSearch.Value) Then
Set rst = Me.RecordsetClone
rst.FindFirst "eartagID=" & Me.txtAddSearch.Value
If rst.NoMatch Then
DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
Me.eartagID.SetFocus
Me.eartagID.Text = Me.txtAddSearch.Value
Me.species.SetFocus
Else
Me.Bookmark = rst.Bookmark
End If
Set rst = Nothing
End If
End Sub
Private Sub Form_Load()
Me.cmdAddSearch.Default = True
Me.txtAddSearch.SetFocus
End Sub
When the form first loads you are looking at the first data record, but txtAddSearch has the focus:
You type in an EarTagID and hit [Enter]. If the record already exists then you are taken to it...
...and if the EarTagID doesn't already exist you are taken to a new record (with that EarTagID already filled in) so you can add the details:

Related

Adding records to table without using inline query in VBA/Access

I am completely new to VBA. I have been told to add records to a table by using a form and a Save button and given some very basic instructions. While I have achieved this with inline query, I have been told to follow some strict methods like usage of QueryDef/QueryDefs and .Parameters.
So far I am trying a very basic project, just to grasp the concepts, but I am unable to add any record to an empty table. In case the table is not empty(I manually enter a record), whenever I click the Save button for saving newer records, the number of records added are somehow doubling with each instance. For example, when I Save for the 1st time, 1 record is added, 2nd time 2 records of the same type is added, 3rd time 4 are added and so on.
The table(tbl_test) has 2 fields --> ID(primary key), Source(Long Text) and Reg No (Number).
The query(qry_test) is made with the Append feature and I have been told to add expressions which makes the code like this -
INSERT INTO tbl_test ( Source, [Reg No] )
SELECT [strSource] AS Expr1, [lngRegNo] AS Expr2
FROM tbl_test;
The form has 2 fields for Source(txt_Source) and Reg No(txt_RegNo) which have blank Record Sources (Unbound). The Save button has the following Event Procedure -
Private Sub btn_save_Click()
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("qry_test")
qdf.Parameters("strSource") = Me.txt_Source
qdf.Parameters("lngRegNo") = Me.txt_RegNo
qdf.Execute
End Sub
I have zero knowledge about VBA and would gladly accept ANY help. It would be great if I get any sort of source code that will explain to all the details about saving records from forms and editing them using these querydef, parameter and recordset stuff.
Welcome to StackOverflow!
If you are using a form to collect data for records that are stored in a table, running a saved append query by QueryDefs to do this is, in my opinion, not the best method.
Whilst an append query does add new records to an existing table, I would tend to use an append query where I've got multiple established records that I want to add to an existing table.
If I'm setting up a data entry form that is designed to collect new data for new records 1-at-a-time, an append query doesn't really suit this purpose.
Instead, there are a number of features built in to the design of MS-Access forms to help collect data and save it to a table. This is because forms are very much intended to be set up so that users can interact with records from a table in a controlled, user-friendly way rather than interact directly with the table object itself.
The first and most important feature of a form in this context is probably the form's record source property. When you create a new form, go in to design view for the form and open the form's property sheet (F4 key). In the "Data" tab of the form's property sheet you'll find the record source property:
The record source essentially connects your form with a set of records, whether those be records in a table object, a query object or an sql query string.
In your case it would be better, in my opinion, to bind your tbl_Test table to your form by referring to it in your form's record source:
It will seem like nothing has happened to your form, but if you now open the "Add Existing Fields" panel (alt + F8), you'll notice that the fields associated with your tbl_Test table are available to you:
Drag them to the detail section of your form...
Then put your form in to Form View:
Essentially what you and your users are seeing is the first blank record in your tbl_Test, but displayed on a form instead.
Entering data in these fields on the form...
...will put that data in to the table we specified in the form's record source...
So hopefully you can see that setting the form's record source property to that of your table, is much cleaner than trying to get an append query to collect data from your form and deliver it your table.
At this point you're probably asking a few questions:
When I have filled in the fields for a record on my form, how do I save that record?
More can be said about this, but for brevity, I'd recommend using a command button for running some vba to save the record; similar to what you've done, but utilising the form's Dirty property instead using an append query:
Here's the click event VBA for my save button example:
Private Sub cmdSave_Click()
If Me.Dirty Then
Me.Dirty = False
End If
End Sub
Me.Dirty is a Boolean (True or False) setting for the form; essentially it is automatically set to True when a user changes something on the form. To save those changes, the Me.Dirty setting will have to be set to False.
Me.Dirty is a bit like the swing gate on a sheep pen. When a shepherd puts a sheep (data) in the pen (form) they will open the gate to the pen. The open gate is like the form's Me.Dirty being set to True. To lock the sheep (data) in, the gate needs to be closed, or in the case of forms, the Me.Dirty property needs to be set to False. The VBA above essentially checks to see if the gate was opened and if it was to close it.
How do I move to a new record in the form once I have saved the current one?
Again, I'd give the user a command button to do this and run some VBA on its click event:
Here's the VBA for moving to a new record:
Private Sub cmdNew_Click()
DoCmd.GoToRecord , , acNewRec
End Sub
Summary
There is a lot more to consider than what I've outlined here, such as:
validating data before it is saved
checking other form events (such as close) to ensure data entry is not lost
navigating to an existing record
But hopefully what I've given you here is at least pointing you in a better direction. Best of luck!
Access is optimized for bound forms. Unbound forms are for special cases only.
Should you prefer unbound forms (could be for many reasons), Access isn't worth the trouble, and you should turn to Visual Studio and WinForms.
In either case, browse for a beginner's tutorial.
If you want to use an unbound for or unbound controls you can create the SQL string in the procedure:
Dim mysql as String
mysql = "INSERT INTO tbl_test ( [source], [reg_No]) VALUES (Me.txt_Source, Me.txt_RegNo)
DoCmd.RunSQL mysql

Can't add record with ID from another table

I have a database which functions similarly to a "help desk" system - an outside user creates a request ticket, then a consultant will use the database for various tracking and reporting.
There is a form that the consultant uses to display and work with the end user request. They select an existing record (request ticket) from a combo box. The form then populates with the information of the request, which the consultant can edit if needed.
I then have a series of buttons on this form that the consultant can use to open different forms (worksheets) and enter data in each one. These are all optional and will vary based on the type of request.
These worksheets all populate the "Consulting" table, while the initial requests are in a "Request" table. There is only one record in the "Consulting" table per record in "Request" (1:1 relationship).
Here is the code I have to open the forms (worksheets):
Private Sub ButtonGap_Click()
DoCmd.OpenForm "Gap Analysis", acNormal, , "[ID] = " & Me!ID, acFormEdit, acDialog
End Sub
This only partially works. If there is existing information in the "Consulting" table with an ID that corresponds to the ID from "Request" (what they selected in the combo box at the start), the worksheet will open pre-populated and editable. Great!
But... if there is no existing information in the "Consulting" table with an ID that corresponds to the ID from "Request", the worksheet opens blank, to a new record. This record autonumbers from where the "Consulting" table left off. This creates a problem if several requests have come in - we are not always working on them in order, so the new record ID in "Consulting" does not match the existing record from the "Request".
I'm sure it's something incredibly simple I'm overlooking. Can anyone help?
I was able to find a way to do this, it appears. If I missed something, please let me know! I don't want to break anything else. :)
I created a query to find the unmatched records, giving me a list of all IDs from Request without a matching ID in Consulting.
From there, I based an append query on these results, to append just the missing IDs to Consulting.
That query runs when the Request form is submitted:
Private Sub Form_AfterUpdate()
DoCmd.OpenQuery "Add Blank Consulting"
End Sub
Now my worksheets on the Consulting form are populating with the correct ID!

How can I use the results of a query in VBA to update a table?

I am sure I am approaching this incorrectly since there has to be a design issue with the database but I am willing to try anything right now.
On a form I have a main subform containing a drop down of different types of lands and two buttons (Prev and Next). This subform data source is a table called Section22_PMLU
Nested in this subform is another subform linked to the parent subform using the PMLU_Code. This data is being updated to table Section22_Data.
When a user clicks the drop down on the parent subform and makes a land selection and then chooses details (characteristics of land) in the child subform this data is correctly displayed in the Data table. Even if the user clicks the drop down again (w/out creating a new record) and adds child records this is reflected in the data table.
The issue is with the PMLU table. If I initally make a selection and add data from nested subform this record is recorded/displayed in the PMLU table. If I click in the drop down field and click "Add New Record" or press Ctrl+ and then choose a new item from drop down - it is recorded/displayed correctly in the table. HOWEVER if I make a selection without creating a new record first this item copies over the one added previously. WHen I attempt to go back (prev button) to see the record it is not displayed. However it is still in the data table.
In order to correct this issue I have to go directly into the PMLU table and add the missing PMLU codes that match the PMLU codes found in the data table.
If I run the following query I get those missing PMLU's. How can I use the results to populate the PMLU table with the missing codes
SELECT Section22_2_Data.PMLU_Code, Section22_2_Data.PMLUType
FROM Section22_2_Data LEFT JOIN Section22_2_PMLU ON Section22_2_Data.[PMLU_Code] = Section22_2_PMLU.[PMLU_Code]
WHERE (((Section22_2_PMLU.PMLU_Code) Is Null))
I used the following code to refresh the table which fixed the issue
Private Sub btnRefresh_Click()
Dim strSQL As String
strSQL = "INSERT INTO Section22_2_PMLU ( PMLU_Code )
SELECT DISTINCT Section22_2_Data.PMLU_Code
FROM Section22_2_Data LEFT JOIN Section22_2_PMLU ON Section22_2_Data.[PMLU_Code] = Section22_2_PMLU.[PMLU_Code]
WHERE (((Section22_2_PMLU.PMLU_Code) Is Null));"
CurrentDb().Execute strSQL, dbFailOnError
' Next 3 only to ensure the append is commited to the table '
' before requerying '
DoEvents
DBEngine.Idle dbRefreshCache
DoEvents
Me.Requery
End Sub

How to get rid of adding new record at the end of a subform?

I use a subform to show the result of a query, but at the end of record there is a *(New) for adding new records. I don't want the user to be able to add new records through this subform. How can I get rid of this?
With the subform in Design View, open its property sheet. Then select the Data tab on the property sheet, find the property named "Allow Additions" and set it to No.
The "Allow Additions" property will not display if you open the design view of the parent form and click on the subform. The subform must be opened in Design View independent of the parent form.
Had exactly the same problem.
My DB is to keep track of basketball box scores. Every new main form created a new blank subform to enter the quarter scores into. The problem was as I Entered through the fields once I hit enter on the last quarter score value a new record was created for the table that Quarter Scores was based on.
I could not use Allow Additions = no. If I did not allow additions there was no quarter score input created when a new main form (for a new game) was created.
I used the code below for a key down event of the Enter key to set the focus on another subform before a new quarter score record was created.The commented lines were to help trouble shoot when creating the code. Key code 13 is the Enter key.
Hope this helps someone, took a while to get this right.
Den
Private Sub HOT2_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode <> 13 Then Exit Sub
'MsgBox "Enter Pressed"
KeyCode = 0
'MsgBox "KeyCode=0"
Forms!FRM_BoxScores.Scrimmage.SetFocus
Forms!FRM_BoxScores!subform_qryReturnVisitingPlayers_BosScores.Form!subform_tblPlayerPoints_BoxScores.Form!PlayerPoints.SetFocus
End Sub
Change Record-set Type to Screenshot in Data Form Properties > Data Tab. Please note user cannot change any Data in form you once you change this
in your subform design grid, open the properties.
Where is says recordset type, set it to snapshot. That will remove that line.
The recordset will NOT be updateable at that time. So if you want to edit records, you have to change it back

Access 2007 Filter Subform Based On Field In Main Form?

I was tasked with creating a simple app to maintain a user's collectibles collection using Access 2007. There were some requests, which I have created and implemented. Those being:
One main form listing all of his collectibles
That same main form has a tabbed control below, with each tab containing a subform that in effect "filters" data based on different criteria from the main form. For example, the 1st subform takes the name of the collectible figure in the main form, and displays all other records using that name in the subform. In other words, if the figure is "Darth Vader", the subform would list all collectibles that have the name "Darth Vader".
I have created the application as per user request, but there is one thing that is bothering both of us so far. The subform's first record is the same as the main form. We both find that redundant, and annoying. Granted, my Access skills is weak at best, so this may be a simple fix, but is there a way to remove the duplicate record in the subform? I have tried implementing a where clause in the subform stating to not include the "Figure ID" in the main form. Problem is, it is acting like a Parameter prompt, asking for the main form's FigureID when I open the subform, or the main form. If I type in the Figure ID, it works, but the prompt is something that is obviously not wanted.
FYI:
The main form is based on a query that basically selects all records from the "Figures" table and other related tables
The subform was created when I dropped the subform control onto the tab control, where I linked the necessary master and child fields
Say you have a form named frmMain. That form includes two fields in its record source: FigureID; and Figure_name. The form also includes a text box control named txtFigureID which is bound to the FigureID record source field.
frmMain also contains a subform control based on a form named frmSub. The record source for frmSub also includes FigureID and Figure_name fields. The subform control's link master/child field property is Figure_name. Therefore frmSub will display all the rows where Figure_name matches the corresponding value in the frmMain's current record.
Now, if you want frmSub to exclude the specific record (as identified by the unique FigureID value) which is the current record in frmMain, add a WHERE clause to frmSub's record source query:
WHERE FigureID <> Forms!frmMain!txtFigureID
I'm only guessing here, but hope that description is close enough to your actual situation to be useful. If not, show us the SQL you're using as the record source for your subform.
Edit: You get the parameter prompt only when you first open frmMain. Afterwards, you can navigate between records in frmMain, and frmSub shows you only the records you want to see ... without asking you again to supply a parameter value.
The reason that happens is because the subform loads before its parent form ... so a control on the parent form is not available when the subform loads.
I think the cure may be to save the subform without the WHERE condition in its record source. Then, when the main form loads, it can re-write the subform's record source to include the WHERE condition.
So, in frmMain's load event:
Private Sub Form_Load()
Dim strSql As String
strSql = "SELECT FigureID, Figure_name FROM YourTable" & vbCrLf & _
"WHERE FigureID <> Forms!frmMain!txtFigureID"
Debug.Print strSql
Me.subformControlName.Form.RecordSource = strSql
End Sub
Watch out for subformControlName. It's a control, not a form. The subform control may have the same name as the form it contains. But it could be a different name.