Kỹ thuật yêu cầu người sử dụng file phải enable

Liên hệ QC

levanduyet

Hãy để gió cuốn đi.
Thành viên danh dự
Tham gia
30/5/06
Bài viết
1,798
Được thích
4,704
Giới tính
Nam
Chào các bạn,
Như các ứng dụng tôi đã giới thiệu với các bạn trong lớp VBA về kỹ thuật để bắt buộc người sử dụng phải Enable Macro khi sử dụng file của chúng ta.
Nay tôi thấy có một module viết về vấn đề này tôi xin giới thiệu với các bạn:
Đầu tiên các bạn hãy tạo một module và chép đoạn code này vào.
Mã:
Option Explicit
'From http://www.cpearson.com/excel/EnableMacros.aspx
Private Const C_SHEETSTATE_NAME = "SheetState"  '<<<< Tinh trang cua worksheet, cac ban co the thay doi
Private Const C_INTRO_SHEETNAME = "Start"       '<<<< Ten worksheet muon hien ra, cac ban co the thay doi
Private Const C_WORKBOOK_PASSWORD = "abc"       '<<<< Passwork cua workbook, cac ban co the thay doi

Sub SaveStateAndHide()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SaveStateAndHide
' This is called from Workbook_BeforeClose.
' This procedure saves the Visible propreties of all worksheets
' in the workbook. This will run only if macros are enabled. It
' saves the Visible properties as a colon-delimited string, each
' element of which is the Visible property of a sheet. In the
' property string, C_INTRO_SHEETNAME is set to xlSheetVeryHidden
' so that if the workbook is opened with macros enabled, that
' sheet will not be visible. If macros are not enabled, only
' that sheet will be visible.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Dim S As String
    Dim WS As Object
    Dim N As Long
    ''''''''''''''''''''''''''''''''''''''''''''
    ' Protection settings. We must be
    ' able to unprotect the workbook in
    ' order to modify the sheet visibility
    ' properties. We will restore the
    ' protection at the end of this procedure.
    ''''''''''''''''''''''''''''''''''''''''''''
    Dim HasProtectWindows As Boolean
    Dim HasProtectStructure As Boolean
    Dim HasProtection As Boolean

    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Save the workbook's protection settings and
    ' attempt to unprotect the workbook.
    '''''''''''''''''''''''''''''''''''''''''''''''
    HasProtectWindows = ThisWorkbook.ProtectWindows
    HasProtectStructure = ThisWorkbook.ProtectStructure

    If (HasProtectWindows = True) Or (HasProtectStructure = True) Then
        HasProtection = True
    End If
    ThisWorkbook.Unprotect Password:=C_WORKBOOK_PASSWORD

    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Make the introduction sheet visible
    '''''''''''''''''''''''''''''''''''''''''''''''
    ThisWorkbook.Worksheets(C_INTRO_SHEETNAME).Visible = xlSheetVisible
    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Delete the Name. Ignore error if it doesn't
    ' exist.
    On Error Resume Next
    '''''''''''''''''''''''''''''''''''''''''''''''
    ThisWorkbook.Names(C_SHEETSTATE_NAME).Delete
    Err.Clear
    On Error GoTo 0
    For Each WS In ThisWorkbook.Sheets
        '''''''''''''''''''''''''''''''''''''''''''''''
        ' Create a string of the sheet visibility
        ' properties, separated by ':' characters.
        ' Do not put a ':' after the last sheet. Always
        ' set the visible property of the Introduction
        ' sheet to xlSheetVeryHidden. Don't put a ':'
        ' after the last sheet visible property.
        '''''''''''''''''''''''''''''''''''''''''''''''
        S = S & IIf(StrComp(WS.Name, C_INTRO_SHEETNAME, vbTextCompare) = 0, _
                    CStr(xlSheetVeryHidden), CStr(WS.Visible)) & _
                    IIf(WS.Index = ThisWorkbook.Sheets.Count, "", ":")
        '''''''''''''''''''''''''''''''''''''''''''''''
        ' If WS is the intro sheet, make it visible,
        ' otherwise make it VeryHidden. This sets all
        ' sheets except C_INTRO_SHEETNAME to very
        ' hidden.
        '''''''''''''''''''''''''''''''''''''''''''''''
        If StrComp(WS.Name, C_INTRO_SHEETNAME, vbTextCompare) = 0 Then
            WS.Visible = xlSheetVisible
        Else
            WS.Visible = xlSheetVeryHidden
        End If
    Next WS
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Save the property string in a defined name.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ThisWorkbook.Names.Add Name:=C_SHEETSTATE_NAME, RefersTo:=Chr(39) & S, Visible:=False

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set the workbook protection back to what it was.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If HasProtection = True Then
        With ThisWorkbook
            If .HasPassword = True Then
                .Protect Password:=C_WORKBOOK_PASSWORD
            Else
                .Protect
            End If
        End With
    End If

End Sub


Sub UnHideSheets()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' UnHideSheets
' This is called by Workbook_Open to hide the introduction sheet
' and set all the other worksheets to their visible state that
' was stored when the workbook was last closed. The introduction
' sheet is set to xlSheetVeryHidden. This maro is executed only
' is macros are enabled. If the workbook is opened without
' macros enabled, only the introduction sheet will be visible.
' If an error occurs, make the intro sheet visible and get out.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Dim S As String
    Dim N As Long
    Dim VisibleArr As Variant
    Dim HasProtectWindows As Boolean
    Dim HasProtectStructure As Boolean
    Dim HasProtection As Boolean
    
    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Save the workbook's protection settings and
    ' attempt to unprotect the workbook.
    '''''''''''''''''''''''''''''''''''''''''''''''
    HasProtectWindows = ThisWorkbook.ProtectWindows
    HasProtectStructure = ThisWorkbook.ProtectStructure
    
    If (HasProtectWindows = True) Or (HasProtectStructure = True) Then
        HasProtection = True
    End If
    ThisWorkbook.Unprotect Password:=C_WORKBOOK_PASSWORD
    
    On Error GoTo ErrHandler:
    Err.Clear
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Get the defined name that contains the sheet visible
    ' properties and clean up the string.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    S = ThisWorkbook.Names(C_SHEETSTATE_NAME).RefersTo
    S = Mid(S, 4, Len(S) - 4)
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set VisibleArr to an array of the visible properties,
    ' one element per worksheet.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If InStr(1, S, ":", vbBinaryCompare) = 0 Then
        VisibleArr = Array(S)
    Else
        VisibleArr = Split(S, ":")
    End If
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Loop through the array and set the Visible propety
    ' for each sheet.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    For N = LBound(VisibleArr) To UBound(VisibleArr)
        ThisWorkbook.Sheets(N - LBound(VisibleArr) + 1).Visible = CLng(VisibleArr(N))
    Next N
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set the workbook protection back to what it was.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If HasProtection = True Then
        With ThisWorkbook
            If .HasPassword = True Then
                .Protect Password:=C_WORKBOOK_PASSWORD
            Else
                .Protect
            End If
        End With
    End If
    
    Exit Sub
    
