Combo Box on form to filter table I imported into Access from Excel - vba

I have been searching for a couple of hours but I can only see examples of combo boxes on forms filtering tables that are based from queries.
My table (which I have put on a subForm) is from a static datasheet that I imported into Access from Excel so therefore does not come from a query.
I want to use a combobox (or a textbox) so that the user can enter in the reference number and it will filter the table (rather than using the filters already provided (as they just get confused))
Is this even possible? I should add, the reason why I want the table showing (and not a query from it) is that I want the user to be able to edit the table once they have found the reference number they are looking for.
Any help would be much appreciated.

You can use the form's filter method to programatically filter the rows. careful though, as you probably are going to need a mechanism to remove the filter, like a separate button as it won't be obvious. OR, you may still want to keep the form's "Navigation Buttons" property to true. this would then have allow the user to see that the rows are filtered, and also allow them to remove the filter.
Use the form's filter methods to filter. so say they want to filter on a field called "value1" with value of 1, it would be like this. if your filter condition is text, then use single qoutes around them.
Me.Filter = "[value1] = 1"
Me.FilterOn = True

I think your question is more about a ComboBox updating a view, right. I don't think this really has anything to do with Excel, right. If this is correct, please see the link below.
http://www.fontstuff.com/access/acctut17.htm
Also, see this.
http://www.fontstuff.com/access/acctut18.htm

Related

ms-Access Not using combo box display values as the lookup value

NOTE
I significantly edited my original post to include more relevant information and removed insignificant information. Some of the comments are based on the information removed, but the integrity of the original question is still intact and the comments are still relevant and useful.
In my database I have a table tblStandards that has a list of compound names with their associated fields.
I created a form to generate a subform which only populates compound names and their data when you select a solution mixture (I called these "handles"). I am using this subform as a means of generating a "Location Finder" of all the respective compounds associated with that solution mixture "handle". The issue is some compounds are used in multiple different mixtures, thus having multiple "handles". I have included a cascading combo box as recommended by #June7, but I am running into an issue with the last combo box filter.
I don’t want to have a separate field attached to my tblStandards with the combo box display value ("handle") just to filter my table (which is what I have done in the past). Using combo box display value field in my table works but it is limited and I wish to make it more modular. I have a second table tblComboBox which has three fields; [Compound Name], [Standard_InternalStd], and [Cal_QC_Handle].
I have the cascading combo box working, except for last filter. I think I found a round-about way to filter based on my tables. I am using an After_Update event with the FilterOn function to filter a TempSubform which is filtering the tblComboBox based on matching the [Cal_QC_Handle] to the cboxSecondChoice, then using TempSubform![Compound Names] field as a second FilterOn function for my MainSubform.
My code is working, but the second FilterOn is only using the first Compound Name from my TempSubform to filter MainSubform. I want to filter based on all the rows in my Tempsubform.[Compound Name]. I think my issue is in my " & Me.Temsubform![Compound Name] &" block of code.
Private Sub cboxSecondChoice_AfterUpdate()
Dim Filter_Tempsubform As String
Filter_Tempsubform = "[Cal_QC_Handle] ='" & Me.cboxSecondChoice & "'"
Forms![Standards_Form]![TempSubform].Form.FilterOn = False
Forms![Standards_Form]![TempSubform].Form.Filter = Filter_Tempsubform
Forms![Standards_Form]![TempSubform].Form.FilterOn = True
Dim Filter_MainSubform As String
Filter_MainSubform = "[Compound Name] = '" & Me.TempSubform![Compound Name] & "'"
Forms![Standards_Form]![MainSubform].Form.FilterOn = False
Forms![Standards_Form]![MainSubform].Form.Filter = Filter_MainSubform
Forms![Standards_Form]![MainSubform].Form.FilterOn = True
End Sub
The issue is the filter is only using one Compound Name (the first on the list) to filter. I need the filter to use all the Compound Names from the newly filtered TempSubform. Apologies if this is a very convoluted approach. Every example that I have seen so far always has the combo box value embedded in the table that they are filtering, which is something I wish to avoid.
UPDATE
I have abandoned my 1st attempt (the double FilterOn function with a temporary Subform) and I have a working form! I had to modify my tblStandards to include a new field which contained values from my final combobox selection (which I wanted to circumvent initially due to my perceived limitations of this design). The new Form-Handle field on my table is a string with multiple single "handles" which I use if the final combobox selection (only a single "handle" can be selected) is in the subform using the wildcard "Like *". Each one of these "handles" corresponds to a solution mixture which is a specific list of compounds.
This solution allows me to have a single compound used to make multiple different solutions, and if you select any of these solutions to make from the dropdown combo box the compound will be returned. I think this is the simplest solution to my issue and I might have just been too stubborn looking for a over-complicated solution.
I modified code from Allen Browne's ms-Access "Filter a Form on a Field in a Subform"
Relationships (All)
Form with cascading comboboxes and filter button
Working code
As #June7 said, cascading ComboBoxes (or ListBoxes) are the standard UI design for multistage filtering of data tables. If I have the available form real estate, I prefer cascading ListBoxes over ComboBoxes, because of the visual cues they provide. For example, look at how Digi-Key does it. Problems with cascading ComboBoxes have been questioned to death here. Boxes which filter data, list or combo, are usually unbound, and should not be simultaneously used to update data. Their sole purpose is to display item choices, select an item, and pass it's value to the next filter.
I'm linking below to a few tutorials, which require little to no VBA code. The 3rd tutorial filters "plants and animals, categorized by their taxonomic rank", which is a similar case to filtering chemical compounds. The 4th is one of my previous answers to a similar question.
Microsoft Access: How to Create Cascading Combo Boxes
Access 2016 - How to Make a City/State Selector (Cascading Combo
Boxes)
Creating Cascading Combo Boxes and List Boxes on Microsoft Access
Forms
Creating Cascading Comboxes in VBA code using RowSource

