Check for "save changes to 'filename' prompt w/ VBA? - vba

First off, this is not about the saveasfilename dialog box.
Is there a way to have a flag set that checks to see if the "want to save your changes to 'filename.xsls'? dialog box appears during a VBA sub ?
Basically I have a macro that copies some data into another file, displays a MsgBox then closes the file and Excel SHOULD prompt the user to confirm that the file is saved. However, I have a legacy program that locks that file sometimes, causing the prompt to not appear, and it looks like the file was saved but actually wasn't. To 'fix' it I have to close all instances of Excel and the program and start over. It doesn't happen often, but you can miss it if you aren't paying attention or someone less experienced in the process doesn't know to check to make SURE they are prompted to save.
What I'd like to know is if there's a way to have some sort of check / flag value, 1/0, true/false, etc to make sure that dialog box appears. If it doesn't then warn the user that they need to restart Excel and the other program. Basically I'm trying to catch an error that should never happen, so this might be unsolvable.
This is the dialog box I'm referring to:
Sometimes it doesn't appear because the file is locked and the VBA sub just continues on.

It would probably better to solve the other problem, but since you don't have posted it, we don't know it.
Anyway, everything you want is described here: https://support.microsoft.com/en-us/kb/213428
You can bascally do this:
Sub Auto_Close()
If ThisWorkbook.Saved = False Then
'ThisWorkbook.Save this would autosave
Application.GetSaveAsFilename 'this displays the save as dialog
End If
End Sub

I ended up doing this as a work around and it's not truly a solution to my question although I suspect there's got to be a way to do it through window classes checking or something. Thank you to everyone who took their time to chime in and offer their brainpower :)
I declared two variables for the file size before and after the sub runs. If the file sizes are equal, then a msgbox appears and says the file may have not been written correctly, or you are overwriting the existing file.
Dim ExportFileByte As Long
Dim ExportBytePostFile As Long
ExportFileByte = FileLen(ExportSourcePath)
' (sub runs here and exports a copy of some data to an .XLS file)
ExportBytePostFile = FileLen(ExportSourcePath)
If ExportFileByte = ExportBytePostFile Then MsgBox ("Error: File may have not have saved, or file is being overwritten without changes (OK)")

Related

Is there a way to put a breakpoint when my active window changes?

Is there a way to put a breakpoint on ActiveWindow.change ? I have a macro that I run in a new, unsaved Excel file, that is supposed to open CSV file, save it as, process it, and keep it in focus. Instead of that, when the macro is done it selects the empty new file that was unsaved, and puts the CSV in the background. This happens even though I use the code below, just before End Sub:
WKB1.Activate
WKB1.Sheets(1).Activate
WKB1.Sheets(1).Range("A1").Select
The thing is the three rows of code above do set the focus correctly, but at end sub it switches back to the unsaved file.
I was thinking that if I can set a breakpoint whenever the active window name changes, I can catch when that happens, because the macro I'm working with is huge, and I can't find the bug manually.
Kind regards,
Daniel
The fix was quite stupid, but I fixed the issue by creating a new ribbon tab and run the macro from the ribbon instead of running it from VBA. Also i removed and Activate o Select commands. The macro was behaving the same, even after i removed the Activate and Select commands, the thing that fixed it was running it from a new menu.

excel background save via vba

The Workbook.Save line in my macro is holding everything up, and while it's important that there's a save step at the end of the macro, I don't mind if it just starts saving and then hands control back to the user.
Is there such a thing as Workbook.Save BackGround or Workbook.Save vbModeLess?
Is there such a thing as Workbook.Save BackGround or Workbook.Save vbModeLess?
Definitively, no. The full list of methods available to the workbook object:
http://msdn.microsoft.com/en-us/library/office/ff847316(v=office.14).aspx
The .Save method does not have any optional arguments:
http://msdn.microsoft.com/en-us/library/office/ff197585(v=office.14).aspx
It seems you are perceiving a "problem" with your code which is not actually a problem, but normal and expected functionality, as I explained in the comments above:
When a user manually saves the file, the application is not interactive. The user can't do anything except wait for the save to finish.
The same occurs when you invoke the .Save method of the workbook object, or the Application.CommandBars.ExecuteMso "FileSave", etc.
This is necessary because (obviously) changes made while saving would not be saved, but the workbook's .Saved property would display True.
This property is used in determining whether to show the "Close this workbook with unsaved changes?" dialog when the user closes the file. If the property is True, then the user can close without any prompt. But of course if you let them make changes this will inevitably lead to unwanted data loss as the user may then close the file with saved state True and unsaved changes to the workbook which have not been reflected in the Saved property.
(Note: there are probably more technical reasons, too, but this is just the common-sense explanation)
If the length of time it takes to save the file is burdensome, you have at least a few options I can think of, first you would want to consider notifying the user that the file is going to be saved and this may take upwards of 45 seconds. This way, they do not think the program is unresponsive or otherwise hanging. You can do this with a MsgBox or a UserForm pretty easily.
Alternatively, you could use either of the above methods to prompt the user, i.e., "Do you want to save the file?"
Etc.
When excel saves a file it created a temporary file with a name like A82732KS.tmp and the quickly delete the original file and rename the temp file (possibly in an atomic operation). To do this excel has to release control of the file to avoid a sharing violation so it necessarily disables any changes in memory in order to guarantee that was is written on file and what is loaded in memory is identical.

