Сохранить выбранные флажки пользовательской формы в массив (для репликации в пользовательской форме)

Как определить все выбранные флажки во фрейме в пользовательской форме и назначить их массиву, чтобы я мог либо/оба: дублировать выбранные флажки в одном или нескольких других фреймах и использовать массив для заполнения ячеек электронной таблицы?

Вопрос из двух частей, но я думаю, что они идут рука об руку (я не уверен). У меня есть пользовательская форма с несколькими фреймами и множеством флажков внутри каждого (SS) — у меня есть стандартное соглашение об именах для всех из них (объяснено внизу).

Мне нужно будет определить, какие флажки выбраны (и выбор в полях со списком), чтобы я мог поместить все это в электронную таблицу. Мне также понадобится возможность для пользователя скопировать все выбранные флажки (и выбор в полях со списком) из одного кадра в один-три других кадра, если он / она хочет. У меня есть кнопка «Копировать», которая инициализирует короткую пользовательскую форму, чтобы выбрать, из какого кадра копировать и какие кадры копировать. (Например: возможность скопировать все выделения из фрейма «Альфа-антенны» в один или несколько фреймов «Бета-антенны», фрейм «Гамма-антенны», фрейм «Дельта-антенны».) Действительно застрял на том, что делать в основная форма, как только я это получу? Я думаю, что один массив даст мне две нужные мне функции (копирование одного кадра в другой и заполнение электронной таблицы), но я не знаю следующего шага. Любая помощь?

Некоторый код/название/SS:

Кнопка, которая загружает основную форму:

Sub CreateADS()
Dim oneForm As Object 
'==========================================================
'On Error GoTo ErrHandler 'Trying to catch errors - will input more down there, later

    ADSinputform.Show
    For Each oneForm In UserForms
        Unload oneForm
        'Unload ADSinputform
    Next oneForm
End Sub

Начальный код основной пользовательской формы:

    Dim myCheckBoxes() As clsUFCheckBox

    Private Sub UserForm_Activate()
        '======================================================
        'couple pre-initialization things here
        '======================================================
    End Sub

    Private Sub UserForm_Initialize()
    Dim chBox As Control
    Dim comboBox As Control
    Dim arrFreq() As String
    Dim i As Long
    Dim siteName As String
    Dim ctrl As Object, pointer As Long

    ReDim myCheckBoxes(1 To Me.Controls.Count)
        For Each ctrl In Me.Controls
            If TypeName(ctrl) = "CheckBox" Then
                pointer = pointer + 1
                Set myCheckBoxes(pointer) = New clsUFCheckBox
                Set myCheckBoxes(pointer).aCheckBox = ctrl
            End If
        Next ctrl

    ReDim Preserve myCheckBoxes(1 To pointer)

        'Use the Split function to create two zero based one dimensional arrays.
        arrFreq = Split("Unused|GSM,850|GSM,1900|UMTS,850|UMTS,1900|CDMA,850|LTE,700|LTE,850|LTE,1900|LTE,2100|LTE,2300", "|")
        For Each comboBox In ADSinputform.Controls
            If TypeOf comboBox Is MSForms.comboBox Then
                For i = 0 To UBound(arrFreq)
                    'Use .List property to write array data to all the comboBoxes
                    comboBox.List = arrFreq
                Next i
            End If
        Next

        MsgBox "This pops up at the end of initialization"
    End Sub

Private Sub cmdCopy_Click()
Dim chkBox As Control
Dim cmbBox As Control
Dim frmSource As MSForms.Frame
'Dim frmSource As String
Dim valSectCopy1 As String 'to validate that a sector is filled in
Dim valSectCopy2 As String 'to validate that an antenna is filled in
Dim valPortCopy As String 'to validate that a port is filled in

Set frmSource = SectorsFrame
valSectCopy1 = ""
valSectCopy2 = ""
valPortCopy = ""


    For Each chkBox In frmSource.Controls 'Sector-level frame
        If TypeName(chkBox) = "CheckBox" And chkBox.Value = True Then
            valSectCopy1 = chkBox.Tag
            valSectCopy2 = valSectCopy1
            Set frmSource = Controls(valSectCopy1)
            Exit For
        End If
    Next chkBox
    If valSectCopy1 <> "" Then
        For Each chkBox In frmSource.Controls 'Antenna-level frame
            If TypeName(chkBox) = "CheckBox" And chkBox.Value = True Then
                valSectCopy2 = chkBox.Tag
                valPortCopy = valSectCopy2
                Set frmSource = Controls(valSectCopy2)
                Exit For
            End If
        Next chkBox
    Else
        GoTo NoSource
    End If
    If valSectCopy2 <> valSectCopy1 Then
        For Each cmbBox In frmSource.Controls 'Port-level frame
            If TypeName(cmbBox) = "ComboBox" And cmbBox.Value <> "Frequency" Then
                valPortCopy = cmbBox.Value
                Exit For
            End If
        Next cmbBox
    Else
        GoTo NoSource
    End If
    If valSectCopy2 = valPortCopy Then
        GoTo NoSource
    End If



    CopySector.Show
        If CopySector.destSectCopy <> "" And CopySector.srcSectCopy <> "" Then
            MsgBox "Copying the " & CopySector.srcSectCopy & _
                " sector to " & CopySector.destSectCopy & " sector(s)."
            Unload CopySector
            Exit Sub
        Else
            Exit Sub
        End If

