从旋转按钮更新表单组件可见性的更好方法?

问题描述 投票:1回答:3

我想知道是否有人能够对更加精简的方式做出如下的解释?

基本上当旋转按钮改变时,它将跳转到标签并更新代码可以正常显示的行,但我想知道是否有一种不那么笨重的方式将其编码到表单中?

    Private Sub Meds_Change()
    meds_txt.Text = Meds.value
End Sub


Private Sub meds_txt_Change()
    If meds_txt.value > 1 Then
        If meds_txt.value = 2 Then GoTo ShowTwo
        If meds_txt.value = 3 Then GoTo ShowThree
        If meds_txt.value = 4 Then GoTo ShowFour
        If meds_txt.value = 5 Then GoTo ShowFive
        If meds_txt.value = 6 Then GoTo ShowSix
        If meds_txt.value = 7 Then GoTo ShowSeven
    Else: GoTo ShowOne
    End If


Exit Sub

ShowOne:

    labelTwo.Visible = False: MNameTwo.Visible = False
    MDoseTwo.Visible = False: MFrequencyTwo.Visible = False
    labelThree.Visible = False: MNameThree.Visible = False
    MDoseThree.Visible = False: MFrequencyThree.Visible = False
    labelFour.Visible = False: MNameFour.Visible = False
    MDoseFour.Visible = False: MFrequencyFour.Visible = False
    labelFive.Visible = False: MNameFive.Visible = False
    MDoseFive.Visible = False: MFrequencyFive.Visible = False
    labelSix.Visible = False: MNameSix.Visible = False
    MDoseSix.Visible = False: MFrequencySix.Visible = False
    labelSeven.Visible = False: MNameSeven.Visible = False
    MDoseSeven.Visible = False: MFrequencySeven.Visible = False
    GoTo Finish
ShowTwo:
    labelTwo.Visible = True: MNameTwo.Visible = True
    MDoseTwo.Visible = True: MFrequencyTwo.Visible = True
    labelThree.Visible = False: MNameThree.Visible = False
    MDoseThree.Visible = False: MFrequencyThree.Visible = False
    labelFour.Visible = False: MNameFour.Visible = False
    MDoseFour.Visible = False: MFrequencyFour.Visible = False
    labelFive.Visible = False: MNameFive.Visible = False
    MDoseFive.Visible = False: MFrequencyFive.Visible = False
    labelSix.Visible = False: MNameSix.Visible = False
    MDoseSix.Visible = False: MFrequencySix.Visible = False
    labelSeven.Visible = False: MNameSeven.Visible = False
    MDoseSeven.Visible = False: MFrequencySeven.Visible = False
    GoTo Finish
ShowThree:
    labelTwo.Visible = True: MNameTwo.Visible = True
    MDoseTwo.Visible = True: MFrequencyTwo.Visible = True
    labelThree.Visible = True: MNameThree.Visible = True
    MDoseThree.Visible = True: MFrequencyThree.Visible = True
    labelFour.Visible = False: MNameFour.Visible = False
    MDoseFour.Visible = False: MFrequencyFour.Visible = False
    labelFive.Visible = False: MNameFive.Visible = False
    MDoseFive.Visible = False: MFrequencyFive.Visible = False
    labelSix.Visible = False: MNameSix.Visible = False
    MDoseSix.Visible = False: MFrequencySix.Visible = False
    labelSeven.Visible = False: MNameSeven.Visible = False
    MDoseSeven.Visible = False: MFrequencySeven.Visible = False
    GoTo Finish
ShowFour:
    labelTwo.Visible = True: MNameTwo.Visible = True
    MDoseTwo.Visible = True: MFrequencyTwo.Visible = True
    labelThree.Visible = True: MNameThree.Visible = True
    MDoseThree.Visible = True: MFrequencyThree.Visible = True
    labelFour.Visible = True: MNameFour.Visible = True
    MDoseFour.Visible = True: MFrequencyFour.Visible = True
    labelFive.Visible = False: MNameFive.Visible = False
    MDoseFive.Visible = False: MFrequencyFive.Visible = False
    labelSix.Visible = False: MNameSix.Visible = False
    MDoseSix.Visible = False: MFrequencySix.Visible = False
    labelSeven.Visible = False: MNameSeven.Visible = False
    MDoseSeven.Visible = False: MFrequencySeven.Visible = False
    GoTo Finish
ShowFive:
    labelTwo.Visible = True: MNameTwo.Visible = True
    MDoseTwo.Visible = True: MFrequencyTwo.Visible = True
    labelThree.Visible = True: MNameThree.Visible = True
    MDoseThree.Visible = True: MFrequencyThree.Visible = True
    labelFour.Visible = True: MNameFour.Visible = True
    MDoseFour.Visible = True: MFrequencyFour.Visible = True
    labelFive.Visible = True: MNameFive.Visible = True
    MDoseFive.Visible = True: MFrequencyFive.Visible = True
    labelSix.Visible = False: MNameSix.Visible = False
    MDoseSix.Visible = False: MFrequencySix.Visible = False
    labelSeven.Visible = False: MNameSeven.Visible = False
    MDoseSeven.Visible = False: MFrequencySeven.Visible = False
    GoTo Finish
