【问题标题】:Update a userform listbox after userform initialization用户表单初始化后更新用户表单列表框
【发布时间】:2016-12-13 02:07:43
【问题描述】:

有没有办法在Userform_Initialize 子之外的UserForm 上更新ListBox

为什么? 我正在构建一个二十一点游戏并使用列表框来告诉用户他们有什么牌/庄家有什么牌。我希望使用一个简单的子 (ShowCards) 将项目添加到列表框中,但我遇到了问题:

Play 按钮调用位于普通模块中的 PlayBlackjack

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

如果您认为需要更多代码,请告诉我。 hand 是卡片类的集合,其中 .CardName 返回类似于 3 of Hearts 的内容

我读到的所有内容似乎都告诉我,用户表单在初始化后是静态的,所以我需要在添加新项目后以某种方式刷新它。我试过Userform.Repaint 没有运气。

所以如果真的没有其他办法,我应该将userHanddealerHand 声明为全局变量,更新它们并调用Useform_Initialize 来获取更新的值并将它们显示给用户吗?考虑到游戏的性质是可以为两个玩家发多张牌,因此在每场游戏中多次重新初始化用户窗体似乎是不明智的。

欢迎所有建议。如果您认为我应该以完全不同的方式来做,我仍然很想听听(但对工作表解决方案不太感兴趣)

更新 #1 为清楚起见,ShowGame 由工作表上的按钮调用,然后 PlayBlackjack 由 Userform 上的 Play 按钮调用(在 userform 代码中没有其他内容)

【问题讨论】:

  • 它会是 me.userhandlist

标签: vba excel userform


【解决方案1】:

啊,我明白了。您不能将 listBox 参数声明为 ListBox。后者是为 Activex 控件保留的,而不是 VBA 控件。将ShowCardssub 的签名更改为:

Private Sub ShowCards(hand As Collection, list As Control) '<~~ or MSForms.ListBox, or simply as Object...

【讨论】:

  • @CallumDA 很高兴为您提供帮助 :)
【解决方案2】:

你也可以使用一个类作为手,并将类列表框设置为表单列表框,例如类 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

在表格中使用

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

编辑:推荐,

为你的卡片使用数字和花色名称,然后你可以执行以下操作,比如启用拆分按钮,顺便说一下,你会使用一系列手,然后是 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

着眼于充分发挥类的潜力,并着眼于事件,以对某些事情做出反应。

【讨论】:

  • 谢谢你,我也开始使用hand 课程,但我没有足够的使用它来感觉它是必要的 - 这是一个有趣的想法。我会玩弄它,看看它是否能让事情变得更整洁
  • 再次感谢,这是一个很棒的建议——我已经测试过了,效果非常好。我想我会在代码审查中发布我的最终代码,以了解我与整体体面的东西有多接近,非常感谢您的帮助。现在我接受了 A.S.H 的回答,因为我认为它对其他人最有用。
  • 不用担心,但正确的解决方案是Public Sub subname(x As MSForms.ListBox) :) 祝你有美好的一天。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多