Excel VBA mulitiple checkboxes - vba

is it possible to create listbox with multiple checkboxes in one row (Excel VBA)?
Thanks
Kamil

I'm not sure I understood your question fully, but I'll elaborate on ListBoxes as much as I can.
First things first: Checkboxes and ListBoxes are different objects in Excel Userforms. The first is the little box that returns a "true/false". The second is a list of items which can be chosen. Clicking in a Checkbox will make the tick mark appear/disappear (or fade if tristate is enabled), while clicking a Listbox row will turn the listbox row "blue"/"white" (or whatever color is being used for the selected rows). In both elements, clicking is a way to toggle between True and False.
While a checkbox only allows for a single information to be marked as True or False, a Listbox allows you to select entries out of a list. That list may be inserted through code (.AddItem method) or passed from a range (.RowSource property)
ListBox objects allow for multiple columns of data to be attributed to one row element, but each row is an entire element (which means you cannot pick the element on row 3, column 2 - only all of row 3). The number of columns is established using the ColumnCount property.
By changing the value of the MultiSelect property, you'll allow the user to select multiple or single row elements simultaneously on your Listbox. Using the Selected( RowIndex ) property, you can check whether or not an item is currently selected (returns True/False). Remember that row indexes start at 0.
Finally, if you're using the MultiSelect property set to fmMultiSelectSingle and have a single column (as far as I know), the Text property can be used to return the selected item's value.
An easy example of a listbox is in Excel can be found at File > Options > Customize Ribbon (or something like that). There are two listboxes, one (on the left) with the visible items and another with the available items. A pair of command buttons is used to move items between boxes. That's a simple application you can likely find already setup online.
Am I on track to answer your question?

Related

