MS Access Form - Between - forms

I've created a form and need to make it so that it searches between 2 years.
So for example if the user enters 1980 and 2000, I need all entries to come up which are between those two years. Any help?!
http://imgur.com/bqdFWFB
The same goes for the length. Thanks in advance! :)

Sure,
Assuming that your form is bound to the table with the date field that you're filtering on, You could implement your search in the header section of that form.
Using design view, add two unbound text boxes (set their input mask to date/time to allow a datepicker to be used if you want). We'll call them txtDateStart and txtDateEnd.
In the after update for your txtDateEnd control on your form, add some vb code.
Me.Filter = "[dateField] BETWEEN " & me.txtDateStart & " AND " & me.txtdateEnd
me.filteron = true
That should be all you need.

Related

Use ContentControls to insert insert LastSavedBy Name, Date and Time information into Word form

I've set up a word form with different sections, each section to be completed by a separate person.
Each section of the form includes a combination of dropdown lists or free text fields set up using named Content controls.
At the end of each section there is field for the staff member to record their name, the date (calendar icon), and a command button with an associated macro to save the form and protect the data once that section has been completed.
While this enables the data to be protected it does not prevent person A from completing the form and entering person B's name. Note, this would not be expected, but traceability is required for regulatory purposes.
I would like to update the macro to protect the sections, save the file (currently working), and then immediately after saving, have the macro populate another field directly under the manually entered name and date with the Microsoft advanced properties of Last Saved By and the date and time. This would confirm the user.
My macro below (InsertMSSavedDetails()) will extract the Microsoft required data, but only if I manually click on the form and run the macro, and then it saves wherever I click on the form and won't save to the named ContentControl box. I'd like to automate this last step so that it is not reliant upon the user and the data is associated with particular section.
My form includes the following code:
Module
Sub ProtectFieldsSections2()
' protects Sections 1 and 2
If MsgBox("Do you want to Lock and Protect this section from further editing?", vbYesNo) = vbNo
Then Exit Sub
Dim sec As Section
Dim cc As ContentControl
Set sec = ActiveDocument.Sections(2)
For Each cc In sec.Range.ContentControls
cc.LockContents = True
Next cc
End Sub
This document:
Private Sub CommandButton2_Click()
ProtectFieldsSection1
ProtectFieldsSection2
ActiveDocument.Save
End Sub
Current code for Adding Microsoft data - which technically works, but not in the manner I need:
Sub InsertMSSavedDetails()
'
ActiveDocument.SelectContentControlsByTitle ("MSSavedDetails")
Selection.TypeText Text:="Check data: "
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"LASTSAVEDBY ", PreserveFormatting:=True
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"SAVEDATE \# ""d/MM/yyyy h:mm:ss am/pm"" ", PreserveFormatting:=True
End Sub
Second issue with the above, is that it would only need to be added the once, when Sub CommandButton2_Click is first selected. If I were to update the Sub CommandButton2_Click, how would I stop if from repeating the cycle of save, insert Microsoft data, save, insert Microsoft data?
NOTE: Use of word vs PDF form. Presently, the form is used in word format, converted to PDF, and electronically signed, however this does not allow others to add their information to the remaining sections. Adobe LiveCycler has been used to design PDF forms but there were issues with maintaining images and graphs, and there were other issues experienced with the Adobe reader, so the option is to remain with word.
Thank you.
Not sure I have completely understood the problems, but
The problem with inserting the field codes LASTSAVEDBY and SAVEDATE is that unless you "lock" them, their values will always reflect the most recent save. Also, if you want the fields to go in a content control, you have to use a rich text content control.
Perhaps better to
save the document
get the underlying property values (the ones that LASTSAVEDBY and SAVEDATE display) and insert them
save the document
If you have content controls named (say)
Section1LastSavedBy
Section1SaveDate
Section2LastSavedBy
etc.
then
you know which commandbutton the user clicked so you know which section you are dealing with
your code can then look something like
Private Sub CommandButton2_Click()
ProtectFieldsSection1
ProtectFieldsSection2
With ActiveDocument
.Save
.SelectContentControlsByTitle("Section1LastSavedBy")(1).Range.Text = _
.BuiltinDocumentProperties("Last Author").Value
.SelectContentControlsByTitle("Section1SaveDate")(1).Range.Text = _
format(.BuiltinDocumentProperties("Last Save Time").Value,"D/MM/YYYY h:mm:ss am/pm")
.Save
End With
End Sub
If you want to construct the content control names programmatically based on Section number, you can.
If you want to lock the content controls against further editing, you can.
I am not sure what problem you are encountering here:
"Second issue with the above, is that it would only need to be added the once, when Sub CommandButton2_Click is first selected. If I were to update the Sub CommandButton2_Click, how would I stop if from repeating the cycle of save, insert Microsoft data, save, insert Microsoft data?"
unless you are using a Save event. If that's the problem we could revisit that part.
It's pretty difficult to stop people tampering with data in Word, but personally I would consider saving copies of these values in, e.g., a Custom XML Part (not mapped to the controls) or Document Variables - possibly also encrypt them - you can use Windows crypto APIs for that.
Incidentally, I suspect the problem you have with your existing code is that .SelectContentControlsBYTitle doesn't Select the controls in the normal Word sense. It just returns a collection of controls with that name.

