Hide excel worksheet via VBA - vba

I have a workbook that has a number of worksheets each one with a colaborator name on it (Windows login username).
I've tried via VBA to loop through all Worksheets to match the actual Windows Logged On username with the matching Worksheet, and after the match is done, only that Worksheet is kept visible (with all the others being hiden).
I've managed to do this partially but i can only do it untill it finds the matching worksheet. For example, if the matching username is the third worksheet (in a total of ten for example) the code stops there. I want it to run through all worksheets and only then hide the non matching Worksheets.
First i have the following module:
Sub WorksheetFilter()
Dim Username As String
Dim Worksheetname As String
Worksheetname = ActiveWorkbook.ActiveSheet.Name
Username = Environ("Username")
If Worksheetname <> Username Then
ActiveSheet.Visible = False
End If
End Sub
Then, i call the previous module on the Workbook_Open() event:
Option Explicit
Dim WS As Worksheet
Private Sub Workbook_Open()
For Each WS In ActiveWorkbook.Worksheets
WorksheetFilter
Next
End Sub
Any hints on how this can be achieved?
Thanks,
VĂ­tor

Use the code below, and put it in the Workbook module under the Workbook_Open event.
Just loop through all sheets and compare each one with the username.
Option Explicit
Public Sht As Worksheet
Private Sub Workbook_Open()
For Each Sht In ThisWorkbook.Sheets
If Sht.Name = Environ("Username") Then
Sht.Visible = xlSheetVisible
Else
Sht.Visible = xlSheetHidden
' option 2: use very hidden, only able to unhide through code (unable to unhide using right-click)
'Sht.Visible = xlSheetVeryHidden
End If
Next Sht
End Sub

Please see below: chopped your code around a bit. You do not need to defien the worksheets name. This is for the module level, you can call it in the workbook open event as per usual
Option Explicit
Dim ws As Worksheet
Dim Username As String
Sub WorksheetFilter()
Username = Environ("Username")
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> Username Then
ws.Visible = False
Else
ws.Visible = True
End If
Next ws
End Sub
Please let me know how this works for you! :)

Related

VBA Hide all sheets that aren't being used in workbook

I have many sheets in a workbook. I have a main sheet/"form" called "JE" and on that sheet there are buttons and macros that lead to other sheets in the workbook. But, the intention is for other users, not myself, to use the workbook. So, I would only like the sheet that is being used to be visible at any given time. At no time do I want more than 1 sheet to be visible by the user. The user can navigate the workbook mainly thru clicking buttons and certain cells in select sheets that will allow them to navigate throughout the entire workbook. I have tried this by adding code into 'ThisWorkbook' module but it doesn't seem to working as I'd like. When I navigate to one sheet and back to another, some sheets remain visible when I'd like them to be hidden so I'm unsure of what other modifications I can make to code below to get my desired result. If anyone can offer up any modifications or changes I can make to accomplish this, I'd really appreciate it.
UPDATE:
I have added this code to my 'ThisWorkbook' Object:
Option Explicit
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name <> Sh.Name Then MySh.Visible = 0
Next MySh
End Sub
but, when I go to double-click values that usually populate cells in my main sheet ("JE") I get a run-time 1004 error. The values still populate the main sheet but it no longer navigates back to the main sheet as I'd like.
If anyone knows of a solution or a mod I can make, I'd really appreciate it.
The code is nice. Simply put it in the Workbook part of the VBA project:
Option Explicit
Private Sub Workbook_Open()
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name = ActiveSheet.Name Then MySh.Visible = xlSheetHidden
Next MySh
End Sub
The ThisWorkbook part is here:
In general, I use always something similar, when I am starting an Excel application. I define two Arrays with Visible and Invisible Worksheets and I iterate over them, making them either visible or not visible. Like this:
Option Explicit
Public Sub HideNeeded()
Dim varSheet As Variant
Dim arrVisibleSheets As Variant
Dim arrHiddenSheets As Variant
arrVisibleSheets = Array(Sheet1)
arrHiddenSheets = Array(Sheet2, Sheet3)
For Each varSheet In arrVisibleSheets
varSheet.Visible = xlSheetVisible
Next varSheet
For Each varSheet In arrHiddenSheets
varSheet.Visible = xlSheetVeryHidden
Next varSheet
End Sub
xlSheetVeryHidden makes it possible to unhide it only from the VB Editor. Otherwise you need xlSheetHidden.
It should be Workbook_SheetActivate:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name <> Sh.Name Then MySh.Visible = 0 'zero - false, 1 - true, 2 - very hidden
Next MySh
End Sub
Sub HideInactive()
Set theActiveSheet = ActiveSheet
For Each Sheet In ThisWorkbook.Worksheets
If Sheet.Index <> theActiveSheet.Index Then Sheet.Visible = False
Next
End Sub
I 've test the code. Thank you for reading.

