Excel crashes, VBA userform cannot save - excel

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.

Related

Macro Enable Workbook is creating new file with SaveAsUI instead of saving itselft

I have to call the below line to save my workbook from another file:
Application.ActiveWorkbook.Save
For the needs of my project, this code needs to be and run in a different file than the one I have open and active.
When this code runs from another workbook, the file that I have it open and actived calls the SaveAsUI to save the file again, even if he was already saved.
Afther run of the code above, the original workbook is losted. I cannot save anymor the active workbook, manually or by macros, and I don't want to save as my original file. Several errors occur, such as:
random filename in the SaveAsUI
Unespected Error, AutoRecover Disabled
Share Rule Violation (PT/BR)
Sorry, I cannot catch this erro in english. Here its translation:
"Your changes could not be saved in 'File' due to a sharing violation. Try saving to another file."
I noticed that this error started after I enabled auto-save for the first time*. I don't know if it is something related to the cloud and Excel gets lost when saving. Also, testing saving the original file outside the network the problem did not appear
I haven't found anything like it on the internet and it has never happened before either.
PS: The workbook with I have enabled AutoSave has nothing to do with those that are giving error. That was a workbook without macros for a much simpler project.
I was able to find what was causing the problem. I initially thought it was the VBA macro part and the "ActiveWorkbook.save" command, but in the end the problem was much deeper.
It turns out that in the same macro that contained the save command there was a call to another function that updated the queries.
the error would stop when going into PowerQuery Editor, going into the spreadsheet query that would later give the share violation error, and in the steps remove the action of promoting the headers.
I have no idea why this is the error. But I tried several other ways in several other places (like every tip in this link1, or this link2, or this link3), the only way that resulted in the solution was this above (that I don't find in any place).
But the promotion of the headers is necessary, so to continue without giving problems I needed to go into the advanced editor and change the second parameter of the line below from "null" to "true" (which is basically to promote headers at the query stage).
let
Source = Excel.Workbook(File.Contents(FilePath), true, true),
With this, everthing now is working fine.

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

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.

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.

Set A Connection String In Excel To A Cell Value

I'm creating a workbook for some folks to be able to manipulate some data, get blessings from all involved, then hand off to someone else to manually enter back into the system... Don't ask, we are afraid of scripting back to the system.
I am attempting to do this in the Data Connections Properties Window.
Data > Connections > Properties > Definition (I can't attach a screen shot cause I'm a noob I guess)
I have many different work arounds. I have even created a VB script that will do this, allow users to change server targets, pass different security credentials, but, just this last Monday there was some kind of office patch that screwed up all activeX and I had to go wipe out a temp file to correct it. I can't do that with a bunch of users that are less than tech savvy that are geographically separated, I don't have RDP authority.
For example, the connection string currently looks like:
DRIVER={iSeries Access ODBC Driver};
System=myserver.network.net;
I was hoping to set it to look like:
DRIVER={iSeries Access ODBC Driver};
System="Overview!D9";
The cell, Overview!D9, could then be changed by who ever to the correct system string, like myserver.network.net or server1.network.net.
Near as I can tell from my research, the connection properties window is pretty cut and dry and this might not be possible. But figured I would ask around.
Assuming System is just a string, then getting the value is simple.
' Assuming System is a String
Dim System As String
System = ThisWorkbook.Worksheets("Overview").Range("D9").Value
If System is part of another string, its much the same
' Get the value to use in the connection string
Dim System As String
System = ThisWorkbook.Worksheets("Overview").Range("D9").Value
Dim ConnectionString As String
ConnectionString = "DRIVER={iSeries Access ODBC Driver}; SYSTEM=" & System & ";"
If security is a problem, and your people generating/manipulating the data don't NEED the macros to do their work (ie, just the person entering the data back into the system does) then you don't need to put the macros in their workbooks.
You can add your macro's to the "Default Workbook" on the data entry person's computer. These macros will then be available to all workbooks they open on their computer.
Your data entry person gets the benefit of scripted automation and your users don't have to worry about email or anti-virus problems.

Open Excel workbook as read-only via VB6

I have an application written in VB6 that writes data to a spreadsheet. I'm using the MS Excel 11.0 Object library to create an instance of Excel and open the book:
Dim xlApp As Excel.Application, remoteBook As Workbook
Set xlApp = New Excel.Application
Set remoteBook = xlApp.Workbooks.Open(sheetName)
In addition to writing to the workbook "sheetName", the program also allows the user to launch the workbook in order to view the cumulative results.
There is a chance, however slim it may be, that a user could have the workbook open for viewing the results while someone else is trying to write to it. I want to give the user writing to the sheet priority. Is there a way I can launch the sheet for viewing as read-only? There is a read-only property of the excel application object, but it is (of course) read-only.
How can I set up my program to write data to the workbook even if someone has accidentally left the file open at their desk?
Simply do this:
Set remoteBook = xlApp.Workbooks.Open( sheetName, , true)
Where true is whether or not to open as Read Only. ReadOnly is the third parameter to this method.
I think you might be able to do it via the Workbook.ChangeFileAccess method as described here. Not sure if it will suit your circumstances though.
Let me make sure I have properly interpreted your issue:
Your app writes an excel file
The App launches the file in Excel
to the User
Now here's what I think you're saying:
Once the user is viewing the sheet, they may or may not want to edit that sheet.
In other words, you don't want to use
Set remoteBook = xlApp.Workbooks.Open( sheetName, , true)
100% of the time because the user viewing may want to change the data.
The downside is that this dastardly user may leave the file open to prevent other users from writing to that file.
Is that correct?
If so, it sounds like you may need to explicit state in your app to "Open for viewing" or "open for read-only" access and then toggle the Read Only property appropriately; which is probably undesirable.
However, you can't force a save on an office doc once someone else has it open.

Resources