MSACCESS - How to customize all the Switchboard entries texts at once by a condition

I have a default Switchboard generated by MS Access and i want to customize every single entry of the list at once.
The Switchboard form by default is set on "contiunous form" and the entry's control is a textbox (ItemText) identified via VBA as OptionLabel1.
I added to the default "Switchboard Items" table a new field called "SecLevel" where i added for each entry/record a value like Admin, Operator and User.
Now i want each item in the Switchboard form's list to change its text color based on "SecLevel" value like red for Admins and blue for Operators.
So i tried like this:
Private Sub Form_Current()
TempVars!CurrentItemNumber.Value = [ItemNumber].Value
Dim ctrl As control
For Each ctrl In Me.Controls
If ctrl.Name = "OptionLabel1" Then
If DLookup("[SecLevel]", "Switchboard Items", TempVars!CurrentItemNumber.Value) = "Admin" Then
Me.OptionLabel1.ForeColor = RGB(255, 0, 0)
ElseIf DLookup("[SecLevel]", "Switchboard Items", TempVars!CurrentItemNumber.Value) = "Operator" Then
Me.OptionLabel1.ForeColor = RGB(0, 0, 255)
Else
Me.OptionLabel1.ForeColor = RGB(0, 0, 0)
End If
End If
Next
End Sub
This doesn't work help..
Wrong Dlookup criteria. You want to fetch the SecLevel of the Switchboard Item with same Item Number as stored in TempVars!CurrentItemNumber.Value. use:
DLookup("[SecLevel]", "Switchboard Items", "[Item Number] = TempVars!CurrentItemNumber.Value")
or TempVars!CurrentItemNumber.Value gets converted to True (if <> 0, first values is fetched as criteria is true for all rows) ot False (if = 0, no values is fetched)
Wrong event.Form_Current event is fired every-time you move the forms recordset cursor to another record. To execute code on form startup, use Form_Open if you don't need values from bound queries/fields (e.g. to check priviligdes and close if not sufficent priv) as it fires before data is fetched.
But as you need [ItemNumber].Valueuse Form_Load event (fires when form with data is loaded.
On a continuous Form a control inside Details-Section is copied for every record, but still has same name. In Form_Current event Me.OptionLabel1 always refers to the control in actual selcted row. All other copies are not affected.
To work around use Conditional Formatting or use Detail_Paint event.
Some other improvements can be:
if you know controls name, no need to loop whole Controls collection, just refer to by using Me.Controls("NameOfControl").
use Select Case to tell different values of an expression apart. E.g.
Select Case DLookup("[SecLevel]", "Switchboard Items", "[Item Number] = " & TempVars!CurrentItemNumber.Value)
Case "Admin" '
' code on Admin here
Case "Operator"
' code on Operator here
Case Else
' code executed if no match in cases
End Select
Be aware of case-insensitive string comparison if usual Option Compare Database is set.
Use proper naming conventions! Even you don't seem to tend to ugly ungarian-notation OptionLabel1 is a poor identifier, not telling us anything useful. See variable names for some good infos (also check the rest of the site as it contains lots of good advices!). In table/field names avoid special chars, only use letters, numbers and underscore, then you don't need square brackets! Also get used to rename controls dropped from a query/table, as otherwise the control and the data field get the same name what can cause some trouble! Another great resource on vba coding is RubberduckVBA addin (try it:)) and their blog. Even they focus a lot on Excel, there is no better resource to learn OOP vba coding. Maybe start with bad habbits and then move on where you like (I recommend OOP Battleship Part 1: The Patterns)

