VBA display selection options - vba

I am trying to write a code that will display a value depending on what checkbox is selected. There are a total of 5 checkboxes and I will be adding additional checkboxes in the future so I was wondering if there is an easy way to determine which checkboxes are checked to determine which values to display. I can do this in a really round about way but I would like minimize my code if possible.
In other words, if i write each scenario out I would have to write a separate code for all of the different selection possbilities:
1 only,2 only,3 only,4 only,5 only
1+2, 1+3, 1+4, 1+5, 2+3, 2+4, 2+5, 3+4, 3+5, 4+5
1+2+3, 1+2+4,1+2+5, 1+3+4,1+3+5, 1+4+5,2+3+4, 2+3+5,3+4+5
1+2+3+4, 1+2+3+5, 1+3+4+5, 2+3+4+5
1+2+3+4+5
Each value is associated with a sub that will fill the array if it is selected. And after the arrays are filled I need to perform an additional function on the ones that are selected. The function performed is the same but I do not want to perform the function if a value is not selected because it will defeat the purpose of my function otherwise. The function itself is to select duplicates from the arrays that were selected into another array.

You can use binary numbers for each checkbox:
First value is 1 (=20)
Second value is 2 (=21)
Third value is 4 (=22)
Fourth value is 8 (=22)
Fifth value is 16 (=24)
Hence, when you sum each permutation, you have a unique number you can check.
1 only is 0, 2 only is 1 and so on
1+2 is 3, 1+3 is 5, 1+4 is 9, 1+5 is 17
and so on
You can create arrays with every case you want to check.
At least, i hope this will give you some ideas or tips.
Regards,

What #JMax is referring to is more commonly known as bit-masking. Here's a quick tutorial:
Create a sample form named Form1 with 5 checkboxes named Check1, Check2, Check3, Check4, Check5. Then add the following two functions in a standard code module:
Function GetSelectedBoxes() As Long
Dim Ctl As Control, Total As Long
For Each Ctl In Forms!form1
If Ctl.ControlType = acCheckBox Then
If Ctl Then
Total = Total + 2 ^ CLng(Mid(Ctl.Name, 6))
End If
End If
Next Ctl
GetSelectedBoxes = Total
End Function
Sub ShowSelectedBoxes()
Dim Total As Long, i As Integer
Total = GetSelectedBoxes
For i = 1 To 5
If Total And 2 ^ i Then Debug.Print "Check" & i & " selected"
Next i
End Sub
Now open Form1 and check boxes 1, 3, and 4. Run the ShowSelectedBoxes routine and you should get the following output in the immediate window:
Check1 selected
Check3 selected
Check4 selected
I used the For...Loop for compactness in my sample, but you can just as easily break it out into separate If...Then statements to do something more meaningful with the checked boxes.
This approach will support up to 31 or 32 separate checkboxes.

Related

How to alphabetize fields in Unhide Columns dialog box in Access VBA?

I have a ton of columns in this table and I want them to be alphabetized so they are easier to find.
I remember seeing how to do this in a Youtube video but I can't find it for the life of me. Below is an example of the code I am using in multiple datasheet type forms. I'm not sure what needs to be added in to make these field lists alphabetize
Private Sub showHideColumns_Click()
frmInventoryListSubform.SetFocus
DoCmd.RunCommand acCmdUnhideColumns
End Sub
The "columns", the controls, have both a name and, optionally, a caption.
So, in your form, you can run this code to list these:
Private Sub ListColumns()
Dim Control As Control
Dim Index As Long
For Index = 0 To Me.Controls.Count - 1
Set Control = Me.Controls(Index)
If Control.ControlType <> acLabel Then
Debug.Print Index, Control.Name, Control.Properties("DatasheetCaption").Value
End If
Next
End Sub
May return a result like this:
0 StipendNo Student Number
2 PayNo Pay Number
4 PayDate
6 PayAmount

Gridview compare to list and set value to gridview checkbox