ErrHandler:
    ThisWorkbook.Worksheets(C_INTRO_SHEETNAME).Visible = xlSheetVisible
    
End Sub

Sau đó ở các thủ tục sự kiện Workbook_BeforeCloseWorkbook_Open các bạn gọi các thủ tục
Mã:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    ''''''''''''''''''''''''''''''''''''''''''''''''
    ' Lưu tình trạng visibility của các worksheet
    ' và dấu tất cả các worksheet ngoại trừ worksheet introduction
    ''''''''''''''''''''''''''''''''''''''''''''''''
    SaveStateAndHide
End Sub

Private Sub Workbook_Open()
    ''''''''''''''''''''''''''''''''''''''''''''''''
    ' Unhide các worksheet. Sự kiện này 
    ' chỉ thực hiện khi Enable Macro
    ''''''''''''''''''''''''''''''''''''''''''''''''
    UnHideSheets
End Sub

Lê Văn Duyệt
 
Lần chỉnh sửa cuối:
Em thường làm thế này :
-Trong file có 1 sheet vô thưởng vô phạt.
-Khi đóng file, tất cả các sheet sẽ được ẩn đi (visible = 2 hoặc visible = xlsheetveryhidden), trừ sheet vô thưởng vô phạt
- Khi mở file cho mở lại tất cả các sheet, việc này đòi hỏi phải enable macro.

Nếu chỉ làm như thế thì code sẽ ngắn gọn hơn rất nhiều.

PHP:
Option Explicit
-------------------------------------------------------------------------
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim Sh As Worksheet
        VothuongVophat.Visible = xlSheetVisible
        For Each Sh In ThisWorkbook.Worksheets
            If Sh.Name <> VothuongVophat.Name Then Sh.Visible = xlSheetVeryHidden
        Next
set sh = nothing
End Sub
--------------------------------------------------------------------------
Private Sub Workbook_Open()
    Dim Sh As Worksheet
        For Each Sh In ThisWorkbook.Worksheets
            If Sh.Name <> VothuongVophat.Name Then Sh.Visible = xlSheetVisible
        Next
        VothuongVophat.Visible = xlSheetVeryHidden
set sh = nothing
End Sub


để thêm phần màu sắc thì khi mở file, mặc dù đã enable macro nhưng phải nhập đúng pass thì các sheet mới mở ra cũng được.