MS Access: Dependent drop down combobox in Split form without affecting the rest? [duplicate]

This question already has an answer here:
How to query combo box of only current record/row in Access data entry form?
(1 answer)
Closed 1 year ago.
I am trying to make a dependent drop down work with my database here but it is giving me a hard time for different reasons that I will explain.
This is what I have:
A form called "tblOTS" (split form based on an actual "tblOTS" table):
As well as a table called "tblAlphaCode":
When looking at the property sheet for the "Alpha Code" combobox (actually called "strOTSAlphaCode") on my tblOTS form, this is what I have:
The current SQL statement under "Row Source" for this strOTSAlphaCode is:
SELECT tblAlphaCode.strAlphaCode, tblAlphaCode.strCategory,
tblAlphaCode.ID, tblAlphaCode.numSortingOrder
FROM tblAlphaCode
ORDER BY tblAlphaCode.strCategory, tblAlphaCode.numSortingOrder;
Basically, when user select an Alpha code in the drop down from "tblOTS" form, it adds the ID of the tblAlphaCodes into the actual tblOTS record.
My goal is to have the user select first a "Category" (here FASTENERS/HARDWARE ...) when adding/modifying an OTS record, and then have the "Alpha Code" drop down dependent on what category was just selected.
I first tried to changed the SQL statement using a WHERE condition on the category field, based on the form category field itself:
SELECT tblAlphaCode.strAlphaCode, tblAlphaCode.strCategory, tblAlphaCode.ID, tblAlphaCode.numSortingOrder
FROM tblAlphaCode
WHERE (((tblAlphaCode.strCategory)=[Forms]![tblOTS]![strOTSCategory]))
ORDER BY tblAlphaCode.strCategory, tblAlphaCode.numSortingOrder;
And created a strOTSAlphaCode.requery in my Form_Current event to update it everytime.
However, it affects the whole form itself as my control source is directly affected by my Row Source in this instance, and the form looks like this:
You can see that the drop down is working beautifully, however, all the fields that do not have the same category as the current record that I work on (FASTENER <> HARDWARE here), are missing their Alpha code (the second record is missing "O-RING" compared to the first picture from this post); this behavior is problematic!
I tried to find workarounds by changing strOTSAlphaCode into a simple text box only containing the Alpha Code ID, added an unbound text box on top with dlookup function to find the actual alpha code related to this ID, and an unbound combobox in between with the exact same SQL statement inside the Row Source Property, that would update the strOTSAlphaCode with some VBA ... not ideal right?? Ahaha. This is why I believe there is a simpler way that I am not aware of, but also I would like to use a "search as you type" code for this combobox later on and this solution was making it very difficult.
How can I make this work? I believe the answer is a simple/different SQL statement to put in my Row Source property, that is probably something related to some type of JOIN statement? Or something else? I expect to write some VBA code to make all of this work flawlessly, but I want to make sure that I have the right SQL statement first.
Thank you June7;
Yes, the link you gave me ( this link ) states 2 solutions, and the second one is the one that I talked about when describing my problem:
for forms in Continuous or Datasheet view, include lookup table in form RecordSource, bind a textbox to descriptive field from lookup
table, position textbox on top of combobox, set textbox as Locked Yes
and TabStop No
So I guess, the answer is that I MUST have a textbox with dlookup setup for my case; I put it on "locked" so that if the user wants to change it by typing in it, he will first have to select the arrow. This will work with what I wanted to do
Cheers,