I have a grid view which has 3000 rows and one checkbox column and 2 textbox column.
I have a parameter list around say around 1700. it varies sometimes 5 or 10.
So I need to compare the list to the grid view and set the 1st checkbox column to true.
I use the compare and select method like below code which works well for a small number of parameter like 50,70
If Paramlist.Count > 0 Then
Dim row As Integer = 0
For Each listItem In Paramlist
Do While (row < gridview1.RowCount)
If Trim(gridview1.Rows(row).Cells(1).Value) = Trim(listItem) Then
gridview1.Rows(row).Cells(0).Value = True
Exit Do
End If
row = row + 1
Loop
Next
End If
It takes a lot of time to compare and set gridCheckbox value to true when I do it with more parameter list and the application seems like it is hanging when the user uses it.
Could anyone suggest me a faster way with less time complexity / best practice to set the grid check box value to true in the grid view.
[UPDATE]
I have attached a image of the exception thrown.
System.Invocation.TargetInvocationException

Dice Roller Populate TextBox(s)

I am still learning basic programming, literally off Visual Basic 2012 v11.
Here is what I am stumped on:
I made a stupid-simple Table-Top Role-Playing Character Log application.
I made a simple dice roller/"random number" procedure and set it to fill a ListBox with each button click of "ROLL" until the max of 6 was reached. That worked fine.
However, I changed my app to link with a database to store simple character information for all of the people playing,etc. Which means I now have separate dataset TextBoxes for each click of "ROLL". Would someone please advise me on the best way to populate one TextBox per button click with a maximum of 6 clicks, please?
I was using a loop to fill the ListBox with exactly 6 entries, and started that line of thought for filling the TextBoxes, but my late-night tired brain cannot find a way to fill ONE box EACH TIME instead of all boxes every single time.
THANK YOU FOR YOUR HELP!
My Code:
Private Sub btnRoll_Click(sender As Object, e As EventArgs) Handles btnRoll.Click
'Roll a character stat up to 6 and add it to the lisbox
'D20 is standard die, but stats below 6 are forgiven for this campagin
Dim Dice As New Random
Dim DiceRoll As Integer = Dice.Next(6, 20)
Dim intCount As Integer = 0
Dim Stat As String = Convert.ToString(DiceRoll)
Do While intCount < 7
Loop
End Sub
I don't believe you've included enough information to give an informed answer.
From my understanding, you'd like to take the result of the roll, and input it into one of several textboxes (you haven't given a number of textboxes, but you'd like it done in less than 6 clicks).
Depending on what the different fields will be, you may want to include your calculations within the loop, along with this, to specify the output and then roll again X times within the loop:
Do While intcount < 7
Select Case intcount
Case 1
txtBox1 = stat
Case 2
txtBox2 = stat
Case 3
txtBox3 = stat
Case 4
txtBox4 = stat
Case 5
txtBox5 = stat
Case 6
txtBox6 = stat
Case Else
'Nothing if not specified with other arguments.
'Roll again
stat = Convert.ToString(Dice.Next(6,20))
Loop

DevExpress XtraGrid GroupRow, CheckEdit Interactions Possibilities