Making VBA apply to renamed tabs & all tabs in a workbook

I don't know very much at all about VBA, but I found the below code on a website and am using it in a workbook.
Private Sub Workbook_Open()
With Worksheets("WFD")
.EnableOutlining = True
.Protect Password:="XXXX", _
Contents:=True, UserInterfaceOnly:=True
End With
End Sub
How should I amend this so that if the Sheet name is changed from "WFD" to something else, the code still works? Also I would like it to apply to all sheets in the workbook.
Thanks very much
If you want this code for each worksheet use code below:
Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In Worksheets
With ws
.EnableOutlining = True
.Protect Password:="XXXX", _
Contents:=True, UserInterfaceOnly:=True
End With
Next
End Sub
You should use the Sheet Object Codename.
This is found in the VB Editor beside the sheet objects in the VB project.
By default they are Sheet1, Sheet2 etc. You can easily change them by clicking and typing a new name etc.
You could of course leave them as default codeName if you like...
This is NOT the same as the worksheet name, which is changed by users on the Sheet tabs in Excel interface.
Private Sub Workbook_Open()
With WFD 'where WFD is the CODENAME of the Sheet Object!
.EnableOutlining = True
.Protect Password:="XXXX", _
Contents:=True, UserInterfaceOnly:=True
End With
End Sub
You could write Worksheets(1) or Worksheets(5), depending on the number of the Worksheet. However, if you start adding and deleting Worksheets, it whould not work (e.g., it would be working on some other worksheet). To see the associated number to the worksheet, run this and check the immediate window:
Option Explicit
Public Sub TestMe()
Dim ws As Worksheet
Dim cnt As Long
For cnt = 1 To ThisWorkbook.Worksheets.Count
Debug.Print cnt; "-> "; Worksheets(cnt).name
Next cnt
End Sub
However, if you have only one Worksheet, Worksheets(1) would always work.

Using VBA to copy a spreadsheet from a secondary workbook into the primary one

I need to take a spreadsheet and compare it with a spreadsheet from another workbook. I know that I can do this using VBA, but I will need to copy a spreadsheet from another workbook so that both spreadsheets will reside within the same workbook and be accessible for comparison. How do I copy a spreadsheet from one workbook into another using VBA?
You don't need to copy the worksheets over to compare them. Simply open both WorkBooks and and set reference to there WorkSheets.
Sub CompareWorkBooks()
Dim wbPending As Workbook
Dim wsPending As Worksheet
Set wbPending = Workbooks("Items Pending")
Set wsPending = wsPending.Worksheet("Items")
Dim wbRecieved As Workbook
Dim wsRecieved As Worksheet
Set wbRecieved = Workbooks("Items Recieved")
Set wsRecieved = Worksheet("Items")
End Sub
If you provide names for Workbooks & WorkSheets and provide column information, we can give you better answers in a shorter period of time. Don't be afraid to post your code either.
If you want a user to select the target workbook and worksheet:
Create a userform
Declare targetWorkbook and tartgetWorksheet at the top of the code module
Add a command button and a combo box
When the button is clicked a file dialog is opened
A reference is now set to the open file
The names of all the worksheets are added to the combo
Changing the combo box value will set the refernce to tartgetWorksheet
Option Explicit
Public targetWorkbook As Workbook
Public tartgetWorksheet As Worksheet
Private Sub CommandButton1_Click()
Dim targetWorkbook As Workbook
Dim ws As Worksheet
Set targetWorkbook = getTargetWorkbook
If targetWorkbook = Nothing Then
MsgBox "Sowmthing went wrong", vbCritical, "Try Again"
Else
For Each ws In targetWorkbook.Worksheets
ComboBox1.AddItem ws.Name
Next
End If
End Function
Function getTargetWorkbook() As Workbook
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
On Error Resume Next
Set getTargetWorkbook = Application.Workbooks.Open(.SelectedItems(1))
On Error GoTo 0
End With
End Function
Private Sub ComboBox1_Change()
Set tartgetWorksheet = targetWorkbook.Worksheets(ComboBox1.Value)
End Sub

