エクセルのInputboxで、入力された文字列を自動的にアスタリスクで隠すようにする方法を探し
http://oshiete.goo.ne.jp/qa/2371878.html
の回答No1のコードがまさに最適なコードで、これまで非常に助かっていました。
ところが、64bitのエクセルでは動かないことがわかりました。
表示されたエラーメッセージの言葉から調べて、PtrSafeという言葉を入れなければならないようなのでAPI宣言を以下のようにしてみました。
#If VBA7 And Win64 Then '64ビット版
Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
(ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _
(ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
#Else '32ビット版
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
(ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _
(ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) 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 GetCurrentThreadId Lib "kernel32" () As Long
#End If
ところが、回答No1のコードで
Sub Report_Open() を実行すると
Public Function InputBoxDK(Prompt, Optional Title, Optional Default, Optional XPos, _
Optional YPos, Optional HelpFile, Optional Context) As String
のところがハイライトされてエラーになります。
どう直せば良いのでしょうか?
全文のコードを乗せると字数制限に引っかかりますので、申し訳ありませんが宣言以外の部分は
http://oshiete.goo.ne.jp/qa/2371878.html
の回答No1のコードを見てくださいますようお願いします。
No.1ベストアンサー
- 回答日時:
(1/2)
こんにちは。
暫く回答お休み中で、質問を読むこともないこの頃なのですが、
たまたま馴染みのアバターをお見かけしましたので、このご質問だけレスしてみます。
Win32 API コールバック、と、64|32bit環境互換については
今の時点での情報が少な過ぎてこちらも確信を持てるものは書けません。
必要な手当てをして、動作確認はしましたが、もっとスマートなやり方があるかも知れません。
お求めに寄り添った直接的な回答として、2回の投稿で記述を掲げますが、
そもそもの方法として、これが唯一のものではないことを知っておいてください。
リンクを張られた質問スレ(元スレ)においては、
「恐らくAccess VBAついての質問であろう」とう前提で回答が付いています。
今回は、Excel カテゴリに書かれた質問ですから、
PasswordCharプロパティを * に設定したTextBoxを配置したユーザーフォーム
(他にPromptを表示するLabel、OKボタンにあたるCommandButton)を用意しておいて、
' ' 標準モジュール
Public rtn
Sub Report_Open()
UserForm1.Show vbModal
If rtn <> "password" Then
MsgBox "社員コードが間違っています。"
End If
End Sub
' ' ユーザーフォームモジュール
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
rtn = TextBox1
End Sub
Private Sub CommandButton1_Click()
Unload Me
End Sub
のようなものを奨めるのがExcel VBA的には本筋だと考えています。
この場合はバージョン互換を意識する必要はありませんし、デザインが自在ですし、
何よりシンプルです。
本題に戻って、、、
AddressOf演算子に渡すFunctionの型は明示的である必要があります。
64bitでは
Function NewProc(...) As LongPtr
32bitでは
Function NewProc(...) As Long
なので、各関数を丸ごと条件付きコンパイルの内側で書き分けてあげる必要があります。
もしも仮に32bit互換を捨てて、64bit環境に限った話としては、
64bit用のDeclare文のすべてと、
各Functionの戻り型、引数、変数について、
Long型の宣言をLongPtr型に(今回必要な記述に関してのみ)
ご提示の記述から全置換すれば期待の動作にはなります。
64bit版については、明らかにLongLong型である場合でも、
LongPtr型で統一して解り易い(編集し易い)ように書いています。
以下、お求めの記述。
' ' ///
Option Explicit
'Constants to be used in our API functions
Private Const EM_SETPASSWORDCHAR = &HCC
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5
Private Const HC_ACTION = 0
#If VBA7 And Win64 Then '〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
' ' 〓〓〓〓〓64ビット版、以下〓〓〓〓〓
Private Declare PtrSafe Function CallNextHookEx Lib "user32" ( _
ByVal hHook As LongPtr, ByVal ncode As LongPtr, _
ByVal wParam As LongPtr, lParam As Any _
) As LongPtr
Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" ( _
ByVal lpModuleName As String _
) As LongPtr
Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
ByVal idHook As LongPtr, ByVal lpfn As LongPtr, _
ByVal hmod As LongPtr, ByVal dwThreadId As LongPtr _
) As LongPtr
Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" ( _
ByVal hHook As LongPtr _
) As LongPtr
Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" ( _
ByVal hDlg As LongPtr, ByVal nIDDlgItem As LongPtr, _
ByVal wMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr _
) As LongPtr
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" ( _
ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As LongPtr _
) As LongPtr
Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As LongPtr
Private Const VER64BIT = True
Private hHook As LongPtr
Private Function NewProc(ByVal lngCode As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Dim strClassName As String
Dim RetVal As LongPtr
Dim lngBuffer As LongPtr
If lngCode < HC_ACTION Then
NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)
Exit Function
End If
strClassName = String$(256, " ")
lngBuffer = 255
If lngCode = HCBT_ACTIVATE Then 'A window has been activated
RetVal = GetClassName(wParam, strClassName, lngBuffer)
If Left$(strClassName, CLng(RetVal)) = "#32770" Then 'Class name of the Inputbox
'This changes the edit control so that it display the password character *.
'You can change the Asc("*") as you please.
SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("*"), &H0
End If
End If
'This line will ensure that any other hooks that may be in place are
'called correctly.
CallNextHookEx hHook, lngCode, wParam, lParam
End Function
cj_mover さん、いつもありがとうございます。
アバタじゃなくてえくぼ、いやホクロなんですが・・・なんて冗談はおいときまして、さっそく64bitエクセルで試したところ当然ですがちゃんと作動してくれました。
助かりました。
本当はおっしゃるようにユーザーフォームを使用するべきなんですね。ただユーザーフォームってこれまでつかったことがないのでなんとなく尻込みしていました。
ユーザーフォームの方も試してみて、またわからないことがありましたら質問させていただきます。
ありがとうございました。
No.2
- 回答日時:
(2/2)
Public Function InputBoxDK( _
Prompt As String, Optional Title, Optional Default, _
Optional XPos, Optional YPos, Optional HelpFile, Optional Context _
) As String
Dim lngModHwnd As LongPtr
Dim lngThreadID As LongPtr
lngThreadID = GetCurrentThreadId
lngModHwnd = GetModuleHandle(vbNullString)
hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
InputBoxDK = InputBox(Prompt, Title, Default, XPos, YPos, HelpFile, Context)
UnhookWindowsHookEx hHook
End Function
' ' 〓〓〓〓〓64ビット版、以上〓〓〓〓〓
#Else '〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
' ' 〓〓〓〓〓32ビット版、以下〓〓〓〓〓
Private Declare Function CallNextHookEx Lib "user32" ( _
ByVal hHook As Long, ByVal ncode As Long, _
ByVal wParam As Long, lParam As Any _
) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" ( _
ByVal lpModuleName As String _
) As Long
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
ByVal idHook As Long, ByVal lpfn As Long, _
ByVal hmod As Long, ByVal dwThreadId As Long _
) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
ByVal hHook As Long _
) As Long
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" ( _
ByVal hDlg As Long, ByVal nIDDlgItem As Long, _
ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long _
) 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 GetCurrentThreadId Lib "kernel32" () As Long
Private Const VER64BIT = False
Private hHook As Long
Private Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim strClassName As String
Dim RetVal As Long
Dim lngBuffer As Long
If lngCode < HC_ACTION Then
NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)
Exit Function
End If
strClassName = String$(256, " ")
lngBuffer = 255
If lngCode = HCBT_ACTIVATE Then 'A window has been activated
RetVal = GetClassName(wParam, strClassName, lngBuffer)
If Left$(strClassName, CLng(RetVal)) = "#32770" Then 'Class name of the Inputbox
'This changes the edit control so that it display the password character *.
'You can change the Asc("*") as you please.
SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("*"), &H0
End If
End If
'This line will ensure that any other hooks that may be in place are
'called correctly.
CallNextHookEx hHook, lngCode, wParam, lParam
End Function
Public Function InputBoxDK( _
Prompt As String, Optional Title, Optional Default, _
Optional XPos, Optional YPos, Optional HelpFile, Optional Context _
) As String
Dim lngModHwnd As Long
Dim lngThreadID As Long
lngThreadID = GetCurrentThreadId
lngModHwnd = GetModuleHandle(vbNullString)
hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
InputBoxDK = InputBox(Prompt, Title, Default, XPos, YPos, HelpFile, Context)
UnhookWindowsHookEx hHook
End Function
' ' 〓〓〓〓〓32ビット版、以上〓〓〓〓〓
#End If '〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
' ' 〓〓〓〓〓
Sub Report_Open()
If InputBoxDK("パスワードを入力して下さい") <> "password" Then
MsgBox "社員コードが間違っています。"
End If
' Debug.Print VER64BIT ' 確認用 64bit環境なら True
End Sub
' ' 〓〓〓〓〓
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
カンパ〜イ!←最初の1杯目、なに頼む?
飲み会で最初に頼む1杯、自由に頼むとしたら何を頼みますか? 最初はビールという縛りは無しにして、好きなものを飲むとしたら何を飲みたいですか。
-
【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
2024年は「名探偵コナン30周年」「涼宮ハルヒ20周年」などを迎えますが、 あなたが「もうそんなに!?」と驚いた○○周年を教えてください。
-
【お題】引っかけ問題(締め切り10月27日(日)23時)
【大喜利】 「日本で一番高い山は富士山……ですが!」から始まった、それは当てられるわけ無いだろ!と思ったクイズの問題
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
入力時のパスワードを「*」などにして見えないようにするには?
Excel(エクセル)
-
フォントの大きさ
Visual Basic(VBA)
-
IF関数で空欄(")の時、Nullにしたい
その他(Microsoft Office)
-
-
4
VBAのコマンドボタンの文字列の改行方法は?
Visual Basic(VBA)
-
5
【Excel VBA】シートコピー時、マクロコードはコピーしたくない
Access(アクセス)
-
6
2つ以上の変数を比較して最大数を求めたい
Word(ワード)
-
7
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
8
コマンドボタンを押すたびに大きくなってしまう
Excel(エクセル)
-
9
エクセルVBA ListBox選択を反映させる
Excel(エクセル)
-
10
VBA/エクセルの日付入力でYYYYMMDD
Excel(エクセル)
-
11
Excelのマクロ名の並び順の法則は?
Excel(エクセル)
-
12
エクセルVBAで、MsgBox やInputBox は、画面の中央以外に表示させたい。
Excel(エクセル)
-
13
エクセルマクロで指定範囲内の図形を削除
Excel(エクセル)
-
14
「指定したフォルダにあるファイルを書き出す」古いマクロの修正
Visual Basic(VBA)
-
15
VBA kernel32 の意味
マウス・キーボード
-
16
Vba LongPtrについて教えてください
Visual Basic(VBA)
-
17
vba クリップボードクリアについて教えてください
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
相手側の携帯が電源切れてる時...
-
face book で女性の方からline ...
-
1コールだけ鳴るけど切れる電話...
-
遠くにいる友達とLINE交換する...
-
ラインナップとラインアップは...
-
Windowsのバッチファイルで正規...
-
よく05(04)lineって見かけるん...
-
「一番上、真ん中、下」を示す英語
-
python flask から fastapiへの...
-
法線(normal line)はなぜそう...
-
swift言語のprintln()関数で「p...
-
毎月記念日をlineで祝うのって...
-
LINEで好きな人が「笑」を全然つ...
-
教えてください
-
Please tell me to some ramen ...
-
生産ラインの品質を表す直行率...
-
着信拒否、ラインブロックと解...
-
「一点鎖線」を英語でいうと?
-
line誤爆してしまいました 全く...
-
line でおはようございます、の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
相手側の携帯が電源切れてる時...
-
1コールだけ鳴るけど切れる電話...
-
face book で女性の方からline ...
-
よく05(04)lineって見かけるん...
-
Windowsのバッチファイルで正規...
-
法線(normal line)はなぜそう...
-
遠くにいる友達とLINE交換する...
-
「一番上、真ん中、下」を示す英語
-
LINEで好きな人が「笑」を全然つ...
-
生産ラインの品質を表す直行率...
-
python flask から fastapiへの...
-
lineのワン切り、なぜ?
-
毎月記念日をlineで祝うのって...
-
line でおはようございます、の...
-
会社の先輩とLINE プライベート...
-
2000年生まれなのですが 00line...
-
ある男子から、ライン追加され...
-
まだそんなに親しくない相手と...
-
並立と並列の違いってなんですか?
-
タイトルの改行
おすすめ情報