I have a custom function in Access 2007 that hinges on grabbing data out of a specific query. It opens Outlook, creates a new email and populates the fields with specific addresses and data taken from the query ("DecisionEmail").
Now I want to make a different query ("RequestEmail") to populate the email with that data. So all I have to do is change this line:
Set MailList = db.OpenRecordset("DecisionEmail")
This is my desired result: If the user is on Form_Decision and clicks the button "Send email", "DecisionEmail" will get plugged into the function and that data will appear in the email. If the user on Form_SendRequest and clicks the button "Send email", "RequestEmail" will get plugged in instead.
My last resort would be to make a new function and use the Conditions field in the Macro interface to choose between them.
I have a vague notion of setting the query names as variables and using an If statement.
Why not save the macro as code, then you can edit away to achieve say:
Function CustomEmail(NameOfQuery As String)
CurrentDB.Openrecordset(NameOfQuery)
End Function
Then, on each form in the desired event:
CustomEmail "DecisionEmail"
Related
What I'm currently doing is that on the Property Editor of my dropdown widget, on the Event Section using the onValueEdit function, I'm trying to create a custom action script which will give a value to my textbox (using widget.root.descendants.NameOfMyTextbox.value) depending on the selected value of my dropdown.
The values of my dropdown are the IDs stored in my MySql database table Process, for example: ID = 1, name = Assembly, manager = George. For the textbox, I would like to get another table field value depending on the selected value of my dropdown through a select statement (like getting the manager value). What kind of app maker queries or functions should be useful in this case?
If your dropdown option binding is #datasources.Process.items then your onValueEdit event simply needs to be:
widget.root.descendants.NameOfMyTextbox.value = newValue.manager;
This would be the only way to set this up however, because this way the options are pointing to your entire record in the Process table and upon selection you can get any other field from that record using newValue.YourField.
I am currently working on a database project using MS Access that allows user to submit their applications via forms and these applications get saved on a masterlist table. I am wondering if MS Access has the ability to support features which allows a user to save a form which they have filled, but not officially submitting it yet, and afterwards at their own discretion they can re-enter to submit their forms, which then only gets captured in the masterlist table. Any suggestions to architect this feature are welcome, or any limitations in doing so
Second suggestion Calls for a few preparations, but makes submitting a very simple task:
Assuming table name is masterlist, add to the table a field
Submitted, Boolean value (Yes/No Value), Default Value = False.
Submitting an application will be done by setting this Field to True.
Change masterlist table name to tbl_masterlist, and create a query:
SELECT * FROM tbl_masterlist Submitted = TRUE. Name this query masterlist.
Now masterlist has only submitted applications.
In design view, Change the Form's RecordSource Property to tbl_masterlist. You can filter out undesired applications from the Form, if you wish, using the From's Filter and FilterOn property
add a checkBox field to applications Form, and in the properties window s set it's Name and ControlSource Properties to Submited, and it's Visible property to False.
Finally, add to applications Form a Submit Button, and in it's OnClick event sub add this code: Me.Submited = True.
When I click on the Create New Form button below, I get the following runtime error 2450 dialog box:
When I click on the debug button, it gives me the following:
The main form is called FindClientsNavigation. The "Create New Form" button in the ListOfForms subform is supposed to cause the NavigationSubForm to replace the ListOfForms form with a new CommunicationForm so that the user can enter information from a new form for the Client with the specific Client ID that is available in the txtClientID textbox, which you can see in the top of the FindClientsNavigation form in my first image above.
How do I alter the code above so that it loads a new CommunicationForm in the NavigationSubForm? And how do I get that new CommunicationForm to have the ClientID stored in it, so that submitting the form will allow the form to be saved with reference to the specific ClientID?
The SourceObject needs to be set to a string, which is the name of the form to use:
.SourceObject = "CommunicationForm"
[Note that Forms is the collection of open forms so you cannot use this to refer to a form in the Navigation Pane - unless you know that this form is open.]
You can use the Client ID (on the main form) for this subform, but there are a number of ways to do this and it depends on your specific requirement:
The subform could be based on a query that refers to the textbox (perhaps txtClientID) on the main form. This is one of the simpler approaches.
You could dynamically set the RecordSource for the subform, using a WHERE clause that refers to the Client ID (similar to the above approach).
You could apply a Filter to the subform, so that it only displays the single record for the Client ID.
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.
So how can I pass a value from one form to another? For example: The user select's an organization from a list and this opens up a trip form that allows a user to enter various information regarding the trip. At one place I would like to add another little pop up form where they can enter contact information (just a name and phone for POC) of the organization they are visiting.
So when that initial form opened from the selection screen it has two IDs that are simply hidden in text boxes (one being the tripID, and the other being the OrgID), so how do I pass these to the second little pop up form so that the contact information has the relative IDs with it.
Thanks.
The best approach in these cases is not to attempted to pass a bunch of variables. It is too much code, and is inflexible. For example, if you need to pass two values, what happens over the years when that requirement grows to 5 values? Trying to maintain and pass a whole whack of values is too much coding work.
Keep in mind that each form in ms-access is really a class object that you can manipulate in code. So, use a object approach here and you find you not only write less code, but your code will be more clean, more modular, no need for global vars, and code you write can often be re-used between different forms.
Here is how:
In general when one form launches another form in the 2nd form in the forms on-open event (in fact, you can even use as late as the on-load event) you can pick up a reference to the PREVIOUS form object. In other words, you can use a object approach here.
At the forms module level, for form I declare a form object as:
Option Compare Database
Option Explicit
dim frmPrevious as form
Then, in the forms on-load event, we go:
Set frmPrevious = Screen.ActiveForm
Now, any code in our form can FREELY use code, events, even varibles declared as public from that previous form in code.
So, if you want to force a disk write of the previous form, and re-load of data.
frmPrevious.Refresh
If you want to set the ID value, then go:
frmPrevious!ID = some value
And, note that you can even declare form previous as a PUBLIC variable for that form, and thus if you two forms deep, you could go:
frmPrevious.frmPrevious!ID = some value
So, simply declare a forms object in EACH forms code module (or at lest the ones where you need to use values in code). The above means any code has a ready made reference to the previous form object. Functions declared as public in a form will become a METHOD of the form, and can be run like:
frmPrevious.MyCustomRefresh
or even things like some option to force the previous form to generate and setup a invoice number:
frmPrevous.SetInvoice
or
frmPrevious.SetProjectStatusOn
So not only can you shuffle values and data back and forth, but you can easily execute features and functions that you build in code for the prevous form.
In fact as a coding standard, MOST of my forms have a public function called MyRefresh.
Note that the beauty of this approach is that you can thus read + use + set values from that previous form. This allows your code to not only receive values, but also set values in that previous form. So this approach is bi-directional. You can shuffle data and values back and forth between the forms. The other advantage here is you NOT restricted to just variables, but can use fields, control values (events, properties) etc.
This approach means that much of the previous form is now at your fingertips.
So don’t try to pass a whole whack of variables. Pass a reference to the form and you have a nice ready made object at your fingertips and it makes this type of coding problem a breeze.
The usual way would be to reference the textboxes in the initial form from the popup form, like this:
Forms!frmInitialForm!tripID
Forms!frmInitialForm!OrgID
However, this tightly binds the popup form to the initial form, so that it cannot be used anywhere else in the application.
A better approach is to use OpenArgs:
DoCmd.OpenForm "frmPopup", OpenArgs:=Me.tripID & ", " & me.OrgID
This places your two values into a string, which is passed to the popup form. You can then parse the two values out of the OpenArgs using the Split function.
For more info about passing parameters using OpenArgs, see:
http://www.fmsinc.com/free/NewTips/Access/accesstip13.asp
This one could help
MS Access: passing parameters from one access form to another