How to make access query criteria in VBA

I am trying to stop a name from appearing in a listbox that is linked to a query. The listbox shows records and fields from a table.
I am unable to just type the following in the criteria field:
Not "Administration"
or
<> "Administration
I am not sure why but I think it might work if i add it in code instead. How do I do this.
Thanks
Probably the field contains invisible characters or leading/trailing spaces. You can check this easily if you change the criteria to = "Administration". If query returns no rows, the data is not exactly equal. You can try criteria Not Like "*Administration*", but this way may not work for all data. Correct condition is <> "Administration"
You have to edit the listbox RowSource property, as follows:
1- show the listbox properties window
2- go to RowSource property under 'Data' Tab
3- click the button next to RowSource property (which will open a Query Editor window)
4- Add the condition:
Trim([ColumnName])<>"Administration"
where you replace ColumnName with your actual column name
I hope this helps out.
(Sorry I'm still using an older MS-Access release nevertheless you should get the idea).

Access form - how to make text field have a control source from a SQL query?

Background
I have two tables:
Projects
EmployeeID
Employee
EmployeeID
Name
I have a query I am basing a form on containing, among other items:
SELECT e.Name FROM Projects p JOIN Employee e ON e.EmployeeID=p.EmployeeID
When I make a form in Access based on this query, I can very easily display e.Name on my form because it is joined from the query.
My real example is of course considerably more complicated than this simple example. The above works fine for read-only queries and scales well. However I would like to use a Splitform view and this becomes very slow with many joins for even small numbers of recordsets. Considering a large percentage of my joins are simple like the above, I am hoping for a way to remove as many as possible.
On the form, e.Name will be read only and not be update-able.
Similar question
In this question I am able to successfully change a combo-box into a lookup. The accepted answer allows a combo box to control Projects.EmployeeID by displaying Employee.Name field in the combo box.
Possible work-arounds
I know one way I could do this is use a combo-box but disable it. This would look a bit weird since it'd have the drop down selector but not be selectable.
Alternatively, I could make it a completely unbound field and write VBA code to update the form each time the recordset changes by running quick queries, getting the text value I am searching for, and updating a label accordingly.
Neither of these are overly appealing, however.
Question
How can I display a single text field on an Access split-form which is the result of a very simple query lookup, based on an ID from the main table field?
You can use Dlookup to return this reference very simply
Construct a Dlookup formula like:
=DLookUp("Name", "Employee", "EmployeeID =" & "[EmployeeID]"
and use this as the ControlSource for the textbox.
Some notes:
The & is important as it binds the formula to the single record displayed on the form
[EmployeeID] refers to the current record displayed on the form. This assumes that "EmployeeID" is included in the query for the form, whether bound to the Projects table or included in the query

query filtering, finding the balance between flexibility and ease of execution

So I've been researching for days now on how to filter a rowsource result on a control in a way that is comfortable, hopefully you understand what I mean by that as I explain. I have found solutions, a bunch of solutions. I'm more concerned with evaluating their benefits and negatives.
I have a specific example, but my concern is really more generic. This, to me, seems like the backbone of my application and so I want to make sure it's being done correctly, the best way, not just in a way that "works".
Basically, I have progressive combo box filters. The first box filters the second box, which then selects a record in a Single Form view. The two combo boxes are in the header of the form.
Lets say I have a table CanadianCities. The two combo boxes might be, cboProvinceFilter "Filter by Province", and cboCitySelect "Select City"
When I load the form the province filter is off, so the cities list is populated with a rowsource that selects ALL the cities (SELECT ID, CityName FROM CanadianCities). But that's a big list, so I have the second combo box to narrow that list down by province (SELECT ID, ProvinceName FROM CanadianProvinces).
So the goal is that on cboProvinceFilter.AfterUpdate to requery cboCitySelect with an altered where clause ("[...] WHERE ProvinceID = [cboProvinceFilter]").
The problem is in how to alter the where clause. Ideally, the above would work right in the designer, but SQL designs seem to be out of the form's scope so cboProvinceFilter doesn't exist there. I agree with the opinion that direct referencing forms is bad. I don't want to marry my sql to the form like that. Plus, I want to use a navigation form, but also have a mobile option, so running the forms individually AND in navigation would be ideal, absolute referencing can't do this.
Having my repetitious SQL statements buried in code feels like poor design, and repeating the same queries with slightly different filtering is terrible when Parameters are exactly for that reason.
And some will scoff at this, but it also feels bad to rewrite the functionality of the Access designer in VBA. If I build my own SQL, execute my own queries, and populate my own lists, why did Microsoft put all the effort into building this productivity assisting tool for? Filtering is not exactly an obscure feature of database management... I feel like there must be a reasonable way to do this sort of thing.
Also, popup forms are obnoxious, so I won't be making specific forms just to have reliable absolute references. That definitely feels like a cop-out.
Solutions that do feel good but I haven't made work...
SQL Parameters
The most sensible way of doing this I feel should be with SQL Parameters, as that's what they're intended for right? The QueryDef would store values for it's parameters that could I could change as needed. However, I would let the queries execute naturally on requery.
So instead of writing the handful of lines to execute the Query and populate the control, I'd just set the parameter values and call requery on my control, which has all that functionality built into it.
So defined some parameters in the SQL statement, then tried to set the values of those parameters in VBA before the Query was executed, but JET always seems to pop-up for the parameters if it doesn't reference an actual object, it wasn't checking my code-set querydefs.
For that to work, it seems that I'd have to execute the SQL manually, and parse my own recordset, and populate the control. Which feels like an excessive amount of repetition for every filter option I'd want to offer.
Relative Referencing
I don't mind referencing forms as long as it's a relative path. Unfortunately [Screen].[ActiveForm] refers to the navigation form, not the actual, active form... So that seems to be out.
Right now I'm thinking my only option is to set rowsource manually then call the control's requery. that's the less offensive feeling option. Might be best to take the current query and string replace the where portion, so i don't have to update every event if the query structure changes.
Final Thought
Anyway, this is getting ranty, so let me know your thoughts. I'm not really looking for code solutions, which is why I offered few to no hard examples. I'm looking for a paradigm for managing this kind of filtering that isn't too restrictive (absolute referencing) or too repetitive/wheel-re-inventing (hard coded sql, executing, control populating).
If your Access version is >= 2007, you can use the TempVars Collection. Here is an Immediate window session.
' add a TempVar with value
TempVars.which_id = 12
' or do it explicitly with Add method
TempVars.Add "which_id", 12
? TempVars!which_id
12
' asking for the value of non-existent TempVar returns Null
? TempVars!bogus
Null
A query can reference the TempVar to filter the result set.
SELECT f.*
FROM tblFoo AS f
WHERE f.id=[TempVars]![which_id] OR [TempVars]![which_id] Is Null;
So you could use that approach in the row source query for the cboCitySelect combo box. Then assign the TempVar value in the After Update event of cboProvinceFilter and next Requery cboCitySelect.
For Access versions < 2007, the TempVars Collection is not available. In that situation you could use a custom VBA function to hold a static value which can be referenced in a query.
SELECT f.*
FROM tblFoo AS f
WHERE f.id=TargetId() OR TargetId() Is Null;
Public Function TargetId(Optional ByVal pValue As Variant) As Variant
Static varReturn As Variant
If IsMissing(pValue) Then
If VarType(varReturn) = vbEmpty Then
varReturn = Null
End If
Else
varReturn = pValue
End If
TargetId = varReturn
End Function