excel vba to reopen excel file without saving - vba

I have the following code, it is about to reopen the current excel file.
Sub CloseMe()
Application.OnTime Now + TimeValue("00:00:02"), "OpenMe"
ThisWorkbook.Close False
End Sub
Sub OpenMe()
MsgBox "The file is reopened"
End Sub
I am trying to make it applicable to activeworkbook, so i change
ThisWorkbook.Close False
to
ActiveWorkbook.Close False
but it ended up close the activeworkbook but didnt reopen the file, any advise? Very sorry if this question seem silly to you.

Try this:
Sub ReOpen()
Application.DisplayAlerts = False
Workbooks.Open ActiveWorkbook.Path & "\" & ActiveWorkbook.Name
Application.DisplayAlerts = True
End Sub

I think there's a thought error ... when the workbook is closing, the contained VBA code is closing as well, so there's no code left to be executed 2 seconds later, and no object that would be the subject of any code.
This will only work if your closing/reopening logic is outside the sheet you want to close/reopen, and to be more specific, residing in a workbook that remains open all the time between closing/reopening the sheet you want to reopen.

I like this, which I adapted from "How To Close And Reopen Active Workbook?"
Sub ReOpen()
ActiveWorkbook.ChangeFileAccess xlReadOnly, , False
Application.Wait Now + TimeValue("00:00:01")
ActiveWorkbook.ChangeFileAccess xlReadWrite, , True
End Sub
It seems more elegant to me and warns if there are unsaved changes. While the original uses ThisWorkbook, I use ActiveWorkbook like #Taosique.

Related

When closing one of the Multi opened instances of Excel that I have Before close code runs

I am having a little issue which is kind of strange.
So I have a macro Workbook (lets call it "Main" for simplification) with all its code that runs almost perfectly except for this little problem. "Main" is usually always open as it is our balances for the day.
When I or another user opens any other workbook at the same time as this one is open everything is fine, but when we close the workbook that doesn't have the code, "Main" runs it's before close code.
So this is my before Close code I have on "Main":
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim Tsweep As Integer
Dim sTime As Date
If ThisWorkbook.Sheets("Coordenador").Range("O2") <> "" Then
For Tsweep = 2 To Range("Coordenador!O1048000").End(xlUp).Row
Application.OnTime EarliestTime:=Range("Coordenador!O" & Tsweep).Value,
Procedure:="CloseC", Schedule:=False
Next Tsweep
End If
CloseC
sTime = ThisWorkbook.Sheets("Coordenador").Range("P15") +
TimeValue("00:30:00")
Application.OnTime EarliestTime:=sTime, Procedure:="SaveWb", Schedule:=False
ThisWorkbook.Save
End Sub[/CODE]
This is the code on "CloseC":
Sub CloseC()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Coordenador")
With ws
.Unprotect Password:=pass
.Range("O:O").ClearContents
End With
For Each Worksheet In ThisWorkbook.Worksheets
Worksheet.Protect Password:=pass
Next
ThisWorkbook.Sheets("Coordenador").Visible = xlSheetVeryHidden
ThisWorkbook.Sheets("LookupList").Visible = xlSheetVeryHidden
End Sub
And the Code on SaveWb:
Sub SaveWb()
Dim vTime As Date
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Coordenador")
ThisWorkbook.Save
vTime = Now
With ws
.Unprotect Password:=pass
.Range("P15") = vTime
.Protect Password:=pass
End With
Application.OnTime vTime + TimeValue("00:30:00"), "SaveWb"
End Sub
To explain this code stops all the OnTime runs that the system might still have. It clears some cells, protects some sheets and it saves. The error than appears when the user closes "Main" and excel tries to run "SaveWb".
I was wondering if there is a way to avoid this since in theory excel runs each instance by itself and even though me and/or the users are closing these other workbooks with the close button top we are not closing "Main" and that workbook remains open. Other idea would be to check if the workbook is still open after 5 seconds and if it is to run "SaveWb" but I haven't found a way to code that.
Thank you for your help in advance!
I have found a work around for this. Thank you all for helping me reach the idea.
Basicly what I did was add a If clause at the start of the before close:
If ActiveWorkbook.Name Like "ReportingReport*" Then
(code)
Else SaveWb
End If

VBA Excel - to exit sub when user cancels GetSaveAsFilename pop up box