Tuy nhiên, dù đã disable macro nhưng dùng ASAP vẫn mở các sheet ra được đấy.

Thân!
 

File đính kèm

  • Book2.xls
    25.5 KB · Đọc: 379
Upvote 0
Mr Okebab đã viết:
Tuy nhiên, dù đã disable macro nhưng dùng ASAP vẫn mở các sheet ra được đấy.

ASAP là đùng kỹ thuật COM Addin được viết trong VB nên nó chạy không liên quan tới việc "Disable Macros" trong Excel.

Đây là một ví dụ.
 

File đính kèm

  • ComAddin.zip
    6.7 KB · Đọc: 357
Upvote 0
TuanVNUNI đã viết:
ASAP là đùng kỹ thuật COM Addin được viết trong VB nên nó chạy không liên quan tới việc "Disable Macros" trong Excel.

Đây là một ví dụ.

Quả thật Kỹ thuật này của anh cực hay. Tuy nhiên em thấy Asap vẫn dùng File xla mà. Vẫn xem code bình thường mà anh.

Thân!
 
Upvote 0
Chào các bạn,
Như các ứng dụng tôi đã giới thiệu với các bạn trong lớp VBA về kỹ thuật để bắt buộc người sử dụng phải Enable Macro khi sử dụng file của chúng ta.
Nay tôi thấy có một module viết về vấn đề này tôi xin giới thiệu với các bạn:
Đầu tiên các bạn hãy tạo một module và chép đoạn code này vào.
Mã:
Option Explicit
'From http://www.cpearson.com/excel/EnableMacros.aspx
Private Const C_SHEETSTATE_NAME = "SheetState"  '<<<< Tinh trang cua worksheet, cac ban co the thay doi
Private Const C_INTRO_SHEETNAME = "Start"       '<<<< Ten worksheet muon hien ra, cac ban co the thay doi
Private Const C_WORKBOOK_PASSWORD = "abc"       '<<<< Passwork cua workbook, cac ban co the thay doi

