[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『ユーザーフォームを隠す』(はg)
調べても出てこなかったためこちらで質問させていただきます。
ユーザーフォームを隠すことは可能でしょうか。
左端に位置を固定させておき、カーソルが左端にいったら表示、離れたら隠したいです。
ここまでくるとエクセルでは難しいような気もするのですが・・・。
< 使用 Excel:Excel2010、使用 OS:Windows7 >
左端 とは 何 の 左端ですか?
(β) 2015/12/10(木) 14:20
(マウスではなく、カーソロでのセル選択での判断も可能ですが、とりあええずマウスです)
標準モジュール
Private Declare Function GetCursorPos Lib "User32" (lpPoint As POINTAPI) As Long Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long) As Long Private Declare Function SetLayeredWindowAttributes Lib "user32.dll" _ (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Long, ByVal dwFlags As Long) As Long
Const GWL_EXSTYLE = (-20) Const LWA_ALPHA = 2 Const WS_EX_LAYERED = &H80000
Type POINTAPI x As Long y As Long End Type
Public FlagLoop As Boolean Public myHwnd As Long
Sub DoLoop() Dim vv As Object Dim MPt As POINTAPI Dim oldPt As String Dim newPt As String
Do While FlagLoop
GetCursorPos MPt Set vv = ActiveWindow.RangeFromPoint(MPt.x, MPt.y) If Not vv Is Nothing Then If TypeName(vv) = "Range" Then If vv.Column = ActiveWindow.VisibleRange.Columns(1).Column Then Transparency 255 Else Transparency 0 End If End If End If
DoEvents
Loop
End Sub
Private Sub Transparency(level As Integer) Dim i As Long Call SetWindowLong(myHwnd, GWL_EXSTYLE, GetWindowLong(myHwnd, GWL_EXSTYLE) Or WS_EX_LAYERED) Call SetLayeredWindowAttributes(myHwnd, 0, level, LWA_ALPHA) End Sub
ユーザーフォームモジュール
Private Declare Function WindowFromAccessibleObject Lib "oleacc" ( _ ByVal pacc As Object, _ ByRef phwnd As Long) As Long
Private Sub UserForm_Initialize() WindowFromAccessibleObject Me, myHwnd FlagLoop = True Application.OnTime Now(), "DoLoop" End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) FlagLoop = False End Sub
(β) 2015/12/10(木) 15:06
【標準モジュール】
Const GWL_STYLE = (-16) Const WS_CAPTION = &HC00000 Const WS_SYSMENU = &H80000 Const WS_BORDER = &H800000 Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long) As Long Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Declare Function GetActiveWindow Lib "user32" () As Long Declare Function MoveWindow Lib "user32.dll" ( _ ByVal hWnd As Long, _ ByVal X As Long, _ ByVal Y As Long, _ ByVal nWidth As Long, _ ByVal nHeight As Long, _ ByVal bRepaint As Long) As Long Declare Function GetWindowRect Lib "user32.dll" ( _ ByVal hWnd As Long, _ lpRect As RECT _ ) As Long
Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type
Dim RC As RECT Dim hWnd As Long Dim iFlag As Long Dim iStyle(1) As Long Dim iWidth As Long Dim iHeight As Long
Sub sInitWnd() hWnd = GetActiveWindow() Call GetWindowRect(hWnd, RC) iWidth = RC.Right - RC.Left iHeight = RC.Bottom - RC.Top iStyle(0) = GetWindowLong(hWnd, GWL_STYLE) iStyle(1) = iStyle(0) And (Not (WS_CAPTION Or WS_SYSMENU Or WS_BORDER)) iFlag = 1 Call sHideWnd End Sub
Sub sShowWnd() If iFlag = 0 Then Call SetWindowLong(hWnd, GWL_STYLE, iStyle(0)) Call MoveWindow(hWnd, 0, 0, iWidth, iHeight, 1) iFlag = 1 End If End Sub
Sub sHideWnd() If iFlag = 1 Then Call SetWindowLong(hWnd, GWL_STYLE, iStyle(1)) Call MoveWindow(hWnd, 0, 0, 10, iHeight, 1) iFlag = 0 End If End Sub
【UserForm1】
Private Sub UserForm_Initialize() Application.OnTime Now, "sInitWnd" End Sub
Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) If X < 10 Then Call sShowWnd Else Application.OnTime Now + TimeValue("00:00:01"), "sHideWnd" End If End Sub (???) 2015/12/10(木) 17:23
全く別の発想というか、カーソルが・・・ということですから、ユーザーフォームはモードレス表示ですよね。
なので、難しいことは考えず、カーソルの動きのみで、画面左端の列にカーソルがいけば表示、はずれれば非表示。 表示されたときに、シート操作を可能にしています。 もし、表示されたときにはユーザーフォーム側操作可能にしたいのであれば★印のコードを消してください。
当該シートのシートモジュールに以下のみ。
Dim flag As Boolean
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim pos As Boolean
If Not Intersect(Target, ActiveWindow.VisibleRange.Columns(1)) Is Nothing Then pos = True
If pos Then If Not flag Then UserForm1.Show vbModeless flag = True AppActivate ActiveWindow.Caption '★ End If Else If flag Then UserForm1.Hide flag = False End If End If
End Sub
(β) 2015/12/10(木) 18:11
βさん、???さん
ありがとうございます!!想像通りものをいただけて大変感謝です!
この内容を理解できるように頑張ります。。
(はg) 2015/12/10(木) 18:21
昨日は本当にありがとうございました。
一つお聞きしたいことがあるのですが、ユーザーフォームが表示される位置はどこで指定されているのでしょうか?
標準モジュールの、
Set vv = ActiveWindow.RangeFromPoint(MPt.x, MPt.y)
If Not vv Is Nothing Then If TypeName(vv) = "Range" Then If vv.Column = ActiveWindow.VisibleRange.Columns(1).Column Then
この中のどこかにあるのかなと思い調べてみて、MPtは現在のマウスの位置を取得していて、RangeFromPointは画面の左端から目的のポイントまでの縦・横方向の距離を指定しているということはわかったのですが、知識が足らずうまく理解することができませんでした。
マウスを左端から離した状態(隠れた状態)で、左端にマウスを持っていくときのことです。
(はg) 2015/12/11(金) 11:37
いえ、提示したコードではユーザーフォームの表示場所は指定していません。 デザインでStartUpPosition プロパティに適切なものを設定してあるんだろうという推測というか前提です。
>>位置を固定するのは「StartUpPosition」を使えば良いということはわかったのですが
とコメントしておられましたから。
ただ、本件、目的にもよりますが、APIを使った大がかりな構えにするまでもなく、 (β) 2015/12/10(木) 18:11 で提示したコードで充分な気がします。
(β) 2015/12/11(金) 11:44
?@複数列に同じユーザーフォームを表示する場合
B列 UserForm1
E列 UserForm1
F列 UserForm1
?A同じく複数列に別々のユーザーフォームの場合
J列 UserForm3
K列 UserForm4
2通り考えられるのですが よろしくお願いします
(昴) 2015/12/11(金) 13:06
2.同じく複数列に別々のユーザーフォームの場合
J列 UserForm3
K列 UserForm4
(昴) 2015/12/11(金) 13:08
回答ありがとうございます。
言われてみればそうですね、そこまで大がかりにする必要はないかもしれません……。
現在は左端に位置を固定させているんですが、A列に書き込む際にマウスでセルをクリックしようとするとフォームが出てきてしまうので、出てくる位置を指定できないかなと思いましたが、キーボードで移動すれば問題ないですよね。
丁寧にありがとうございました。(>_<)
(はg) 2015/12/11(金) 13:11
To (昴)さん
別トピを立てられたほうがいいとは思うんですが。
それと、
>>1.複数列に同じユーザーフォームを表示する場合 >>B列 UserForm1 >>E列 UserForm1 >>F列 UserForm1
浅学にして、どうしたら、このようなこと(同じユーザーフォームを画面上に複数表示する)ができるのかわかりません。 教えていただけますか?
(β) 2015/12/11(金) 14:05
何度もコメントを付けて申し訳ありません。もう一つだけ質問させていただきたいのですが……。
ユーザーフォームを起動したまま新しくブックを開くことができないのですが、これは起動している間は処理が[実行中]となっているからなのでしょうか?
(はg) 2015/12/11(金) 14:24
(昴) 2015/12/11(金) 14:38
(はg)さん
>>ユーザーフォームを起動したまま新しくブックを開くことができないのですが
最初にアップした「裏での監視」版ですね。 うらでグルグル回っているので、なかなかサービスの順番が回ってこないと思いますが、 それでも、できるはずです。
ちょっと、試してみますが、その環境にいないのでしばらくお待ちください。
★ところで、こちらでは勝手に モードレス表示だと思っているんですが、それでいいのですね?
(β) 2015/12/11(金) 14:43
To (昴)さん
オリジナル質問、まだ継続中ですから、このトピ内でのやりとりはやめましょう。 新規トぴを立ててください。
なお、そのさいは、
>>3つ同じものはあまり多くないですが
多くないけど、もしあるなら、ほんとうにそうできるということを確認してから質問したほうがいいですよ。 じゃないと、そこのところで、回答者さんから、おかしいよ! というコメントが入り、時間がもったいないですから。
(β) 2015/12/11(金) 14:46
(はg)さん お邪魔してすみませんでした。
(昴) 2015/12/11(金) 14:51
ありがとうございます。お待ちしています。
はい、ユーザーフォームは、
UserForm1.Show vbModeless
で開いています。
(はg) 2015/12/11(金) 16:32
今、エクセルのある環境に戻ってきました。
こちらで、マクロを実行させながら
・ユーザーフォームが表示されている状態でファイルメニューから開く ・ユーザーフォームが非表示の状態でファイルメニューから開く
いずれも、問題なく開くことができます。
ただし、ファイルを開いた時点で、エクセル区画がプロジェクトリセットされ 表示されていたユーザーフォームも消えますし、裏で【実行中】だったコードも 実行停止になります。
いずれにしても【開くことはできます】
そちらでブックを開く、その操作手順は、どんな方式ですか?
なお、事前予告(?) 明日、早朝から月曜日深夜まで外出し、PCを見ることができません。 今晩中に解決しない場合は、火曜日以降になります。
(β) 2015/12/11(金) 17:17
回答ありがとうございます。
すみません、ファイル→開くでファイルを指定すれば開くことが出来ました。
ユーザーフォームを起動している状態で、フォルダを開きファイルをダブルクリックして開こうとすると開けないようです……。
裏で実行中のものは変わらず実行中となっています。
お忙しいのにお手数をお掛けしてすみません。私もこれからパソコンの使えない環境に移動するのですが、月曜日に必ず確認します。宜しくお願いします。
(はg) 2015/12/11(金) 18:01
なるほど! こちらでも確認しました。
う〜ん・・・・
DoEvents制御に加え、API Sleep も加えてハンドリングしてみましたが、やはりダブルクリックが無視されますね。 (無視 というか、おそらく、その指令を Windows から エクセルに渡そうとしても、エクセルが受け取らない?)
調べてみて、何かわかればアップしますが、さてどうなりますか・・・
エキスパートさんのヘルプがほしいところですねぇ。
(β) 2015/12/11(金) 19:26
色々とありがとうございます。
(はg) 2015/12/14(月) 18:08
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.