Solved Listbox AfterUpdate and click when there is no selection

Local time
Today, 08:03
Joined
Sep 16, 2023
Messages
36
I have a problem that, although I haven't thought about it much, I don't think I see an easy solution.
In a multiselect lisbox when I click with the mouse and select an items/row, afterupdate and click are activated, but when I use the down arrow and I only position myself (not selecting) the 2 events are also activated, and although it is correct because I am in another row and afterupdate was activated because there was an update of the listbox, there was no selection.
Additionally, try in the beforeupdate event to see if the items were selected or not to compare it later with the new value of selected, but in the beforeupdate the new value is already present (selected), making it impossible to compare it to see if it changed.
In summary: there is no afterupdate event for a selected items, but one for the listbox and it is updated with anything (change of focus, positioning in another row, selecting it or not
Is there a way to only do things when a row is selected (changes color) and not when I scroll through the list?
 
I don't understand issue. Even by cursor movement on list, the OldValue is still what is in field. It isn't changed until record edit is committed to table.

Not sure what you mean by "no afterupdate event for a selected items" - AfterUpdate is triggered for click or cursor movement.
 
I had forgotten the OldValue can help me, I thought so
What I'm saying is that the afterUpdate event is triggered by moving from one row to another although there is no update of selected, no row has changed to selected/deselected.
I have to discard the movements or positioning in the rows since I am only interested in the selected/deselected changes
And thanks for responding
 
Oldvalue did not work, since the items do not have oldvalue, only the control and the listboxes always return null to value and oldvalue.
I think I will have to do everything manually, that is, I will memorize each selection value of each item and then compare them to see if they have changed and so I know which items were selected or deselected live to be able to do the job I need
 
Multi select listboxes do not have an oldvalue. By definition of what they are they need to be unbound. You need to refer to the listbox selecteditems property
 
The problem is simple, the multiselect listbox is not used to select anything, because it has no event before selecting or after selecting, therefore it is not useful to be used and know live if something was selected or not.

It's funny that a control that is specifically for selecting lists does not have an event for that, but rather has an event that is activated for selecting and moving.
By the way, the click event is simply activated after BeforeUpdate -->AfterUpdate -->Click unless the beforeupdate event has been canceled. And it does not identify any mouse click since it is also activated with a displacement, that is, positioning itself in another items/row
 
I think I have a somewhat improved solution.
If I use the set Listbox1.ItemsSelected.Count and memorize it, I can detect if an item was selected/deselected, since this counter will tell me one more or one less than previously, and if it has not changed then I do not take it into account because it would be a displacement or movement.
I only memorize one piece of information (total of selected ones) and not the entire selection, in any case, I always know where I am (position) in the listbox, to know which one was selected/deselected.
Of course I have which ones are selected and also the array of only the selected ones.
Unless someone knows a better way, I'll use this one.
 
Salomonic solution, lol
It works perfect:
Code:
Declarations
Dim Totalselect As Integer

- Load Event
    Totalselect=ListBox1.ItemsSelected.Count

-EventBeforeUpdate
   If Totalselect=ListBox1.ItemsSelected.Count Then Cancel=1
    'This cancels the AfterUpdate and click events (unless you need them for something)

-EventAfterUpdate
    ' Now it only enters when there is an effective selection or deselection of an items/Row
    Totalselect=ListBox1.ItemsSelected.Count    'I update the TotalSelected
    'do everything else that has to do with selecting an item and there will be no false select when moving position
 
Last edited:
Okay
I want to execute a code when selecting/deselecting in a multiselect listbox
This code will do things live, since I need to know in what order the items were selected, since selecting 4 and 7 will not be the same as selecting 7 and 4. and of course it cannot execute this code if I only move or move through the list with the arrows, you only have to execute this code if I select or deselect an item.
That's all
 
1694922960995.png

Very nice example, thank you very much for your dedication. impressive, and can be very useful, thank you.
However
As I explained before
Whether I use mouse click or down arrow, the system uses
BeforeUpdate -->AfterUpdate -->Click
Therefore I still have the problem (although it has already been solved manually)
 
Ooops, I missed the "multiselect" qualification in original post.
 
Okay
I want to execute a code when selecting/deselecting in a multiselect listbox
This code will do things live, since I need to know in what order the items were selected, since selecting 4 and 7 will not be the same as selecting 7 and 4. and of course it cannot execute this code if I only move or move through the list with the arrows, you only have to execute this code if I select or deselect an item.
That's all
Based on this, a multiselect listbox is not the best idea, you could use a transfer box design, where you basically select something in listbox 1 and it appears in listbox 2. That way your users will know the order in which things will be executed. There is no built-in way to know in what order things were selected, so, unless you memorize the order or you add a column where the order appears, then it will become tricky.

I was able to figure out how to do this by using a combination of dictionaries and strings and just the AfterUpdate event of the listbox.
Code:
Option Compare Database
Option Explicit

Private item As Variant, dict As Object

Private Sub Form_Load()
    Set dict = CreateObject("scripting.dictionary")
End Sub

Private Sub lbx_choice_id_AfterUpdate()
    Dim prevList As String, currentList As String
   
    ' add to existing dictionary
    For Each item In Me.lbx_choice_id.ItemsSelected
        If Not dict.Exists(item) Then
            dict.Add item, Me.lbx_choice_id.Column(1, item)
        End If
        prevList = prevList & "," & item
    Next item

    ' remove from dictionary if no longer selected
    For Each item In dict
        If InStr(prevList, item) = 0 Then
            dict.Remove item
        End If
    Next item
   
    ' build string
    For Each item In dict
        currentList = currentList & "," & dict(item)
    Next item
   
    'cleanup and print list
    Msgbox Mid(currentList, 2)
End Sub
 

Attachments

Based on this, a multiselect listbox is not the best idea, you could use a transfer box design, where you basically select something in listbox 1 and it appears in listbox 2. That way your users will know the order in which things will be executed. There is no built-in way to know in what order things were selected, so, unless you memorize the order or you add a column where the order appears, then it will become tricky.
Thanks, I understand, but the user sees the order in a live form/report
 
Look again at the events. The ONLY reason the Before and After update events fired was because you clicked on the control. Scrolling does NOT fire any of those three events.

The form I started with logs all form level events except the MouseMove (way too much noise) Then I added the listbox control but I only added logging to the three events you talked about - Before and After update and click for that control. To see what other events might be firing, add the logging code to every of the listbox event EXCEPT the MouseMove. The MouseMove is just annoying and obfuscates everything else due to the volume of log records it generates.

I agree with Edgar_, it would be far less confusing to use a temp table or the dictionary object if sequence is important to you.
Thank you, I may be wrong, but in the video I click initially and then down arrow several times and these are the events that appear
 
I had to put it public
I thought that with the link you could see it even if it was private
but apparently I have to send the Google account of each user who wants to see it and not just the link
 
Last edited:
The video doesn't show anything except that you clicked on the control. If you click on the control, it fires the Before/AfterUpdate events. If you want to scroll but NOT select, you have to click on the down arrow.
No, first I click and then use the arrows only 4 times and the 3 events continue to appear
You can see a dotted line on each item indicating the new position if you click and without selecting
Is it the application you sent me?
Can you try it yourself?
 
I changed my listbox to Simple multiselect and tested AfterUpdate event. It is triggered when cursor moves through items, even if I don't click into listbox - I click on scroll bar then use cursor keys - no item is highlighted, just dotted line around current item line. The AfterUpdate event already has code to build filter criteria and since no items are actually selected, there are no values for the filter.

I get same behavior Luis describes.
 
I understand you but I have to focus on the control, I could do it with tab but a client will not do that, also this should work even when clicking and then arrow and then clicking and then arrow, making only 2 selections not 4, but The events are activated 3 (Before/after/click), 4 times
I'm trying to do what you tell me, I'm using Google Translate, I don't know if that's why, lol
 

Users who are viewing this thread

Back
Top Bottom