13

マクロがまだシートをインポートしているときに進行状況バーを表示するユーザーフォームを作成しました ここに画像の説明を入力

問題は、ユーザーが赤い[X]ボタンを押して閉じて処理を中断できることです。

この赤い運命のボタンを非表示にして、潜在的なユーザーが実行中にクリックするボタンを混乱させないようにする方法はありますか?

編集:

私はこれを試しました

'Find the userform's Window
Private Declare Function FindWindow Lib "user32" _
        Alias "FindWindowA" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String) As Long

'Get the current window style
Private Declare Function GetWindowLong Lib "user32" _
        Alias "GetWindowLongA" ( _
        ByVal hWnd As Long, _
        ByVal nIndex As Long) As Long

'Set the new window style
Private Declare Function SetWindowLong Lib "user32" _
        Alias "SetWindowLongA" ( _
        ByVal hWnd As Long, _
        ByVal nIndex As Long, _
        ByVal dwNewLong As Long) As Long

Const GWL_STYLE = -16
Const WS_SYSMENU = &H80000

これをuserform_initializeで使用しました

   Dim hWnd As Long, lStyle As Long

   'Which type of userform
   If Val(Application.Version) >= 9 Then
      hWnd = FindWindow("ThunderDFrame", Me.Caption)
   Else
      hWnd = FindWindow("ThunderXFrame", Me.Caption)
   End If

   'Get the current window style and turn off the Close button
   lStyle = GetWindowLong(hWnd, GWL_STYLE)
   SetWindowLong hWnd, GWL_STYLE, (lStyle And Not WS_SYSMENU)

このエラーメッセージが表示されます ここに画像の説明を入力

このコードはhereから取得されました。何が間違っているのかわからず、すでにコメントを削除しました。これは私が見つけた最も単純なコードなので、ユーザーフォームに統合したいと思います。どんな助けでも大歓迎です。

4

6 に答える 6

15

以下は、このように呼び出すことができるルーチンです。

subRemoveCloseButton MyForm

またはフォーム内から:

subRemoveCloseButton Me 

必要なコードは次のとおりです。

Private Const mcGWL_STYLE = (-16)
Private Const mcWS_SYSMENU = &H80000

'Windows API calls to handle windows
#If VBA7 Then
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#Else
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If

#If VBA7 Then
    Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
#End If

#If VBA7 Then
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#Else
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If


Public Sub subRemoveCloseButton(frm As Object)
    Dim lngStyle As Long
    Dim lngHWnd As Long

    lngHWnd = FindWindow(vbNullString, frm.Caption)
    lngStyle = GetWindowLong(lngHWnd, mcGWL_STYLE)

    If lngStyle And mcWS_SYSMENU > 0 Then
        SetWindowLong lngHWnd, mcGWL_STYLE, (lngStyle And Not mcWS_SYSMENU)
    End If

End Sub
于 2013-03-01T08:38:06.393 に答える
10

次のスニペットから解決できます。

ボタンを選択しcmdCloseます メニュー バーでView | Code 、カーソルが点滅している場所を選択し、次のコードを入力します。

Private Sub cmdClose_Click()
  Unload Me
End Sub

メニュー バーで、 を選択View | Objectして、ユーザー フォームに戻ります。

ユーザーが Esc キーを押してフォームを閉じることができるようにするには:

[cmdClose] ボタンを選択します。 [プロパティ] ウィンドウで、Cancelプロパティを次のように変更します。True

ユーザーが X ボタンをクリックしてフォームを閉じないようにするには

UserForm開くとX右上にがあります。[フォームを閉じる] ボタンを使用するだけでなく、[X] を使用してフォームを閉じることもできます。それを防ぐには、次の手順に従います。

UserForm の空の部分を右クリックします [View | Code 手順] ドロップダウンから選択し、右上にある [QueryClose] を選択します

カーソルが点滅している場所に、次のサンプルから強調表示されたコードを貼り付けます

Private Sub UserForm_QueryClose(Cancel As Integer, _
  CloseMode As Integer)
  If CloseMode = vbFormControlMenu Then
    Cancel = True
    MsgBox "Please use the Close Form button!"
  End If
End Sub

メニュー バーで、 を選択View | Objectして、ユーザー フォームに戻ります。これで、ユーザー フォームの をクリックするXと、メッセージが表示されます。

http://www.contextures.com/xlUserForm01.htmlから

于 2013-03-01T08:35:29.773 に答える
6

これは、@Peter Albertの上記の回答の改善です

  • Windows API 呼び出しが Office x64 セーフになりました
  • FindWindowExcel UserForms のみを検索するように呼び出しが改善されました。元の回答の関数は、すべてのウィンドウ クラスを検索します (例: Explorer ウィンドウや他のプログラムのウィンドウ)。そのため、他のプログラムやエクスプローラ ウィンドウの [x] ボタンが、それらの名前がユーザー フォームと同じ名前である場合に削除されることがあります。

Private Const mcGWL_STYLE = (-16)
Private Const mcWS_SYSMENU = &H80000

'Windows API calls to handle windows
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
  
#If Win64 Then
    Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" ( _
        ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If

Public Sub RemoveCloseButton(objForm As Object)
    Dim lngStyle As LongPtr
    Dim lngHWnd As LongPtr
    
    Dim lpClassName As String
    lpClassName = vbNullString
    If Val(Application.Version) >= 9 Then
       lpClassName = "ThunderDFrame"
    Else
       lpClassName = "ThunderXFrame"
    End If
    
    lngHWnd = FindWindow(lpClassName, objForm.Caption)
    lngStyle = GetWindowLongPtr(lngHWnd, mcGWL_STYLE)

    If lngStyle And mcWS_SYSMENU > 0 Then
        SetWindowLongPtr lngHWnd, mcGWL_STYLE, (lngStyle And Not mcWS_SYSMENU)
    End If
End Sub

サンダーDフレーム?
Excel の UserForms は、実際には Windows クラスThunderDFrameであり、これは 2002 年以降の Microsoft Office アプリケーションのすべての UserFroms のクラスです。それ以前はThunderXFrame.

于 2016-10-27T13:43:01.450 に答える
2

これは古い質問であることは知っていますが、OPが引用したユーザーフォームのタイプについては、閉じるボタンを削除、非表示、または無効にする必要はありません。もっと簡単な方法があります;)

ユーザーが操作する要素 (ボタンなど) を持たず、目的が終了すると自動的に閉じるユーザー フォームの場合は、フォームを無効にするだけで問題ありません。

ユーザー フォームを無効にするには: ユーザー フォームのプロパティで、Enabled に対して False を設定します。ユーザーフォームは、コードが非表示にするまで表示されます。ユーザーはフォームに対して何もできません (閉じることができない、移動できないなど)。

また、ユーザー フォームがまだ表示されている間にユーザーがメイン ウィンドウで他の操作を実行できるようにするかどうかによって、ShowModal を設定するかどうかが決まります。

于 2015-06-16T06:18:38.533 に答える
2

ボタンを無効にする便利な方法は、次のとおりです。

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = 0 Then Cancel = True
End Sub

これはボタンを取り除くわけではありませんが、ボタンをクリックしても何の効果もありません。

于 2016-11-18T20:14:55.527 に答える