Улучшить 33 кода флажков сабов до немногих? (Флажок для автоматической даты в закладках) - PullRequest
0 голосов
/ 21 января 2019

:) Я новичок в VBA! У меня есть рабочий код для вставки даты, где у меня есть закладка при использовании флажка (ActiveX). Проблема в том, что у меня есть 33 флажка (на самом деле я хочу 33x2. Один для да и один для нет). Таким образом, я получил 33 Subs и 33 закладки. Бьюсь об заклад, этот код может быть более эффективным, затормозив его до нескольких подводных лодок. Annyone имеет любую идею, если это можно сделать? Код ниже является первым из 33 повторяющихся подпрограмм, в котором имя Sub и закладки - agi1, agi2 agi3 .....

Private Sub agi1_Click()

Dim rngFormat As Range
 Set rngFormat = ActiveDocument.Range( _
 Start:=ActiveDocument.Bookmarks("agi1").Range.Start, _
 End:=ActiveDocument.Bookmarks("agi1").Range.End)
 With rngFormat
 .Font.Size = 8
 End With

   Dim v
   Dim BMRange As Range
   v = ThisDocument.agi1.Value

'Sjekke om boks er sjekket eller ikke
   If v = True Then

'Sett inn dato i bokmerke
Set BMRange = ActiveDocument.Bookmarks("agi1").Range
With Selection.Font
 .Size = 9
End With
BMRange.Text = (Format(Date, "dd.mm.yyyy"))

Else

'Erstatte dato med tom tekst hvis boks ikke er sjekket
Set BMRange = ActiveDocument.Bookmarks("agi1").Range
BMRange.Text = " "

End If
'Sett inn bokmerke på nytt
ActiveDocument.Bookmarks.Add "agi1", BMRange

End Sub

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Вы можете использовать тонирование событий, возможно, чтобы.

В обычном модуле создайте коллекцию и заполните ее для хранения классов, которые будут управлять событиями флажка.

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

Public col As Collection

Public Sub SETUP()

Dim o As InlineShape
Dim c As MSForms.CheckBox
Dim cust As clsCustomCheckBox

Set col = New Collection

For Each o In ActiveDocument.InlineShapes

    Set c = o.OLEFormat.Object
    Set cust = New clsCustomCheckBox
    cust.INIT c
    col.Add cust

Next o

End Sub

, а затем иметь модуль класса с именем clsCustomCheckBox и иметь код как

Private WithEvents c As MSForms.CheckBox

Public Function INIT(cmdIN As MSForms.CheckBox)
    Set c = cmdIN
End Function

Private Sub c_Click()
    MsgBox "Here you can get the name " & c.Name
End Sub

Это будет перенаправлять каждый щелчок флажка на классы c_click, а не на его собственные.

Так что для вас

Dim rngFormat As Range
 Set rngFormat = ActiveDocument.Range( _
 Start:=ActiveDocument.Bookmarks(c.name).Range.Start, _
 End:=ActiveDocument.Bookmarks(c.name).Range.End)
 With rngFormat
 .Font.Size = 8
 End With
.......
0 голосов
/ 21 января 2019

Элементы управления ActiveX всегда регистрируют свои обработчики событий следующим образом:

Private Sub NameOfTheControl_NameOfTheEvent({args})

Если вы переименуете обработчик, элемент управления перестанет работать - потому что name обработчика must должно быть сформировано, как указано выше, с подчеркиванием, разделяющим имя элемента управления и имя обработанного события.

Так что, если ваши элементы управления должны существовать во время компиляции, нет никакого способа обойти это: для 33 элементов управлениявам нужно 33 обработчика.

Это не значит, что вам нужно, чтобы эта огромная процедура повторялась 33 раза!

Извлеките процедуру.Выделите все тело этого обработчика, обрежьте его.

Теперь создайте новый прототип процедуры:

Private Sub HandleCheckBoxClick(ByVal controlName As String)

End Sub

и вставьте туда тело.Затем замените все места, в которых у вас есть жестко запрограммированный "agi1", ссылкой на этот параметр controlName:

Dim rngFormat As Range
Set rngFormat = ActiveDocument.Range( _
    Start:=ActiveDocument.Bookmarks(controlName).Range.Start, _
    End:=ActiveDocument.Bookmarks(controlName).Range.End)
With rngFormat
    .Font.Size = 8
End With

'...

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

v = ThisDocument.agi1.Value

Вы можете получить элемент управления MSForms.CheckBox через коллекцию ThisDocument.InlineShapes, но , который не позволит вам найти флажок по его имени , поэтому вам нужнофункция, которая может сделать это за вас:

Private Function FindCheckBoxByName(ByVal controlName As String) As MSForms.CheckBox
    Dim sh As InlineShape
    For Each sh In ThisDocument.InlineShapes
        If TypeOf sh.OLEFormat.Object Is MSForms.CheckBox Then
            If sh.OLEFormat.Object.Name = controlName Then
                'return the MSForms control:
                Set FindControlByName = sh.OLEFormat.Object
            End If
        End If
    Next

И теперь вы можете сделать это:

Dim cb As MSForms.ChecBox
Set cb = FindCheckBoxByName(controlName)
If cb Is Nothing Then
    MsgBox "No ActiveX CheckBox control named '" & controlName & "' was found in ThisDocument."
    Exit Sub
End If
v = cb.Value

После того, как все ссылки на элемент управления ActiveX параметризованы, ваши 33 обработчики теперь могут выглядетькак это:

Private Sub agi1_Click()
    HandleCheckBoxClick "agi1"
End Sub

Private Sub agi2_Click()
    HandleCheckBoxClick "agi2"
End Sub

'...

Private Sub agi33_Click()
    HandleCheckBoxClick "agi33"
End Sub

В качестве альтернативы, вы можете создать флажки во время выполнения, а затем обработать их событие Click в специальном модуле класса, но это немного сложнее ;-)

...