Access VBA: How to count items of a ComboBox? - ms-access

In my ComboBox I have some items already selected.
I would like to count them with VBA. I was expecting to find something like the following string, but I get Compile error: Argument not optional.
Me.<ComboBox_name>.ItemData.Count
I also thought to use the following string but it gives me 0 items:
Me.<ComboBox_name>.ItemSelected.Count

To count the options, it is:
Me!<ComboBox_name>.ListCount
or to be precise, in case you use column headings:
Me!<ComboBox_name>.ListCount - Abs(Me!<ComboBox_name>.ColumnHeads)

Comboboxes are generally used for selecting or showing the selection of a single item, whereas listboxes naturally support multiple selections.
That said, if you're linking a multivalued* table field to a Combobox, for example, you could have a Combobox with multiple selections. If that's the case, the only time the values will be available in the .ItemsSelected property is while the Combobox has focus and is dropped down.
A way to work around this is to assign the Combobox's .Value property to an array. The array will contain the selected values. You may count them by taking the upper bound of the array and adding 1:
Dim comboitems() as Variant
Dim count as Long
comboitems = yourcombobox.Value
' array is 0-based so add one to get the count
count = UBound(comboitems) + 1
If the array is multidimensional, you read the value this way:
' array is 0-based so add one to get the count
count = UBound(comboitems, [dimension]) + 1
' where [dimension] is a 1-based index equivalent to the 'column' of the data
I hope that helps!
*Note: multivalued fields are usually ill-advised, as they are poorly
supported by Access and usually mean you should be normalizing your
tables, i.e. breaking out the multivalued field into another table.

Related

The value expression for the textbox4 refers directly to the field

I have mult dataset and i used expression and set the dataset as well but getting error
" The value expression for the textbox4 refers directly to the field dataex without specifying a dataset aggregate. when the report contains multiple datasets"
= Mid((Fields!Dateex.Value,3,2) + "-" + Left(Fields!Dateex.Value,2) + "-" + Right(Fields!Dateex.Value, 4),"Gas")
Your dataset "Gas" can contain 1 or more records. If you have a textbox that is not inside a tablix or other bound control then you need to tell SSRS how to deal with more than one record.
So, you need to do one of the following depending on your situation.
If textbox4 is in a table/tablix/matrix etc, you need to set the dataset property of the table/tablix/matrix to Gas, you can then remove the "Gas" part from your expression
If textbox4 is NOT part of a table/tablix/matrix etc, AND "Gas" only ever contains 1 record then you can change all your references from Fields!Dateex.Value to FIRST(Fields!Dateex.Value)
If textbox4 is NOT part of a table/tablix/matrix etc, AND "Gas" contains more than one record then you will have to decide how you can identify the record you need, this might mean using a lookup etc. If you get to this point, edit your question and show some sample data and you report design, without this it's difficult to help you.

Calculating a value in continuous form

I currently am using a continuous form in MS Access that the users input values into one field. In the form there are three records under one field. I'm not sure if this is possible or even how to do it, but I would like to subtract the value in the first record from the value in the second to calculate the value for the 3rd. Form in question
In the example I provided it would be 20-10 and then have the third record be 10. The field name is Initial_Value. I've been looking online and I haven't seen any information on how to grab those values to do this with VBA. The name of the form is "frm_main_process_values" and is a subform of "frm_main_msmt".
Add column with measurement type (initial, final, change, it can be hidden) and use for Value textbox with calculated control source based on function: =CalcDrop([ResType],[Result]).
And create public function in module with static variables, which remember previous values:
Public Function CalcDrop(strResType As String, lngVal As Long) As Long
Static lngInit As Long
Static lngFinal As Long
Select Case strResType
Case "initial"
lngInit = lngVal
CalcDrop = lngVal
Case "final"
lngFinal = lngVal
CalcDrop = lngVal
Case "change"
CalcDrop = lngInit - lngFinal
End Select
End Function
You will need to make sure that the rows order is the same for each series: initial, final, change. Here are results, column "Value" is calculated:
This is not possible in a continuous form, since the Value textbox has only one ControlSource, it can't be a bound field and a calculated value at the same time.
If it's always three records, and you pre-fill the form with the three records, and they have a defined order with a sorting field, you could have a button that calculates the value and writes it to the third record. But that would be a very odd usage of a continuous form.

