Userform OptionButtons эксклюзивные в двух направлениях - PullRequest
1 голос
/ 11 февраля 2020

У меня есть пользовательская форма с кнопками, организованными как таблица в столбцах и строках. Я хочу активировать только одну кнопку для каждого столбца и строки. На данный момент это работает со всеми кнопками, являющимися кнопками выбора и всеми кнопками выбора строки в одном кадре. Затем для столбцов я начал писать для каждой кнопки подпрограмму типа:

Private Sub Col1Row3_Click()

For i = 1 To 2
 Me.Controls("col1Row" & i) = False
Next i

For i = 4 To 14
 Me.Controls("col1Row" & i) = False
Next i

End Sub

Это работает, но я уверен, что есть более элегантный способ. Какие-нибудь мысли ? Спасибо!

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

Простая подпроцедура

Попытка продемонстрировать простой способ упростить код, остающийся близким к вашему подходу, с помощью

  1. с использованием подпроцедуры
  2. установка всех опционных кнопок на False в al oop и, в конечном счете, активная снова на True.
Sub Only(ByVal rowNum As Long, ByVal colName As String, Optional ByVal maxRow As Long = 14)
' Purpose: set all OptionButtons to False except the one for row rowNum
    Dim currRow     As Long
    For currRow = 1 To maxRow
        Me.Controls(colName & "Row" & currRow) = False
    Next
    Me.Controls(colName & "Row" & rowNum) = True
End Sub

Пример вызова без сложных петель

Private Sub col1Row3_Click()
    Only 3, "col1"
End Sub

Дополнительная подсказка

Вместо повторения вызов процедуры для каждой из ваших опционных кнопок, можно было бы получить прибыль от программирования классов (~> WithEvents). Для более глубокого понимания вас могут заинтересовать, например, массивы элементов управления VBA , если вы хотите сгруппировать элементы управления с одинаковым типом имени и одинаковыми процедурами обработки событий, предварительно определенными в классе.

0 голосов
/ 20 февраля 2020

Итак, просто чтобы ответить на мой вопрос благодаря помощи ТМ, в случае, если это может помочь кому-то еще (или если у кого-то есть что-то более чистое, чтобы предложить).

Я нашел две возможности:

Чтобы разрешить только один выбор для каждого столбца и строки, если элементы управления являются кнопками параметров:

  • Содержит каждую строку или столбец в кадре, скажем, строка для этого примера
  • Иметь класс с элементом управления в качестве свойства и control_click в качестве метода. Метод проверяет все элементы управления столбца (столбец, найденный по имени, если имя элемента управления имеет имя «имя» и переменная & numcolumn или благодаря номеру свойства столбца).

В общем случае для всех типов элементов управления и, черт возьми, я не ожидал, что буду так сильно бороться с флажками, которые принимают любое изменение за клик. метод. Метод проверяет все строки и столбцы благодаря массиву как свойству класса Arr (строка управления, столбец управления) или только благодаря имени с элементами управления с именем «Имя» & row & col

Пример для флажков с именем CheckBoxRxCy (т.е. CheckBoxR01C01)

В модуле (я использую определения для объявления всего)

Public ClickCtrl  As Boolean 'the boolean which prevents the checkbox from going crazy

В классе ClassForExclusives (classe, который обрабатывает событие когда галочка изменена)

Public WithEvents ControlExcl As MSForms.CheckBox       'the control with events enabled


Private Sub ControlExcl_Click()

If ClickCtrl = False Then       'inhibits reaction to value change
GoTo line1

Else
For Each control2 In UserForm1.Controls

    If control2.Name <> ControlExcl.Name Then  'avoid setting the tickbox xhanged to false

        If Right(control2.Name, 2) = Right(ControlExcl.Name, 2) Or Mid(control2.Name, 10, 2) _
        = Mid(ControlExcl.Name, 10, 2) Then 'same row/col
        ClickCtrl = False
        control2.Value = False

        End If

    End If

ClickCtrl = True 'allows the clicks to trigger the code again

Next control2
End If

line1:

End Sub

в пользовательской форме

Dim ArrControls() As New ClassForExclusives         'Set the array with the controls as ClassForExclusives

Private Sub UserForm_Initialize()
ClickCtrl = True

For Each Chkbox In Me.Controls
    If TypeOf Chkbox Is MSForms.CheckBox Then
        i = i + 1
        ReDim Preserve ArrControls(1 To i)
        Set ArrControls(i).ControlExcl = Chkbox

    End If
Next Chkbox
End Sub
...