Solved Last selected item in a list box (1 Viewer)

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
Hi.

I have a multi-choice list, and I want to get the value of the last selected item.

ScreenShot001.jpg

That is, I have the list box on the left (the one on the right only shows selected items). The name and description appear in that list box. Well, what I want to achieve is that, every time I select an item in the list box on the left, the description referring to that selected item appears in the text box below (although I already have several selected, which always takes the last).

Thanks.
 

Isaac

Lifelong Learner
Local time
Yesterday, 18:37
Joined
Mar 14, 2017
Messages
8,777
By "last" are you referring to the one most recently selected, or literally/physically the bottom-most one?
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
the one most recently selected
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
Because the description is too long to display in the list box, and I wanted to pull out the last selected item to display in the text box.
 

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 18:37
Joined
Oct 29, 2018
Messages
21,455
Hi. The only thing I could think of is to maintain a list of selections yourself, so that you can always know which item was selected last. Just a thought...
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:37
Joined
May 21, 2018
Messages
8,525
I would roll my own
Code:
Private OrderedItems As New Collection


Private Sub List0_AfterUpdate()
  Dim idx As Integer
  idx = Me.List0.ListIndex
  If Me.List0.Selected(idx) Then
    Debug.Print idx & " add"
    OrderedItems.Add idx, CStr(idx)
  Else
    OrderedItems.Remove CStr(idx)
  End If
  MsgBox GetLastIndex
End Sub

Public Function GetLastIndex() As Long
  If OrderedItems.Count > 0 Then
    GetLastIndex = OrderedItems.Item(OrderedItems.Count)
  Else
    Err.Raise 9999, , "No Items in listbox.  Make sure to check count of OrderedItems before calling"
  End If
End Function
What the @theDBguy suggested.
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
There are two things:

On the one hand, it is fixed. I have added this couple of lines:

Code:
   Me.Description = Me.LstPautas.Column (2, GetLastIndex)
   Me.Description.Requery

And secondly, I can't find a way to differentiate between when there is one selected and there is none, because in both cases GetLastIndex gives zero.

Besides, it gives me an error 5 when I remove items from the list box in the line

Code:
    OrderedItems.Remove CStr(idx)
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:37
Joined
May 21, 2018
Messages
8,525
Besides, it gives me an error 5 when I remove items from the list box
Understand the listindex is unique to the records when selected. If you filter or resort the list, these values have not meaning. You would have to store the actual values.

I can't find a way to differentiate between when there is one selected and there is none, because in both cases GetLastIndex gives zero
That is not possible. Need to show your code. I purposely throw an error when the count is 0 so that you check for this case. Can you show how you are using this. Works fine for me.
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:37
Joined
May 21, 2018
Messages
8,525
FYI I wrote this to return the last value selected that is still selected. This would be different than the last item selected regardless if still selected. I am not sure if the latter makes sense but depends on what you are doing.
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
That is not possible. Need to show your code. I purposely throw an error when the count is 0 so that you check for this case. Can you show how you are using this. Works fine for me.
It is that I had deactivated it so that it would not show the fault, because it is annoying for the user. You already know there is none because you are seeing it in the list box. I'm checking if I can adapt it to what I want it to do.
Understand the listindex is unique to the records when selected. If you filter or resort the list, these values have not meaning. You would have to store the actual values.
So what can I do?
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:37
Joined
May 21, 2018
Messages
8,525
It is that I had deactivated it so that it would not show the fault, because it is annoying for the user. You already know there is none because you are seeing it in the list box. I'm checking if I can adapt it to what I want it to do.?

That was the whole point of throwing an error, I want to make sure that the person writing code does not just deactivate it, but writes code to handle it. You need to check the itemsselected to make sure something is selected.

In my example this would force me to

So if you plan to filter or sort then working with indices has no meaning. You have to save the actual values. Not sure what you are doing. But if you filter the listbox, I assume you would want to remove those values from OrderedItems.

Code:
Private OrderedItems As New Collection



Private Sub List0_AfterUpdate()
  Dim idx As Long
  Dim lst As Access.ListBox
 
  Set lst = Me.List0
  idx = Me.List0.ListIndex
  UpdateOrderedItems lst, idx, 0
  'Check here or get error 999
  If lst.ItemsSelected.Count > 0 Then
    MsgBox GetLastItem
  Else
    MsgBox "No items"
  End If