SSRS Multi Value Parameter. Check whether "Select All" is selected

I have a multi value parameter in my SSRS Report. I want to find out whether (Select All) is checked in that parameter.
In other words, whether all the values in the parameter are checked or only some values are checked.
Is it possible?
I am able to find out number of selected values through Parameters!Parameter.Count. Is there a way to find out total of items in that parameter?
In case anyone is still having issues doing this, I just coded this easy fix.
=IIF(COUNTROWS("dataset").Equals(Parameters!parameter.Count),"it is equal","this is not equal")
For the specific use-case of showing the selected filter on your report in a textbox, here's the expression that will show "All" if "(Select All)" is selected, otherwise it will show all the selected values as a comma-separated list:
=IIF(
Parameters!YourMultivalueParam.Count = countrows("YourDataset"),
"All",
Join(Parameters!YourMultivalueParam.Label,", ")
)
(split onto multiple lines for readability)
countrows reference: https://technet.microsoft.com/en-us/library/dd255215.aspx
Credit to other answers, just want to extend them for this common scenario.
Your approach sounds good: I would make the options for the parameter come from a dataset.
Then you can use =COUNTROWS("DataSetName") to return the total number of options for your parameter and compare this with Parameters!*Parameter*.Count as you suggest.
I also faced this problem and I solved it this way.
I have one multivalued parameter named "Carrier". Then I have added one parameter "CarrierHidden" which is same as "Carrier" only thing is I made its Visibility as Hidden.
="Carrier=" & Switch(Parameters!CarrierHidden.Count = Parameters!Carrier.Count, "All",
Parameters!Carrier.Count > 1 And Parameters!CarrierHidden.Count > Parameters!Carrier.Count, "Multi",
Parameters!Carrier.Count = 1, Parameters!Carrier.Label(0))
The easy way will be to count the number of the selected parameters and compare them to the dataset
=IIF(Parameters!company_number.Count = CountRows("Dataset1"), True, False)
The problem is if you're trying to pull something for another data set then cross referencing the row count in another dataset won't work. You will have to go with what the previous post states. Create an internal parameter of the exact type and assign the default value to the entire dataset. That way you have the max count of the rows since the hidden parameter.count = rowscount. That way you can use it within another dataset also provided that dataset is AFTER the first one is populated.
According to Microsoft's SSRS help search:
=Parameters!<ParameterName>.Count
Returns the integer value 1. For a single-value parameter, the count is always 1.
I verified this does indeed work, check the integer returned for the built-in parameter count field.
Allow multiple values on a parameter selection. Checking the value of the above field will let you know how many values the user actually chose.
In my situation, I allow multiple values on company number. This gives users the ability to choose one company to report on or several at once. Per client request, if they choose more than one, display data horizontally. If only one company is chosen in the parameter list, show the data vertically and hide the other tablix.
So my visibility show or hide expression looks like this in the one tablix:
=IIF(Parameters!company_number.Count > 1, True, False)
and like this in the other:
=IIF(Parameters!company_number.Count = 1,True,False)

MS Access ComboBox.Column - use name instead of index?

