Hide worksheet in Excel Add-In from other VBA Projects - vba

I have an Excel Add-In which I am building which stores users settings in a Settings worksheet within the Add-In. I use the Settings sheet essentially as storage for boolean values and potentially, the user's registration details.
However, if I open up a new VBA Project and include the Add-In as a reference (In VBA: Tools > References > MY Add-In) then I can access the Settings worksheet and potentially break the password on it and hack the registration details.
The Settings sheet is set to be xlVeryHidden however it can be accessed via VBA code. Is there anyway to prevent this in Excel? In a module for example I can use the Option Private Module method.

If you password protect and lock the project then your code and the worksheet objects can't be viewed. Go to Tools > VBAObject properties > Protection tab then tick 'Lock Project For Viewing' and then set a password in 'Password to view object properties'.
However, there is nothing to stop a hacker from...
For s = 1 to Sheets.Count
Sheets(s).visible = True
Next s
...to see your Settings sheet.
There are a few options:
1) Have the settings sheet in a seperate workbook, or some other format like .txt and read from that (recommended).
2) Use some kind of encryption in your Setting sheet and decrypt it in your code, a really simple example is to use numbers in place of text so 'example' would = '5,24,1,13,16,12,5', but obviously you want to employ something more sophisticated that than and you can search online for many ways to do it.
3) Use 2, but store the decryption code somewhere else.
Be aware though, that for someone who knows what they're doing there really is no way to prevent a VBA hack, unless you use option 1/3 and have a way to store the file somewhere that isn't publicly accessible.

Related

Excel Add-In Configure Variables and Save

I have been asked to create an Excel Add-in for people to load a series of xml documents into Excel spreadsheets from Excel. I will write an add-in and publish its location for people to download their own local copies for use. I would Ideally like to have some constants for the VBA configurable by each end user, to customize their experience and function.
I thought it would be nice to have one button to run the Add-in and another button called "Configure" or something, which would edit the values of some of the variables in the VBA, and save the new values so that next time the user open Excel, the Add-in remains configured for them. Is anything like this possible and do you have some suggestions about what path I should follow to get there?
Is there any way to get the variables to persist? I guess I would need to save the values somewhere on the local version of the Add-in, but if so, what is the best way to store a set of parameters?
Any general advice would be most welcome; I have not actually written the add-in yet, being still in the design stages.
I do not advise using cells to store settings as the user may F it up.
However VBA does support Registry edits.
SaveSetting "Macro name", "Settings", "Username", "John Doe"
The above code will save a setting or registry key called Username with the name John Doe in the appname called Macro name and the section Settings.
So in short you only need to change the last two strings when you save new settings. The first two should (to make it easy for you) be the same all the time.
The keys will be stored in : HCU\Software\VB and VBA Program Settings\Your app name\
To get the setting you use:
GetSetting("Macro name", "Settings", "Username")
Another solution is to use txt-file.
It's still better than cells but not as good as above mentioned registry.
settings = "Username=John Doe, Worktitle=Janitor"
MyFile = "C:\myapp\settings.txt"
fnum = FreeFile()
Open MyFile For Output As #fnum
Print #fnum, settings
Close #fnum
Now you have a txt file with the settings that you can read and parse.

How secure is this VBA password protecting script?

I'm building a worksheet on microsoft excel and it will deal with sensible business data. The worksheet will be placed on a USB drive and have to move from place to place constantly. Therefore I've created a feature in excel VBA to enable/disable password protection. Here is how it works.
A page named settings is xlVeryHidden containing the user's password in a cell, another cell in the page contains the word yes or no. Depending on weather password protection is activated or not. When the user first opens the Workbook all sheets are xlVeryHidden except one containing a button to continue, they click on the button which runs a macro to check weather in the settings sheet the word is yes or no. Depending on so, they are prompted with a login or all the sheets are unhidden.
The code for the login is the following:
If PasswordTextbox.Text = ThisWorkbook.Sheets("Settings").Range("J5").Value Then
And after that all sheets are unhidden. Else it will give an error Msg Box.
Also the VBA code editor will be protected with excels default system.
What I'm asking here: Is my system fairly secure? For a regular computer user would this be hard to crack?
Thanks in advance :)
I'll add that it is pretty easy to unprotect your macro to get access to your code. If possible, you should think about implementing a protected database to store your sensitive data and populate your excel file from there, after proper authentication from the user.

Check Excel Macro Security Settings

