Is there a method for opening a copy of a document through VBA? - excel

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.

Related

How to prevent user from saving changes to the master excel file?

I have a fair understanding of basic to intermediate VBA coding - here's the predicament I am having at work - I am responsible for maintaining this master excel file that consists of 35 tabs and macros and event procedures etc. - this file is used by the other team (more than 10 people) as the primary tool for carrying out their daily tasks - as the author i always keep an original copy of this file as a backup for any contingent event, and I put a copy of the file in the team folder for the team to use.
However, it sometimes happens that some of the team members would open this file in the team folder and make changes (they are told not to) as normal practice and accidentally save the changes withtout realising it - now that potentially creates an issue for the next user (good user) who would make a copy of this file and save it to their own folder and continute to work on with it (good practice) but they did not realise there has been data left in the workbook from the previous user - this kind of incident could create a disatrous consequency if it's left unnoticed.
I am trying to think up a way or series of codes that can resovle the issue - i just do not know which way to begin with - I was thinking of using SheetChange or Open (eg upon detecting any change then save as a new file in a different location) event - with that i ran into another issu- how i do ensure the subject event will not intervene other events that already exist in the workbook in the subsequential workbook?
any suggestion on structuring the code to accommedate this situation?
many thanks in advance
#VBA #event #savechange
as described in above
I would keep the master copy well hidden from them.
Then, consider putting passwords on sheets they MUST not change.
Or, consider sub-master files for the detail that each team can change and then your master file can link to those sub-files to get the latest data.
I had a project to manage that had 6 team members. Gave them each their own file and linked to their data. Also passworded the functions so they could not change or delete them.
Save the file as an Excel Macro-Enabled Template (.xltm) file.
This way, on double-clicking the file (as you would to open any other file), it creates a new file and will not automatically overwrite the old file when saving.
Instead of taking copies of the file, your users simply have to 'open' the file then later save as whatever they need to.

Keep custom functions aligned with their source files

In this link, it says that
During development and testing, you can manually clear your computer's cache of registration metadata by deleting the folder <user>\AppData\Local\Microsoft\Office\16.0\Wef\CustomFunctio‌​ns.
I then make a test as follows:
I load a manifest.xml pointing to the original customfunctions.js in my server in a workbook. After closing the workbook, a file is automatically saved in ...\Wef\CustomFunctio‌​ns\V1.
I modify manually customfunctions.js in my server by replacing Excel.Script.CustomFunctions["CONTOSO"]["ADD42"] by Excel.Script.CustomFunctions["CONTOSO"]["ADD42NEW"].
I open a new workbook, in a cell, after enter =contoso., the IntelliSense shows me contoso.add42 rather than add42new. After entering =contoso.add42(5;4), the cells shows #GETTING_DATA and does not return a value. That's understandable because it works on a function which does not exist anymore.
If we click on another cell and enter e.g., =2+3, we see the workbook is refreshed, and #GETTING_DATA becomes #NAME?. And now IntelliSense shows contoso.add42new rather than contoso.add42.
To conclude, I think there may be a bug: when we open a workbook, IntelliSense should give the updated list of custom functions defined in the current customfunctions.js.
Actually, what is ideal is that the custom functions in workbook always keep aligned with what are defined in customfunctions.js. If there was not this bug, today we still needed to close a workbook and reopen one to get updated. Does anyone know if there is a workaround to make custom functions in an opened workbook keep updated on the fly? Is there a refreshing trigger that allows us to make custom functions in an opened workbook update from the current customfunctions.js?
Thanks for the question! As you've discovered, custom function definitions are currently updated only on-demand rather than on every single document-open event.
We've received a bunch of feedback in this area and so we're considering some changes to how registration works so that the list of functions in IntelliSense/autocomplete gets updated at the beginning of a session instead of in the middle of one.
I don't have details to share right now, but be on the lookout for some changes here in a few months.

User option in Access to select unique filepath for Excel source data

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.

Create a user comment field linked to read-only Oracle database

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.

Excel crashes, VBA userform cannot save

I have a userform in Excel in which the user enters information and then hits an "add stock" button. Upon pressing this button, the information is entered into a spreadsheet and then the spreadsheet is saved with "ActiveWorkbook.Save".
The problem is that the work computers are old and Excel has a tendency to crash. When the spreadsheet is autorecovered, the add stock function no longer works, it crashes with a code 75 error. It seems that ActiveWorkbook.Save doesn't work in this case, until the user manually hits CTRL-S. The boss is adamant that our users are not computer savvy enough to manage this so I need to somehow check if Excel has crashed and if so automatically save the file before they start using it.
How would I check if we're in an autorecovery state, and then save it (without ActiveWorkbook.Save) so that the user can continue using the form without issues? Many thanks.
I can't find a direct way to check this, but here are a couple of kludgy options. It seems that if there are two states a workbook that an Autorecovered workbook can be in: Last saved by user or Autosaved. The caption reflects which state it's in. This function will check for the existence of that phrase in the caption.
Public Function IsInAutoRecoverMode(wb As Workbook)
Dim wn As Window
Set wn = wb.Windows(1)
IsInAutoRecoverMode = _
wn.Caption Like "*[Autosaved]?" Or _
wn.Caption Like "*[Last saved by user]?"
End Function
I'm not sure if there are more states that just this and this will certainly fail in non-English environments, so use with care.
When Last saved by user, the Workbook.Path property is where the file is stored. When Autosaved, the Workbook.Path property is equal to Application.AutoRecover.Path. Well, they're equal on my machine. That may just be a coincidence, but I doubt it.
Because the Last saved by user Path isn't distinctive, you can't use it to determine if you're in Autorecover mode. But if the user open the Autosaved workbook, you probably don't want to just Save, but rather Save As in the right location. You might need to use both these techniques to get the solution you want.
Make sure you tell your boss that these work-arounds because you're so industrious and inventive, but they are not documented and might fail at any time. At least, I wouldn't use them without understanding that they're based on some guesses. Let us know what you end up with.

Resources