Apply Filter (1 Viewer)

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
I am looking to apply a filter to a recordset on loading a form, for some reason I just cannot get the syntax.

Code:
Private Sub Form_Load()
DoCmd. ApplyFilter , "[Field] = "????????""

I am trying to remove items that have more or less than eight characters.

Any help with an addled brain would be greatly appreciated.:banghead:
 

Mark_

Longboard on the internet
Local time
Today, 05:20
Joined
Sep 12, 2017
Messages
2,111
Not sure if this would help, but in the source query could you use and expression that returns the LEN([Field]), then filter on that?
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
I have this working now, well sort of.

It works in an independent form but not when used as a sub-form.
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
Interestingly:
Code:
Private Sub Form_Load()
DoCmd. ApplyFilter , "[Field] = '????????'"
Doesn't work loading the subform on it's own (no records found) but the following does:
Code:
Private Sub Form_Load()
DoCmd. ApplyFilter , "[Field] = 'ABC12345'"
This pulls all records with ABC12345 but the question marks don't seem to work.

After that I am still stuck getting the syntax when it is used as a sub-form.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 07:20
Joined
Feb 28, 2001
Messages
27,156
Oh, the problem is with a sequence of question marks that return nothing? Have you tried the LIKE operator rather than the "=" operator? According to this article, a filter clause is like a WHERE clause, so the same syntax rules would apply. The rules for LIKE would condone an attempt to match a specific-length string with the question-mark symbol.

https://msdn.microsoft.com/en-us/vba/access-vba/articles/form-filter-property-access

https://msdn.microsoft.com/en-us/library/bb208897(v=office.12).aspx

By the way, if it was a cut/paste, then

Code:
DoCmd. ApplyFilter , "[Field] = [COLOR="Red"]"[/COLOR]????????[COLOR="red"]"[/COLOR]"

wouldn't work because the wrong "inner" quotes were used. But your later posts showed a correction to use the single quote that should have worked better syntactically. But I think now your problem is semantics.
 
Last edited:

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
Yes, the LIKE works but I am now still left with it not functioning in a sub-form:confused:
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 20:20
Joined
May 7, 2009
Messages
19,230
Private Sub Form_Load()
Me.Filter = "[Field] like '????????'"
Me.FilterOn = True
End Sub
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
Hi Arnelgp,

I had just found that one out and got it all working, unfortunately I am now stuck at the final stage. I have placed a tick box on my main form and if it is ticked I want to refresh the subform with just data that has that field with 8 characters, for the form load I have:
Code:
Private Sub Form_Load()

Me.Filter = "[Blade] LIKE '????????'"
If Forms![frmMain]![chkFan] < 0 Then
Me.FilterOn = True
Else
Me.FilterOn = False
End If
End Sub
and then on the tick box I have:
Code:
Private Sub chkFAN_AfterUpdate()
Me.test.Requery
End Sub
This does not work:banghead:
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 20:20
Joined
May 7, 2009
Messages
19,230
if test is a subform:

