Select case among different checkboxes inside frame - Userform issue - vba

I have putted several checkboxes in a frame and I need to make an select case statement among these checkboxes. Is there a way to select the checkboxes which are within the frame through a select case statement?
I have tried it below ( my frame is named diet_frame ) but I get a type mismatch error.
Private Sub add_button_Click()
Dim target_range As Range: Set target_range = Range("A2:G29")
Dim period As String
target_range.End(xlDown).Offset(1, 0).Select
With Selection: i = 1
Selection.Value = name_input
Selection.Offset(0, i) = period_input.Value
Select Case diet_frame <<<--- name of my frame, trying to get to the checkboxes placed inside it.
Case meat_input.Value = True
Selection.Offset(0, i + 1) = carnivore
Case vegetation_input.Value = True
Selection.Offset(0, i + 1) = herbivore
Case vegetation_input = True And meat_input = True
Selection.Offset(0, i + 1) = omnivore
End Select
Selection.Offset(0, i + 6) = group_input.Value
End With

Frames are usually used to group option (radio) buttons, to make them mutually exclusive. I don't think they provide the functionality you expect. You need to be explicit about a few things: Where are name_input, period_input, group_input coming from? If those are cells I expect to see some "RangeRefersTo". Do you have a single set of checkboxes or many sets aligned with these many rows of the Selection object? Programmatically generated or manually (and left as-is for the life of workbook)? You might have meant a "ForEach ... in Selection" rather than a "With"? The With is not going to iterate through cells for you. By the way, you aren't incrementing your "i" column-number so why not just hard-code the 1, 2, and 7? If you have lots of static checkboxes use the tag property to store the row number associated with them. That is a way to tie them to specific cells if you don't have bound-cells for them. If you have lots of boxes and bound-cells then you can't re-use the 3 names for them without going to some extra trouble. You want to poll a bunch of checkboxes?
(quite possibly pseudocode)
Dim ctrl as control
For Each ctrl in controls
If ctrl.typeof = "checkbox" then
'maybe further specificity based on If ctrl.name = "somename" ...
' more code...
cells(ctrl.tag,7).value2 = whatever
End if
As far as your "Select", your code will run as-is if you just put Select Case True (weird but it works) but for Omnivores you're setting the value 3 times. Actuall you don't even need VBA. You can do all this with cell formulas. Put 1 for true in bound cell for meat, 2 for veggie. Put a sum of them in an IF or CHOOSE formula in the target cell (where "...vore" will appear). So 1 is Carnie, 2 is Veggie, 3 is Omni. On a Gnu/Linux box or I'd be more explicit.

The help says that
the select case statement requires a numeric or string expression - ie an expression which result can be evaluated as a number or a string via the play of automatic conversions. So strictly on the form, and unless the Frame object default property actually returned a numeric or string expression, you're going to get a type mismatch error there with your code
the result of the expression from the select case statement is going to be matched against the result of the expressions for the different Case clauses - so these expressions need to be type compatible as well
Try and use the True keyword as your expression for the select case statement - booleans are automatically convertible to both numbers and strings -, and the values of your checkboxes for each Case clauses. This would also require for you to move the case where both your checkboxes are True to the first place in your Case hierarchy - reason for this is that when expressions match for more than one Case clause, only the statements following the first match are executed

Related

MS Access Retrieve Values from ListBox

