MS Access popup form conditional on combobox value - ms-access

I am working on a database to store a heap of animal behavioural observation data and am working on creating a form to input data (one of many forms). The main form feeds into a table called "FocalSample" and the subform feeds into a "FocalData" table.
This is the form at present
There will be multiple records in the subform to a single overarching sample, a sample is a 10 minute period and a single animals behaviour is documented over that 10 minutes, noting time in minutes and seconds to calculate duration of time spent in each behaviour.
I need popup forms to come up depending on what is selected in the "Behaviour Type" field of the subform, as the kind of data recorded for a "feed" observation compared to a "social" observation is very different. I have created separate tables for the different behaviour types of data and forms that are set as "popup" forms, but need help with the code to get it to do what I need! :P
I have been trying a variation of the following code that I found here (http://www.justskins.com/forums/pop-up-form-based-238440.html)
Private Sub Campaign_AfterUpdate()
Dim strFormName As String
Select Me.Campaign.Value
Case "In Honor", "In Memory"
strFormName = "HonorMemory"
Case "In-Kind"
strFormName = "InKind"
End Select
DoCmd.OpenForm strFormName, , , , , acDialog
End Sub
But I keep getting an error message after the first row.
Here is the error and code screen
Similar to the other forum link I attached, I also need the popup form to draw a lot of info from the main form, but I'd just be happy to be able to get the popup forms working at the moment.
Sorry for so much detail - I am in a remote area of Africa and only have limited access to internet so am trying to give as much info up front!
Example of popup form - you might be able to determine fields that will feed off the focalsample form
Another example of a popup form - different behaviour type to the previous
EDIT
I have jigged the code now based off previous response but am not getting a different error.This is the code with the error line highlighted - I am not sure what table name to add if any
Error code

The line Select Me.Campaign.Value should read Select Case Me.Campaign.Value.

Related

How to populate data in a one to many relationship between two forms when the target form's table has no matching entry?

This is probably a dumb question, but I'm a noob, so forgive me. I have two tables with a one to many relationship based on a OrderNumber. Essentially, I have some order details in one table, including OrderNumber (the one side of the relationship) and I am trying to get a list of LotNumbers in the other table using the OrderNumberLot (the many side) to link them together, as there can be many lot numbers on one order. The primary key in tblOrderDetails is OrderNumber and the primary key in tblLotNumber is LotID (auto number), but the linked field is OrderNumberLot. I made a open form button located on frmOrderDetail to open frmLotNumbers (based on the tblLotNumber). The deal is when frmLotNumber opens the OrderNumberLot field is blank. I understand there is no associated record in tblLotNumber, because I am trying to enter it, but how do I get the OrderNumber from the previous form, frmOrderDetail, with the button to automatically populate in the OrderNumberLot field in frmLotNumbers? I certainly don't want people to have to type it, because they will screw it up as badly as I have this explanation of my question! Thanks in advance for the help.
I agree with June7 on using a subform-approach for your purpose.
If you already have created the form, you could simply drag it from the sidebar onto your mainform and set the "Link Master Fields" and "Link Child Fields" to "OrderNumber" and "OrderNumberLot" - or you just use the subform-wizard and follow its instructions.
Though, some people dislike subforms in general and try to avoid them whenever possible - which might make sense at further stages of development. Instead of subforms, you could then use vba to transfer information from one form to another.
Lets say your button is named bt_openform
Private Sub bt_openform_Click()
'Open the desired form. The option "acFormAdd" forces the form
'to add a new entry whenever loading and requerying.
'As we want to add a new record, we will not use the filter settings
DoCmd.OpenForm "frmLotNumber", , , ,acFormAdd
'Next, store information from the initial form into the newly opened form
'To refer to data from the current form (meaning the one, in which the Sub is triggerd),
'you can use "Me.fieldname" and to refer to another form, use "Forms!formname!fieldname"
Forms!frmLotNumber!OrderNumberLot = Me.OrderNumber
End Sub
You could also do it the other way around and retrieve the information when loading the form:
Private Sub Form_Load()
Me.OrderNumberLot = Forms!frmOrderDetail!OrderNumber
End Sub
To be on the safe site, one might want to nest this function in an if statement, to check whether frmOrderDetail is open or not. This way, you can open your frmLotNumber from different forms without causing troubles
If CurrentProject.AllForms("frmOrderDetail").IsLoaded Then Me.OrderNumberLot = Forms!frmOrderDetail

How to autofill tableA-fieldA based on tableA-fieldB by getting the data from tableB?

First, some context: I am used to working with Excel, and I have been using it to create production calculators for my worldbuilding hobby. Due to some recent problems with excessive amounts of data needing calculation, I have finally given in and tried switching it all into Access.
I have been doing some readings on how to use Access, and based on that I decided on the following:
1) I have a temperature table for regions (boreal, temperate...) with specific production levels (1,2...)
2) I have a precipitation table for regions (wet, arid...) with specific production levels (1, 2...)
3) I then have a biome table where I mix the above regions to create my biomes with the following fields:
- Biome.
- Precipitation (dropdown menu from table 2).
- Temperature (dropdown menu from table 1).
- Productivity level (which should be Precipitation Production Level from Table 2 times the Temperature Production Level from Table 1).
QUESTION: How can I have the Productivity Level in table 3 be automatic?
NOTE 1: I don't know VBA and this is my first time working with Access.
NOTE 2: I habe been told to just create table 3 as a form, but I do not think that works with what I want to do. Just in case it may be relevant (and I am not seeing the obvious), I'll next describe my first goal at building this database.
DATA ENTRY FORM: all the tables referenced below are connected by the concatenation of latitude-longitude. I have only built it partially (main form and city subform) successfully.
- main form based on table with 3 fields: latitude, longitude, terrain.
- subform based on table with 3 fields: city name, foundation date, collapse date.
- 3 subforms based on 3 tables, each representing a time period, with 2 fields: biome (biomes change in a given area depending on time periods), and its productivity levels.
After building the world, coordinate by coordinate, I will then go to the next phase - creating tables where I identify plants and animals, plus products derived from them and their levels of productivity. This will then be used to create my world's economy system and a list of characters in different levels of wealth.
I can make this work somewhat easily in Excel (without using VBA), but the amount of data will kill the file before I can use it. I only hope I'll manage to pull it off in Access - but I'll deal with this monster one step at a time. Right now, I am just focusing on the question I posted above. Thank you for any assistance you may be able to give me.
You want a database trigger meaning that entering data into biome table in the specified columns "triggers" the calculation for your third table. Access does not support triggers but there is a workaround. You use a form and create events to the textboxes of the triggering attributes.
Create a new form based on your biome table. I suggest you get the triggers to work first. Later you can add it to your form with all the subforms. Since you are new to Access you do not want to deal with subforms so soon because they make everything more complicated than it needs to be.
You rename the textboxes Precipitation, Temperature, ProductivityLevel to something like txtPrecipitation txtTemperature txtProdLevel
You open the VBA-Editor and try the following code in your new form:
.
'Trigger Events
private sub txtTemperature_Change()
call CalculateProductivityLevel()
end sub
private sub txtPrecipitation_Change()
call CalculateProductivityLevel()
end sub
private sub txtTemperature_AfterUpdate()
call CalculateProductivityLevel()
end sub
private sub txtPrecipitation_AfterUpdate()
call CalculateProductivityLevel()
end sub
'Calculation Procedure
private sub CalculateProductivityLevel()
'Check if both attributes have values. If not do not calculate anything
if (Len(me.txtTemperature & "") = 0) OR (Len(me.txtPreciperation & "") = 0) Then
exit sub
else
me.txtProdLevel = me.txtTemperature * me.txtTemperature
end sub
Note
The trigger events will call the calulcation procedure when there are new entries in the two attributes or new entries are saved.
Make sure to put the code in the new form tab of your VBA-editor
untested code so there might be some errors