Me.test.Form.Requery
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
OK, I was trying to speed up a database that loaded data based on a query of a query of a query (no wonder it was so slow.

I am trying to load a sub form with a lot of variations, to do this I am using a module to query the data and then a filter on the data as follows:
Code:
Public Function scanresults()

Dim scandata As String

    scandata = "SELECT  Scans.Scanned, " & _
                "Scans.ID, Scans.Blade, Scans.Engine, " & _
                "Scans.Part, Scans.Hours, Scans.Cycles, " & _
                "Scans.Result, Scans.Tank, Scans.Operator, " & _
                "Scans.Details, Scans.Co, MRO.MRO " & _
                "FROM Scans INNER JOIN MRO ON Scans.Co = MRO.ID " & _
                "WHERE (Scans.Scanned BETWEEN Forms!frmMain!tStartDate And Forms!frmMain!tEndDate)" & _
                "AND Scans.Blade LIKE '*' &(Forms!frmMain!tBlade) & '*'" & _
                "AND Scans.Engine LIKE '*' &(Forms!frmMain!tEngine) & '*'" & _
                "AND Scans.Part LIKE '*' &(Forms!frmMain!tPart) & '*'" & _
                "AND Scans.Hours >= (Forms!frmMain!tHours)" & _
                "AND Scans.Cycles >= (Forms!frmMain!tCycles)" & _
                "AND Scans.Co LIKE (Forms!frmMain!cboMRO)" & _
                "AND Scans.Tank LIKE '*' &(Forms!frmMain!tSystem) & '*'" & _
                "AND Scans.Operator LIKE '*' &(Forms!frmMain!tUser) & '*'" & _
                "AND Scans.Result LIKE '*' &(Forms!frmMain!tStatus) & '*'" & _
                "ORDER BY Scans.Scanned, Scans.ID;"
                
                Forms!frmMain!test.Form.RecordSource = scandata
                If Forms![frmMain]![chkFan] < 0 Then
                    Forms!frmMain!test.Form.Filter = "[Blade] LIKE '????????'"
                    Forms!frmMain!test.Form.Filter = True
                Else
                    Forms!frmMain!test.Form.Filter = "[Blade] LIKE '????????'"
                    Forms!frmMain!test.Form.Filter = False
                End If
                
End Function

The form load just runs the scanresults()

This does not seem to work as required.
 

Minty

AWF VIP
Local time
Today, 13:20
Joined
Jul 26, 2013
Messages
10,371
If you are changing the record source why not apply the filter in the query itself ?
Then if you check the box simply change the record source again?
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
Hi Minty,
That may be the bit I was struggling with.
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
In theory this works:
Code:
Public Function scanresults()
Dim scandata As String
If Forms!frmMain.Form.chkFan.Value < 0 Then

    scandata = "SELECT  Scans.Scanned, " & _
                "Scans.ID, Scans.Blade, Scans.Engine, " & _
                "Scans.Part, Scans.Hours, Scans.Cycles, " & _
                "Scans.Result, Scans.Tank, Scans.Operator, " & _
                "Scans.Details, Scans.Co, MRO.MRO " & _
                "FROM Scans INNER JOIN MRO ON Scans.Co = MRO.ID " & _
                "WHERE (Scans.Scanned BETWEEN Forms!frmMain!tStartDate And Forms!frmMain!tEndDate)" & _
                "AND Scans.Blade LIKE '*' &(Forms!frmMain!tBlade) & '*'" & _
                "AND Scans.Blade LIKE '????????'" & _
                "AND Scans.Engine LIKE '*' &(Forms!frmMain!tEngine) & '*'" & _
                "AND Scans.Part LIKE '*' &(Forms!frmMain!tPart) & '*'" & _
                "AND Scans.Hours >= (Forms!frmMain!tHours)" & _
                "AND Scans.Cycles >= (Forms!frmMain!tCycles)" & _
                "AND Scans.Co LIKE (Forms!frmMain!cboMRO)" & _
                "AND Scans.Tank LIKE '*' &(Forms!frmMain!tSystem) & '*'" & _
                "AND Scans.Operator LIKE '*' &(Forms!frmMain!tUser) & '*'" & _
                "AND Scans.Result LIKE '*' &(Forms!frmMain!tStatus) & '*'" & _
                "ORDER BY Scans.Scanned, Scans.ID;"
                
                Forms!frmMain!test.Form.RecordSource = scandata
    Else
    
    scandata = "SELECT  Scans.Scanned, " & _
                "Scans.ID, Scans.Blade, Scans.Engine, " & _
                "Scans.Part, Scans.Hours, Scans.Cycles, " & _
                "Scans.Result, Scans.Tank, Scans.Operator, " & _
                "Scans.Details, Scans.Co, MRO.MRO " & _
                "FROM Scans INNER JOIN MRO ON Scans.Co = MRO.ID " & _
                "WHERE (Scans.Scanned BETWEEN Forms!frmMain!tStartDate And Forms!frmMain!tEndDate)" & _
                "AND Scans.Blade LIKE '*' &(Forms!frmMain!tBlade) & '*'" & _
                "AND Scans.Engine LIKE '*' &(Forms!frmMain!tEngine) & '*'" & _
                "AND Scans.Part LIKE '*' &(Forms!frmMain!tPart) & '*'" & _
                "AND Scans.Hours >= (Forms!frmMain!tHours)" & _
                "AND Scans.Cycles >= (Forms!frmMain!tCycles)" & _
                "AND Scans.Co LIKE (Forms!frmMain!cboMRO)" & _
                "AND Scans.Tank LIKE '*' &(Forms!frmMain!tSystem) & '*'" & _
                "AND Scans.Operator LIKE '*' &(Forms!frmMain!tUser) & '*'" & _
                "AND Scans.Result LIKE '*' &(Forms!frmMain!tStatus) & '*'" & _
                "ORDER BY Scans.Scanned, Scans.ID;"
                
                Forms!frmMain!test.Form.RecordSource = scandata
    End If
                
End Function
However, how do I stop my field options neuralising each other.
Code:
"AND Scans.Blade LIKE '*' &(Forms!frmMain!tBlade) & '*'" & _
"AND Scans.Blade LIKE '????????'" & _
The first one shows everything, so the second one doesn't reduce it.
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
To explain further, I am trying to include all data or just data with eight characters.
Code:
"AND Scans.Blade LIKE '*' &(Forms!frmMain!tBlade) & '*'" & _
"AND Scans.Blade LIKE '????????'" & _

This one doesn't work as the search box (tBlade) when empty shows everything and just the ones with eight characters. What I want is to show the ones with eight characters and then filter them by the search box.

My full list has:
ABC
DEF12345
ABC12345

If I put A in the search box I will get:
ABC
ABC12345

I want to tick the checkbox and reduce the list to:
DEF12345
ABC12345

and then put A in the search box and just get:
ABC12345

instead I get
ABC
ABC12345
 

Minty

AWF VIP
Local time
Today, 13:20
Joined
Jul 26, 2013
Messages
10,371
Only use one of them not both ? You either want just the 8 char ones or all of them?
This is perhaps a little more efficient
Code:
    scandata = "SELECT  Scans.Scanned, " & _
                "Scans.ID, Scans.Blade, Scans.Engine, " & _
                "Scans.Part, Scans.Hours, Scans.Cycles, " & _
                "Scans.Result, Scans.Tank, Scans.Operator, " & _
                "Scans.Details, Scans.Co, MRO.MRO " & _
                "FROM Scans INNER JOIN MRO ON Scans.Co = MRO.ID " & _
                "WHERE (Scans.Scanned BETWEEN Forms!frmMain!tStartDate And Forms!frmMain!tEndDate)" & _
                "AND Scans.Engine LIKE '*' &(Forms!frmMain!tEngine) & '*'" & _
                "AND Scans.Part LIKE '*' &(Forms!frmMain!tPart) & '*'" & _
                "AND Scans.Hours >= (Forms!frmMain!tHours)" & _
                "AND Scans.Cycles >= (Forms!frmMain!tCycles)" & _
                "AND Scans.Co LIKE (Forms!frmMain!cboMRO)" & _
                "AND Scans.Tank LIKE '*' &(Forms!frmMain!tSystem) & '*'" & _
                "AND Scans.Operator LIKE '*' &(Forms!frmMain!tUser) & '*'" & _
                "AND Scans.Result LIKE '*' &(Forms!frmMain!tStatus) & '*' " 
	If Forms!frmMain.Form.chkFan.Value < 0 Then
				scandata = scandata & "AND Scans.Blade LIKE '????????'" & _
                "ORDER BY Scans.Scanned, Scans.ID;"                
       Else
    		scandata = scandata & "AND Scans.Blade LIKE '*' &(Forms!frmMain!tBlade) & '*'" & _
    			"ORDER BY Scans.Scanned, Scans.ID;"  
   	End If
                
                Forms!frmMain!test.Form.RecordSource = scandata
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 20:20
Joined
May 7, 2009
Messages
19,230
you can incorporate the code here:
Code:
Public Function scanresults()

Dim scandata As String

    scandata = "SELECT  Scans.Scanned, " & _
                "Scans.ID, Scans.Blade, Scans.Engine, " & _
                "Scans.Part, Scans.Hours, Scans.Cycles, " & _
                "Scans.Result, Scans.Tank, Scans.Operator, " & _
                "Scans.Details, Scans.Co, MRO.MRO " & _
                "FROM Scans INNER JOIN MRO ON Scans.Co = MRO.ID " & _
                "WHERE (Scans.Scanned BETWEEN Forms!frmMain!tStartDate And Forms!frmMain!tEndDate) "

                If Forms![frmMain]![chkFan] < 0 Then
                    scandata = scandata & "And [Blade] LIKE '????????' "
                Else
                    scandata = scandata & "AND Scans.Blade LIKE '*" & (Forms!frmMain!tBlade) & "*' " & _
                End If

   scandata = scandata & _
                "AND Scans.Engine LIKE '*" & (Forms!frmMain!tEngine) & "*' " & _
                "AND Scans.Part LIKE '*" & (Forms!frmMain!tPart) & "*' " & _
                "AND Scans.Hours >= " & (Forms!frmMain!tHours) & " " & _
                "AND Scans.Cycles >= " & (Forms!frmMain!tCycles) & " " & _
                "AND Scans.Co LIKE " & (Forms!frmMain!cboMRO) * " " & _
                "AND Scans.Tank LIKE '*"  & (Forms!frmMain!tSystem) & "*' " & _
                "AND Scans.Operator LIKE '*" & (Forms!frmMain!tUser) & "*' " & _
                "AND Scans.Result LIKE '*" & (Forms!frmMain!tStatus) & "*' " & _
                "ORDER BY Scans.Scanned, Scans.ID;"
                
                Forms!frmMain!test.Form.RecordSource = scandata
                
End Function
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
Hi Minty,

That is the problem,

I want to show all records and then filter them or just the eight character ones and then filter them using the same filter box for either function.
 

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
I have now placed a query at the front which selects all records or just those with eight characters:

I have then based my record source in exactly the same way as before but against the query, this slows things down slightly but it's not painfully slow.

I would still love to know a single stage method to achieve this;)
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 07:20
Joined
Feb 28, 2001
Messages
27,156
I can see one possible (not certain) reason for performance issues. And you said it does not work as intended.

