iT邦幫忙

0

EXCEL如何再已設定VBA禁止儲存與另存狀況下使用按鈕控制項進行儲存

  • 分享至 

  • xImage

已再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 程式碼 再進行檔案儲存?

看更多先前的討論...收起先前的討論...
blanksoul12 iT邦研究生 5 級 ‧ 2022-01-05 09:28:25 檢舉
可以看看 inputbox 輸入密碼才可以正式存檔. 但 vba 的保安是很容易破解的.所有東西都是君子協定
yunglin73 iT邦新手 5 級 ‧ 2022-01-05 09:39:23 檢舉
這我有再考慮
但目前只要再程式碼中打上ThisWorkbook.Save
他就會執行Private Sub workbook_BeforeSave
變成禁止儲存
了解容易破解~主要是公司多數人不懂VBA 上頭的主管想要做一個簡單管控
結果是要「可以儲存」、「不許儲存」還是「只有點自訂按鈕才可以儲存」?
yunglin73 iT邦新手 5 級 ‧ 2022-01-05 09:56:01 檢舉
目前檔案已設定 "不可以儲存","不可以另存"

所以目前要設定一個"自訂按鈕點" 下去之後才可以儲存
但該按鈕打到ThisWorkbook.Save此程式碼後
只要一執行就會 牽動 Private Sub workbook_BeforeSave部分的程式碼
變成無法儲存的狀況

PS.因為後期要增加1個vba程式碼(除了本身儲存外還要再另一個路徑同步儲存一次檔案),所以才會先以 "按鈕控制項"方式先進行程式碼測試撰寫
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
blanksoul12
iT邦研究生 5 級 ‧ 2022-01-05 11:37:53
最佳解答
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
blanksoul12 iT邦研究生 5 級 ‧ 2022-01-05 11:52:08 檢舉

從網上抄來的,可把輸入的密碼變成 "*"

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
海綿寶寶
iT邦大神 1 級 ‧ 2022-01-05 10:13:39

以下未經實測,純粹假設

1.定義一個全域變數 gMySave
2.自訂按鈕的 VBA 裡加 gMySave = true
3.worbook_BeforeSave 裡用 gMySave (true/false) 來區別是「一般儲存/另存新檔」或是「自訂按鈕儲存」

我要發表回答

立即登入回答