MS Access 2007 - controlling UI behaviour after attempt to insert duplicate record

Creating a simple UI using MS Access, hoping to do minimal actual coding (actually helping a friend who is not a coder).
Simplified requirement: Single table, primary key is phone number, lots of other non-mandatory fields. Display a form allowing just the phone number to be entered, if a record with that key exists display the full record, if a record with that key does not exist bring up an form allowing the other fields to be entered for this phone number and hence create a new record.
Q1: Any simple way to achieve this kind of function? Example?
We've got some of this going with a standard form, can execute code if insertion fails, but a standard dialogue box is displayed warning about the duplciate key violation.
Q2: How can we trap that attempted insertion, avoid having the dialogue come up?
You will have to get your hands dirty and write some code to get this outcome. A starting point would be something like this presto code. Post back if you get stuck on any of the parts.
If fCheckIfRecordExists(lYourKey)=True then
Docmd.OpenForm “frmEditExistingRecord”
Else
Docmd.OpenForm “frmEnterNewRecord”
End if
Public function fCheckIfRecordExists (lYourKey as Long) as Boolean
‘Code to check if a record exists, simple method is to use dLookup or a count SQL statement with the criteria as the key you are trying to find
End function
EDIT:
First things first make a form with 1 text box called txtPhone_number and a command button called cmdSearch.
Next put this bit of code in the module behind the form
Public Function fDoes_record_exist(strPhone_number As String) As Boolean
If DCount("Phone_number", "tblYour_table", "Phone_number=" & strPhone_number) > 0 Then
fDoes_record_exist = True
Else
fDoes_record_exist = False
End If
End Function
Next you need to put some code behind the click event of the command button. This code can be expanded on to check for a valid phone number later if you want
If fDoes_record_exist(Me.txtPhone_number) = True Then
DoCmd.OpenForm "frmShow_existing_record"
Else
DoCmd.OpenForm "frmEnter_new_record"
End If
That should set you on your way nicely but post back if you run into problems
Here is an overview of the process with Access logic:
You need an unboud control labelled Phone in the form header, where user will be able to enter the phone number to search. You need to use the After_Update event of that control to trigger your search. There will be a second Phone control, bound this time, in the Detail section of the form for effective data entry/update.
Use the Form_Error event to intercept the error message when user tries to save a duplicate key, in order to display a nice message, and eventually Cancel his changes.
The advice from Kevin Ross to use VB Code is clearly one approach, and I think is appropropriate if we anticipate less trivial requirements in future. However I'm in a situation where I'm helping someone with zero coding background and hence if possible I'd prefer to let them use simple Macros rather than full-scale VB.
As it happens the functionality I require can be implemented with just Macros, and it depends on the suggestion from iDevelop.
The outline of the solution I used:
Create an InitialEntry form with no association to any particular table, it has:
a data entry field for the telephone number
a read-only text box where I can display a message
a button labelled Add
a button labelled Show
I write three macros:
A macro AlreadyExists that displays a message saying "We already that one"
A macro NewEntry that opens a data entry form for my table, in Add mode, and which copies the phone number from InitialEntry!TelephoneNumber
A macro TestForExisting this uses a condition
DCount("*","MyTable","[PhoneNumber] = [FormPhoneNumber] " ) > 0
to control whether to execute AlreadyExists, and a similar test to control whether to call NewEntry.
While this is not as efficient as VB, it does seem to be understandable by a non-coder, so at least we can implement our application.