The "not working as intended" part: Minty points out that if you are building the string and want to take account some things checked on the form, you build the string conditionally, either by having alternate contributions or NO contributions for each checkbox you have. So to make your code more efficient at the expense of one tedious part (building the string), consider not making the question so complex every time by using conditional contributions. Once the string is built correctly and loaded to the sub-form, you can do the requery as noted by ArnelGP.

More on "not working" and a comment on performance: Consider these similar but not identical constructs. Construct A is yours, lifted via cut/paste. The rest are modifications I have made, and watch out for them having mixed single and double quotes in places.

Code:
 "AND Scans.Co LIKE (Forms!frmMain!cboMRO)" & _      'construct A

 "AND Scans.Co LIKE '" & Forms!frmMain!cboMRO) & "'" & _        'construct B

 "AND Scans.Co LIKE '*" & Forms!frmMain!cboMRO) & "*'" & _     'construct C

 "AND Scans.Co = '" & Forms!frmMain!cboMRO & "'" & _              'construct D

Every time you have one of these, construct A forces the query engine to reach back into the Access environment to pick up the value from the combo box. I would like to think that the engine (Jet or Ace depending on version of Acess) optimizes this but unfortunately it is a black box and I don't know how many times it has to reach back. The SQL specification doesn't include statements about how often a reach back occurs during query implementation because implementation is a vendor issue. However, consider that you have more than one of these "reach back" cases in your presented query.