I have a vb.net Application that starts a Excel macro.
Is there a way to check the macro Security Settings of the Excel first?
Imports Excel = Microsoft.Office.Interop.Excel
Private Sub macrotest ()
objExcel.Workbooks.Open(strPath)
if ***'Check her what macro Security Settings is selected!*** Then
objExcel.Run("SortIO")
end if
End Sub
This seems to have cross-posted to the Excel VBA questions page: would you mind speaking a little more slowly?
... reads slowly ...
Well, I can give you an answer in VBA: the Excel.Application.AutomationSecurity property.
The available values are enumerated by Office.MsoAutomationSecurity:
1 msoAutomationSecurityLow
2 msoAutomationSecurityByUI
3 msoAutomationSecurityForceDisable
These are the settings for macros available in the API exposed to VBA. The user interface, visible in the 'Developer' tab of the ribbon, corresponds to the registry settings explained by NoAlias in the previous answer:
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Excel\Security\VBAWarnings
With the following enumerated values:
Enable all macros
Disable all macros with notification
Disable all macros except digitally signed macros
Disable all macros without notification
If you go down the registry route, a VBA coder's advice would be to use the safe registry classes exposed by WMI scripting... And check that your user does actually have the privileges to make that registry write: there may be a registry policy in place preventing it.
I found on this site that you can check the registry for the security settings. The one issue I found was that my registry key was not in the exact place that was referenced on the site. That being said, you may want to just Try Catch it or make a more elaborate method for finding the VBAWarnings key in the registry.
Dim strVBASecuritySetting As String = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Excel\Security", _
"VBAWarnings", String.Empty)
If strVBASecuritySetting = "1" Then
objExcel.Run("SortIO")
End If
These are the possible values for VBAWarnings:
Enable All
Disable All with Notification
Disable All Except Digitally Signed
Disable All without Notification

Excel protect and unprotect workbook VBA

I have a workbook that contains several (lookup) tabs that I don't want any users to be able to unhide. However, there is one tab that contains admin info that I would like admin users to be able to see. I have a button and macro that prompts for an admin password before unhiding this tab, but if I protect the workbook structure (so that hidden tabs are not accessible for other users) the vba fails. Is there no way to protect/unprotect the workbook from within the admin macro? I have tried various combinations of ActiveWorkbook.Unprotect, ActiveWorkbook.Protect and ActiveWorkbook.ProtectStructure to no avail - both within the admin macro and WorkbookOpen. The error msg I most commonly encounter is "Can't assign to read-only property" even after having ActiveWorkbook.Unprotect at the top of my code. Does anyone know how to work around this? I don't really want to have to leave all tabs open to being unhidden with a second password on the Admin worksheet itself - clumsy!
Instead of protecting the whole workbook, set the Visible property of the sheets you want to hide to xlSheetVeryHidden - you can do this manually in the properties window of the VBA editor. Now those sheets won't show up in the Unhide… dialog. Your macro could swap the visibility of your admin-only sheet from xlSheetVeryHidden to xlSheetVisible and back.
By itself this doesn't protect your workbook from a user who knows how to access the VBA editor and properties, but if you need to do that there seem to be a lot of answers to a quick web search - it may depend on your version of Excel.

Allow for users to change sheet names, VSTO

This is similar to my question here, but my workaround dosn't help for these instances and the cause is more defined. I have a workbook level customization that will add sheets from a folder where it retains the name of the sheet that was copied in. This works well and doesn't cause any problems unless the user renames the sheet. If the user renames the sheet, saves the workbook, and then come backs to it, then tries to do any action which references the workbook or worksheet they get the error:
Microsoft.VisualStudio.Tools.Applications.Runtime.ControlNotFoundException:
This document might not function as expected because the following control is missing:
Sheet5. Data that relies on this control will not be automatically displayed or updated,
and other custom functionality will not be available. Contact your administrator or the
author of this document for further assistance. --->
System.Runtime.InteropServices.COMException: Programmatic access to the Microsoft Office
Visual Basic for Applications project system could not be enabled. If Microsoft Office
Word or Microsoft Office Excel is running, it can prevent programmatic access from being
enabled. Exit Word or Excel before opening or creating your project.
Now closing and opening the Excel doesn't help, moving the sheet to a new position doesn't help, and deleting the offending sheet doesn't help if more than 1 sheet has been added. The base template has 6 sheets, and I've tried adding the sheets to the middle (where we would want them) and at the end (just for kicks). This doesn't seem to help. If you delete all the added sheets, save the workbook, and open it again, then functionality is restored. The sheets that are added are not named sheets in the VSTO, but are referenced mostly by number or name (there are 6 sheets to start with, so if they get added after 3 they would have an index of 4 to (ThisWorkBook.Sheets.Count-3), or if Sheet.Name is not any of the names from the original 6 (which they would never be, and I have scripted a prevention for).
My problem is that I really need to be able to allow the users to add a generic report sheet if the ones I've designed won't work. This means I need to be able to add a sheet, allow them to rename it, save it and come back to it. This error doesn't happen until the sheet has been saved, closed, and re-opened if that helps anyone. I also can not replicate this on any machine with VS2012 installed, even if the project was never worked on in that computer (VSTO just installed). Though all those VS2012 machines were used for other Excel VSTO projects. I can however replicate it on XP-Win8 and Excel Office '07-365.
**So my distilled question: is there a way to allow a user to add sheets and rename them (outside of the VSTO preferably), without running into a Runtime.ControlNotFoundException?
Thanks.
Basically, you need to re-initialize the sheets as VSTO objects everytime the workbook is re-opened. Since these sheets aren't hard-coded into your solution, VSTO has no way of recognizing them unless your code looks for such things and "re-connects" them at run-time. This is explained in the VSTO documentation:
http://msdn.microsoft.com/en-us/library/cc442981.aspx
But I believe you require an add-in in order to do this for sheets. I don't think it can be incorporated into the workbook's "code behind".