Access 2010 - enter references to form elements as the value of a text field

Is there a way to take a value from a field on a form and use it as a reference to a different field in the same form, and not just literally? I want to be able to manually enter something like [txtFlavor] in one field and have it show the actual flavor, the value of the field named "txtFlavor" in another field, and not just the string "[txtFlavor]". I'm basically trying to store some vba references (terminology?) in a table so I can bring up a string of text with references to values on the form.
I have been asked to create a system that will store letter templates in Access 2010 and allow users to choose a record with personal information and insert that info into a template letter, preferably displaying it on a form immediately in plain text. I already proposed using reports to do this but that was unacceptable to the end users. They really just want a form that combines
a) contact records, one at a time
with
b) letter templates, one at a time
I've been trying to store the template info with it's form references in a table, but I have yet to be able to make references pull data from another text field on the form.
Is it possible and/or sensible to try to store something like the following in a table, or to enter it into a field on a form?
[txtFlavor] & " is dull but popular."
and then have it show up elsewhere in the form as
Vanilla is dull but popular.
I sure feel dumb and am sure I've missed something obvious. Everything I do is just repeated literally and not interpreted as a reference.
You could get your users to create their templates using 'tags' as placeholders for the database information, in a similar way to how you would design a merge document in Word. So in your example above, the template document would look like:
{Flavor} is dull but popular.
When it comes time to create the merged result you would need to use the Replace function to change these tags to actual data values. So if you had a read-only text box on your form, the control source could be:
=Replace([txtTemplate], "{Flavor}", [Flavor])
I assume you would have lots of potential tags, so using this approach you would need to nest the Replace functions. I have split my nesting across multiple lines to make it a bit more readable:
=Replace(
Replace(
Replace([txtTemplate], "{EmpName}", [EmpName]),
"{EmpAddress}", [EmpAddress]),
"{EmpPhone}", [EmpPhone])
If you had many more database fields/tags this would start to become very unwieldy so I would recommend using some VBA to make life easier, maybe something along the lines of:
Dim rsSource As Recordset
Dim strMerge As String
Dim intField As Integer
'Assuming your form has a field called EmpNo (numeric data) that you can use to pull data...
Set rsSource = CurrentDb.OpenRecordset ("Select EmpName, EmpAddress, EmpPhone From Employees Where EmpNo = " & Me.EmpNo)
strMerge = txtTemplate
For intField = 0 to rsSource.Fields.Count - 1
strMerge = Replace(strMerge, "{" & rsSource(intField).Name & "}", rsSource(intField))
Next intField
txtMerge = strMerge
rsSource.Close
Set rsSource = Nothing
You could put this code in the AfterUpdate event of your txtTemplate text box and it would update the contents of the txtMerge text box. You either need your tag names to match your database columns, or else you could alias the columns in the Select statement so they match the tag names.

How to apply two filters to a split form to robustly update records in a table