You can MAYBE speed up what you wrote as construct A by picking up the value and using it as though it were a constant - by switching to construct B. Then the only time you reach into the form is when you build the string. If you think about it, the combo box isn't going to change during the query so it might as well be converted to a constant in the string that was going to use the value.

But then there is the issue of the use of LIKE. Depending on what you wanted to do, you might consider the two different ideas expressed by constructs C and D.

Construct C is essentially "get everything that contains whatever is selected by the combo box as a formal substring." That usage of LIKE is essentially the classic "CONTAINS" operation. Variations of this leave off the leading or trailing asterisks to change "CONTAINS" to "BEGINS WITH" or "ENDS WITH" cases.

Given that construct A didn't use wild cards and I don't recall any particular combo box formatting property that would allow it, the only way that the LIKE statement would differ from an equals-sign in behavior would be if the actual table/list from which the combo box was selecting included the asterisk or question-mark in the selection source. So unless there are embedded wild card characters in the data presented from the combo box, you might as well have used construct D (strict equality). Because without those wild cards, LIKE and equals-sign are the same.

In terms of intent, using the equals-sign when you meant it that way makes it easier to read six months from now when you finally get it working and go on to something else, but then have to come back to this. And at that putative future date, you read that complex statement and ask yourself, "What the HELL was I trying to do when I wrote this?"
 
Last edited:

Tieval

Still Clueless
Local time
Today, 13:20
Joined
Jun 26, 2015
Messages
475
Hi Doc_Man,

It does now work as intended but in two stages.

My database is only about 14Mb with all data being text and numbers.

I have a concept which is a continuous form containing numerous fields of data (11) in approximately 100,000 rows. The aim is to display all 100,000 rows in a continuous form and trim the data down by search criteria, dates, types etc..

Unfortunately the application needs to work like this as there are no obvious paths for manipulation so it needs to be a central form with all the possibilities available to you on the screen. To this end I have a form with all the controls and a sub-form with the data being re-queried every change.

A few years ago as a complete novice I got it to work perfectly using some very dodgy methods including make tables (clearing and then refilling), queries on queries etc. but as the data increases it has become very slow (every change taking about twenty seconds).

Now as a novice I am re-writing it and trying to speed it up.
 

Users who are viewing this thread

Top Bottom