End Sub


Public Sub UpdateOrderedItems(lstbox As Access.ListBox, idx As Long, TheColumn As Integer)
  Dim val As Variant
  If lstbox.Selected(idx) Then
    OrderedItems.Add lstbox.Column(TheColumn, idx), CStr(lstbox.Column(TheColumn, idx))
   Else
     OrderedItems.Remove CStr(lstbox.Column(TheColumn, idx))
   End If
End Sub


Public Function GetLastItem() As Variant
  If OrderedItems.Count > 0 Then
    GetLastItem = OrderedItems.Item(OrderedItems.Count)
  Else
    Err.Raise 9999, , "No Items in listbox.  Make sure to check count of OrderedItems before calling"
  End If
End Function
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
In the end I have made a mixture of both that you have passed me and it works as I want.
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
Code:
Private Sub LstPautas_AfterUpdate()
  On Error GoTo err_lbl
  AddRemoveSelections Me.LstPautas, "TFichaClinicaPautas", "PautaIdUnido", "FichaClinicaIdUnido", Me.IdFichaClinica
  Me.LstPautasAsignadas.Requery
  Dim idx As Integer
  idx = Me.LstPautas.ListIndex
  If Me.LstPautas.Selected(idx) Then
    Debug.Print idx & " add"
    OrderedItems.Add idx, CStr(idx)
  Else
    OrderedItems.Remove CStr(idx)
  End If
  If OrderedItems.Count > 0 Then
    Me.Descripcion = Me.LstPautas.Column(2, GetLastIndex)
  Else
    Me.Descripcion = ""
  End If
  Me.Descripcion.Requery
err_exit:
    Exit Sub
err_lbl:
    Select Case Err.Number
        Case 5
            Resume Next
        Case Else
            MsgBox Err.Number & ": " & Err.Description, vbInformation, NombreBD
    End Select
End Sub

Code:
Public Function GetLastIndex() As Long
  If OrderedItems.Count > 0 Then
    GetLastIndex = OrderedItems.Item(OrderedItems.Count)
  End If
End Function
 

Gasman

Enthusiastic Amateur
Local time
Today, 02:37
Joined
Sep 21, 2011
Messages
14,238
Cant't the index be stored when the item is selected/clicked?
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
No need, that way it works for me. What I have had to add is a hidden independent field where to copy the id (obtained as indicated above) and then add a subform and be able to show a text box with long text, which if I put it in the form, all the text does not appear. length.
 

MajP

You've got your good things, and you've got mine.
Local time
Yesterday, 21:37
Joined
May 21, 2018
Messages
8,525
I never really read you explanation before writing the code or looked at the image. I looked at the title and @theDBguy suggestion. Maintaining the selections in a separate collection is something I do in other instances and it made sense to me.

However, looking at your user interface where you make selections on the left and show your selections on the right and the details below, I would think you can have a better UI. Whatever selection I select from the list on the right is the selection to display. So you can review any of the current selections.
1. I would make a procedure to show in the memo field whatever I select from the right hand listbox
2. When you pick an item in the left it should add it to the right and select it. Call procedure in step 1.
3. When you unselect an item on the left, it removes it from the selected items on the right. If that item was selected then the right listbox should unselect everything and show nothing in the memo.
4. Whatever you then select in the right can show in the memo.
 

zelarra821

Registered User.
Local time
Today, 03:37
Joined
Jan 14, 2019
Messages
809
Something like what you propose I had thought, but this morning, when I spoke with the person for whom I am doing the database, he told me that he needs a field to enter observations to each pattern. This almost discards the list boxes, and the best is a continuous form, with the Name, Description, Observation and Add fields.
 

Isaac

Lifelong Learner
Local time
Yesterday, 18:37
Joined
Mar 14, 2017
Messages
8,777
Cant't the index be stored when the item is selected/clicked?
This is kind of what I was thinking. @zelarra821 you could probably reduce all that to about a line of code.
Since the listbox's listindex will be whatever was last selected, even on a multi select
 

Users who are viewing this thread

Top Bottom