ShowSix:
    labelTwo.Visible = True: MNameTwo.Visible = True
    MDoseTwo.Visible = True: MFrequencyTwo.Visible = True
    labelThree.Visible = True: MNameThree.Visible = True
    MDoseThree.Visible = True: MFrequencyThree.Visible = True
    labelFour.Visible = True: MNameFour.Visible = True
    MDoseFour.Visible = True: MFrequencyFour.Visible = True
    labelFive.Visible = True: MNameFive.Visible = True
    MDoseFive.Visible = True: MFrequencyFive.Visible = True
    labelSix.Visible = True: MNameSix.Visible = True
    MDoseSix.Visible = True: MFrequencySix.Visible = True
    labelSeven.Visible = False: MNameSeven.Visible = False
    MDoseSeven.Visible = False: MFrequencySeven.Visible = False
    GoTo Finish
ShowSeven:
    labelTwo.Visible = True: MNameTwo.Visible = True
    MDoseTwo.Visible = True: MFrequencyTwo.Visible = True
    labelThree.Visible = True: MNameThree.Visible = True
    MDoseThree.Visible = True: MFrequencyThree.Visible = True
    labelFour.Visible = True: MNameFour.Visible = True
    MDoseFour.Visible = True: MFrequencyFour.Visible = True
    labelFive.Visible = True: MNameFive.Visible = True
    MDoseFive.Visible = True: MFrequencyFive.Visible = True
    labelSix.Visible = True: MNameSix.Visible = True
    MDoseSix.Visible = True: MFrequencySix.Visible = True
    labelSeven.Visible = True: MNameSeven.Visible = True
    MDoseSeven.Visible = True: MFrequencySeven.Visible = True
    GoTo Finish

Finish:
End Sub

enter image description here

excel vba forms excel-vba
3个回答
2
投票

从概念上讲,我会将所有控件加载到一维数组中并使它们在循环中可见......就像这样(这是在表单的代码空间中):

Dim MyCtls(6) As Control

Private Sub SpinButton1_Change()
    ' let the index not go outside the array dimension
    If Me.SpinButton1 < 1 Then Me.SpinButton1 = 1
    If Me.SpinButton1 > 7 Then Me.SpinButton1 = 7

    Me.SpinText = Me.SpinButton1
End Sub

Private Sub SpinText_Change()
Dim Idx As Integer

    For Idx = 1 To 7
        ' controls with indices <= spinbutton value are visible, higher ones are dark
        If Idx <= Me.SpinText Then
            MyCtls(Idx - 1).Visible = True
        Else
            MyCtls(Idx - 1).Visible = False
        End If
    Next Idx

End Sub

Private Sub UserForm_Initialize()
Dim Idx As Integer

    ' load TB1..7 controls into array (index 0-6)
    For Idx = 1 To 7
        Set MyCtls(Idx - 1) = Me.Controls("TB" & Idx)
    Next Idx
End Sub

有7个文本框TB1TB7加载成一维数组...你可以使用4个数组 - 每个字段类型1个...重要的是名字可以通过循环计数器Idx以某种方式构建...其余的应该是自我解释的。


1
投票

更少数组的更通用替代方案

只是为了向您展示一种更通用的方法,您不需要为每个列/控件类型乘以数组的数量,甚至可以使用“One”,“Two”等来遵循您的命名约定(例如LabelOne,labelTwo ..) 。

必要的步骤

  • 定义常数MEDSCOUNT(= 7种药物)和CTLCOUNT(= 4种不同的控制名称)
  • UserForm_Initialize()中定义您的Control名称前缀和计数字符串
  • 使用辅助程序ShowCtls与单个参数(药物的数量)

主要代码

Option Explicit                  ' declaration head of code module

Const MEDSCOUNT As Integer = 7   ' define maximum number of medications           = 7
Const CTLCOUNT  As Integer = 4   ' define number of control names (prefixes only) = 4
Dim aCnt(), aCtl()               ' declare Counter strings and Control name prefixes

Private Sub UserForm_Initialize()
' Define your Counter strings and Control name prefixes
' (Note: first item with index 0 is a DUMMY in both cases)
  aCnt = Array("ZERO", "One", "Two", "Three", "Four", "Five", "Six", "Seven")
  aCtl = Array("DUMMY", "label", "MName", "MDose", "MFrequency")
End Sub

Private Sub Meds_Change()
' .. just to be on the safe side
  If Meds.value > MEDSCOUNT Then Meds.value = MEDSCOUNT
  If Meds.value < 1 Then Meds.value = 1
' show number of medications
  meds_txt.text = Meds.value
End Sub

Private Sub meds_txt_Change()
' call HELPER procedure with number of necessary medications (>> see below)
  ShowCtls Me.meds_txt.value
End Sub

meds_txt_Change()调用的助手程序

Private Sub ShowCtls(nMeds As Integer)
  Dim i As Integer, ii As Integer
' hide fields greater than number of medications
   For i = 2 To MEDSCOUNT  ' NOTE: number 1 remains visible anyway
       For ii = 1 To CTLCOUNT
          Me.Controls(aCtl(ii) & aCnt(i)).Visible = IIf(i > nMeds, False, True)
       Next ii
   Next i
End Sub

暗示

您可以通过仅更改UserForm_Initialize()事件(当然还有实际控件的名称)来轻松调整命名逻辑。


0
投票

ShowOne有0个属性设置为True,ShowTwo有4个,ShowThree有8个等等 - 你可以看到它是(0,4,8,12,16,20,24)。因此,您可以编写一个函数,将此数字作为参数,然后相应地设置属性。请注意,属性是相关的 - 例如如果

    labelTwo.Visible = True

    MNameTwo.Visible
    MDoseTwo.Visible 
    MFrequencyTwo.Visible

也是真的。因此,您可以将这些4设置为x,接下来设置为4等等。然后将(x,y,z,...)作为函数参数传递。

© www.soinside.com 2019 - 2024. All rights reserved.