i have ComboBox controls with multiple columns as a Row Source in an Access 2007 form.
i'm currently getting the selected values out of each ComboBox item this way...
value = ComboBoxName.Column(i) 'where i is the index.
i would like to use the actual names of the columns as with Recordset's...
value = ComboBoxName.Recordset.Fields("columnname")
(please note that this does not work properly on the Recordset's of the ComboBox'es: it only works AFTER the first time the ComboBox is changed)
my questions:
can i do something to "make this work" on a ComboBox's Recordset?:
value = ComboBoxName.Recordset.Fields("columnname")
is there a method that directly gets the value of the selected record using the name ?
does the ComboBox or it's Recordset have a method i can use to get a column index by specifying a column name ?
i would like to avoid writing a function and i don't feel comfortable specifying column indices which may change in the future.
There is no simple way to do this. You can create a recordset, or you can assign values to variable for each column name (FirstCol=0).
As an aside, why would the columns change? If you are using a select statement, the combo will fail if the table is changed.
PFIELD = Me.Form.Combo6.Column(0, 0)

Ms access: Autocomplete field with values from another table

please forgive me for my poor english and my big ignorance on programming.
I'm using Ms Access 2003.
Let's suppose i have two tables:
Table1: ID (autonumber), [...], Keywords (memo)
Table2: ID (autonumber), Keyword (text)
I want:
1) As the user types letters in Table1.Keywords that my database searches in Table2.keyword for the nearest value and proposes it by autocompleting (just like google proposes a search word as you type)
2) When user presses ", " that he can add one more keyword in the same field (and the autocomplete still runs for this next value)
3) If he types a keyword not included in Table2 and press ", " that he is asked if he wants this value to be added in Table2
Well, i'm not sure if all these are clear... maybe they are a lot of things...
But i'd appreciate if you could help me...
Thanks in advance
J.
It would be complicated to do it with a single control, but with two controls, a dropdown list for choosing the value to add, and a textbox displaying the memo field, you could have the combo box's AfterUpdate event append a comma and the chosen value to the existing data. Something like this:
Private Sub cmbChooseKeyword_AfterUpdate()
If Not IsNull(me!cmbChooseKeyword) Then
Me!txtKeywordMemo = (Me!txtKeywordMemo + ", ") & Me!cmbChooseKeyword
End If
End Sub
You'd also want the rowsource of your combo box to not list items that are already entered, so this is one way that would work for a relatively short list of keywords:
SELECT tblKeywords.*
FROM tblKeywords
WHERE InStr(Forms!MyForm!txtKeywordMemo, tblKeywords.Keyword) = 0;
Then you'd add:
Me.Dirty = False
Me!cmbChooseKeyword.Requery
...at the end of the AfterUpdate code above (inside the End If):
Private Sub cmbChooseKeyword_AfterUpdate()
If Not IsNull(me!cmbChooseKeyword) Then
Me!txtKeywordMemo = (Me!txtKeywordMemo + ", ") & Me!cmbChooseKeyword
Me.Dirty = False
Me!cmbChooseKeyword.Requery
End If
End Sub
...and you'd want to add the requery to the OnCurrent event of your form, as well (so that when you arrive on a record, the combo box already omits any keywords that are already in the list).
Now, all that said, I'd completely recommend against doing this. This is a denormalized way to store the data, and this leads to problems:
what if you want to delete one keyword?
what if you want the keywords to be sorted in alphabeticsal order?
what if you have 100s of thousands of records and you want to search this field with LIKE "*Keyword*" -- will it bog down to be terribly slow (no indexes, and not used well even if there were)?
You really should use a proper many-to-many structure, with an additional table between the one where you're currently storing the keyword memo and your keyword list table. This "joins" the two, and would then give you a list.
You could then use a subform with a dropdown list to populate each row of the join table.
If you like presenting the keywords on reports as a comma-separated list (as you're currently storing them), you can write a simple function to do the concatenation for you at the presentation layer of your reports (concatenation functions for that purpose are a frequent Access question here on Stackoverflow).
Why not use a "Combo Box" and set its Row Source Type to Table/Query, and then make the Row Source a query on the second table. Just make sure you don't turn on Limit to List.
CodeSlave mentions a way that will work. But it will only work for one value. There is no way to do the multi-words-separated-by-commas thing. Only one word at a time.
As for the Adding new values. The combobox control support an OnNotInList event which can do what you say.
Seth