I wrote a code which assigns to a button. When the button is pushed, it creates a new workbook and asks the user where to save the new file.
I want to make sure that if the user clicks cancel then it closes the new workbook and exits the sub.
I have wrote it as below but I don't know how to write a better code. I know that the if can be improved.
Option Explicit
Sub Create_a_new_workbook_and_save_it()
Dim xlPath As String
Workbooks.Add
Application.DisplayAlerts = False
xlPath = Application.GetSaveAsFilename(Title:="Select where you want to save your file") & "xlsm"
If xlPath = "Falsexlsm" Then
ActiveWorkbook.Close
Exit Sub
End If
ActiveWorkbook.SaveAs _
Filename:=xlPath, FileFormat:=52
Application.DisplayAlerts = True
End Sub
The above code working fine as you want....

Suppress "Save As" prompt

I looked this topic up and found some help but the suggestions do not seem to be working.
I am opening a CSV file into EXCEL make some changes and then want to save the results back to the same file name and the CSV format.
I want to do this without the prompt that I am getting to make sure I want to save the file.
We are using a macro enabled excel file to import the data make changes and then save.
This whole process with initiated by a batch file that will open the Excel application and the designated file at regular period of time so that is why we do not want the prompt to stop the process.
Here is the code I am using in VBA to do the work, as well as the other subs I found that were suppose to help me suppress the prompt.
This code is in the TheWorkbook of the file and not a module.
Am I missing something?
code
Sub fixfile()
Const strFileName = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv"
Dim wbkS As Workbook
Dim wshS As Worksheet
Dim wshT As Worksheet
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
Set wbkS = Workbooks.Open(Filename:=strFileName)
Set wshS = wbkS.Worksheets(1)
wshS.UsedRange.Copy Destination:=wshT.Range("A1")
wbkS.Close SaveChanges:=False
'This is the area of work that we doing to the data
'Through here
Application.DisplayAlerts = False 'IT WORKS TO DISABLE ALERT PROMPT
ActiveWorkbook.SaveAs Filename:= _
"W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat _
:=xlCSVMSDOS, CreateBackup:=False
Application.DisplayAlerts = True 'RESETS DISPLAY ALERTS
Application.Quit
End Sub
Private Sub Workbook_Open()
fixfile
End Sub
Sub CloseandSave()
ActiveWorkbook.Close SaveChanges:=True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Save
End Sub
The problems in your code are due to the following.
When you call SaveAs on the macro-enabled workbook, you had already appended a worksheet to it:
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
and then you're trying to save it as csv, which is a text file with only one worksheet, so Excel complains that you will loose information.
Moreover, you're doing the update to the csv twice: once in the
ActiveWorkbook.SaveAs Filename:= ...
Where, as a result, the current workbook becomes the saved workbook, and then again in the Workbook_BeforeClose. In the latter you dont disable the alerts, but anyway there's no need to save again.
I have come to the conclusion that what you want is to use the macro-enabled wb just as a utility for calculation, and you care only for updating the CSV workbook.
For simplicity, we will disable the alerts for the whole session, because the macro-enabled WB is used as a utility and we dont want the batch job to stop for any reason. However you can do it the traditional way, before and after saving, if you feel more comfortable with it.
' Code module ThisWorkbook
Option Explicit
Private Sub Workbook_Open()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
fixCSVFile
' Do the following only if you want the macro-enabled WB to keep
' a copy of the CSV worksheet. but my feeling is you dont want to
' ThisWorkbook.Save
'''''''''''''''''''''
Application.Quit
End Sub
Sub fixCSVFile()
Const strFileName = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv"
Dim wbkS As Workbook, wshS As Worksheet, wshT As Worksheet
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
Set wbkS = Workbooks.Open(Filename:=strFileName)
Set wshS = wbkS.Worksheets(1)
wshS.UsedRange.Copy Destination:=wshT.Range("A1")
wbkS.Close SaveChanges:=False
'This is the area of work that we doing to the data
' For purpose of testing:
wshT.Range("A1").Value = wshT.Range("A1").Value + 1
' Now we will export back the modified csv
wshT.Move '<- Here we have a temporary workbook copy of the modified csv
With ActiveWorkbook
.SaveAs Filename:=strFileName, FileFormat:=xlCSVMSDOS, CreateBackup:=False
.Close False
End With
End Sub
One more thing, the macro-enabled WB is now such that it closes as soon as it opens so it will be difficult to edit or modify (although there are workarounds). Therefore you should save a back-up copy of it without the Application.Quit, as a testing/maintenance copy. Only the copy that you put in production for the sake of the batch job should have the Application.Quit statement.
Based on the comment in the answers that the reason for opening the file and immediately saving it with no other changes...
So we needed to do what we were doing to get the file edit date to
change but not the actual file.
...this is a complete X-Y problem. If you need to change a file's modified time, just change the file's modified time instead of jumping through all of the opening and re-saving hoops:
Sub UpdateFileModifiedDate()
Const filePath = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv"
Dim handle As Integer
handle = FreeFile
Open filePath For Binary As #handle
'Read the first byte.
Dim first As Byte
Get #handle, 1, first
'Write it back
Put #handle, 1, first
Close #handle
End Sub
This will be insanely faster than your current process, will only set the file modified date and time to the time that you run the Sub, and doesn't risk any of the other issues you can run into cycling a CSV file through Excel (date formats and locale issues, truncating decimals, conversions to exponential notation, etc., etc.).
since you're going to consciously overwrite an existing file you can just:
first delete it with a Kill command
then do the SaveAs
so change this code section:
'This is the area of work that we doing to the data
'Through here
Application.DisplayAlerts = False 'IT WORKS TO DISABLE ALERT PROMPT
ActiveWorkbook.SaveAs Filename:= _
"W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat _
:=xlCSVMSDOS, CreateBackup:=False
Application.DisplayAlerts = True 'RESETS DISPLAY ALERTS
Application.Quit
to this:
'This is the area of work that we doing to the data
'Through here
Kill strFileName '<-- delete the old file
ActiveWorkbook.SaveAs Filename:= _
"W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv", FileFormat _
:=xlCSVMSDOS, CreateBackup:=False
Application.Quit
furthermore your code can be refactored by properly handling the ActiveWorkbook and ActiveSheet objects and reduce the variables and code amount, like follows:
Sub fixfile()
Const strFileName = "W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv"
Workbooks.Open(Filename:=strFileName).Worksheets(1).UsedRange.Copy Destination:=Worksheets.Add(After:=Worksheets(Worksheets.Count)).Range("A1") '<--| open 'strFileName', reference and copy its 1st worksheet 'UsedRange' and paste it to a newly added worksheet in the macro workbook. After this statement we're left with the opened workbook as `ActiveWorkbook`
ActiveWorkbook.Close SaveChanges:=False '<--| close `ActiveWorkbook`, i.e. the just opened one. We're left with macro workbook as `ActiveWorkbook` and its newly created worksheet as `ActiveSheet`
'This is the area of work that we doing to the data
'Through here
ActiveSheet.Move '<--| move `ActiveSheet` (i.e. the newly created sheet in macro workbook) to a "new" workbook having that sheet as its only one. We're left with this "new" workbook as `ActiveWorkbook`
Kill strFileName '<--| delete the "old" 'strFileName'
ActiveWorkbook.SaveAs Filename:=strFileName, FileFormat:=xlCSVMSDOS, CreateBackup:=False '<--| save `ActiveWorkbook` (i.e the "new" one) as the new 'strFileName' file
ActiveWorkbook.Close SaveChanges:=False '<--| close `ActiveWorkbook` (i.e the "new" one) without changes (we just "SavedA"s it)
Application.Quit
End Sub
It seems like you are making changes to two files. In addition to the csv file that you are opening, you appear to be adding a sheet to the excel file that is running the VBA code with these lines:
Dim wshT As Worksheet
Set wshT = Worksheets.Add(After:=Worksheets(Worksheets.Count))
So my guess is that you are indeed suppressing the save prompt for the csv file but you are also getting a save prompt for the changes you made to the excel workbook when you attempt to close it. So I think you need to suppress that prompt as well by also turning off DisplayAlerts in the CloseAndSave sub, or wherever the excel workbook is actually being closed.
I don't get why you are copying the CSV sheet into a new sheet in the macro enabled workbook. This is where your problem starts!
You should just be dealing with the data in wshS and saving wbkS instead.
Done, no more problems.
When you call
ActiveWorkbook.SaveAs Filename:= _
"W:\Webshare\Documents Acquired in 2017\Jim Excel\snr-room-schedule.csv",
FileFormat:=xlCSVMSDOS, CreateBackup:=False`
you're renaming the current macro enabled file within excel to the CSV file as far as Excel sees it.
When Application.Quit is called, it is going to call
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Save
End Sub
Which is where the prompt that you are complaining about is happening.
Even if you remove it, after Workbook_BeforeClose is called, Excel is still going to check all the open files' .Saved flag.
Excel will prompt you to save any files where .Saved = False
But if you set ThisWorkbook.Saved = True then Excel will close the file without asking to save.
Solution:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Saved = True
End Sub

Macro runs only once

I have a "master" timesheet macro which users open and complete. Upon close I force a macro (in ThisWorkbook) to run and rename the master to a filename held in range save name.
This works perfectly the first time the user opens Excel, edits and closes the workbook. However, if the user opens "master" timesheet the second time, completes another timesheet and closes, without closing Excel in between, then the macro does not run.
I have searched extensively to see if there is some "global variable" that I need to reset but with no joy.
Here is the code. Any advice would be appreciated.
Private Sub Workbook_BeforeClose(SaveAsUI As Boolean)
If Not SaveAsUI Then
Cancel = True
Application.EnableEvents = False
MSG1 = MsgBox("This File will be saved as....... " & Sheets("Timesheet").Range("savename").Value & ".xlsm", vbOKOnly, "Confirm")
Me.SaveAs Filename:=ThisWorkbook.Path & "\" & Sheets("Timesheet").Range("savename").Value & ".xlsm"
ActiveWorkbook.Close False
Application.EnableEvents = True
End If
End Sub
#Bob, seems as if this has something to do with the BeforeClose event. Before closing the workbook, you're trying a SaveAs. This could cause some issues. Did you try to debug this macro? If yes, what did you found?

Deleting Sheet with VBA crashes Excel

I am trying to delete a worksheet when the user click's on an image (button) in Excel. However this makes excel crash and restart, forgetting any unsaved progress.
This is my sub:
Sub DeletePlan()
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
Dim SheetNamesToCopy As String
SheetNamesToCopy = ActiveSheet.Name
' Check what addon sheets exists for the media, then add existing ones to string
If CheckSheet("periodeplan", True) = True Then
ThisWorkbook.SheetS(SheetNamesToCopy & " - periodeplan").Delete
End If
If CheckSheet("ukesplan", True) = True Then
ThisWorkbook.SheetS(SheetNamesToCopy & " - ukesplan").Delete
End If
If CheckSheet("Input", True) = True Then
ThisWorkbook.SheetS(SheetNamesToCopy & " - Input").Delete
End If
SheetS("Totalplan").Select
ThisWorkbook.SheetS(SheetNamesToCopy).Delete
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
End Sub
The application crashes most of the time. But not always... Any ideas what might be wrong?
(I have tested and confirmed that the delete function causes the crash, but its not always the same sheet).
Edit: This function is not deleting the last sheet in the workbook. There are 20 more sheets. Also i use Application.Calculation = xlCalculationAutomatic, because there are allot of formulas, and i do not want excel to calculate changes before all is connected sheets are deleted.
Any hint or answer is appreciated :)
The error occurs when the button that initiates the macro is located on one of the sheets that are to be deleted.
So the answer is: Do not create a button (or image linked to a macro) that deletes the sheet it is on.
If anybody can add to this answer with a reason for this error, please do so ;)
I just ran into this problem myself! I'm going to defer to more experienced designers on a way to refine this technique, but as a general concept, I do have a working solution:
If you allow the macro to run it's course and then delete the sheet, it doesn't crash. Something like this:
Sub Delete_This_Sheet()
Application.OnTime Now + TimeValue("00:00:02"), "Watergate"
Sheets("Sheet with a death sentence").Visible = False
End Sub
Sub Watergate() 'To make things go away
Application.DisplayAlerts = False
Sheets("Sheet with a death sentence").Delete
Application.DisplayAlerts = True
End Sub
Resurrecting this thread because I had the same issue and want to share the solution.
I had a very simple sub to delete worksheets:
Sub deletetraindoc()
Dim ws As Worksheet
Application.ScreenUpdating = False
For Each ws In ThisWorkbook.Sheets
'This if statement looks for any worksheet that contains the term "Form"
'Any worksheet that contains that string will be deleted
If InStr(ws.Name, "Form") > 0 Then
Application.DisplayAlerts = False 'Deactivates the standard deletion confirmation
ws.Activate
ws.Delete 'Deletes the worksheet
Application.DisplayAlerts = True 'Reactivates display alerts
End If
Next
Application.ScreenUpdating = True
End Sub
This inconsistently caused crashing until I added the line "ws.Activate" to activate each worksheet before deleting, which seems to have resolved the issue. I've run into this problem in many other situations performing actions on worksheets, but it usually would result in an object error instead of a complete crash.
I found that in Office 2013, you cannot place a button that overlaps a cell that that macro changes. Interesting enough, it doesn't occur if the change is numeric in nature, but if it is alphanumeric, it blows up excel when you attempt to delete that tab. Turns out, it blows it up when attempting to delete the tab manually (by mouse click) or by the macro attempting to do it. THUS, my lesson learned from this thread and applying it to my specific situation is to never place a development button over the cell it changes (in my case, it was simply a cell that gives the status of what that macro was doing). Excel 2013 does not like that situation while Excel 2010 simply didn't care.
I do believe you nare right and the only way around this is to ensure this macro is on the total plan sheet. Also you're doing a few unnecessary steps and the select a sheet should be to activate and select a cell.
Sub DeletePlan()
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
Dim SheetNamesToCopy As String
SheetNamesToCopy = ActiveSheet.Name
'dont delete total plan
If sheetnames = "Totalplan" then exit sub
SheetS("Totalplan").Activate
Activesheet.Cells(1,1).select
'Turn off errors if sheet doesn't exist
On error resume next
ThisWorkbook.SheetS(SheetNamesToCopy & " - periodeplan").Delete
ThisWorkbook.SheetS(SheetNamesToCopy & " - ukesplan").Delete
ThisWorkbook.SheetS(SheetNamesToCopy & " - Input").Delete
ThisWorkbook.SheetS(SheetNamesToCopy).Delete
On error goto 0
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
End Sub
You can delete the active sheet from a button (or image) on the active sheet. You just have to work around it.
ActiveSheet.Move before:=Worksheets(1)
Worksheets(2).Activate
Worksheets(1).Delete
I had a similar, but not identical problem. I had a macro that deleted all the chart sheets with the following command, but although it operated correctly, Excel 2013 was doomed to fail as soon as I tried to save the file, and would "recover" by reverting to the previously saved situation, throwing away any subsequent work:
Oh, and it worked fine until I moved from, I think it was, Excel 2010 to 2013, changing to Windows 10 at the same time.
The command of doom was:
ThisWorkbook.Charts.Delete
Thanks to some inspiration from the answers above, I first inserted a save before the deletion action and then changed the delete as follows (it turned out the saves were not after all needed but I like to have them there, even if I comment them out):
Dim graphSheet As Chart
ActiveWorkbook.Save
For Each graphSheet in this Workbook.Charts
graphSheet.Delete
ActiveWorkbook.Save
Next graphSheet
I should also mention that there is a preceeding Application.DisplayAlerts = False before the for loop and of course the Application.DisplayAlerts = True after the Next... statement to cut out the unwanted
are you sure you want to do this type question?
Again, thanks to your contributors for the inspiration.
I wanted a button that would delete a sheet, as the workbook was protected and could 'export' results but couldn't delete unwanted results.
My simple workaround was to have the macro hide the sheet, but then to delete the last hidden sheet, so the files dont become huge with dozens of hidden sheets.
I created a range in a hidden sheet called "DeleteSheet", to store the name of the hidden sheet.
Sub Delete_Sheet()
ActiveWorkbook.Unprotect Password:="Patrick2017"
ActiveSheet.Unprotect Password:="Patrick2017"
On Error Resume Next
' (In event there is no hidden sheet or the sheet is already deleted, resume next)
'The below finds the name of the previously hidden sheet to delete, and stores it.
Dim DeleteSheet As String
DeleteSheet = Range("DeleteSheet")
'The below is to avoid the main sheet being deleted
If ActiveSheet.Name = "POAL Calculator" Then
Exit Sub
End If
' The below stores the current sheets name before hiding, for deleting next time the
' macro is run
Range("DeleteSheet") = ActiveSheet.Name
ActiveWindow.SelectedSheets.Visible = False
' The below deletes the sheet previously hidden
Application.DisplayAlerts = False
Sheets(DeleteSheet).Delete
ActiveWorkbook.Protect Password:="Patrick2017"
Application.DisplayAlerts = True
End Sub
How about moving the button code to a module?
I have had an issue with that in Excel 2016 whereby Option explicit didn't work if the code was in a module, but if the code is in a module, then you 'should' be able to delete the sheet where the button was.