NoSource:
    MsgBox "You have not filled in a sector to copy." & vbCrLf & _
        "Please fill out sector info for at least one sector and try again."
    Exit Sub


    End Sub

Код пользовательской формы анкеты:

Public srcSectCopy As String
Public destSectCopy As String


Private Sub cmdCopy_Click()
Dim optBtn As Control
Dim chkBox As Control

srcSectCopy = ""
destSectCopy = ""

    For Each optBtn In Me.Controls
        If TypeName(optBtn) = "OptionButton" Then
            If optBtn.Value = True Then
                srcSectCopy = optBtn.Tag
            End If
        End If
    Next optBtn

    If srcSectCopy = "" Then
        MsgBox "You have not selected a sector to copy." & vbCrLf & _
            "Please select a sector to copy from and try again."
        Exit Sub
    End If

    For Each chkBox In Me.Controls
        If TypeName(chkBox) = "CheckBox" Then
            If chkBox.Value = True Then
                If destSectCopy = "" Then
                    destSectCopy = chkBox.Tag
                Else
                    destSectCopy = destSectCopy & ", " & chkBox.Tag
                End If
            End If
        End If
    Next chkBox

    If destSectCopy = "" Then
        MsgBox "You have not selected any sectors to copy to." & vbCrLf & _
            "Please select one or more sectors to be duplicated and try again."
        Exit Sub
    End If

    Msg = "this will copy the " & srcSectCopy & _
        " sector to " & destSectCopy & " sector(s)." & vbCrLf & _
        "Do you want to continue with the operation?"
        Ans = MsgBox(Msg, vbQuestion + vbYesNo)
        Select Case Ans
            Case vbYes
                Me.Hide
            Case vbNo
                Exit Sub
          End Select


End Sub

Private Sub UserForm_Initialize()

End Sub



Private Sub AlphaSect_OptBtn_Change()

    Select Case (AlphaSect_OptBtn.Value)
        Case True:  AlphaSect_CheckBox.Enabled = False
        AlphaSect_CheckBox.Value = False
        Case False: AlphaSect_CheckBox.Enabled = True
    End Select

End Sub

Private Sub BetaSect_OptBtn_Change()

    Select Case (BetaSect_OptBtn.Value)
        Case True:  BetaSect_CheckBox.Enabled = False
        BetaSect_CheckBox.Value = False
        Case False: BetaSect_CheckBox.Enabled = True
    End Select

End Sub

Private Sub GammaSect_OptBtn_Change()

    Select Case (GammaSect_OptBtn.Value)
        Case True:  GammaSect_CheckBox.Enabled = False
        GammaSect_CheckBox.Value = False
        Case False: GammaSect_CheckBox.Enabled = True
    End Select

End Sub

Private Sub DeltaSect_OptBtn_Change()

    Select Case (DeltaSect_OptBtn.Value)
        Case True:  DeltaSect_CheckBox.Enabled = False
        DeltaSect_CheckBox.Value = False
        Case False: DeltaSect_CheckBox.Enabled = True
    End Select

End Sub


Private Sub cmdCancel_Click()

  Msg = "Are you sure you want to cancel and exit without copying?"
        Ans = MsgBox(Msg, vbQuestion + vbYesNo)
        Select Case Ans
            Case vbYes
                Me.Hide
                Unload Me
            Case vbNo
                Exit Sub
          End Select

End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  If CloseMode = vbFormControlMenu Then
    ' user clicked the X button
    ' cancel unloading the form, use close button procedure instead
    Cancel = True
    cmdCancel_Click
  End If
End Sub

Следующий класс:

Option Explicit
Public WithEvents aCheckBox As MSForms.CheckBox
Private Sub aCheckBox_Click()
Dim chBox As Control
Dim chBoxTag As String

chBoxTag = aCheckBox.Tag

If Right(aCheckBox.Parent.Name, 10) = "Port_Frame" Then
    If aCheckBox.Value = True Then ADSinputform.Controls(chBoxTag).Enabled = True
    If aCheckBox.Value = False Then
        ADSinputform.Controls(chBoxTag).Enabled = False
    End If
Else
    If aCheckBox.Value = True Then ADSinputform.Controls(chBoxTag).Visible = True
    If aCheckBox.Value = False Then
        ADSinputform.Controls(chBoxTag).Visible = False
        For Each chBox In ADSinputform.Controls(chBoxTag).Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If
End If
End Sub

Я не уверен, что это можно сделать, и я не совсем уверен, с чего даже начать. Я знаю, что могу просмотреть все элементы управления и прочитать состояние или выбор поля со списком, но что делать после этого?

Именование: кадры: "AlphaSect_Frame", "BetaSect_Frame", "GammaSect_Frame"

