Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 11 Home : Microsoft 365)
セルが編集中の状態を解除するか、編集中でもuserformのボタンを有効にする方法について
投稿日時: 25/10/06 15:51:44
投稿者: suekunx

お世話になっております。
Excelのセルを編集中の状態で、userformを表示しているのですが
userformのボタンを押すことができません。
vbaでセルの編集中の解除か、もしくは、編集中でもuserformのボタンを押せる方法はありませんでしょうか。
よろしくお願い申し上げます。

回答
投稿日時: 25/10/06 17:18:01
投稿者: Suzu

そのユーザーフォームはどのように呼び出しているのでしょうか?
 
セル編集中に、フォームを呼び出す方法が思いつきません。
それとも、フォームから、セルを編集中にしている??
 
思いつくのは、ThisWorkBook の、Worksheet_SheetBeforeDoubleClick イベントなのですが
この イベントは、セルの編集中には 発生しないイベントのはず・・
 
編集モードにない状態から、イベントが発生
イベントのVBAが終了してから、セルが 編集モードに変わるので・・
 
もし、Worksheet_SheetBeforeDoubleClick にて発生させているのであれば
プロシージャの最後で
Cancel = True
を実行すれば良いでしょう。
 
 
違うイベントで発生させているのであれば 状況と、イベントについてご説明ください。

投稿日時: 25/10/07 07:51:25
投稿者: suekunx

タイマーで起動しています。
10秒経過したら、パスワード要求をフォームで表示します。

回答
投稿日時: 25/10/07 09:37:46
投稿者: Suzu

引用:
タイマーで起動しています。
10秒経過したら、パスワード要求をフォームで表示します。

 
セル が 編集モードである時には、
VBAの実行は 一時停止になる認識です。
 
編集モードから抜けないと プロシージャは実行されませんから
タイマーでも、フォーム表示はできない認識でいます。
 
 
タイマーもいくつか方法がありますから、
当方の確認した方法ではない手法で実行しているのかもしれませんので
必要ならお聞きしますが。。
 
とりあえず、
ユーザーフォーム表示をどんなメソッドで行っているかにもよりますが
フォームをモードレスとして表示してはどうでしょう。
 
UserForm1.Show vbModeless
 
 
希望の動作にならないのであれば、実行コード等、再現できる情報を提示ください。

投稿日時: 25/10/07 10:19:55
投稿者: suekunx

ソースを送信できません。
Forbidden Accessになります。
よろしくお願い申し上げます。

投稿日時: 25/10/07 10:26:01
投稿者: suekunx

' タイマーが発火したときに呼ばれるプロシージャ
Sub TimerProc()
    Dim i As Long
    Dim ws As Worksheet
    KillTimer 0&, TimerID
    TimerID = 0
     
    Call 選択解除
 
    UserForm1.Show
 
End Sub
' タイマー開始(10秒後に発火)
Sub StartTimer()
    If TimerID = 0 Then
        TimerID = SetTimer(0&, 0&, 7000&, AddressOf TimerProc)
    End If
End Sub

投稿日時: 25/10/07 10:27:01
投稿者: suekunx

Sub 選択解除()
keystop = SetTimer(0&, 31000&, 1000, AddressOf 入力解除)
 
End Sub
 
'================================================
Sub 入力解除()
    KillTimer 0&, keystop
    '入力モードなら
    If Not Excel.Application.CommandBars.FindControl(ID:=18).Enabled Then
    'Escを押して離す
        Call PostMessage _
        (Excel.Application.hWnd, WM_IME_KEYDOWN, VK_ESC, 0&)
        Call PostMessage _
        (Excel.Application.hWnd, WM_IME_KEYUP, VK_ESC, 0&)
        DoEvents ' Esc の反映を待つ
        Sleep 800
    End If
 
End Sub

投稿日時: 25/10/07 10:28:16
投稿者: suekunx

'マクロを実行させるタイマーAPI
Public Declare Function SetTimer Lib "user32" _
(ByVal hWnd As Long, ByVal nIDEvent As Long, _
ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
 
'タイマーを止めるAPI
Public Declare Function KillTimer Lib "user32" _
(ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
 
'キー入力などを送信するAPI
Public Declare Function PostMessage Lib _
"user32.dll" Alias "PostMessageW" _
(ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
 
Public Const VK_ESC = &H1B 'Escボタン
Public Const WM_IME_KEYDOWN = &H290& 'ボタン押して
Public Const WM_IME_KEYUP = &H291 'ボタン離す
 
Public keystop As Long '適当変数
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

投稿日時: 25/10/07 10:33:14
投稿者: suekunx

Suzu さんの引用:

 
フォームをモードレスとして表示してはどうでしょう。
UserForm1.Show vbModeless
 

 
パスワード要求画面なので、Excelを編集できない状態で使用したいです。

投稿日時: 25/10/07 10:35:56
投稿者: suekunx

選択解除をCallするだけなら、編集状態を解除できるのですが、
フォームを呼び出すと、編集状態が解除できないのです。
よろしくお願い申し上げます。

投稿日時: 25/10/07 10:39:23
投稿者: suekunx

suekunx さんの引用:
選択解除をCallするだけなら、編集状態を解除できるのですが、
フォームを呼び出すと、編集状態が解除できないのです。
よろしくお願い申し上げます。

 
編集状態が解除できないからか、フォームのボタンのイベントが反応しません。

投稿日時: 25/10/07 13:59:41
投稿者: suekunx

#If VBA7 Then
    #If Win64 Then
        Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
        Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" _
            (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
        Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
            (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long
    #Else
        Private Declare Function GetForegroundWindow Lib "user32" () As Long
        Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
            (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
        Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
            (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    #End If
#End If
Public Const WM_IME_KEYDOWN = &H290& 'ボタン押して
Public Const WM_IME_KEYUP = &H291 'ボタン離す
 
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const VK_ESCAPE = &H1B
 
Sub 強制セル編集解除()
    Dim hWndEdit As LongPtr
    Dim className As String * 256
    Dim length As Long
 
    hWndEdit = GetForegroundWindow()
    length = GetClassName(hWndEdit, className, 256)
 
    If length > 0 Then
        'className = Left(className, length)
        className = Left(className, 6)
        Debug.Print "ClassName:" & className & ":"
        'If className = "EXCEL6" Then
        'If className = "XLMAIN" Or className = "EXCEL6" Then
            ' ESCキーを InPlaceEdit に送信
' PostMessage hWndEdit, WM_KEYDOWN, VK_ESCAPE, 0
' PostMessage hWndEdit, WM_KEYUP, VK_ESCAPE, 0
            PostMessage hWndEdit, WM_IME_KEYDOWN, VK_ESCAPE, 0
            PostMessage hWndEdit, WM_IME_KEYUP, VK_ESCAPE, 0
            Sleep 300
            DoEvents
        'End If
    End If
End Sub
これで解決いたしました。
ありがとうございました。