View Full Version : VB code for hiding/ unhiding sheets
kvinay_00
Apr 30, 2009, 10:42 PM
Hello,
I am working on VB code in Excel 2003 for getting below result -
(1) After opening the file, it will always go to "First worksheet". This will have a message informing user that macros must be enabled to use this workbook. This sheet will be the only one that is visible if the user doesn't enable macros.
(2) When the user enables macros, the balance sheets automatically shows (gets unhide) and user can use all sheets.
The workbook shall be unusable unless it is opened with macros enabled.
I have tried to write the code many times with my little knowledge on VB but getting errors.
Can you help please?
Thanks in advance
JBeaucaire
May 1, 2009, 06:04 AM
The most common technique involves hiding all sheets except one during the "save" event. The one sheet that is left visible during the save event is a front sheet that instructs the user to make sure macros are enabled so the other sheets will be made visible/usable when the sheet is opened.
Create a sheet called "Macros" in your workbook. Put a message on that sheet explaining to close the workbook and reopen with macros enabled.
Add ALL of this code to the ThisWorkbook module:
Option Explicit
Const WelcomePage = "Macros"
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Evaluate if workbook is saved and emulate default propmts
With ThisWorkbook
If Not .Saved Then
Select Case MsgBox("Do you want to save the changes you made to '" & .Name & "'?", _
vbYesNoCancel + vbExclamation)
Case Is = vbYes
'Call customized save routine
Call CustomSave
Case Is = vbNo
'Do not save
Case Is = vbCancel
'Set up procedure to cancel close
Cancel = True
End Select
End If
'If Cancel was clicked, turn events back on and cancel close,
'otherwise close the workbook without saving further changes
If Not Cancel = True Then
.Saved = True
Application.EnableEvents = True
.Close savechanges:=False
Else
Application.EnableEvents = True
End If
End With
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Call customized save routine and set workbook's saved property to true
'(To cancel regular saving)
Call CustomSave(SaveAsUI)
Cancel = True
'Turn events back on an set saved property to true
Application.EnableEvents = True
ThisWorkbook.Saved = True
End Sub
Private Sub Workbook_Open()
'Unhide all worksheets
Application.ScreenUpdating = False
Call ShowAllSheets
Application.ScreenUpdating = True
End Sub
Private Sub CustomSave(Optional SaveAs As Boolean)
Dim ws As Worksheet, aWs As Worksheet, newFname As String
'Turn off screen flashing
Application.ScreenUpdating = False
'Record active worksheet
Set aWs = ActiveSheet
'Hide all sheets
Call HideAllSheets
'Save workbook directly or prompt for saveas filename
If SaveAs = True Then
newFname = Application.GetSaveAsFilename( _
fileFilter:="Excel Files (*.xls), *.xls")
If Not newFname = "False" Then ThisWorkbook.SaveAs newFname
Else
ThisWorkbook.Save
End If
'Restore file to where user was
Call ShowAllSheets
aWs.Activate
'Restore screen updates
Application.ScreenUpdating = True
End Sub
Private Sub HideAllSheets()
'Hide all worksheets except the macro welcome page
Dim ws As Worksheet
Worksheets(WelcomePage).Visible = xlSheetVisible
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVeryHidden
Next ws
Worksheets(WelcomePage).Activate
End Sub
Private Sub ShowAllSheets()
'Show all worksheets except the macro welcome page
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVisible
Next ws
Worksheets(WelcomePage).Visible = xlSheetVeryHidden
End Sub
(source material (http://www.vbaexpress.com/kb/getarticle.php?kb_id=379))
kvinay_00
May 1, 2009, 08:35 PM
Hello,
Thank you so much for your reply.
However, this code is showing below error -
Runtime error '1004'
Method 'Visible' of object'_worksheet' failed
Can you look at this please?
Thanks in advance.
JBeaucaire
May 1, 2009, 11:12 PM
Sure, but I don't see your workbook attached. I can't look into it until you post it.
Click on GO ADVANCED and use the paperclip icon to attach your workbook.
You *DID* name the one sheet "macros" like instructed, right? The one page that remains visible when all the others are hidden?
kvinay_00
May 2, 2009, 03:52 AM
I have attached a Test Sheet for your reference and eagerly wait for your comments.
I sincerely appreciate your help.
Thank you so much.
kvinay_00
May 2, 2009, 04:02 AM
Hello JBeaucaire!
Issue resolved, I had earlier kept the code in different sheet. I am sorry for that.
Now it is working fine.
Thank you very much for your help.
ScottGem
May 2, 2009, 05:41 AM
Just because I'm a stickler for accuracy, I just wanted to point out this is VBA code not VB code. Visual Basic for Applications is a superset of Visual Basic which contains extension to control the specific application. There are very distinct differences between VB and VBA so the two shouldn't be mixed.
JBeaucaire
May 2, 2009, 07:33 AM
Hello JBeaucaire!
Issue resolved, i had earlier kept the code in different sheet. i am sorry for that.
Now it is working fine.
Thank you very much for your help.
Glad to help. Glad it's working for you. This is a very useful technique. Here's a couple more tips for you:
SAVE YOUR USEFUL MACROS:
As you develop macros to do "general" repeatable things, it's good to save them so that you can import them into your sheets any time you need them.
Go into the VBEditor
Highlight the ThisWorkbook module with your new working codes in it
Click on FILE > EXPORT FILE
In the popup, create a folder called "CODES" or MACROS"
In the new folder save the macro with a decent descriptive name, like: "ForceMacros(ThisWorkbook).cls"
HIDE YOUR CODE:
Even though the sheet can still be opened with macros off, a nosy user might open the VBEditor to see why. If the THISWORKBOOK module is visible, they can do damage trying to figure out how to undo it.
in the VBEditor, right-click on the VBAProject title in the left pane
Select VBAProject Properties
Click on the Protection tab
Lock the project for viewing and add a password
Save and close your sheet
The next time you open the sheet and VBEditor, the code will not be visible...you will need to enter the password before it will show it to you
BEWARE OF SAVVY USERS
The hidden sheets are hidden by macro, so can only be UNHIDDEN by macro. A savvy VB-knowledgeable user can write a macro in another sheet and use it to unhide sheets in yours. Just be aware it is possible... though not probable.
The only 100% sure way to keep everyone from fiddling with your sheets is to not give them sheets, give them PDF printouts.
kvinay_00
May 6, 2009, 12:37 AM
Hello Friends,
I have added another code as below with aove code. But getting an error of conflict.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim myWS As Worksheet
For Each myWS In Worksheets
If myWS.Range("R51").Value = "Check Culprit Code Allocation" Then
Cancel = True
MsgBox "Please check culprit code allocation on " & myWS.Name
End If
Next myWS
End Sub
I am attaching the Test file for reference.
Can you help please?
Thanks a lot in advance!
JBeaucaire
May 6, 2009, 08:59 AM
It's telling you that you ALREADY have a Worksheet_BeforeSave event macro in the ThisWorkbook module. It's further up. You only get one of these per book.
JBeaucaire
May 6, 2009, 09:02 AM
I'm presuming the FOR/NEXT part is of primary importance, so I merged the two macros together like so:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim myWS As Worksheet
For Each myWS In Worksheets
If myWS.Range("R51").Value = "Check Culprit Code Allocation" Then
Cancel = True
MsgBox "Please check culprit code allocation on " & myWS.Name
End If
Next myWS
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Call customized save routine and set workbook's saved property to true
'(To cancel regular saving)
Call CustomSave(SaveAsUI)
Cancel = True
'Turn events back on an set saved property to true
Application.EnableEvents = True
ThisWorkbook.Saved = True
End Sub
kvinay_00
May 7, 2009, 11:09 PM
Thanks a lot for your reply.
I tried to put the combined code but still getting some error. I am attaching the file for your reference.
I would appriciate if you can go thourgh the code and just see the operation on the sheet and you will be able to understand the errors better.
I sincerely thank you for your help.
kvinay_00
May 7, 2009, 11:11 PM
Sorry, forgot to attach file.
kvinay_00
May 13, 2009, 02:21 AM
Hello JBeaucaire,
Can you please go through the sheet sent earlier and check the error I am getting?
Thanks in advance.
JBeaucaire
May 13, 2009, 06:55 AM
Try this one:
kvinay_00
May 13, 2009, 08:57 PM
Thanks a lot JBeaucaire for your help!
Now it's working fine. One last question, the file is working fine with 'unprotected' workbook. However, when I lock the workbook, I am getting an error.
Would you mind to try the file by protecting workbook?
I am sorry for bothering you so much.
Thanks once again.
JBeaucaire
May 13, 2009, 10:47 PM
Which sheets? Protected how? Protected to what degree? I imagine these sheets are designed to be "worked with", so you'll need to be more complete in your description of the level of protection on each sheet.
I already know the macros wouldn't work efficiently on protected sheets. That's the kind of thing you start with when planning this stuff out...
kvinay_00
May 13, 2009, 11:19 PM
It is normal protection available in excel (Tools/ Protection) and not by any macro.
Since I intend to circulate these sheets to various people, I am thinking to protect the workbook just to disable any deletion/ addition etc by the user.
The error is occurring when I protect the workbook.
JBeaucaire
May 14, 2009, 01:41 AM
Well, you're probably in for a bit of wrangling, you'll most likely need some macro to unprotect your sheets, too. But this is the amended code that protects the sheets during saving. Obviously you don't want it unprotecting automatically, but you'll have to play with how you use your sheet.
Protection + active macros makes for interesting rodeos. I noted the new lines in red.
Option Explicit
Const WelcomePage = "Macros"
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Evaluate if workbook is saved and emulate default propmts
With ThisWorkbook
If Not .Saved Then
Select Case MsgBox("Do you want to save the changes you made to '" & .Name & "'?", _
vbYesNoCancel + vbExclamation)
Case Is = vbYes
'Call customized save routine
Call CustomSave
Case Is = vbNo
'Do not save
Case Is = vbCancel
'Set up procedure to cancel close
Cancel = True
End Select
End If
'If Cancel was clicked, turn events back on and cancel close,
'otherwise close the workbook without saving further changes
If Not Cancel = True Then
.Saved = True
Application.EnableEvents = True
.Close savechanges:=False
Else
Application.EnableEvents = True
End If
End With
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim myWS As Worksheet
For Each myWS In Worksheets
If myWS.Range("R51").Value = "Check Culprit Code Allocation" Then
Cancel = True
MsgBox "Please check culprit code allocation on " & myWS.Name
End If
Next myWS
'Turn off events to prevent unwanted loops
Application.EnableEvents = False
'Call customized save routine and set workbook's saved property to true
'(To cancel regular saving)
Call CustomSave(SaveAsUI)
Cancel = True
'Turn events back on an set saved property to true
Application.EnableEvents = True
ThisWorkbook.Saved = True
End Sub
Private Sub Workbook_Open()
'Unhide all worksheets
Application.ScreenUpdating = False
Call ShowAllSheets
Application.ScreenUpdating = True
End Sub
Private Sub CustomSave(Optional SaveAs As Boolean)
Dim ws As Worksheet, aWs As Worksheet, newFname As String
'Turn off screen flashing
Application.ScreenUpdating = False
'Record active worksheet
Set aWs = ActiveSheet
'Hide all sheets
Call HideAllSheets
'Save workbook directly or prompt for saveas filename
If SaveAs = True Then
newFname = Application.GetSaveAsFilename( _
fileFilter:="Excel Files (*.xls), *.xls")
If Not newFname = "False" Then ThisWorkbook.SaveAs newFname
Else
ThisWorkbook.Save
End If
'Restore file to where user was
Call ShowAllSheets
aWs.Activate
'Restore screen updates
Application.ScreenUpdating = True
End Sub
Private Sub HideAllSheets()
'Hide all worksheets except the macro welcome page
Dim ws As Worksheet
Worksheets(WelcomePage).Protect UserInterfaceOnly:=True
Worksheets(WelcomePage).Visible = xlSheetVisible
For Each ws In Worksheets
If Not ws.Name = WelcomePage Then
ws.Protect , UserInterfaceOnly:=True
ws.Visible = xlSheetVeryHidden
Else
ws.Visible = xlSheetVisible
End If
Next ws
End Sub
Private Sub ShowAllSheets()
'Show all worksheets except the macro welcome page
Dim ws As Worksheet
For Each ws In Worksheets
ws.Protect , UserInterfaceOnly:=True
ws.Visible = xlSheetVisible
Next ws
Worksheets(WelcomePage).Visible = xlSheetVeryHidden
End Sub
kvinay_00
May 14, 2009, 02:36 AM
Thank you for your reply.
Honestly I am not in wrangling. My be I did not express exactly what I am looking for.
I am attaching the same file which you have edited. I have just added protection to the workbook. Password is "1". Now when you open this workbook with protection ON, you will notice an error.
I wish to protect the workbook so that the users are not able to move/ copy/ delete/ add sheets (just to make it foolproof).
May be you can have a look on the sheet and suggest.
Thanks a lot.
JBeaucaire
May 14, 2009, 09:51 AM
Honestly, at this point, I point people away from Excel. To provide spreadsheet information to OTHERS for review only, I do not send spreadsheets. I send PDFs. PDFs can be read by anyone anywhere and cannot be edited in any way. They are secure and simple.
I use a free PDF tool called PrimoPDF (PrimoPDF.com) that installs as a printer driver so I can make PDFs instantly from inside any program. PrimoPDF includes password protection and print suppression... all the things you would want from a PDF utility.
Our company stopped sending Excel files around years ago and we haven't been sorry, not once.