"No current record" after Cancel in combo_BeforeUpdate

I'm trying to prevent circular (or even cascading) references in my data, and it seems it's only working part of the time.
In Access 2007, I have the following table:
create table mfr (
mfr_id Autonumber,
mfr_nm Text(255),
mfr_is_alias_for_id Long Integer
)
I'm importing a bunch of data from Excel, and the mfr_nm is one of the columns from the worksheet. I can't control how data gets entered into Excel, so I want a way of capturing alternate spellings as being "really" same thing. So far, so good (I think...).
Now I've built a form off of this table. I've got a ComboBox for the alias--again, so far, so good. However, when I add this code to the BeforeUpdate event, things get "interesting" (error handling omitted):
If Not IsNull(cboMfrAlias) Then
If Not IsNull(DLookup("mfr_is_alias_for_id", "mfr", "mfr_id=" & cboMfrAlias)) Then
MsgBox """Alias for"" must not also be an alias.", vbExclamation
Cancel = True
End If
End If
This works exactly as I expect it to when the form is in Form View, but if I'm in Datasheet View my MsgBox is immediately followed by an Access-generated "No current record" error that is not caught by error handling within the BeforeUpdate sub.
Can I catch this error? Where?
Your dropdown list should filter out entries that are aliases. In other words, don't display a choice the user can't make.
You'd do this by simply eliminating from the dropdown the choices where mfr_is_alias_for_id Is Not Null.
I've implemented this in various guises and it works fine.
I'm addressing the "No Current Record" error part of your question, from so long ago. After checking google for an answer, I found this link which was helpful. However, instead of using NZ() to transform the troublesome binary field in an aggregate query, I used troublesomefield: IIF([troublesomefield] IS NULL,NULL,[troublesomefield]) and this worked to banish the error. So my solution is only a small variation on the original answer I found, but it gets around the error and let you keep nulls if you want to...

MS Access 2003/2007 - Passing data through a variable on unbound forms vs. a hidden text box

Ok so I hope the title of the question matches what I about to ask, but here is what I am trying to get at:
So I have an access database that uses a number of unbound forms, and the purpose of the forms are to collect data and save to various tables with VBA click events using SQL statements (INSERT or UPDATE based on whether the ID of the record is present on the form in a hidden text box). When entering a new record (via INSERT), I get the row number with
MyRow = db.openrecordset("SELECT ##Identity")(0) 'thanks David
So you maybe getting the picture. If I have another form that relates to the first form in terms of the record, I just open a recordset and pass that value to another hidden text box.
So my question is, is there a better way to do this regarding passing that value (or just using that value) using a variable instead of this awkward method. So I realize a lot of folks are going to go with the obvious answer of, "Why not just make your forms bound instead of all this code"...and I am sure that is a valid answer, however I inherited this database which was already put together like this, and re-structuring it would be a daunting task.
Any and all advice, or learning resources are greatly appreciated, as they always are!
I use unbound controls on forms for all these kinds of values. The current solution of using an unbound form is sounder than using global or form level variables. If I recall the details correctly while debugging code and you hit the stop button you lose all global or form level variables. Or if the user hits an unhandled error.
Have you looked at OpenArgs?
DoCmd.OpenForm "Form1", , , , , , "Hello"