繁体   English   中英

Excel VBA 输入框

[英]Excel VBA Input box

我有以下excel文件的输入框。 我不想显示输入字符而需要显示输入框字符 * ,该怎么做?

Private Sub Workbook_Open()

Dim UserName As String

UserName = InputBox("Please Enter Your USER NAME.")

Range("O1") = UCase(UserName)


End Sub

谢谢,赫瓦奇

使用用户窗体创建一个具有文本框和两个按钮的用户窗体在文本框属性中,在 PasswordChar 框中输入 *

在此处输入图片说明

在 userForm 模块中使用以下代码。

Private Sub CommandButton1_Click()

If TextBox1 = "123456" Then
MsgBox "Correct"
Else
MsgBox "Incorrect"
End If
Unload Me

End Sub

Private Sub CommandButton2_Click()

'cancel button

Unload Me
End Sub

Private Sub UserForm_Initialize()

Me.Caption = "Enter Password"

End Sub

您的用户表单将如下所示

在此处输入图片说明

可以在 vba 中屏蔽 InputBox 文本。

    Option Explicit

'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'March 2003
'////////////////////////////////////////////////////////////////////


'API functions to be used
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

'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


Private hHook As Long


Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim RetVal
    Dim strClassName As String, 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, 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

Function InputBoxDK(Prompt, Title) As String
    Dim lngModHwnd As Long, lngThreadID As Long

    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)

    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)

    InputBoxDK = InputBox(Prompt, Title)
    UnhookWindowsHookEx hHook

End Function

我知道这是一个老问题,但 Daniel Khan 的Bhanu Pratap代码需要更新才能在 Office 365 中使用它。该代码是为 32 位 Excel 环境编写的,但现代 Excel 使用的是 64 位环境并在他的代码上返回错误。 我几乎以为我无法挽救他的代码! 因为我终于找到了如何让它工作,我想把它贴在这里以防其他人也觉得它有用。

Excel 64 位代码:

Option Explicit

'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'March 2003
'
'Code updated by Joseph for Excel 64-bit Environments
'February 2020
'PtrSafe added & Long to PtrLong conversion
'see https://social.msdn.microsoft.com/Forums/office/en-US/c414ef6d-fa9a-406c-9644-e479e7e72d0b/addressof-function-data-type-mismatch?forum=accessdev
'////////////////////////////////////////////////////////////////////

'API functions to be used
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

'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

Private hHook As LongPtr


Public Function NewProc(ByVal lngCode As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
    Dim RetVal
    Dim strClassName As String, 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, 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, Title) As String
    Dim lngModHwnd As LongPtr, lngThreadID As LongPtr

    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)

    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)

    InputBoxDK = InputBox(Prompt, Title)
    UnhookWindowsHookEx hHook
End Function

感谢Bhanu Pratap提供 Daniel Klann 的实现,即动态更改内置 InputBox 以屏蔽密码提示中使用的字符。 将此模块添加到项目并调用 PasswordInputBox 比添加新表单容易得多。

感谢Joseph316将代码更新为 64 位,使其在 Office 365 Excel(版本 16)中工作!

我采用了 Daniel & Joseph 代码,重命名了一些变量并添加了一些注释,以便更容易理解代码在做什么。 没有功能差异。

Option Explicit

'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'March 2003
'
'Code updated by Joseph for Excel 64-bit Environments
'February 2020
'PtrSafe added & Long to PtrLong conversion
'see https://social.msdn.microsoft.com/Forums/office/en-US/c414ef6d-fa9a-406c-9644-e479e7e72d0b/addressof-function-data-type-mismatch?forum=accessdev
'
' Code names and comments updated by Barbara Bazemore Kiszka for clarity
' November 2020
'////////////////////////////////////////////////////////////////////

'API functions to be used
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

' 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

Private hMaskedInputHook As LongPtr

' This is a helper function. You probably don't want to call this directly.
Public Function AddMaskToInputBox(ByVal lngCode As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
    Dim RetVal
    Dim strClassName As String, lngBuffer As LongPtr
    
    ' If we are not active, skip this step
    If lngCode < HC_ACTION Then
        AddMaskToInputBox = CallNextHookEx(hMaskedInputHook, lngCode, wParam, lParam)
        Exit Function
    End If
    
    ' Initialize the string where we are going to check for the InputBox class
    strClassName = String$(256, " ")
    lngBuffer = 255
    
    If lngCode = HCBT_ACTIVATE Then        'A window has been activated
        RetVal = GetClassName(wParam, strClassName, lngBuffer)
        
        ' Check to see if this is the InputBox window
        If Left$(strClassName, RetVal) = "#32770" Then
            ' This changes the edit control so that it displays 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 hMaskedInputHook, lngCode, wParam, lParam
End Function

' Call this function to display Password prompt dialog
Public Function PasswordInputBox(Prompt, Title) As String
    Dim lngModHwnd  As LongPtr, lngThreadID As LongPtr
    
    ' Set up a Windows hook so the the masked chars are set up the next time we display an InputBox
    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)
    
    hMaskedInputHook = SetWindowsHookEx(WH_CBT, AddressOf AddMaskToInputBox, lngModHwnd, lngThreadID)
    
    ' Prompt the user for the password, masking the input characters
    PasswordInputBox = InputBox(Prompt, Title)
    
    ' Go back to normal InputBox behavior
    UnhookWindowsHookEx hMaskedInputHook
End Function

ImputBox 不支持屏蔽,因此您不能在其中隐藏字符。 你需要使用一些像带有白色字符的 TextBox 或类似的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM