Конфликт между восемнадцатью OLEObjects и пользовательской формой

#excel #vba

#excel #vba

Вопрос:

Я пытаюсь удалить ActiveX OLEObject с листа, а затем запустить UserForm как vbModeLess .

В приведенном ниже коде:

Сначала подраздел создает OLEObject (a Label ) на листе «mySheet» с его заголовком и именем.

 Sub creteOleo()

    Dim rng As Range
            
    Set rng = Sheets("mySheet").Range("B2:C3")
            
    With Sheets("mySheet").OLEObjects.Add(ClassType:="Forms.Label.1", _
                                            Link:=False, _
                                            DisplayAsIcon:=False, _
                                            Left:=rng.Left, _
                                            Top:=rng.Top, _
                                            Width:=rng.Width, _
                                            Height:=rng.Height)
        .Name = "myOleo" 'A name
        .Object.Font.Size = 13
        .Object.Caption = "test"
    End With
End Sub
  

Затем подзаголовок, который удаляет его, затем запускает пользовательскую форму (пользовательская форма содержит только метку, она предназначена для тестирования, поэтому внутри нет кода) с vbModeLess состоянием.

 Sub deleteOleo()
    Sheets("mySheet").OLEObjects("myOleo").Delete
    UserForm1.Show vbModeless
End Sub
  

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

Эта проблема появляется только тогда, когда пользовательская форма запущена в vbModeLess состоянии, поэтому я выбрал другой способ (скрытие объекта вместо его удаления), который работает, но мне любопытно узнать, почему VBA ведет себя таким образом.

Я понимаю, что, поскольку Excel выполняет UserForm1.Show после завершения удаления OLEObject , это не должно мешать ему. Более того, это не похоже на удаление всех объектов, а только определенного.

Ответ №1:

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

Логические

  1. Показать форму в Modal
  2. В UserForm_Activate() случае измените его обратно на Modeless .

В модуле

 Option Explicit

Sub creteOleo()
    Dim rng As Range
    
    Set rng = Sheets("mySheet").Range("B2:C3")
    
    With Sheets("mySheet").OLEObjects.Add(ClassType:="Forms.Label.1", _
                                          Link:=False, _
                                          DisplayAsIcon:=False, _
                                          Left:=rng.Left, _
                                          Top:=rng.Top, _
                                          Width:=rng.Width, _
                                          Height:=rng.Height)
                                          
        .Name = "myOleo" 'On lui donne un nom
        .Object.Font.Size = 13
        .Object.Caption = "test"
    End With
End Sub

Sub deleteOleo()
    Sheets("mySheet").OLEObjects("myOleo").Delete
    
    DoEvents
    
    Dim frm As New UserForm1
    
    frm.Show
End Sub
  

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

 Option Explicit

Private Declare Function EnableWindow Lib "user32.dll" (ByVal hWnd As Long, _
ByVal fEnable As Long) As Long

Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function GetParent Lib "user32.dll" (ByVal hWnd As Long) As Long

Private Sub UserForm_Activate()
    EnableWindow GetParent(FindWindow(vbNullString, Me.Caption)), 1
End Sub
  

В действии

введите описание изображения здесь

Комментарии:

1. Интересно, что даже после всех этих лет, когда VBA был языком по умолчанию для использования макросов в Excel, все еще существуют подобные странные ошибки. В любом случае, спасибо за очень подробное объяснение, я ценю это!