Sub SaveStateAndHide()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SaveStateAndHide
' This is called from Workbook_BeforeClose.
' This procedure saves the Visible propreties of all worksheets
' in the workbook. This will run only if macros are enabled. It
' saves the Visible properties as a colon-delimited string, each
' element of which is the Visible property of a sheet. In the
' property string, C_INTRO_SHEETNAME is set to xlSheetVeryHidden
' so that if the workbook is opened with macros enabled, that
' sheet will not be visible. If macros are not enabled, only
' that sheet will be visible.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Dim S As String
    Dim WS As Object
    Dim N As Long
    ''''''''''''''''''''''''''''''''''''''''''''
    ' Protection settings. We must be
    ' able to unprotect the workbook in
    ' order to modify the sheet visibility
    ' properties. We will restore the
    ' protection at the end of this procedure.
    ''''''''''''''''''''''''''''''''''''''''''''
    Dim HasProtectWindows As Boolean
    Dim HasProtectStructure As Boolean
    Dim HasProtection As Boolean

    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Save the workbook's protection settings and
    ' attempt to unprotect the workbook.
    '''''''''''''''''''''''''''''''''''''''''''''''
    HasProtectWindows = ThisWorkbook.ProtectWindows
    HasProtectStructure = ThisWorkbook.ProtectStructure

    If (HasProtectWindows = True) Or (HasProtectStructure = True) Then
        HasProtection = True
    End If
    ThisWorkbook.Unprotect Password:=C_WORKBOOK_PASSWORD

    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Make the introduction sheet visible
    '''''''''''''''''''''''''''''''''''''''''''''''
    ThisWorkbook.Worksheets(C_INTRO_SHEETNAME).Visible = xlSheetVisible
    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Delete the Name. Ignore error if it doesn't
    ' exist.
    On Error Resume Next
    '''''''''''''''''''''''''''''''''''''''''''''''
    ThisWorkbook.Names(C_SHEETSTATE_NAME).Delete
    Err.Clear
    On Error GoTo 0
    For Each WS In ThisWorkbook.Sheets
        '''''''''''''''''''''''''''''''''''''''''''''''
        ' Create a string of the sheet visibility
        ' properties, separated by ':' characters.
        ' Do not put a ':' after the last sheet. Always
        ' set the visible property of the Introduction
        ' sheet to xlSheetVeryHidden. Don't put a ':'
        ' after the last sheet visible property.
        '''''''''''''''''''''''''''''''''''''''''''''''
        S = S & IIf(StrComp(WS.Name, C_INTRO_SHEETNAME, vbTextCompare) = 0, _
                    CStr(xlSheetVeryHidden), CStr(WS.Visible)) & _
                    IIf(WS.Index = ThisWorkbook.Sheets.Count, "", ":")
        '''''''''''''''''''''''''''''''''''''''''''''''
        ' If WS is the intro sheet, make it visible,
        ' otherwise make it VeryHidden. This sets all
        ' sheets except C_INTRO_SHEETNAME to very
        ' hidden.
        '''''''''''''''''''''''''''''''''''''''''''''''
        If StrComp(WS.Name, C_INTRO_SHEETNAME, vbTextCompare) = 0 Then
            WS.Visible = xlSheetVisible
        Else
            WS.Visible = xlSheetVeryHidden
        End If
    Next WS
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Save the property string in a defined name.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ThisWorkbook.Names.Add Name:=C_SHEETSTATE_NAME, RefersTo:=Chr(39) & S, Visible:=False

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set the workbook protection back to what it was.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If HasProtection = True Then
        With ThisWorkbook
            If .HasPassword = True Then
                .Protect Password:=C_WORKBOOK_PASSWORD
            Else
                .Protect
            End If
        End With
    End If

End Sub


Sub UnHideSheets()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' UnHideSheets
' This is called by Workbook_Open to hide the introduction sheet
' and set all the other worksheets to their visible state that
' was stored when the workbook was last closed. The introduction
' sheet is set to xlSheetVeryHidden. This maro is executed only
' is macros are enabled. If the workbook is opened without
' macros enabled, only the introduction sheet will be visible.
' If an error occurs, make the intro sheet visible and get out.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Dim S As String
    Dim N As Long
    Dim VisibleArr As Variant
    Dim HasProtectWindows As Boolean
    Dim HasProtectStructure As Boolean
    Dim HasProtection As Boolean
   
    '''''''''''''''''''''''''''''''''''''''''''''''
    ' Save the workbook's protection settings and
    ' attempt to unprotect the workbook.
    '''''''''''''''''''''''''''''''''''''''''''''''
    HasProtectWindows = ThisWorkbook.ProtectWindows
    HasProtectStructure = ThisWorkbook.ProtectStructure
   
    If (HasProtectWindows = True) Or (HasProtectStructure = True) Then
        HasProtection = True
    End If
    ThisWorkbook.Unprotect Password:=C_WORKBOOK_PASSWORD
   
    On Error GoTo ErrHandler:
    Err.Clear
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Get the defined name that contains the sheet visible
    ' properties and clean up the string.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    S = ThisWorkbook.Names(C_SHEETSTATE_NAME).RefersTo
    S = Mid(S, 4, Len(S) - 4)
   
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set VisibleArr to an array of the visible properties,
    ' one element per worksheet.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If InStr(1, S, ":", vbBinaryCompare) = 0 Then
        VisibleArr = Array(S)
    Else
        VisibleArr = Split(S, ":")
    End If
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Loop through the array and set the Visible propety
    ' for each sheet.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''
    For N = LBound(VisibleArr) To UBound(VisibleArr)
        ThisWorkbook.Sheets(N - LBound(VisibleArr) + 1).Visible = CLng(VisibleArr(N))
    Next N
   
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set the workbook protection back to what it was.
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    If HasProtection = True Then
        With ThisWorkbook
            If .HasPassword = True Then
                .Protect Password:=C_WORKBOOK_PASSWORD
            Else
                .Protect
            End If
        End With
    End If
   
    Exit Sub
   
ErrHandler:
    ThisWorkbook.Worksheets(C_INTRO_SHEETNAME).Visible = xlSheetVisible
   
End Sub

Sau đó ở các thủ tục sự kiện Workbook_BeforeCloseWorkbook_Open các bạn gọi các thủ tục
Mã:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    ''''''''''''''''''''''''''''''''''''''''''''''''
    ' Lưu tình trạng visibility của các worksheet
    ' và dấu tất cả các worksheet ngoại trừ worksheet introduction
    ''''''''''''''''''''''''''''''''''''''''''''''''
    SaveStateAndHide
End Sub

Private Sub Workbook_Open()
    ''''''''''''''''''''''''''''''''''''''''''''''''
    ' Unhide các worksheet. Sự kiện này
    ' chỉ thực hiện khi Enable Macro
    ''''''''''''''''''''''''''''''''''''''''''''''''
    UnHideSheets
End Sub

Lê Văn Duyệt
Cho em hỏi. Em có thấy Macro chạy. Kiểm tra trong True setting em cố ý disable đi từ trước thì vẫn disable nhưng code vba vẫn có thể chạy. Như vậy code này không quan tâm Macro cài đặt là Enable hay Disable thì nó vẫn chạy bình thường phải không ạ?
 
Upvote 0
Web KT
Back
Top Bottom