Only I am able to save a macro-enabled workbook?

All, I have created a workbook that has some macros in it to import data. The idea is that the file is a master file, and every time you import data with it, it is supposed to place that data on the end of the existing data, and then you save it and move on.
The problem is, I am the only user that can save the workbook. Now, two of the sheets in my workbook I have protected, so that they cannot be edited. I have done this so that nothing can accidentally be removed (buttons, instructions, notes, etc). My users have agreed that this protection is a good thing.
But what I think is happening is our network is making anyone who didn't author this file open it as Read Only, and then they cannot save to it. I first thought maybe if added a save macro (and command button) that it would fix it. No dice.
Next, I had the workbook unprotect, and then re-protect itself when the user clicks the save button. Nope, still opening as Read Only.
I then put code in the Workbook_Open() Sub that changed it from Read Only to Read Write. This caused a box to popup when opening the sheet that said the file was in use by "Another User," and it was locked for editing.
The last thing I tried was adding the other users as Authors to the workbook. And it STILL opens as a Read Only file.
I think this has to do with the network settings here in our office (well, corporate-wide, but anyway). These are policies that cannot be changed. Can anyone help me find a work-around that allows my sheets to be locked for editing, but allows my users to save to my workbook?
You can see here that I have added three other users as Authors of the file (This is the information page of the file as opened by a user.):
So it turns out that the issue was not related at all to the workbook...
When attempting to Save As in the folder where the workbook was located, we found out that the user I was using for the tests simply did not have write permissions to the folder in question. I had write permissions to it based on a previous assignment.
So much frustration over something so simple.

Excel changes Link to Add-in

