I want to distribute excel workbook, protected with an activation key
This is the steps of my idea of protection.
I want to create a key generator to activate the use of the workbook using this data
a pass provided for myself
activation date
username
When the workbook is open, ask for the first key my generator creates, so they need to contact me to get the key to use the product.
When the key is entered, the excel workbook must
a) locks to the location the workbook was saved to work,
b) changes internally the activation key using this criteria.
activation key
a pass emmbeded in code
username
In this way when the workbook is copied to other location, even in the same computer, will ask for a new key, before work, because of the change of location and the change of password. I must prevent be "saved as" to protect it even more. I will developed to work to excel 2007 or higher.
How do you see my idea?
I never worked before doing that things, so, I need suggestions, example code, and all the stuff you want give me, to achieve the goal.
Excel protection is not designed to handle this kind of scenario in a secure way: its only meant to handle casual user errors.
The only secure way of handling this is to convert the Excel application to a compiled DLL: although using obfuscated .NET comes close.
Related
I am relatively new to VBA and I need a solution to a problem I have.
Currently I have two excel documents - one which is a form where the user enters data and this is then sent to a second document which acts as a database for this information. My issue is that when people are looking in the database data cannot be sent to the second document because it is open and there are overwrite errors.
It is my intention to have the databases location hidden away within a network drive so it cannot be found meaning the only way to access I is through a button on the first document.
Is there a way that when the open button is pressed to access the database that a copy of the document is opened instead of the actual document itself so data can still be sent?
So, you have a few options here:
a) Use an actual database. Not so much to solve this specific problem (that too) but also because making a "database" in excel is usually a terrible idea in the long run. But I know that is not always possible, and it's overkill in many situations so...
b) Have that "database" workbook set as "Shared Workbook". Shared Workbooks come with their own host of issues (namely, can't edit certain aspects like the VBA in them, conditional formatting, and others). But if it's strictly for reading and writing data, it can work. It also comes with its own version control, so that's good.
c) What you originally asked. It is quite simple really, as you said, you make a copy of the document, ideally in one of the user's local folders . You can do this using FSO (see VBA to copy a file from one directory to another)
The only issue with this last approach is that you need some way to track when the user has closed that temporary file, in order to delete it (if you absolutely don't want to leave any traces). Otherwise, you can just leave it, and overwrite that same file each time the user presses the "View Database" button.
I am working off of a great solution created by #MattHall from 2011 to a question that I also shared about importing a dynamic range from Excel into Access.
Specific to that--though in general for future VBA's--my question is whether there is an additional way to be able to point to the Excel source file if it is moved without having to go into the VBA editor every time?
For my specific needs, I am trying to work on these Access and Excel files with others through a shared BOX that has a different file path for whoever is working on it.
USER 1 may be: C:\Users\USER1\Box Sync\filename.xlsx
USER 2 may be: C:\Users\USER2\Box Sync\filename.xlsx
...and so forth for any other users. I am curious how we can all work off this when the file path used in the VBA created and used by USER1 is not accessible by USER2? Could there be some code that allows for the every user to locate the file each time through their own filepath?
It would be a pain to do that but I also do not know a better option as we are not working off a shared server and this is unfortunately limited to Box share at the moment.
EDIT: If anyone could also suggest how to integrate their recommendation into the 'Dynamic Range' code in solution from #MattHall in the linked Stackoverflow, that would particularly helpful to my request.
We have an application to track work orders (hundreds of thousands) built on an Oracle database. Data entry is cumbersome and report features non-existent. IT is inflexible. We do not get support from that end. Accordingly, users have created Excel "tools" to run queries and make sense of data using ADO or ODBC connections.
What we also need is a way to record comments on specific work order (WO) records and have those comments travel with those records somehow. There are multiple users using their own spreadsheets, all querying the same database.
I'm envisioning a junction-table approach, perhaps using Access, where some VBA could take a users comment from the row in the worksheet, capture the WO number, user id, date, and comment text and store it in an Access table. Those fields could then be retrieved by some more code. This would allow any user to see all comments by any other user related to a specific WO.
I'd greatly appreciate feedback ... on the practicality, preferable constructive, but brutally honest is ok too.
Much thanks,
Kevin
Apart from this being a horrible mess you could:
use SQL Server instead of access - you can get a free copy that will probably cater for your needs. Access will also work, but it is bodge. SQL server is more professional!
I would avoid doing data entry in excel. You could build a front end (possibly in Access with SQL Server backend) that allows data entry. You could add pretty simple code to all your workbooks, which will probably reference code that will be in an excel addin. The addin has code to simply open an access database, open a form and find the WO that the user was viewing in excel.
2a. Or you could use an excel addin with a data entry form, to do data entry, but beware managing the locking, refreshing and update of displayed data.
Creating excel addins is easy, (re-)distributing them is easy, access (or whatever front end you use) is designed to do record management (ie lock and update or lock and cancel or just view) etc.... Plus you want to avoid addinghte same or similar code to all your workbooks.
Each users workbook would have very simple code. Just to tell the addin what WO you want to operate on.
Do you have sharepoint? If so Access 2013 can deliver forms as webpages - very easily, so you might not even have to manage a front end access file.
Happier now?
For those that may stumble on this post, what we ended up doing was use VBA to store comments in a separate SQL database. Users double click the cell with the WO number to get an input form prompting for comments with options to add new, append or remove existing. Entries are passed to the SQL db and also to columns in the worksheet so users can see all the entries. Time stamp/Network ID provides when/who provided comment. Existing comments are fetched when users re-open file. Works great.
I tested it by assigning an excel a password. This excel was kept in dropbox, and as I assigned a password to the excel, it was entirely downloaded on every comp that it was shared with. Is there a way that I assign the password and the whole file does not get modified? I am sure that it is not an issue with Dropbox as this is what happened with SugarSync as well.
Without deeper knowledge of the internals I still would say NO - Excel has to store your password for this file SOMEHOW, so I'll guess it will be encrypted and stored within your file, hence binary changing it.
Just so you can check this for yourself:
Make a new Workbook and save it.
Open it, just password protect it, and save it as another Workbook (like the first time)
Now compare those with any HEX or Binary-Comparing tool.
Password protection means that the file is encrypted. There is no point in password protecting a file if it is not encrypted. The only other way to prevent people from viewing a file without encrypting it is to restrict access to it. This can be accomplished by:
1) Modifying the permissions on your computer so that it can only be seen using your password protected account.
2) Not sharing the file with other dropbox users (or share it only with the people you want to see it).
Neither of these is a terribly good security method on it's own. File encryption is always more secure, ideally when used with the above.
We have a lot of VBA code in spreadsheets and a lot of time people save them to local drives. When we want to upgrade the spreadsheets we push a new version out to a shared drive but dont have any way of enforcing that people dont use the old versions of the spreadsheets.
Is there some best practice here to deploy vba spreadsheets so if someone loads an old version it wont open or will ask you to upgrade. It seems like this must be an issue for any custom solution so i would have through MS would have some solution here.
Does microsoft have a standard versioning / deployment solution for this or do i need to come up with some home grown solution (spreadsheet pings a database on startup to check version)
If its just the VBA code you want to be able to upgrade one solution is to separate all the code into an XLA that sits on an accessible server.
then the users Excel has an addin loader that gets the latest version from the server, or you could embed the loader in the workbook.
There is a working example reversioning Addin Loader available at
http://www.decisionmodels.com/downloads.htm
Though I've not done this. I've see people do something similar where they store the code in dlls in the database, and then verify that the local ones are the same on start up.
Add a custom property to the workbook, such as a GUID, Integer, Date, or whatever you need. On startup, check the value and determine if VBA should continue or whatever implementation you decide. Usually, I open the "shared" latest version of the document and inspect its custom property. If user is not using latest version, display a message prompting the user to get the latest version. This is usually good enough. I have done this for years with great success for Access, Word, and Excel VBA.
One real problem is people who ignore the prompt to update. They will do this because they fear losing data, bugs in latest version, and so on. You need to address their concerns and not try to "lock" them in to your "solution" to this problem. I strongly recommend you always provid a means of "importing/upgrading" data to latest version of workbook.
Fairly simple to implement. If you address the above mentioned problem effectively, people will start to trust the "prompt" and you will find this is a really simple and effective solution.
If you workbook is tied to a database, it gets a little more complicated. Generally, you do not allow the user to maintain the data outside of the database. When they want to modify the data, you generate the workbook for them. After they are done modifying data, you import the data. (The workbook is saved for "backup" purposes or the user can maintain a copy of the workbook for reference or an archive.) This has the advantage of eliminating the need to maintain document version since the document is "virtual".
Define a current version property. Use whatever way for that, like a constant in VBA.
Find a standard way to access the latest version. It could be on a shared drive always on the same path, or whatever other means you have.
If current version number < latest version number then:
Ask to upgrade
Show the upgrade procedure
Possibly do some locking on normal VBA operations until the upgrade is done
An easy solution would be:
Store a version number somwhere in the workbook (on a hidden sheet for example so that it will not get removed accidentally) or as a variable.
Store a text file with the latest version number on your share
Include a macro which automatically reads the latest-version-textfile and compares the version number to the one in the currently running workbook. If its too old just show a message-box (telling the user to update) and close the workbook.
I'm using a similar approach and it works fine.