UPDATE: 3/20/2019
After subthread conversation (below), I renamed the ListBox. ItemsSelected property WORKS. Value still returning NULL int he code
This is my first time dealing with multi-select lists in Access. I have a report form with some dropdowns, checkboxes, and a listbox. The listbox contains almost 70 items - Let's call them "Cities".
The ListBox allows multiple selections. In VBA, I'm taking each of the parameters - from the other controls on the form, to create a giant WHERE condition that feeds my report.
The problem is that Access is not reading the values selected from the ListBox. When I step through that line of code, the value is NULL.
So far:
Dim s As Variant
s = Me.City.Value & ""
This is where I know I wrong-turned, but, not having dealt with a multi-select ListBox before, I don't know the syntax to get the values read.
Next: Check for whether or not values are selected in List "s":
If s <> "" Then
Check for other parameters in the current WHERE condition. IF none exist, THEN
If c.WhereCondition = "" Then
c.WhereCondition =
Set WHERE Condition by comparing List values (which are Strings) to the Yes/No values of equivalent fields in Source table.
I have to compare the List values to the 70 fields in the table - to pull out those records that match.
No, there's not 1 field - say Cities, with 70 possible values. Instead, each of the 70 possible Cities is its own Yes/No field. I inherited this DB. It's how it was built.
Currently, my attempt at this looks like:
c.WhereCondition = "( City1 = -1 OR City2 = -1 OR City3 = -1 OR .....)
`IF there are parameters in the current WHERE clause, THEN compare values in List to Source table, AND APPEND result to WHERE condition with "AND"
ELSE
c.WhereCondition = c.WhereCondition & " AND (City1 = -1 OR City2 = -1, OR ...)
End If
End If
I hope I was able to explain this well enough. The 1st problem is getting the values read. I won't know if my attempt at comparison is right or wrong without that.
THIS took a LOT of breadcrumbs to get me here!
Solution:
Dim s As Variant
Dim i As Integer
Dim ctl As Control
Set ctl = Me.Counties
If ctl.ItemsSelected.Count <> 0 Then
For Each s In ctl.ItemsSelected
t.WhereCondition = ctl.ItemData(s) & " = -1"
Next s
End If
I had to rename the control from County to Counties. Looks like the former was part of the report, and screwing everything else up. I did this after initially deleting & re-adding the control.
The comments here really helped. I just needed to figure out how to work with the properties in order to get what I wanted.
I have to compare 70 yes/no fields to the data, pulling out only those that return True. Hence the -1.
It compiles. It runs. Fingers crossed for data accuracy.
Thanks!

IIF false expression impacting truthiness?

I am developing an SSRS tablix report and struggling to remove some error messages from certain cells. The Expression in the cell is as follows:
=Iif(IsNothing(First(Fields!Details.Value)) , "", Join(Code.RemoveDuplicates(LookupSet(Fields!studyTitle.Value, Fields!studyTitle.Value, Fields!Link.Value ,"DataSet1")), vbCrLf ))
The custom function that's referenced is as follows:
Public Shared Function RemoveDuplicates(ByVal items As Object()) As String()
System.Array.Sort(items)
Dim k As Integer = 0
For i As Integer = 0 To items.Length - 1
If i > 0 AndAlso items(i).Equals(items(i - 1)) Then
Continue For
End If
items(k) = items(i)
k += 1
Next
Dim unique As [String]() = New [String](k - 1) {}
System.Array.Copy(items, 0, unique, 0, k)
Return unique
End Function
The problem I'm encountering is that cells in the output will display "#ERROR" if they are being run through the custom function with multiple blank values.
The goal of the initial IIF statement is to test those rows first to make sure that the function is only applied to those rows that have values, and the other cells should just be blank. The problem is that I'm still seeing errors for those cells, as if the false condition is applied anyway.
However, if I edit my IIF statement to have the same test condition but different true-part and false-part i.e.:
Iif(IsNothing(First(Details.Value)), "true", "false"))
Then suddenly I see exactly the rows I would expect to see marked true and false. If this is the case then I can't figure out where the errors are coming from in my initial statement.
I know the issue has to be somewhere with the RemoveDuplicates function because when I take that part out and just Join my duplicated values then I see no errors, and the false rows are the same as identified above.
Does anyone see something I'm missing that is generating this error or causing this seemingly inconsistent behavior from the IIf function?
Use If instead of IIf. The If construct shortcuts the evaluation, while the IIf evaluates all expressions.
=If(IsNothing(First(Fields!Details.Value)) , "", Join(Code.RemoveDuplicates(LookupSet(Fields!studyTitle.Value, Fields!studyTitle.Value, Fields!Link.Value ,"DataSet1")), vbCrLf ))
This is only available in VB.net and is not available in VBA. In VBA, you would use a standard If-Then-Else construct.

VBA ComboBox Value by Index

I've got a form that contains a combobox which contains the values
With io6
.AddItem "90°"
.AddItem "180°"
.AddItem "270°"
.AddItem "360°"
End With
The member of this method I am actually using is .ListIndex. When a user selects 270 degrees, I am sending a 2 to a variable. When I read the variable, I want have the combobox correctly show the appropriate value. In other words, if the variable is 1, I want the combo box to show 180 degrees. Is that achievable without a select\if statement that writes into .Value?
Sub varChange(val as integer)
With comboBox
Select Case val
Case 1
.value = "90°"
Case 2
.value = "180°"
Case 3
.value = "270°"
Case 4
.value = "360°"
End Select
End With
End Sub
The most direct I can ask this question is, can the method element be set based on the index? Can I set the combo box element based on the index rather than having to write in a new value?
I'm not sure if I got it right, but I think you want to get the list index of the selected item.
You can get that by
x = io6.ListIndex + 1
The +1 is there since ListIndex is 0 based, but you wanted it 1 based.
And something completely different,
Remove the brackets. Method calls without return values does not use them in VBA
Edit after comment
To take this the other way, i.e getting a value from an index value, do like this:
y = io6.List(x - 1)
sValue = combobox.List(combobox.ListIndex,0)
The most direct I can ask this question is, can the method element be set based on the index? Can I set the combo box element based on the index rather than having to write in a new value?
Yes,
I used the following line:
io6.ListIndex = val - 1
So in your code it's:
Sub varChange(val as integer)
comboBox.ListIndex = val - 1
End Sub

If cell is blank then make variable equivalent to any value

I have a workbook with 3 List Boxes. Each List Box is populated by a list that is created, each List Box contains a "Blank" data point. I am trying to write a script that goes:
For lpRows = 1 to 100
For lpColumns = 1 to 8
If ListBox1 = "" and ListBox2 = "Val" And ListBox3 = "Var" Then
Sheets(RndmSheet).Cells(lprows,lpcolumns) = Sheets(DiffSheet).Cells(lprows,lpColumns)
else
end if
However, my code isn't working because VBA is simply searching for a blank cell, where I would prefer it to return any value that contains both ListBox2 and ListBox3, but Listbox1 would be irrelevant.
Is there an easy way to use a wildcard to achieve what I want or will I need to simply make a rather large nested if statements to handle this?
I just added in an if statement
if sheets(rndmsheet).cell(lpRows,lpColumns) = "" then
VarCell = Sheets(rndmsheet).cell(lprows,lpcolumns)
end if
Sorry if that doesn't really make sense.

Macro query spread over multiple-sheets

Wording my question is slightly tricky so I've included screen-shots to make this easier. I have 2 separate spreadsheets which are currently not linked together in anyway. What I've been asked to do is:
For the drop-downs which have a * next to them, have this * drop-down get converted into a acronym (I.e. If it's Home Visit *, then this will be converted to HV), and have it automatically entered into Cell Position X. Please refer to Image 1 then Image 2)
So the user would click on Sheet one, select the relevant drop-down field and then assign how much time that task took. The second sheet would then update itself with this information - it would insert the users name, program and activities. This is where it gets very tricky. Based off the drop-down selection, if it is asterisked (*), then based off the field-type it will convert it into a set acronym which would then be placed in one of the data fields based off the entry date that has been provided.
I designed both spread-sheets and they have macros in the background, but I can't seem to work out how to best perform this. Would you suggest a transpose function which checks firstly the date criteria and then an INDEX(MATCH) function to match the criteria against a pre-defined name-range which converts Home Visit etc. to HV automatically? I'm also unsure of how to insert delimiters for each new entry that is read. If anyone can provide help I would be very grateful.
I'm not 100% sure I understand your question, but here goes:
What about adding a Worksheet_Change event to look for changes in the drop-down's cell, and then converting it to an acronym?
Place the following code inside the sheet of interest:
Private Sub Worksheet_Change(ByVal Target As Range)
'If Cell A1 is changed, put the acronym into A2
If Target.Row = 1 And Target.Column = 1 Then
Cells(2, 1) = GetAcronym(Target.Value)
End If
End Sub
Function GetAcronym(TheText As String) As String
Dim result As String
Dim x As Long
'Always grab the first letter
result = Mid(TheText, 1, 1)
'Get the other letters
For x = 2 To Len(TheText) - 1
If Mid(TheText, x, 1) = " " Then result = result & Mid(TheText, x + 1, 1)
Next x
GetAcronym = UCase(result)
End Function