I am storing data on eye colour, for example. I have a table about containing 100's of contact details for people in many different local authorities (LA). These contact details change frequently and a team of users will update the table when necessary.
I want to make a split form to do this for us. The idea is to be able to use a drop-down menu for both the LA (location) and the eye colour in the form, to filter the table below to show only the relevant contact details.
The user can then quickly find the correct record, click on it, this will autofill the rest of the form, and any details can be changed and then saved.
My problem is that I can't make the form robust enough to not erroneously overprint existing contact details, and I can't get a two step filter process to work. The contact details for previous records don't seem to clear, even when filtering for different places, so it is easy to muddle up and overprint records.
Here is a screen shot of the form so far:
example of the split form, filtered for records from Broadland but not by colour yet
Here is the VBA
Option Compare Database
Private Sub Detail_Click()
End Sub
Private Sub LA_AfterUpdate()
Me.Filter = "[LA] = " & Chr(34) & Me.LA & Chr(34)
Me.FilterOn = True
End Sub
Private Sub UpdateRecord_Click()
RunCommand acCmdSaveRecord
Me.Requery
End Sub
If anyone could help with:
How do I filter for colour as well as place?
How can I make the form save the amended record and then clear the form so that no records are overprinted?
If I filter for one thing and click to bring up the full record, how can I make the form drop this record and change to a different one if I decide to re-filter and pick a different record
I would be very grateful! Thank you in advance.
Answer for question 1
1.Open form Design View
2.Click at the table at the bottom of your form
3.Open Property Sheet for that table
4.Open Data at Property Sheet. You will see Link Master Fields and Link Child Fields. Click at ... sign and it will appear Subform Field Linker. Fill in the master and child field's column as you desired (eg. LA, color, place). Then the form will show the result.
Answer for Question 2
You have to use vba code under UPDATE RECORD button. For clearing the form after saving the record, use DoCmd.OpenForm "your form name",,,,acFormAdd
Example answer for question 2:
Private Sub TESTSAVE_Click()
If MsgBox("Changes have been made to this record." _
& vbCrLf & vbCrLf & "Do you want to save these changes?" _
, vbYesNo, "Changes Made") = vbYes Then
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Close
DoCmd.OpenForm "NewATN2",,,,acFormAdd
Else
DoCmd.RunCommand acCmdUndo
End If
End Sub

Access 2013 - Embedded query filtered by combo box on form

I'm new to Access and this is the problem I'm suffering: I have four tables - Task, Person, Role, and TaskPerson (mapping table). I have a form that at the top has a unbound combo box displaying a list of people from Person. In the body of the form I have a query pulling from the Task and TaskPerson tables that is embedded as a datasheet. The fields from TaskPerson perform a lookup on Person and Role to display the actual values. Each task can have multiple people assigned to it and each person can have multiple roles. I am looking to pick a name from the combo box with the datasheet updating to only show the tasks associated with that person (i.e. matching the name from the combo box to the name in the person field (which is a lookup) on the form and only showing those tasks).
I have tried adjusting the Record Source for the query so the person field criteria would pull from the combo box using
'Forms![Task Form]![Combo11]'
but that hasn't worked. I have also tried a version of this answer:
Private Sub Form_SelectionChange()
' If the combo box is cleared, clear the form filter.
If Nz(Form) = "" Then
Me.Form.Filter = ""
Me.FilterOn = False
' If a combo box item is selected, filter for an exact match.
' Use the ListIndex property to check if the value is an item in the list.
ElseIf Me.Combo11.ListIndex <> -1 Then
Me.Form.Filter = "[Combo11] = '" & _
Replace(Me.Combo11.Text, "'", "''") & "'"
Me.FilterOn = True
End If
End Sub
While the code is not balking, it also isn't grabbing the selected name from the combo box, so it doesn't update. A likely factor is when I type Me.Combo11.Text, it doesn't actually display Combo11 as an option. I tried typing it in, in hopes of working, but I know that is a bit foolish.
Any detailed answers would be appreciated. I'm still learning my way around and I get lost a bit easily.
Steve.
The first method is the easier one.
In the query you have
WHERE TaskPerson = Forms![Task Form]![Combo11]
Note that there are no ' around the combo reference. With 'Forms![Task Form]![Combo11]' the whole thing is interpreted as string, so it doesn't work.
Then in Combo11_AfterUpdate you simply have
Me.Requery
Disadvantage of this method: you always have to select a person, or the form will be empty.
The second method:
Your query lists all record, the combobox applies a filter. Or removes it, if the user clears the combobox.
I suggest going back to the answer you used, and only replace
Combo_Reported_LOB_Selection by Combo11
and
[ReportedLOB] by [TaskPerson]
And the code doesn't go into Form_SelectionChange(), but into Combo11_AfterUpdate()