Currently, I am displaying an XtraGrid that contains Group Rows. I have a "Select All" DevExpress.XtraEditors.CheckEdit control (which is different from this elusive "Select All" check box control I am reading about in the documentation). It is different for a reason: I want the check box to do something other than "Select All" (which comes in only three different varieties according to the DevExpress Docs.).
I want a user to be able to do one of two things with the CheckEdit control. [1] If no Group Rows are expanded, I want to select all Group Rows. [2] If one or more Group Rows are expanded, I only want to select the expanded rows.
Presently, I am able to manipulate the controls to do only one of the two things (see code). My question is twofold: is this possible; and, if so, how would I go about it?
Here is my code that does the second of the two 'things' described above:
'If the CheckEdit control is checked:
xtraGrid.SelectAll()
Dim rowHandles() As Int32 = xtraGrid.GetSelectedRows()
If rowHandles.Count > 0 Then
For Each RowHandle As Int32 In rowHandles
If xtraGrid.IsGroupRow(RowHandle) Then
xtraGrid.UnselectRow(RowHandle)
End If
Next
End If
As you can see, all this really is just a work around. There is also presumably more overhead than needed in my calling .GetSelectedRows(). I am just attempting to sort through the row types in order to keep the row selected or .UnselectRow()
You can use GridView.GetRowExpanded method to check whether a specific group row is expanded. For iterating through visible rows you can use GridView.RowCount property. To get row level just use GridView.GetRowLevel method. Also you need to check wether a row is new item row or is filter row by using GridView.IsNewItemRow method and GridView.IsFilterRow method. For all of this methods you need to get Row handle by using GridView.GetVisibleRowHandle method. When you are working with selection is better to use GridView.BeginSelection method and GridView.EndSelection method outside of your code.
UPDATE: If you want to select hidden rows within a collapsed group then you can use GridView.GetChildRowCount method and GridView.GetChildRowHandle method to get all hidden rows.
Here is some sample code that is performing your two things together:
Private Sub SomeSub
If xtraGrid.GroupCount = 0 Then
xtraGrid.SelectAll()
Exit Sub
End If
xtraGrid.BeginSelection()
xtraGrid.ClearSelection()
Dim isExpanded As Boolean = False
For rowVisibleIndex = 0 To xtraGrid.RowCount - 1
Dim rowHandle As Integer = xtraGrid.GetVisibleRowHandle(rowVisibleIndex)
If xtraGrid.IsNewItemRow(rowHandle) Then
Continue For
End If
Dim level As Integer = xtraGrid.GetRowLevel(rowHandle)
If level = 0 Then
If Not isExpanded Then
isExpanded = xtraGrid.GetRowExpanded(rowHandle)
If isExpanded Then
xtraGrid.ClearSelection()
Else
xtraGrid.SelectRow(rowHandle)
End If
End If
Else
xtraGrid.SelectRow(rowHandle)
'Update: select hidden rows
If xtraGrid.IsGroupRow(rowHandle) And Not xtraGrid.GetRowExpanded(rowHandle) Then
SelectRowHierarchy(rowHandle)
End If
End If
Next
xtraGrid.EndSelection()
End Sub
Private Sub SelectRowHierarchy(rowHandle As Integer)
Dim childCount As Integer = xtraGrid.GetChildRowCount(rowHandle)
For childIndex As Integer = 0 To childCount - 1
Dim childRowHandle As Integer = xtraGrid.GetChildRowHandle(rowHandle, childIndex)
xtraGrid.SelectRow(childRowHandle)
If xtraGrid.IsGroupRow(childRowHandle) Then
SelectRowHierarchy(childRowHandle)
End If
Next
End Sub

Macro Explanation

I was looking into how to create a shortcut with the help of VBA. The macro would basically allow me to filter the range based on cell's value. I found this macro on the internet
Public Sub FilterOnCellValue()
Dim nField As Long
With ActiveCell
nField = .Column - .CurrentRegion.Cells(1).Column + 1
.CurrentRegion.AutoFilter Field:=nField, Criteria1:=.Value
End With
End Sub
The code works fine, but I have a hard time trying to understant how the dude create. So what I know so far is the guys is creating a variable. but for some reason the variable is not in a string format but in "long" and the code works perfectly when I filter based on text in a cell. I thought that long can only be used for numbers, correct me if I am wrong (which i think I am:)). Secondly. whats up with .column - .currentregion. cells.....+1? I real have no idea what he did there.
Would really appreciate some help here. the forum has been very useful to me so far.
The secret to understanding anything is to break it into parts
Anyways, the documentation of Autofilter states that
Public Sub FilterOnCellValue()
Dim nField As Long
With ActiveCell
'.Column: Column Number i.e A=1,B=2 etc
'.CurrentRegion.Cells(1).Column: Gets the col No of the firstcell of the data region
nField = .Column - .CurrentRegion.Cells(1).Column+1
'Autofilter takes column number as the parameter
'see example below
'nField: gets the col number of the filter value within the region
' leftmost field is 1 hence +1
.CurrentRegion.AutoFilter Field:=nField, Criteria1:=.Value
End With
End Sub
for e.g if your data is in this format
A B
1 ID Value
2 1 Apple
3 2 Orange
4 3 Banana
5 4 Apple
6 5 Banana
Lets say you click on cell B5(Apple) and run the macro then
The macro first gets the column number of the selected cell =2
checks which column the current region's (A1:B6) first cell(ID) is in =1
calculate value in Step 1-Step 2 to get which column the selected value lies in, with respect to the region (A1:B6) , the idea is using the .column as reference to find out the column number of selected value within the region result of the step:2-1+1=2
Filters the column number passed from step 3(in our example value is 2) of the region A1:B6 for the selected value(Apple)
Hope this helps