Datagridview.Rows(#).Selected not updating CurrentRow.Index

VB.Net 4.6.1
Windows Forms application
I have a bound datagridview that I'm trying to sort and select. The data loads fine and I can click the headers (with some code) and the sorting works well. I'm working on reselecting a record after the sort is complete and I'm running into some trouble.
Assume that I have a datagridview with 20 records in it. On the form I also have a button that runs the following:
MessageBox.Show(MyDataGridView.CurrentRow.Index.ToString)
I also have a Sub that handles MyDataGridView.Sorted and in it I have one test line as follows:
MyDataGridView.Rows(2).Selected = True
After the data loads I click on the 11th record (selectionmode fullrowselect) and then I click the button. Box pops up and says "10" (0 based index). I click one of my column headers, the data sorts and the highlight bar jumps up to the 3rd record (index 2). However when I hit my currentrow.index button it still says 10. Additionally if I hit the down arrow key the selection bar jumps down to the 11th (index 10) record in the list.
It seems that using "Selected" doesn't update the currentrow.index value and since it is read-only I can't force it. Can anyone educate me on what's going on because, as it is, my users would be confused if the arrow up and down keys didn't work properly after a sort.
Thank you!
"Current" and "selected" do not mean the same thing. How could they, when multiple rows can be selected but there can only be one current row? The current row is the row that currently contains the caret and a selected row is one that is highlighted. If you want the row at index 2 to be the current row then you need to make a cell in that row the current cell, i.e. assign a cell in that row to the CurrentCell property.

Comparing two list boxes Vb.net

Listbox 1 contains names of hairdressers and Listbox 2 contains services provided by all of them then in Listbox 3 both the selected hairdresser(only 1 allowed) and and selected services are contained. There is a remove button which removes items from Listbox 3. I want a code for the button that if a hairdresser is removed all services also get removed otherwise only services are removed.
For Each str As String In Hairdresser.lstHairdresser.Items
If Not lstHairdresserAndServices.Items.Contains(str) Then
lstHairdresserAndServices.Items.Clear()
Else
'more code here but above statement never gets true
End If
Next
If the hairdresser is always the first item in the 3rd listbox, all you have to do is check if the selectedindex equals 0. If so, clear the listbox. Otherwise just remove the selected item.
Alternatively, you could search the the 1st listbox for the selected string. If found clear the listbox otherwise remove the selected item.
It is also possible to mark the listbox items when you add then to the listbox. Set the tag property to something like "hairdresser" or "service" and when the remove button is clicked all you have to do is check the tag property.
Finally I would recommend a different approach: Instead of adding the items to the listbox, fill a data structure with the hairdresser's name and services, display this structure in the listbox and when the remove button is clicked compare the selected item to the structure to find out what was selected.

Number Picker in Access / VBA

I am trying to put a number picker in a form in MS Access 2007. Here's an example of what I am trying to make:
I cannot find this in the default form controls, and have tried to make one myself using a listbox. Listboxes can be modified to look just like the number picker above, however the arrows only change the view, of the list, and not the actual selection (that is the value). For example, with the list box, if I have it range from 1 to 3, and default at 1 - when I change it to 2 via the arrows, the value of the listbox does not change, and is still one.
Does anyone know how to get a number picker in Access?
So you want to create a list of numbers and allow users to change the value displayed (AND stored as the control's value) using up and down arrows, such that they select the next or previous in the list.
I would suggest creating a text box and two buttons. Populate an array with the list of values. When a button is clicked it would:
A. Find the position in the array of any value already entered into the text box (eg loaded from a database)
B. Get the next or previous item from the array.
The array is populated as required (probably when the form is opened).
If you just need to allow the user to enter a whole integer number (ie a number spinner) you would do as follows:
Create one using a (locked) textbox and two buttons. Just add a textbox (name it something like txtValue) and two buttons (btnUp and btnDown), then add code like this to the Click event of those buttons:
Private Sub btnUp_Click()
Me.txtValue = Nz(Me.txtValue, 0) + 1
End Sub
Private Sub btnDown_Click()
Me.txtValue = Nz(Me.txtValue, 0) - 1
End Sub
You could add if statements to limit the data being entered
Or you can use a 3rd party control.
http://www.fmsinc.com/microsoftaccess/controls/components/spin-button/index.html
There are probably more, but be aware that using these sorts of controls in Access is unsupported, and there is no guarantee moving forward that they will work in Access. You're far better off using the native methods described earlier.

VB Getting the selected item from a List View

I have a list view with two columns and I'd like to be able to save the value of the leftmost column for the selected row, or even better make it so that once the user clicks on either the right or left column of any given row, the entire row selects and not only the field that was clicked.
However I'm struggling to get the field saved which is more crucial than the row highlighting.
In a list box it would be
string = listbox1.selecteditem.tostring
However this doesn't seem to work for the list view. It won't even let me put "Selecteditem" and instead requires I put selecteditems, however this doesn't seem to do what I want either.
When I use the code:
string = ListView1.SelectedItems.ToString
I get the result of
string = "System.Windows.Forms.ListView+SelectedListViewItemCollection"
Despite the selected field actually being "EGG".
I need to have two columns so can't switch to using a listbox, although that seems like it would be the easier solution.
When I tried googling this question I could only find things for C#
Set FullRowSelect on to get the entire row to select.
SelectedItems.ToString refers to the collection of selected items.
SelectedItems(0).Text refers to the first selected item's text property.

Gray out a form row's (detail's) button conditionally with VBA code

I have a standard form in MS-Access which lists a bunch of orders, and each row contains order no, customer, etc fields + a button to view notes and attached document files.
On request from our customer we should gray out the button btnAnm (or check or uncheck a checkbox) depending on a calculation from two queries to two other tables (a SELECT COUNT WHERE and a check if a text field is empty).
I've tried btnAnm_BeforeUpdate(...) and btnAnm_BeforeRender(...) and put breakpoints in the subs, but none of them trigger. The same if I use the control Ordernr instead of btnAnm.
I'd like a function in the Detail VBA code to be triggered for each "Me." (row) so to speak, and set the row's control's properties in that sub.
What do I do? I've looked at the help file and searched here.
*Edit: So I want to do something that "isn't made to work that way"? Ie. events are not triggered in Details.
As an alternative, could I base the value of a checkbox on each line on a query based on the 'Ordernr' field of the current row and the result of a SELECT COUNT from another table and empty field check?
Do I do this in the query the list is based on, or can I bind the extra checkbox field to a query?
A description of how to do this (combine a COUNT and a WHERE "not empty" to yes/no checkbox value) would be perfectly acceptable, I think! :)*
You cannot do much with an unbound control in a continuous form, anything you do will only apply to the current record. You can use a bound control with a click event so that it acts like a button.
Presumably the related documents have a reference to the order number that appears on your form, which means that you can create a control, let us call it CountOrders, with a ControlSource like so:
=DCount("OrderID","QueryName","OrderID=" & [OrderID])
The control can be hidden, or you can set it up to return true or False for use with a textbox, you can also use it for Conditional Formatting, but sadly, not for command buttons.
Expression Is [CountOrders]>0
You can also hide the contents and add a click event so that is acts in place of the command button. Conditional Formatting will allow you to enable or disable a textbox.
As I understand your question, you have a continuous form with as command button that appears on each row - and you'd like to enable/disable the button conditionally depending on the contents of the row.
Unfortunately you can't do that. It seems that you can't reference the individual command buttons separately.
Having wanted to do something similar in the past I came up with two alternate ways of setting up my interface.
Put a trap into the onClick code for the Button. Which is icky, because it is counter intuitive to the user. But it gets you that functionality now.
Move the command button (and editable fields) up into the form header, and make the rows read only. Your users then interact with the record only in the header, and select the record they want work with in the list below. As I recall this is known a Master-Detail interface.