已再VBA設定程式碼如下
Private Sub workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If SaveAsUI = True Then
ThisWorkbook.Saved = Flase
Cancel = True
MsgBox "禁止另存新檔喔", vbInformation
Else
ThisWorkbook.Saved = Flase
Cancel = True
MsgBox "禁止存檔喔", vbInformation
End If
End Sub
請問如何設定一個按鈕控制項的VBA 程式碼 再進行檔案儲存?
Private Sub workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
save_password = InputBox("Input password if you want to save this file")
If save_password <> "123456789" Or WorksheetFunction.Trim(save_password) = "" Then
If SaveAsUI = True Then
ThisWorkbook.Saved = Flase
Cancel = True
MsgBox "禁止另存新檔喔", vbInformation
Else
ThisWorkbook.Saved = Flase
Cancel = True
MsgBox "禁止存檔喔", vbInformation
End If
End If
End Sub
從網上抄來的,可把輸入的密碼變成 "*"
Private Sub workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
save_password = InputBoxDK("Input password if you want to save this file", "")
If save_password <> "123456789" Or WorksheetFunction.Trim(save_password) = "" Then
If SaveAsUI = True Then
ThisWorkbook.Saved = Flase
Cancel = True
MsgBox "禁止另存新檔喔", vbInformation
Else
ThisWorkbook.Saved = Flase
Cancel = True
MsgBox "禁止存檔喔", vbInformation
End If
End If
End Sub
開一個模組放以下 coding
#If VBA7 Then
Public Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, _
ByVal ncode As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Public Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias _
"GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr
Public Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
(ByVal idHook As Long, ByVal lpfn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As Long) As LongPtr
Public Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As Long
Public Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _
(ByVal hDlg As LongPtr, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Public Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
#Else
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function GetModuleHandle Lib "kernel32" Alias _
"GetModuleHandleA" (ByVal lpModuleName As String) As Long
Public 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
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Public 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
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public Declare Function GetCurrentThreadId Lib "kernel32" () As Long
#End If
'Constants to be used in our API functions
Public Const EM_SETPASSWORDCHAR = &HCC
Public Const WH_CBT = 5
Public Const HCBT_ACTIVATE = 5
Public Const HC_ACTION = 0
#If VBA7 Then
Public hHook As LongPtr
#Else
Public hHook As Long
#End If
'----------------------------------
'public PASSWORDS FOR INPUTBOX
'----------------------------------
'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'March 2003
'64-bit modifications developed by Alexey Tseluiko
'and Ryan Wells (wellsr.com)
'February 2019
'////////////////////////////////////////////////////////////////////
#If VBA7 Then
Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPtr
#Else
Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
#End If
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
'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
#If VBA7 Then
Dim lngModHwnd As LongPtr
#Else
Dim lngModHwnd As Long
#End If
Dim lngThreadID As Long
lngThreadID = GetCurrentThreadId
lngModHwnd = GetModuleHandle(vbNullString)
hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
InputBoxDK = InputBox(Prompt, Title)
UnhookWindowsHookEx hHook
End Function
以下未經實測,純粹假設
1.定義一個全域變數 gMySave
2.自訂按鈕的 VBA 裡加 gMySave = true
3.worbook_BeforeSave 裡用 gMySave (true/false) 來區別是「一般儲存/另存新檔」或是「自訂按鈕儲存」