Excel 2010 Macros Fun with Buttons - vba

Ok so I am creating a spreadsheet that can be edited by another user but locked otherwise. What I am hoping to do is create 3 buttons. "What If" "Exit What if" and "Reset"
"What if" will allow for the user to input data.
"Exit what if" will allow for the user to exit the input mode and revert back to the default. document.
Then "Reset" will allow for the user stay in "What if" but reset all the values to default.
Then I want the button "What if" to appear somewhere up in the left but when you click it, its replaced by "Exit" and "Reset"

I suggest you to explain a little more you question, but so far for what I can infere you have the folloing issuse:
have a excel sheet with formulae and data locked.
offer edit the page, but no save the changes, as "a consult" to the data.
I can primarily offer the following:
Create a backup sheet where your save you base page
Unlock the sheet for editing.
if you exit the editing, restore the data from the backup to the main sheet.
if you reset the editing, do the same procedure as exit plus unlock again the data. (for how it was charted the code flow, the copied sheet has his data locked)
This will result in the followin code:
Sub BackUpData() 'this will be linked to you "what if" button
Sheets("Data_Sheet").Select 'select shhet with data, just in case
Range("A1:M56").Select ' range of your important data in your excel sheet
Cells.Select
Selection.Copy
Sheets("BackUp_Sheet").Select
Range("A1").Select 'lets paste the data in the same positiĆ³n
ActiveSheet.Paste
Application.CutCopyMode = False
Sheets("Data_Sheet").Select
End Sub
This make a copy of the data and the formulas, copying charts without breaking his datasource is another problem, maybe your can elabore on this matter. Have any charts?
Sub RestoreData() 'this will be linked to you "Reset" and "Exit" button
Sheets("BackUp_Sheet").Select 'select shhet with data, just in case
Range("A1:M56").Select ' range of your important data in your excel sheet
Cells.Select
Selection.Copy
Sheets("Data_Sheet").Select
Range("A1").Select 'lets paste the data in the same positiĆ³n
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
Usual room for improvement:
Dinamicaly select the range, but no select all the sheet, because memory isssuses may arise. (I run out of resources when try to copy all the cell of excel 2007 in my laptop :P).
Remove flicker with Application.ScreenUpdating.
I haven`t check if this work when the *backup_Sheet* is hidden.
The other isssuse is unlock the data in the sheet.
Sub UnlockMySheet()
'password here won`t protect the business logic or the code from prying eyes, just the user from themselves
ActiveWorkbook.Unprotect
ActiveSheet.Unprotect
Range("D9,B13").Select ' select the editable cells
Selection.Locked = False
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
ActiveSheet.EnableSelection = xlUnlockedCells
ActiveWorkbook.Protect Structure:=True, Windows:=True
End Sub
Usual room for improvement:
Maybe I forgot the protect protocol and I`m just leaving the page exactly as it was. (sorry no time to proof this code).
Sugestion from stackoverflow collective mind.
and that is, for now

Related

Sheet inaccessible to macro: Error 1004: Application/Object Defined Error

This is happening in several of my macros, but this is the one in from of me:
Private Sub resettool()
'''resets step 2 input and user input on MPP tabs
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Call showsheets 'makes all of these sheets .Visible = True
'clear data from lookups and data corrals
Sheets("Media by Copy Lookup").Range("b1",Range("b1").End(xlToRight).End(xlDown)).ClearContents
Sheets("Total Media Lookup").Range("d1",Range("d1").End(xlToRight).End(xlDown)).ClearContents
Sheets("Total Media Lookup").Range("b2:c100").ClearContents
Sheets("Media by Copy Data").Range("a1",Range("a1").End(xlToRight).End(xlDown)).ClearContents
'etc etc
End Sub
It continues with similar data-clearing lines for a while. This started happening when I took someone else's code and cleaned it by removing the .Select usages as people on here have suggested. It seems that the macro isn't able to access the sheets I'm referencing, because a line runs successfully if I step into the code, manually select the referenced sheet, and then hit go (but then of course I get the same error when I try to edit another sheet).
Any ideas why the macro wouldn't be able to access these sheets unless I explicitly activate/select them? The sheets are all visible, so that shouldn't be the problem.
P.S. I've seen the guide on using .Rows.Count).End(xlUp) instead of End(xlDown) to find the bottom of my data and will implement that soon, but this issue is occurring no matter how I define the range; it's about the sheet.

Command button to paste table based on cell value

I have an Excel sheet in which I'm trying to make a walkthrough type of thing, for training new employees. At its core, I want to have a dropdown menu (got that already) filled with options, and then a command button that will check the contents of the drop down cell, and copy-paste a table from a hidden sheet onto the main sheet. For some reason, I can't get the button to work. This is what I've got so far:
Private Sub button_desk_Click()
Application.ScreenUpdating = False
'Create Table
If Worksheets("Walkthrough").Range("A2").Value2 = "Getting your desk set up" Then
Sheets("Settings").Select
Range("lookup_desksetup[[#All],[Getting your desk setup]]").Select
Selection.Copy
Sheets("Walkthrough").Select
Range("B5").Select
ActiveSheet.Paste
End If
Application.ScreenUpdating = True
End Sub
I've tried a few different approaches for this, including not using the .Select command, but I can't seem to get anything to work.
Sheets("Settings").Select
Range("lookup_desksetup[[#All],[Getting your desk setup]]").Select
Selection.Copy
Sheets("Walkthrough").Select
Range("B5").Select
ActiveSheet.Paste
is a long winded way of saying
Sheets("Settings").Range("lookup_desksetup[[#All],[Getting your desk setup]]").copy _
destination:= Sheets("Walkthrough").Range("B5")
However I suspect that your problem is that "lookup_desksetup[[#All],[Getting your desk setup]]" is a very funny range name and may not actually exist as a valid name in that sheet?

Refreshing pivot tables on locked sheet with data from sheet locked by diff password

I'm having a number of issues designing a VBA that will allow me to refresh pivot tables in one sheet with data from another sheet.
There are five sheets that we want our field teams to access, enter data into and edit (as a procurement tracker). These five sheets are to be protected by one password (say, Minneapolis). Data from these five sheets feed into pivot tables on the next six sheets and we would like these protected by a different password that only HQ knows (say, jambalaya). All of these sheets (i.e. those with pivot tables) tab names start with LOG. Following these eleven sheets are two sheets for guidelines. We're also working in a binary format but have also tried the macro-enabled format (although not necessarily with all the different iterations of code). We preferred binary because it makes for a smaller file size and this is important for, for ex., teams in South Sudan with slow and limited internet access but need to be able to send this back and forth to HQ.
Our problem is that in order to get the pivot tables to refresh, we have to unprotect, refresh and reprotect the sheets and we're meeting problems here. I've found a number of examples of solutions for this on the internet but we're having trouble with things like autofilters not working properly, some sheets being left unlocked, or fixing these but not being able to refresh the pivot tables.
Sub UnprotectRefreshAll()
Dim ws As Worksheet
On Error Resume Next
For Each ws In ActiveWorkbook.Worksheets
ws.Unprotect Password:="jambalaya"
Next ws
ActiveWorkbook.RefreshAll
For Each ws In ActiveWorkbook.Worksheets
ws.Protect Password:="jambalaya", _
AllowUsingPivotTables:=True
ActiveSheet.Protection.AllowFiltering = False
ActiveSheet.Protect AllowFiltering:=True
Next ws
Application.Calculate
End Sub
If I run this code in the VBA on the page with data that feeds into the pivot tables (called PROCUREMENT TRACKER), the autofilters work and other pages are properly locked, and this page is locked but without a password. If I run it from a button linked to that macro on the PROCUREMENT TRACKER page, the autofilters on the page don't work (and for some reason it lands on the second to last page, one of the guidance pages). There is also still the issue of wanting to have a different password for this, and if we start it with Minneapolis, it'll revert to jambalaya anyway. I was hoping that it would be possible to have it only refresh pages with the password jambalaya (and have tried a couple different codes for that), but it still changes the page it's run on even if that password is Minneapolis. I've also seen some options where you prompt the user to enter in the password but we DONT want to give the teams access to the password jambalaya, ONLY Minneapolis.
Sub LetsTryThis()
Dim I As Integer
On Error Resume Next
For Each Worksheet In ActiveWorkbook.Worksheets
If Current.Name Like "LOG*" Then
Worksheet.Unprotect Password:="jambalaya"
End If
Next
ActiveWorkbook.RefreshAll
For Each Worksheet In ActiveWorkbook.Worksheets
If Worksheet.Name Like "LOG*" Then
Worksheet.Protect Password:="jambalaya", _
AllowUsingPivotTables:=True
ActiveSheet.Protection.AllowFiltering = False
ActiveSheet.Protect AllowFiltering:=True
End If
Next
End Sub
Because the pages with pivot tables all start with LOG, I tried doing this code above as well, hoping it would only refresh the sheets with pivot tables. If I run this macro in the VBA from the PROCUREMENT TRACKER sheet, there is an issue of leaving the PROCUREMENT TRACKER sheet locked but without a password, and then if I do it from the button on the PROCUREMENT TRACKER sheet, it lands on the last LOG sheet (i.e. the ones with pivot tables), leaving that page protected without a password and it leaves the PROCUREMENT TRACKER sheet (again, the one with the button and the data used in the pivot tables) completely unprotected.
Ideal outcome:
(1) Have one password (such as Minneapolis) for sheets 1-4 where the field team can enter data into
(2) Have a second password (such as jambalaya) for sheets 5-12 with the pivot tables (and guides) that only HQ knows. These pivot tables pull data from sheet 3 (PROCUREMENT TRACKER).
(3) Find a way to refresh the pivot tables on tabs 5-10 without leaving anything unprotected/protected without password in the process and without altering features such as the use of autofilters.
The biggest issue you are facing here is the use of ActiveSheet. Stay away from that unless absolutely needed. It's causing behavior that you feel like you can't trace - as it often does.
Do the following
Manually protect Minneapolis sheets as needed. Then never do anything with them :)
Use this code for refresh.
Code
Option Explicit
Sub RefreshData()
ProtectPivotSheets False
ThisWorkbook.RefreshAll
ProtectPivotSheets True
End Sub
Sub ProtectPivotSheets(switch As Boolean)
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name Like "LOG*" Then
If switch Then
ws.Protect Password:="jambalaya", AllowUsingPivotTables:=True
Else
ws.Unprotect "jambalaya"
End If
End If
Next
End Sub

Hide a worksheet based on username

I already have a macro below that un-hides a worksheet at the click of a button and works okay. However I want this macro to be changed so that ONLY two users (whose usernames are "JSMITH" AND "DTAYLOR") are able to unhide this sheet called "Rates".
If someone else (whose username is not one of the two mentioned above) tries to unhide the sheet, I want Excel to display a message "you're not authorised to open this".
Moreover, I need to make sure that only those two users are able to un-hide in a traditional way without vba (eg by right-clicking on a visible worksheet tab and choose Unhide or from any worksheet tab, choose Format, Sheet, and then Unhide).
Can you please advise how to modify the following code to do the all the things described above?
Sub Hide_AllRatesSheet()
Worksheets("Rates").Visible = False
ThisWorkbook.Sheets("Names").Activate
End Sub
Note: you could use xlSheetVeryHidden property to allow unhiding it only from code (and not by mouse right-click).
Try something like the code below:
Sub Hide_AllRatesSheet()
Select Case Environ$("username") '<-- check username
Case "JSMITH", "DTAYLOR"
If ActiveSheet.Name <> "Rates" Then '<-- make sure "Rates" is not the ActiveSheet
Worksheets("Rates").Visible = False
Else
ThisWorkbook.Sheets("Names").Activate
Worksheets("Rates").Visible = False
End If
Case Else
MsgBox "you're not authorised to open this"
End Select
End Sub

VBA Copy and Paste SQL Data as Values in Excel Spreadsheet Not Pasting

I have written a code which open a worksheet that contains a SQL data connection, I then refresh the data, copy the values and attempt to paste that information into the original spreadsheet.
the data does not paste, however, if i manually step through the code hitting F8 the data pastes - i can't figure out why this is -
if this is an easy question my apologies, I am new to VBA, I asked around my office and searched google - still can't find an answer - here is the code
Sub getdata()
'
' getdata Macro
'
' Keyboard Shortcut: Ctrl+a
'
' make holdings report tab visible and clear the contents
Sheets("Holdings Report").Visible = True
Sheets("Holdings Report").Activate
Range("A2:J65536").Select
Selection.ClearContents
' open the original holdings report, refresh data, copy data
Workbooks.Open "\\hcc-fileprint\sys\Share\Institutional Group\Rebalancing\HCNet Update.xlsm"
Sheets("Sheet1").Activate
Application.Wait Now + TimeValue("00:00:02")
ActiveWorkbook.RefreshAll
Application.Wait Now + TimeValue("00:00:02")
ActiveWorkbook.RefreshAll
Range("A2:J65536").Select
Selection.Copy
'activate the rebalancing spreadsheet paste the values and then hide the tab
ThisWorkbook.Activate
Sheets("Holdings Report").Activate
Range("A2").Select
ActiveSheet.paste
End Sub
Could it be that you're actually not copying anything, because the database query started with RefreshAll is running in the background and has not returned any data by the time you reach Copy?
I see that you're waiting 2 seconds, but that might simply not be long enough, whereas single-stepping gives Excel more time to get the data.
Unfortunately, there doesn't seem to be a specific event that you could react to when RefreshAll has completed, which would be the "right" way of going about it. Perhaps Workbook.SheetChange is fired though; you could try that.
Just a shot in the dark, really, but the copy/paste code itself doesn't seem wrong, and you didn't say that you get any errors.
Need to Modify the paste command to paste the values.
ActiveSheet.PasteSpecial xlPasteValues