Can't add record with ID from another table - ms-access

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!

Related

How to Prefill form from another DB based on the field value

I'm trying to create a solution to fetch data for a new record of SmallDB from secondary BigDB.
I created a linked table of BigDB to have it on SmallDB, so later I could use OnClick event of Button and it would be easier to reach that data.
Situation: I search form for the PersonID, but get negative result (this particular PersonID doesn't exist).
Then, in the form I create new record and enter this new Person ID in the PersonID field.
My plan is to be able to click FetchData button and pre-fill Name, Last Name and other details to the form from BigDB for this particular PersonID.
Then I would save the record with save button.
It looks to me, that solution could be similar to: https://stackoverflow.com/a/53180365
But I don't know how to ensure that I would get data from BigDB only for that particular PersonID that I entered into Form field.
Or perhaps in my situation another method would work better?
Thank you!
Following example code from link referenced in question, apply filter criteria to query object via PARAMETERS. However, unless you have query object set up with PARAMETERS clause, I don't see need for QueryDefs and instead of referencing query object, can use SQL statement in code.
Assuming PersonID is a text type field:
Dim db as Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM tablename WHERE PersonID='" & Me.tbxPID & "'")
If Not (rs.EOF And rs.BOF) Then
If you are not on new record row of form, either first move to it manually or with code, or use another approach. An INSERT SELECT action SQL can create a new record in SmallDB with data from BigDB.

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

Using a form to display previous entries and add new ones

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:

How to directly update a record in a database from a form number (Access 2007)

I have a job-tracking system, and there is a query that returns results of all jobs that are overdue.
I have a form that displays each of these jobs one-by-one, and has two buttons (Job has been completed, and Job not completed). Not completed simply shows the next record.
I cannot find a way to get access to the current record to update it's contents if the "Has been Completed" button is pressed, the closest I can get is the long number which represents the records position in the form.
The VBA to get the index of the record in the form is as follows.
Sub Jobcompleted(frm As Form)
Dim curr_rec_num As Long
curr_rec_num = frm.CurrentRecord
End Sub
This is my first shot at VBA, and after an hour of searching I cannot find anything to solve my problem.
Am I going about this the entirely wrong way? Working in Microsoft Access 2007
Further Info All tables are normalized
Vehicle Table: Contains vehicle_id(pk), as well as rego and model etc
Job Table: Contains job_id(pk), vehicle_id(fk) and other info about what needs to happen, as well as the next occurance date, days between each occurance of the job (all jobs repeat) and other info
Job History Table: Contains job_history_id(pk), job_id(fk), date completed and comments
When the job completed button is pressed, it should create a new entry in the job history table with the current date, any comments and the job id
This is the script I am trying to get working
Private Sub Command29_Click()
Dim strSQL1 As String
Dim strSQL2 As String
Set Rs = CurrentRs
Set db = CurrentDb
strSQL1 = "INSERT INTO completed_jobs(JOB_ID, DATE_COMPLETED, COMMENTS) VALUES " & Rs!job.ID & ", " & Date
db.Execute strSQL1, dbFailOnError
strSQL2 = "UPDATE job SET JOB_NEXT_OCCURANCE = JOB_NEXT_OCCURANCE+JOB_RECURRANCE_RATE WHERE job.ID = Rs!job.ID"
db.Execute strSQL2, dbFailOnError
End Sub
Note: Line Set Rs = CurrentRs is completely incorrect, I believe this is what I need to figure out? This is called on button-press
I am posting an image which shows the form (non-continuous).
#HansUp, I get what you are saying, but I dont quite think it's applicable (I did not provide enough information first time around for you to understand I think)
#sarh I believe this Recordset that you are talking about is what I need, however I cannot figure out how to use it, any hints?
#Matt I am 90% sure I am using a bound form (Like I said, new to Access, been looking at everything people have suggested and learning as I go). There is of course an ID for the job (Just not shown, no need to be visible), but how would I access this to perform an operation on it? SQL I can do, integrating with Access/VBA I am new at
As I understand your situation, your form is data-bound bound (you can get record index), so - your form already located on this record. If you need to update some field of underlying dataset, you can write something like
Me!SomeField = ...
DoCmd.RunCommand acCmdSaveRecord
If your form has control bound to "SomeField", then the form will be updated automatically.
If this will not help, you can look to a couple of another directions:
1) Update records using SQL code. For example, you have ID of record that should be updated in the form data set, so you can write something like:
Call CurrentDB.Execute( _
"UPDATE SomeTable SET SomeField = SomeValue WHERE SomeTableID = " & Me!SomeTableID, dbSeeChanges)
2) You can look at the Bookmark property - both Recordset and Form has this property, it describes the record position. So you can write something like this (not the best example, but can help you to get an idea):
Dim Rs as Recordset
Set Rs = Me.RecordsetClone 'make a reference copy of the form recordset
Rs.Bookmark = Me.Bookmark 'locate this recordset to the form current record
Consider a simpler approach. I doubt you need to be concerned with the form's CurrentRecord property. And I don't see why you should need a command button for "Has been Completed" and another for "Has not been Completed".
Add a "Yes/No" data type field to the table which is used by your form's record source. Set it's default value property to 0, which represents False or No. Call it "completion_status". Create a new form using that record source. Then your form can have a check box control for completion_status.
Newly added records will have False/No as completion_status --- the check box will appear unchecked. The completion_status for other records in the forms can be toggled between Yes (checked) and No (unchecked) using the check box control.

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.