Referencing Most Recently Added Worksheet

I have a userform that fields the user's input to take certain actions within a workbook, one of the actions is inserting a new tab in the workbook and having the user input the new sheet's name within an input box. I want to be able to then reference this new sheet (but I won't know what someone else might name it) and to paste a chart object within the newly created sheet.
So far the adding sheet code is working fine, but any of my attempts to paste the chart range are not working. My current code for adding the worksheet is:
Private Sub MyChart_Click()
Dim Answer As String
Dim sht_name As Variant
On Error Resume Next
If Me.OptionButton2.Value = True Then
Unload Me
sht_name = InputBox("Please enter value")
If sht_name <> "" Then
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = sht_name
Else
Exit Sub
End Sub
My chart lives in another worksheet ("Sheet2") and I am trying to just copy it into the newly created sheet whenever the user selects this OptionButton2 in the Userform... Any help is appreciated.
When you use the Worksheets.Add method, that sheet automatically is activated. To test this you can run this small portion of code:
Option Explicit
Private Sub SheetReference()
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Test"
Debug.Print ActiveSheet.Name
End Sub
And the output you would see is
Test
So in your case, you could declare a worksheet variable and then set the reference after you call the add method. Something like this:
Option Explicit
Private Sub MyChart_Click()
Dim Answer As String
Dim sht_name As Variant
Dim ws As Worksheet
On Error Resume Next
If Me.OptionButton2.Value = True Then
Unload Me
sht_name = InputBox("Please enter value")
If sht_name <> "" Then
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = sht_name
Set ws = ActiveSheet
With ws
'Do whatever you need to do on the worksheet
End With
Else
Exit Sub
End If
End Sub

how to make visual basic work on protected worksheets (no password on protection)

I have a work book with several worksheets that I would like to protect. I am not using a password on the protection. I have some visual basic code associated with this sheet to expand the row width on merged cells. The code will not work when the sheets are protected.
I did find some guidance on adding unprotect code to my code, but can't figure out where to put it and how to address the fact that there is no passord. Further guidance woudl be greatly appreciated!
Here is my code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim NewRwHt As Single
Dim cWdth As Single, MrgeWdth As Single
Dim c As Range, cc As Range
Dim ma As Range
With Target
If .MergeCells And .WrapText Then
Set c = Target.Cells(1, 1)
cWdth = c.ColumnWidth
Set ma = c.MergeArea
For Each cc In ma.Cells
MrgeWdth = MrgeWdth + cc.ColumnWidth
Next
Application.ScreenUpdating = False
ma.MergeCells = False
c.ColumnWidth = MrgeWdth
c.EntireRow.AutoFit
NewRwHt = c.RowHeight
c.ColumnWidth = cWdth
ma.MergeCells = True
ma.RowHeight = NewRwHt
cWdth = 0: MrgeWdth = 0
Application.ScreenUpdating = True
End If
End With
End Sub
You could probably do something like this:
Surround your code with .Unprotect and .Protect
Sub protectSheet()
Dim ws As Worksheet
Set ws = Sheets(1)
With ws
.Unprotect "password"
'Insert Code Here
.Protect "password"
End With
End Sub
try this:
Private Sub Workbook_Open()
Dim wSheet As Worksheet
For Each wSheet In Worksheets
wSheet.Protect Password:="Password_here", _
UserInterFaceOnly:=True
Next wSheet
End Sub
Put this code in 'ThisWorkbook' then use the Workbook_Open Event.
This code protects all the WS everytime you open the WB
but allows macro to run due to UserInterfaceOnly set to true
You need to protect the sheet with password.
If you want a user to edit some cells even if the worksheet is protected then set the locked property of those cells to false before protecting the sheet.
Now when Worksheet_Change is triggered or any procedure is called which is trying to make some changes to excel range (locked cells = true) then you need to Unprotect the Sheet at beginning of the code and protect it at the end again. You may refer #sobin answer for syntax.
Also you may use error handlers and explicitly protect the sheet. This is done to avoid situation wherein the sheet is unprotected and then there is error which comes up for any reason then that would leave the sheets unprotected.