#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:
Да, это недокументированная ошибка (по крайней мере, я никогда не находил никакой документации по этому поводу). Сказав это, вы можете достичь желаемого, выполнив следующее.
Логические
- Показать форму в
Modal
- В
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, все еще существуют подобные странные ошибки. В любом случае, спасибо за очень подробное объяснение, я ценю это!