I need to link up an .xls (must not have macros) to a macro on our network. I thought I had found a good solution, which uses a shape to link up to a macro that is set an add-in in Excel. This method worked well for over a year, but now things are starting to act REALLY ODD. Excel keeps changing my links from the network to the local drive!
Basically, at my computer I run code that creates a button and sets the .OnAction value to 'SPC_BUTTONS.xlam!EXPORTSPC' which excel sometimes updates to 'G:\NetworkLocation\SPC_BUTTONS.xlam!EXPORTSPC' (sometimes it leaves it alone). I linked up the add-in to run from the network (and don't copy it locally) so this is a correct address for it. However when I move the file from my computer, to the network and on to the final computer, the link will change to 'C:\NetworkLocation\SPC_BUTTONS.xlam!EXPORTSPC'. The file's links work until the point it lands on the local computer.
'Check if SPC Button already exists
Dim exportButton As Shape
On Error Resume Next
Set exportButton = InspectionWS.Shapes("SPC Button")
On Error GoTo 0
If Not exportButton Is Nothing Then
'Delete the old button
InspectionWS.Shapes("SPC Button").Delete
End If
'Create "SPC Button"
InspectionWS.Shapes.AddShape(msoShapeRectangle, 770, 600, 160, 36).Name = "SPC Button"
Set exportButton = InspectionWS.Shapes("SPC Button")
With exportButton
.ShapeStyle = msoShapeStylePreset34
.TextFrame2.TextRange.Characters.Text = "Export SPC Data"
.TextFrame2.TextRange.Font.Size = 20
.TextFrame2.WordArtformat = msoTextEffect8
.OnAction = "EXPORTSPC"
End With
The first time I saw this problem was when I had changed the add-in. I had made another macro in that file called EXPORTSPC2, and had swapped names with original when it was time to go live. That's when all of the links became broken. I swapped back the names and decided to just swap the code, in case position mattered. Still didn't help with the linking.
I looped the original macro that set up the buttons on every file again, but that failed to rectify the problem. Several hours later, after trying a lot of options I found setting .OnAction to just 'EXPORTSPC' did again get some files to link up again, but ONLY if I did it on the local computer. I had tried the full address, a local address (and moving the add-in location), and SPC_BUTTONS.xlam!EXPORTSPC and of those still ended up with 'C:/Networklocation.xlam!EXPORTSPC'... even when set on the local computer.
The problem is, yesterday, it happened again when someone had replaced the updated files with another set of files he had been modifying on the network. This time around I wasn't surprised to see that they didn't link up (although disappointed), but was surprised that the my code looping the update to EXPORTSPC failed to 'take' for all of the files on the second computer. Only a handful of them would actually change to EXPORTSPC, and I ended up having to assign the link locally on the final computer(s), by hand, for each of the 45 .xls files.
Really, I can't keep doing any of this local repairing, as it creates machine downtime.
So my questions! Is there a better way to do what I'm trying to accomplish (.xls to add-in)? Any idea as to why is moving these files causing excel to change the link, forcing me to set them up locally? Why does it suddenly not accept anything but EXPORTSPC as the link name? Does excel save some sort of ID for macros/add-in/buttons I'm unaware of I'm accidently breaking?
Really, Any sort of insight will help. Thanks!
EDIT:
I did find an error in my looping code, which effected the issue I had on the second computer. It was looping through each workbook fine and saving... but I didn't activate the workbook before running the code, which was pretty important (DOH!). This only resolves the problem I ran into yesterday where I had to edit by hand.
However, digging a little deeper, I do feel like I have a better understanding. I used the code below to determine if what I see in 'Assign Macro' matches the stored .OnAction value, which it does not. Testing on my computer this code:
exportButton.OnAction = "'G:\NetworkLocation\SPC_BUTTONS.xlam!'EXPORTSPC"
would cause the 'Assign Macro' to change to 'EXPORTSPC', even though debugging
debug.print exportButton.OnAction
still displayed the original OnAction value. When I moved the file to the shop floor computer, 'assign macro' would display 'G:\NetworkLocation\SPC_BUTTONS.xlam!'EXPORTSPC until I clicked it, and then it would switch to EXPORTSPC.
So it seems Excel does keep track of where the macro is located once it detects the correct location. I swapped the macros around and it seemed to have broke the connection. My guess is excel then modifies the location to the C:\ once it's internal link is broken. If anyone has any elaboration/verification of this, I'd love to hear it.
I do recall having the add-in button becoming unchecked randomly, which may have been playing into why links kept breaking and reverting to the c:\ while I was debugging what would work. I'm not sure what was causing that either. But using the all forms of exporting seemed to work today. I'm still not convinced that I won't see it again though, since I don't fully understand what was the catalyst of unchecked boxes and swapped links.
If Not exportButton Is Nothing Then
With exportButton
.OnAction = "'SPC_BUTTONS.xlam'!EXPORTSPC"
'.OnAction = "EXPORTSPC"
'.OnAction = "'G:\NetworkLocation\SPC_BUTTONS.xlam'!EXPORTSPC"
End With
Debug.Print exportButton.OnAction
End If
So parts of the process still seem fuzzy, but at least now I know how to better track what I'm seeing.
Try this -- qualify the Add-In filename:
.OnAction = "SPC_BUTTONS.xlam!EXPORTSPC"
I have tested this with an XLAM on a network drive, and an XLS file on my desktop. I have copied the XLS file to a network location, and it still works. I have also done a SaveAs to put the XLS file on yet another network drive, and the action continues to work.
This of course requires that the user's instance of Excel has the Add-In enabled.
Alternatively, try enclosing the path & filename in single-quotes:
.OnAction = "'G:\NetworkLocation\SPC_BUTTONS.xlam'!EXPORTSPC"
This method seems to be preserving the OnAction absolute path.

Keep getting Excel and Windows Prompts while working with Interop Services

All of this is being done in VB.NET using the Excel 14.0 Interop Services
I am at my wits end. I keep getting prompts from windows and excel during the middle of a batch run.
The program i have takes in a workbook with batch records, then runs simulations on each batch record, then writes the results back out to the excel file.
The steps:
Open workbook
check to see if workbook is already in use by another program.
if it is in use. we try to close the workbook. then we wait for a set amount of time before trying again.
if the workbook is not in use we continue.
Get the contents
Mark the records as being processed
save and close the file.
process the records.
do the same process above to open the workbook.
save the results to the workbook.
close the workbook.
loop these processes until all the records have been simulated.
Ok the problems that can occur:
Workbook is already in use or two programs are trying to interact with the save workbook at the same time.
Ok now for the problem that i am having.
When the workbook is being interacted with by two programs at the same time. a prompt will show saying the file is currently in use.
another problem that happens that i can't explain is excel will show a prompt saying that the file is now ready to be modified with the options read-write, notify, cancel.
I need to find a way to handle these prompts programmatically.
If any one can point me in the right direction I would be very greatful.
You can prevent the prompts from appearing by setting:
Dim xlApp As Excel.Application = New Excel.Application
xlApp.DisplayEvents = False
But I've not found a way to actually "catch" the prompts and do something useful. I've noticed that often if Interop cannot get hold of a file then it will throw an exception. The exception rarely contains any way to distinguish what the actual error is, but you can sometimes work it out based on what could happen at that point.