Флажки первого уровня: "A1Checkbox", "A2Checkbox", "A3Checkbox"... "B1Checkbox", "B2Checkbox"... "C1Checkbox", "C2Checkbox"

Флажки второго уровня: "A1P1Checkbox", "A1P2Checkbox", "A2P1Checkbox", "A2P2Checkbox"... "B1P1Checkbox", "B1P2Checkbox", "B2P1Checkbox", "B2P2Checkbox"... "C1P1Checkbox", "C1P2Checkbox", " Флажок C2P1", "Флажок C2P2"

Скриншоты формы пользователя:

Основная форма пользователя

Копировать анкету пользователя


person JGR    schedule 25.01.2016    source источник
comment
Вы можете получить доступ к элементам управления напрямую, используя Controls("ControlNameHere"), поэтому вы можете использовать свое определенное соглашение об именах для копирования настроек между двумя элементами управления, если вы знаете их имена. Каждый фрейм имеет свою собственную коллекцию элементов управления.   -  person Tim Williams    schedule 25.01.2016
comment
@TimWilliams, вы говорите, что я могу реплицировать альфа-кадр в бета-кадр, и мне не нужно захватывать каждый отдельный выбор в альфа-канале (и его подкадрах), чтобы активировать каждый отдельный флажок в бета-версии?   -  person JGR    schedule 25.01.2016
comment
Нет — вам по-прежнему нужно перебрать элементы управления и сопоставить их с соответствующими элементами управления в другом фрейме, основываясь на вашем соглашении об именах. См. пример моей игрушки ниже.   -  person Tim Williams    schedule 25.01.2016
comment
@TimWilliams ага - попался. Я попробую. С полем со списком, каково соответствующее значение для .Value (это все еще .Value, если я хочу скопировать более 850)? Я вернусь вскоре после проб и ошибок - спасибо.   -  person JGR    schedule 25.01.2016
comment
Я тестировал только с флажками - должно быть достаточно легко узнать для других типов элементов управления.   -  person Tim Williams    schedule 25.01.2016
comment
@TimWilliams Ваш ответ решает половину моих проблем (на данный момент) и дает мне направление по проблеме массива. На этом этапе, когда я сосредоточился на копировании, я получил ответ на вопрос — позже я займусь вводом данных из пользовательской формы в ячейку рабочего листа. Большое спасибо.   -  person JGR    schedule 25.01.2016


Ответы (1)


Вот простой пример формы с двумя фреймами, в каждом из которых есть два флажка:

Dim f1 As Frame, f2 As Frame, c As Control

Set f1 = Me.Frame1 'has checkboxes "f1cb1", "f1cb2"
Set f2 = Me.Frame2 'has checkboxes "f2cb1", "f2cb2"

'loop over all controls in Frame 1
For Each c In f1.Controls
    If TypeName(c) = "CheckBox" Then
        'set the value of the corresponding control in the other fame
        Me.Controls(Replace(c.Name, "f1", "f2")).Value = c.Value
    End If
Next c
person Tim Williams    schedule 25.01.2016
comment
Тим, с этим у меня проблемы, он не ставит галочки. Я вставил окно сообщения для устранения неполадок (MsgBox "currently on " & Me.Controls(c.Name).Name & vbCrLf & _ "copying " & Me.Controls(Replace(c.Name, "f1", "f2")).Name), и это не похоже на замену имени фрейма (я получаю В настоящее время на A2Checkbox копирование A2Checkbox). - person JGR; 25.01.2016
comment
Я настроил его с альфой и без изменений. (например, MsgBox "currently on " & Me.Controls(c.Name).Name & vbCrLf & _ "copying " & Me.Controls(Replace(c.Name, "a", "b")).Name по-прежнему дает В настоящее время на A2Checkbox копирование A2Checkbox), а Me.Controls(Replace(c.Name, "a", "b")).Value = c.Value (или альфа) не дублирует выбор.) Я чувствую себя немного плохо, потому что я недостаточно знаю, чтобы знать, что не должно работать, поэтому я меняя вещи с помощью лучших догадок. - person JGR; 25.01.2016
comment
В моем примере используется более простое соглашение об именах, чем вы используете — вам нужно настроить f1 и f2 на то, что имеет смысл в вашем случае. В вашем случае (например) вы замените начальный A на B при копировании из альфа-кадра в бета-кадр. В вашем случае, поскольку у вас есть только однобуквенные идентификаторы фреймов, вы должны ограничить замену с помощью дополнительных параметров Replace(c.Name, "A", "B", 1, 1) - это ограничит одну замену вместо замены всех экземпляров (например) A - person Tim Williams; 25.01.2016
comment
Очень, очень жаль, Тим - верхний/нижний регистр имел значение. Когда я написал Replace(c.Name, "a", "b"), это ничего не заменило, потому что принято использовать верхний регистр. Я использовал Replace(c.Name, "A","B"), и он отлично работает. Большое спасибо за помощь в этом, и я сожалею об ошибках пользователя (кодера ??). - person JGR; 25.01.2016