Excel 调用窗体时,VBA窗体(自动)绑定/绑定到ActiveWorksheet。显示VBA无模式

Excel 调用窗体时,VBA窗体(自动)绑定/绑定到ActiveWorksheet。显示VBA无模式,excel,vba,Excel,Vba,很难向谷歌描述,但情况如下 我在功能区上有一个按钮,该按钮链接到将启动我的表单的sub: Sub Start() MyForm.Init MyForm.Show vbModeless End Sub 我的表单调用的代码执行一些操作并创建一个新工作簿。创建新工作簿时,表单将消失。当返回表单时,它会提取显示表单时处于活动状态的工作簿。我希望新工作簿和表单处于活动状态,以便使用新工作表从表单执行更多操作 是否有其他方法调用/加载表单以使其不“链接”到工作簿?是的,可以通过使用APIS

很难向谷歌描述,但情况如下

我在功能区上有一个按钮,该按钮链接到将启动我的表单的sub:

Sub Start()
    MyForm.Init
    MyForm.Show vbModeless
End Sub
我的表单调用的代码执行一些操作并创建一个新工作簿。创建新工作簿时,表单将消失。当返回表单时,它会提取显示表单时处于活动状态的工作簿。我希望新工作簿和表单处于活动状态,以便使用新工作表从表单执行更多操作


是否有其他方法调用/加载表单以使其不“链接”到工作簿?

是的,可以通过使用API
SetWindowPos
FindWindowA
实现。您可以阅读这些API

这就是你想要的吗

代码

Option Explicit

Private Const SWP_NOMOVE = 2
Private Const SWP_NOSIZE = 1    
Private Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2

Private Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long

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

Sub Sample()
    Dim hwnd As Long

    UserForm1.Show vbModeless

    '~~> Find the handle of the userform
    hwnd = FindWindowA("ThunderDFrame", UserForm1.Caption)

    '~~> Set the form as the top most window
    SetTopMostWindow hwnd, True
End Sub

Private Function SetTopMostWindow(hwnd As Long, Topmost As Boolean) As Long
    If Topmost = True Then
        SetTopMostWindow = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
    Else
        SetTopMostWindow = SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)
        SetTopMostWindow = False
    End If
End Function
测试

  • 将代码粘贴到具有userform的工作簿模块中
  • 打开两本工作簿
  • Userform1
    替换为您的用户名
  • 运行程序
    示例

  • @braX这不起作用,因为它会同时激活工作表。这很接近…表单始终位于顶部。。。试试这个。使用表单中的代码创建新工作簿,然后表单将位于新工作簿的顶部。单击表单,它将自动激活第一个工作簿。是的,这是您无法摆脱的(AFAIK),因为表单已绑定到第一个工作簿。