5

Is there any way to update a ListBox on a UserForm outside of the Userform_Initialize sub?

Why? I am building a blackjack game and using listboxes to tell the user what cards they have/ the dealer has. I was hoping to use a simple sub (ShowCards) to add items to the listboxes but I've run into problems:

enter image description here

The Play button calls the PlayBlackjack sub which sits in a normal module

Option Explicit

Dim cards As New Collection

Sub ShowGame()
    UFDisplay.Show
End Sub

Sub PlayBlackjack()
    'fill the cards collection with 5 shuffled decks
    PrepareCards

    Dim i As Integer
    Dim userHand As New Collection
    Dim dealerHand As New Collection

    'deal cards (removing the dealt cards from the cards collection)
    For i = 1 To 2
        DealCard cards, userHand
        DealCard cards, dealerHand
    Next i

    ShowCards userHand, UFDisplay.UserHandList <-- ERROR HERE (Type mismatch)

    'more code to follow
End Sub

Private Sub ShowCards(hand As Collection, list As ListBox)
    Dim i As Integer

    For i = 1 To hand.Count
        list.AddItem hand(i).CardName
    Next i
End Sub

Let me know if you think you need any more of the code. hand is a collection of card classes where .CardName returns something like 3 of Hearts

Everything I read seems to tell me that the userform is static after being initialized so I would need to refresh it in some way after adding the new items. I tried Userform.Repaint with no luck.

So if there really is no other way, should I declare userHand and dealerHand as global variables, update them and call Useform_Initialize to take the updated values and show them to the user? Given the nature of the game being that multiple more cards could be dealt for both players it doesn't seem sensible to be re-initializing the userform multiple times each game.

All suggestions welcome. If you think I should have done it completely differently I'd still be keen to hear (but not so interested in worksheet solutions)

Update #1 For clarity, ShowGame is called by a button on the workshet, then PlayBlackjack is called from the Play button on the Userform (nothing else in the userform code)

1
  • it will me me.userhandlist Commented Dec 12, 2016 at 17:04

2 Answers 2

4

Ah, I see. You cannot declare the listBox parameter as ListBox. The latter is reserved for Activex controls, not VBA controls. Change the signature of your ShowCardssub into this:

Private Sub ShowCards(hand As Collection, list As Control) '<~~ or MSForms.ListBox, or simply as Object...
Sign up to request clarification or add additional context in comments.

1 Comment

@CallumDA glad to help :)
4

You could use a class for the hand also, and set the class listbox to be the form listbox, for example, the class clsHand

Public colHand As collection
Public lstToUpdate As MSForms.ListBox

Private Sub Class_Initialize()
    Set colHand = New collection
End Sub

Friend Function AddCard(card As clsCard)
    colHand.Add card, CStr(colHand.Count)
    If Not lstToUpdate Is Nothing Then
        lstToUpdate.AddItem card.strCardName
    End If
End Function

It's use in a form

Private clsPlayerHand As clsHand

Private Sub UserForm_Initialize()
    Set clsPlayerHand = New clsHand
    Set clsPlayerHand.lstToUpdate = Me.ListBox1
End Sub

Private Sub CommandButton1_Click()
    Dim clsC As New clsCard
    clsC.strCardName = "one"
    clsPlayerHand.AddCard clsC
End Sub

EDIT: Recommendation,

Use the numeric and the suit name for your cards, then you can do the following, say enabling the split button, incidentally, you'd use an array of hands then arrHands(x) ...

Public colHand As collection
Public lstToUpdate As MSForms.ListBox
Public cmdSplitButton As MSForms.CommandButton

Private Sub Class_Initialize()
    Set colHand = New collection
End Sub

Friend Function AddCard(card As clsCard)
    colHand.Add card, CStr(colHand.Count)
    If Not lstToUpdate Is Nothing Then
        lstToUpdate.AddItem card.CardName
    End If
    If Not cmdSplitButton Is Nothing Then
        If colHand.Count = 2 Then _
        cmdSplitButton.Enabled = colHand(1).NumericPart = colHand(2).NumericPart
    End If
End Function

Look at using classes to their full potential and look at events also, to react to certain things.

3 Comments

Thank you for this, I did start with a hand class too but I wasn't using it enough to feel like it was necessary - this is an interesting idea. I'm going to play around with it and see if it makes things much neater
Thanks again, this was a great suggestion - I tested it out and it worked really well. I think I'll post my final code on code review to see how close I get to something decent overall, your help was much appreciated. For now I accepted A.S.H's answer because I think it'll be most useful for other people.
No worries, but the proper solution would be Public Sub subname(x As MSForms.ListBox) :) Have a good day.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.