Filter form based on unbound control value - forms

I have a form bound to a query, except for one field that I am leaving unbound. The idea is that the user will enter a value in that textbox and press a button to bring up the record. I have some code that I thought would work based on the interwebs. When I use DoCmd.ApplyFilter(filter_string) I get a popup asking for the value to filter on (which is not what I want). When I go ahead and paste it in, the form does not get filled. When I use Me.Form.Filter = filter_string, sometimes the form fills, but always with the same record, regardless of what the filter_string says. An example filter_string is
filter_string = "InventoryDetailsID = 'B01MFC000100/01'"
I have another similar form that, instead of filling with an existing query, generates the query (with 5 joins) and fills the form from the resulting recordset. It works just fine, but is slow because it has to run the query each time. That is why I want to use a method where I generate the query once, and then filter it.
Edit
Oh, and I also tried using a variant on the run-the-query-every-time approach, where I query the already generated query (the one I'm trying to filter). I'm using:
query_string = "SELECT * FROM qry_ISBN_All WHERE InventoryDetailsID LIKE '" & Me.InventoryDetailsID & "';"
But I get the error Run-time error '3061' Too few parameters, expected 1
Edit II
Private Sub btn_Seek_Click()
Dim temp As String
filter_string = "InventoryDetailsID = '" & Me.InventoryDetailsID & "'"
Me.temp = filter_string
Me.FilterOn = True
Me.Form.Filter = filter_string
Me.FilterOn = True
'DoCmd.ApplyFilter (filter_string)
' Dim query_string As String
' query_string = "SELECT * FROM qry_ISBN_All WHERE InventoryDetailsID LIKE '" & Me.InventoryDetailsID & "';"
End Sub
Typical filter string is given. It is printed to the form control Me.temp.

After this line:
Me.Filter = filter_string
Add this in:
Me.FilterOn = True
Also I agree, run the query every time approach is definitely overkill. The filter should provide you with the functionality you seek. You just simply have to "turn it on" after you set it.

Related

Navigate programmatically through the records of a continuous form

I would like to navigate through the records of a continuous form in Access 97. I don't find how to do it. This is what I tried:
Me.RecordSetClone.MoveFirst moves to the first record logically, but not in the UI. Also the CurrentRecord property does not change.
I cannot set the CurrentRecord property, it is readonly. Me.CurrentRecord = 1 gives an error.
DoCmd.GoToRecord Record:=acFirst seems to have no effect.
What is the correct way to move to the first record in a continuous form (and to the next/previous)?
Use the Bookmark property of RecordsetClone and Form.
Caveat: I'm pretty sure all this worked in Access 97, but that was a really long time ago.
Sub DemoNavigate()
Dim RS As DAO.Recordset
Set RS = Me.RecordsetClone
RS.MoveFirst
' or
RS.AbsolutePosition = 0
' Navigate in form
Me.Bookmark = RS.Bookmark
' next record
RS.MoveNext
' or
RS.AbsolutePosition = 1
Me.Bookmark = RS.Bookmark
' Move to searched record
RS.FindFirst "someField = 42"
Me.Bookmark = RS.Bookmark
End Sub

Conditional formatting on Access form looking up a value

I've created a form within Access which uses a cross-tab query as its data source.
The column headings for the query are 1, 2, 3, 4 and 5 representing week numbers.
The values display items such as 3/3 = 100.00% or 0/13 = 0.00% or 3/14 = 21.00%.
I've added conditional formatting to the text boxes on the form.
Expression Is Right([2],7)="100.00%" works and displays the figure in bold red when the percentage is 100.
Expression is Val(Right([2],7))=100 also works - converting the text value to a numeric value.
The problem I'm having is that I'm not always looking for 100% - it depends on the value within a table. What I'm trying to do is
Val(Right([2],7))=(SELECT ParamValue*100 FROM tbl_System WHERE Param='SampleSize') - this doesn't work.
Neither does:
Eval(Val(Right([2],7))=(SELECT ParamValue*100 FROM tbl_System WHERE Param='SampleSize'))
or
Val(Right([2],7))=EVAL(SELECT ParamValue*100 FROM tbl_System WHERE Param='SampleSize')
or
Val(Right([2],7))=DLookUp("ParamValue","tbl_System","Param= 'SampleSize'")*100
or
Val(Right([2],7))=Eval(DLookUp("ParamValue","tbl_System","Param= 'SampleSize'")*100)
The SQL for the cross-tab query is:
TRANSFORM NZ(Sum(Abs([Include])),0) & "/" & NZ(Count(*),0) & " = " &
FormatPercent(NZ(Round(Sum(Abs(Include))/Count(*),2),0),2)
SELECT tbl_TMP_PrimaryDataSelection.TeamMember
FROM tbl_TMP_PrimaryDataSelection
GROUP BY tbl_TMP_PrimaryDataSelection.TeamMember
PIVOT tbl_TMP_PrimaryDataSelection.WeekNum In (1,2,3,4,5)
I don't think you can use a function in there, be it system or user-defined.
But you can define the FormatCondition dynamically at runtime, like this:
Dim txtFld As TextBox
Dim objFrc As FormatCondition
Dim strExpr As String
Set txtFld = Me!myTextBox
' Remove existing FormatConditions
txtFld.FormatConditions.Delete
' The dynamic expression
strExpr = "Val(Right([2],7))=" & DLookUp("ParamValue","tbl_System","Param='SampleSize'")*100
' Assign a new FormatCondition to text box
Set objFrc = txtFld.FormatConditions.Add(acExpression, , strExpr)
' Set the format
objFrc.ForeColor = &HFF0000
This example simply removes and recreates all FormatConditions. If you have a fixed number of conditions, you can also use the FormatCondition.Modify method (see online help).
Edit:
The final code I have used executes on the Form_Load event and adds a format to each of the five weekly text boxes:
Private Sub Form_Load()
Dim aTxtBox(1 To 5) As TextBox
Dim x As Long
Dim oFrc As FormatCondition
Dim sExpr As String
With Me
Set aTxtBox(1) = .Wk1
Set aTxtBox(2) = .Wk2
Set aTxtBox(3) = .Wk3
Set aTxtBox(4) = .Wk4
Set aTxtBox(5) = .Wk5
For x = 1 To 5
aTxtBox(x).FormatConditions.Delete
sExpr = "Val(Right([" & x & "],7))>=" & DLookup("ParamValue", "tbl_System", "Param='SampleSize'") * 100
Set oFrc = aTxtBox(x).FormatConditions.Add(acExpression, , sExpr)
oFrc.ForeColor = RGB(255, 0, 0)
Next x
End With
End Sub
Edit 2
Yes, defining FormatConditions via VBA is especially useful when dealing with multiple controls in a loop. You can do this in Design View too and save the FormatConditions permanently, simply to avoid going through the FormatConditions dialogs one by one. Or if the customer later decides that he'd rather have a different color. :)
Note: You could use Set aTxtBox(x) = Me("Wk" & x) in the loop. But actually you don't need multiple TextBox variables, you can simply re-use it.

Subform to search record on main form

I have a subform like so:
When i click the 'select' button, i wish for the record on the main form to navigate to the appropriate one (the one which holds the same Staff ID).
What I have tried so far is for when the button is pressed to run the following vba:
Private Sub Command6_Click()
Dim rs As Object
Dim strLinkValue As String
strLinkValue = Forms![navigation form]![NavigationSubform]![teacher search qry subform]![Staff ID].Value
Set rs = Forms![navigation form]![NavigationSubform]![teacher search qry subform].Form.RecordsetClone
rs.FindFirst "[Staff ID] = '" & strLinkValue & "'"
Forms![navigation form]![NavigationSubform].Bookmark = rs.Bookmark
End Sub
But when I do this I get run-time error 438 (object doesn't support this property or method).
Any ideas? I feel like I'm over-complicating things.
You first got error 438 ("Object doesn't support this property or method.") at this line ...
Set rs = Forms![navigation form]![NavigationSubform].Recordset.Clone
Changing from Recordset.Clone to Form.RecordsetClone cured the error (at that line).
Unfortunately you then got error 438 again when attempting to set Bookmark at this line ...
Forms![navigation form]![NavigationSubform].Bookmark = rs.Bookmark
The reason for the error at that point was because [NavigationSubform] is a subform control, and a control does not have a Bookmark property. You need to set the Bookmark on the Form contained within that control.
This code does what I believe you want. I tested it in Access 2010 with a copy of your database.
Dim rs As DAO.Recordset
Dim strLinkValue As String
strLinkValue = Me![Staff ID].Value
With Me.Parent.Form
Set rs = .RecordsetClone
rs.FindFirst "[Staff ID] = '" & strLinkValue & "'"
.Bookmark = rs.Bookmark
End With

DoCmd.BrowseTo acBrowseToForm MULTIPLE WHERE conditions

I am new to Access 2010 VBA but have solid SQL background. I am trying to open/browse a form from a toogle button based on complex filter.
The form is called: FormSuivi
In SQL, the filter would be like this:
WHERE Randomise = 'Y' AND ActualSxDate is not null
AND datediff('d', Date(),ActualSxDate) > 140 AND DCD = 0;
In this Accessdatabase, the following field's types are:
Randomise: text
ActualSxDate: Date
DCD: Yes/no -> integer (-1/0)
For now, all I managed to do is to implement one condition at a time:
Private Sub Toggle25_Click()
DoCmd.BrowseTo acBrowseToForm, "FormSuivi", , "Randomise = """ & "Y" & """"
End Sub
How can all the conditions listed in SQL be squeezed into a VBA command line?
The parameter WhereCondition can be a full WHERE string, without the WHERE keyword. Including ANDs, parentheses, etc.
Single quotes ' help to keep the string readable (as opposed to """ constructs).
Variables need to be concatenated, e.g.
Dim S As String
S = "Randomise = '" & strRandomise & "' AND ActualSxDate is not null " & _
"AND datediff('d', Date(),ActualSxDate) > 140 AND DCD = " & bDCD
DoCmd.BrowseTo acBrowseToForm, "FormSuivi", , S

Access fields in form using vba

I created a query and a form in Microsoft Access 2010. The form, named TEST, looks as follows:
Field1 Field2
a 200
b 400
In VBA I tried to access the different fields in the form:
Form_TEST.Field1....
I want to save the values 200 and 400 in an integer variable (Dim a As Integer) and print it using MsgBox. How can i achieve that??
You can use the Me as the open form and assign the variable if you know the name of the text box.
Dim intValue as Integer
'If text box name = TextBox1
intValue = Me.TextBox1.Value
I'll try to help you.
I understood you created the form with the wizard putting the 2 fields on the form.
What is not clear is the View that you are using.
Well, your form can be displayed in different ways:
- Single form
- Continuous forms
- Datasheet
This is defined by the Default View property.
To see the properties of you form press F4 to see properties and select "Form" as the object that you want to see.
If your form is Single Form or Continuous form you can access the two fields you put on it simply addressing them.
Click on the controls you put on the form and press F4 to see the control name.
CASE 1 - SINGLE FORM VIEW
Let's assume that your controls are named Text1 (200) and Text2 (400) and for convenience your form is a single form.
So you can refer to values in the 2 controls writing
Dim intText1 As Integer, intText2 As Integer
intText1 = Me.Text1.Value
intText2 = Me.Text2.Value
The .Value property is not mandatory cause it's the default property.
At this point you can print out intText1,2 with a MsgBox
MsgBox "Text1 = " & CStr(intText1)+ " - Text2 = " & CStr(intText2)
This will show Text1 = 200 - Text2 = 400
CASE 2 - CONTINUOUS FORMS VIEW
Let's now assume that your view is Continuous form.
So the field that contains 200 and 400 is just one but each record (row) is a form repeated as many times as the number of records.
In this case to access all the records and store them to an array you can use this in the Form_Load event (you can access it by the Control Properties Window - F4)
Option Explicit
Option Base 1 ' Set the base index for vectors to 1
Dim rst as DAO.Recordset ' Define a recordset to allocate all query records
Dim Values as Variant ' Define a variant to allocate all the values
set rst = me.RecordsetClone ' Copy all records in rst
rst.MoveLast ' Go to last record
intNumRecords = rst.RecordCount ' Count records
rst.MoveFirst ' Go back to recordset beginning
ReDim Values(intNumRecords) ' Resize Values to allocate all values
i = 1
Do While Not rst.EOF ' Cycle over all records
Values(i) = rst!FieldName ' FieldName is the name of the field of
' the query that stores 200 and 400
i = i + 1 ' Move to next array element
rst.MoveNext ' Move to next record
Loop
rst.Close ' Close recordset
set rst = Nothing ' Release memory allocated to rst
for i = 1 To intNumRecords ' Show easch value as message box
MsgBox Values(i)
next i
NOTES
Please NOte that this solution works if you have less than 32767 records to show (the maximum integer with sign that you can store).
The msgbox obliges you to press OK at each value. It's not so comfortable.
Please tell me if it's what you were looking for.
Bye,
Wiz