I am using Excel 2013, and have a macro that copies a "master" worksheet to the end of the workbook, once filled in by the user. The worksheet that's copied, is renamed, according to the "master" report number. Is there a way that once the sheet is copied to the end, it can be locked so the user can not make any changes to it. I just want them to be able to view it. I've researched some sample code online, but nothing seems to do what I am trying to do. Anyone have any ideas or can help? Much thanks
You can use the .Protect and .Unprotect properties. Below is an example sub that protects all worksheets, charts in a workbook and then protects the workbook itself. Here's a site with more detailed info, and it would also be good to review how items are protected in Excel generally.
Sub protectWk(wk As Workbook)
Dim sh as Worksheet, ch as Chart
For Each sh In wk.Worksheets
sh.Protect ("password")
Next
For Each ch In wk.Charts
ch.Protect ("password")
Next
wk.Protect ("password")
wk.Close SaveChanges:=True
End Sub
Related
Situation
Trying to copy a range of cells that include formulas from worksheet called "Sheet1" to the rest of other worksheets I found that I could do it performing "Fill Across Worksheets". It worked fine, so my next step was to record a Macro for it to be more efficient and worked just fine too.
The Problem
The problem is that when I include a new worksheet and run the Macro, the Macro does not consider the new worksheet so this last worksheet doesn't get updated.
I am including below the code created by the macro. In it I can see that it's including only the worksheets I have now in the workbook, so this is where I need help.
( My excel is in Spanish so when you read Ctrl+Mayus+Q, Mayus means Shiftkey )
Help
What I need is a way to modify this Macro so when it runs it will check and update all worksheets. Or, maybe it's because a Macro can't do this I may need a VBA code ? If this VBA is the way to resolve it, can you help me here with this ?
I appreciate all help
Thank you
Javier
Sub Macro2()
'
' Macro2 Macro
'
' Acceso directo: Ctrl+Mayús+Q
'
Range("A5:D12").Select
Sheets(Array("Sheet1", "Sheet2", "Sheet3", "Sheet4")).Select
Sheets("Sheet1").Activate
ActiveWindow.SelectedSheets.FillAcrossSheets Range:=Selection,
Type:=xlAll
Sheets("Sheet1").Select
End Sub
This is a work around, concerning that you want all the worksheets to have the value of the first worksheet in range A5:D12:
Sub TestMe()
Dim ws As Worksheet
Dim selAddress As String
selAddress = "A5:D12"
For Each ws In Worksheets
'ws.Range(selAddress).Value2 = Worksheets(1).Range(selAddress).Value2
ws.Range(selAddress).Formula = Worksheets(1).Range(selAddress).Formula
Next ws
End Sub
See How to avoid using Select in Excel VBA.
I need VBA code for Excel which: will be activated by a button in an empty workbook, loop through open workbooks, copies only sheets called "specificsheetname" from workbooks and pastes it into a new worksheet in the button activator workbook. So idea is that it will combine many worksheets from different workbooks into a one workbook. I tried this:
Sub workbookFetcher()
Dim book As Workbook, sheet, wsNew, wsCurr As Worksheet
Set wsCurr = ActiveSheet
For Each book In Workbooks
For Each sheet In book.Worksheets
If sheet.Name = "COOLING_RAW" Then
Set wsNew = Sheets.Add(After:=wsCurr)
book.Worksheets("COOLING_RAW").Copy
Set wsNew = book.Worksheets("COOLING_RAW")
End If
Next sheet
Next book
End Sub
It kind of works but it pastes all the copied worksheets to a new workbook. That's not what I want, I want them to pasted in the same workbook.
As I said in my comment:
Sub workbookFetcher()
Dim book As Workbook, sheet as Worksheet
For Each book In Workbooks
For Each sheet In book.Worksheets
If sheet.Name = "COOLING_RAW" Then
book.Worksheets("COOLING_RAW").Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
End If
Next sheet
Next book
End Sub
If you want it to be after the ActiveSheet and the ActiveSheet is in the middle of other sheets, you can still use your wsCurr and just increment the index.
If you've got Excel 2016, then the newly bundled PowerQuery functionality under the Get & Transform part of the ribbon is by far the best way to do this. Suggest you google something like PowerQuery Combine Workbooks and you'll see heaps of great tutorials showing you exactly what to do. It pretty much makes lots of VBA redundant, and it is childs-play to learn compared to VBA.
If you've got any other version of Excel from 2010 up and have admin rights on your machine, you can download and install PowerQuery from Microsoft's site...it's a free add-in
you don't need to iterate through each single workbook worksheets, while you just try to get the wanted sheet and copy it if it actually exists
moreover you want to avoid searching ThisWorkbook itsel for wanted worksheet, too!
Option Explicit
Sub workbookFetcher()
Dim book As Workbook, sht As Worksheet
For Each book In Workbooks
If book.Name <> ThisWorkbook.Name Then ' skip ThisWorkbook and avoid possible worksheet duplication
If GetWorksheet(book, "COOLING_RAW", sht) Then sht.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) ' if currently searched workbook has wanted worksheet then copy it to ThisWorkbook
End If
Next
End Sub
Function GetWorksheet(book As Workbook, shtName As String, sht As Worksheet) As Boolean
On Error Resume Next ' prevent subsequent statement possible error from stoping the function
Set sht = book.Worksheets(shtName) ' try getting the wanted sheet in the passed workbook
GetWorksheet = Not sht Is Nothing ' return 'True' if successfully got your sheet in the passed workbook
End Function
I'm very new to VBA macros and have taught myself some code but I'm struggling with my current piece of work and can't find the answer I am looking for.
I want to copy a range of cells (B3:N21) from one workbook to another "master" workbook - which seems simple enough - but I would like it to copy into a blank/new worksheet in the Master copy every time the Macro is run.
The range contains formulas, I would only need the values copied to the Master workbook.
Any help with this would be greatly appreciated.
Thanks
Worksheets("Sheet1").Range("C1:C5").Copy
Worksheets("Sheet2").activate
Worksheets("Sheet2").Range("D1:D5").PasteSpecial _
Operation:=xlPasteSpecialOperationAdd
End With
I think you only need paste special, this is an example
try this
Option Explicit
Sub main()
Dim masterWb As Workbook
Dim mySht As Worksheet
Set mySht = ThisWorkbook.ActiveSheet '<~~ assuming you're copying values from active worksheet of the workbook the macro resides in
' beware: if you start the macro while the active sheet is not the one you want, this will lead to unespected results
Set masterWb = Workbooks("Master") '<~~ Change "Master" with whatever name your master workbook must have
' beware: we're assuming "Master" workbook is already open, otherwise this line will throw an error
With masterWb.Worksheets.Add
.Range("B3:N21").Value = mySht.Range("B3:N21").Value
End With
End Sub
mind the comments
the code above can be reduce to a much less verbose (and self explanatory, too) one like follows
Sub main2()
Workbooks("Master").Worksheets.Add.Range("B3:N21").Value = ThisWorkbook.ActiveSheet.Range("B3:N21").Value
End Sub
where apply the same comments of the lengthy code, which is:
assuming you're copying values from active worksheet of the workbook the macro resides in
beware: if you start the macro while the active sheet is not the one you want, this will lead to unespected results
change "Master" with whatever name your master workbook must have
beware: we're assuming "Master" workbook is already open, otherwise an error would be thrown
I have the following code in on a workbook.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim ws As Worksheet
For Each ws In Worksheets
If ws.Name <> "Main Page" Then
ws.Visible = xlSheetHidden
End If
Next ws
ThisWorkbook.Save
End Sub
But when the workbook is next open pages that were left open at the end are still open. I don't have any other macro's or vba script that sets the pages to be unhidden yet, I'm am just doing to manually to test it.
There are no errors that come up, the code complies correctly and runs. I even check the loop with breakpoints and it does go through every worksheet correctly.
Can anyone see what might be the problem? Have I missed one vital key word or something? Its driving me nuts, worse than trying to track down ; in c#
Ask any questions you think would help.
Matt
you should try something like
ws.Visible = xlSheetVeryHidden
Check if the workbook is protected. If it's protected, you have to unprotect the workbook first.
Is there a way to first, unprotect a workbook at the beginning of opening, run all the workbook_open() macros and then re-protect the workbook so that a common user can not change anything on any worksheets? I'd like to prevent the common user from changing anything but allow the macros to do its auto-update and computations.
Any suggestions? Is this even feasible?
What I think you're looking for is the Worksheet.Protect method.
At the beginning of your Workbook_Open event, place this code:
ThisWorkbook.Sheets("SheetYouWantToUnprotect").Unprotect _ Password:="TheSheetPassword"
Then at the end of your Workbook_Open event code, you want to protect the sheet again, so place this code:
ThisWorkbook.Sheets("SheetYouWantToProtect").Protect _
Password:="SheetPassword"
Of course, you can do this with more than one sheet if multiple sheets need to be unprotected. If each sheet has the same password, place a simple loop at the beginning of your Open event:
Dim sht as Worksheet
For Each sht in Thisworkbook.Sheets
sht.Unprotect Password:="YourPassword"
Next sht
At the end of your code you can use the same loop to protect the sheets, just change .Unprotect to .Protect.
Or, if there are many different passwords (aside from recommending you change them all to one password), you can place as many instances of the first line of code I mentioned as it takes to unprotect the necessary sheets.
Note: There are many more optional arguments to the .Protect method which I did not cover, but you can find an exhaustive list here.
EDIT: Here's more info on the Unprotect method.
Yes, it can be done
Private Sub Workbook_Open()
Dim WS As Worksheet
For Each WS In ThisWorkbook.Sheets
WS.Unprotect Password:="YourPassword"
WS.Protect Password:="YourPassword", UserInterfaceOnly:=True
Next WS
End Sub
The UserInterfaceOnly:=True allows VBA to act on any part of your worksheets while the common user can only interact with "unlocked" cells.