Kill Excel after user close Userform - vba

We have tried to fix these problem for a couple of days and we posted on another forums but still no answer, may be you guys can help us here.
I am having a problem with excel running after the Userform is closed, I think what I have supposed to end the application but it doesn't, it keeps excel running in the background and I have to end the process with task manager.
I created a vba file to copy a file to the temp folder and run a macro which opens excel and the userform.
Any help is appreciate it.
This is the vba script that copy and opens the macro:
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
FSO.CopyFile "C:\pdfv6.xlsm", "C:\Windows\Temp\"
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Run "'C:\Windows\Temp\pdfv6.xlsm'!module1.macro1"
objExcel.DisplayAlerts = False
Set objExcel = Nothing
objExcel.Application.Quit
And this is part of the vba module:
Sub Macro1()
Application.Visible = False
UserForm1.Show
End Sub
Set objExcel = Nothing
And this is the Sub that deals with closing the Userform and the application.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
Unload Me
ThisWorkbook.Close savechanges = False
Application.Quit
End
End If
End Sub

I found the problem.
I was using Application.Quit twice
Once in the vbs script and then when I was closing the form.
I got rid of the one in the vbs script and everything is fine now.
thank you for your help.

Related

Running vba code whenever a workbook is opened

I'm writing vba which manipulates data within a worksheet however I'm trying to make it run whenever a workbook is opened.
The problem I'm having is that due to the workbook (that the code needs to run on) is different/new every time, I need the auto_open code to be within a personal macro workbook.
Sub Auto_Open()
Dim bookname As String
Dim checkbook As String
Dim Workbook As Workbook
For Each Workbook In Application.Workbooks
bookname = Workbook.Name
checkbook = Left(bookname, 3)
If checkbook = "EDN" Then
Data_generator
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
Else
End If
Next Workbook
End Sub
When this code runs it checks all open workbooks and sees if the first 3 letters of it are 'EDN', if it is then run the public sub called 'Data_generator', save it and quit. If it isn't check the next open workbook, etc.
When a file is opened from windows explorer, excel launches (with both the desired workbook and the personal macro workbook) however because excel opens the personal macro workbook first and runs the code before opening the desired workbook it doesn't find a workbook called 'EDN'.
If the above code is ran after both workbooks have opened then the code works as intended and cycles through each open workbook to see if there's one called 'EDN' (this was proved by putting a messagebox after the 'then' and running the code), if so run the sub.
I've proved this by putting a messagebox after the 'else', when this is done it displays the messagebox with the workbook I want, not open. After the message box is cleared, the workbook then opens.
Is there any way to make the desired workbook open first or any other work around for this?
You can create an Add-in that runs whenever a workbook is open
https://msdn.microsoft.com/en-us/library/office/gg597509(v=office.14).aspx
this tool may help to create the Add in http://www.andypope.info/vba/ribboneditor.htm
You should be able to use the Application.OnWindow event to trigger a macro when a file is opened or closed.
In ThisWorkbook
Private Sub Workbook_Open()
Call StartTracking
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call StopTracking
End Sub
In a Module
Function StartTracking()
Application.OnWindow = "AutoRunOnWindowChange"
End Function
Function StopTracking()
Application.OnWindow = ""
End Function
Function AutoRunOnWindowChange()
If Left(ActiveWorkbook.Name, 3) = "EDN" Then
Call Data_generator
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.Quit
End If
End Function

Preventing Excel prompt from Word VBA

I'm working with VBA on Word and Excel. I have the Word running a userform which will automatically open an Excel file. User should fill some data in Excel file and then go back to the Word userform. When user finish filling all fields in Word userform, it will run some VBA code on Word that copy data from Excel to Word. After finished, the Excel file will be closed automatically. Therefore, I need to prevent user from closing the Excel app manually.
In order to do that, I use these code in Excel VBA in Sub Workbook_BeforeClose. If user close the Excel application window, it will show a message box that ask whether the user is still working with the Word userform. The code as follows:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
answer = MsgBox("Are you still working with Word userform?", vbYesNo)
If answer = vbYes Then
Cancel = True
MsgBox "This workbook should not be closed. It will be automatically closed when you finish working with Ms. Word Template Userform."
Else
Application.ThisWorkbook.Saved = True
End If
End Sub
In the Word VBA, I have code to close the Excel file:
Sub closeExcelApp()
If Not excelApp Is Nothing Then
excelApp.DisplayAlerts = False
excelWb.Close savechanges:=False
Set excelWb = Nothing
excelApp.Quit
End If
Set excelApp = Nothing
End Sub
This Sub will be called when the Word VBA code done copying data from Excel to Word. However, calling this Sub will cause the Workbook_BeforeClose called. Meanwhile, I don't want the Workbook_BeforeClose called when I call this closeExcelApp sub from Word VBA.
Any suggestion?
You can just disable events:
Sub closeExcelApp()
If Not excelApp Is Nothing Then
excelApp.DisplayAlerts = False
excelApp.EnableEvents = False
excelWb.Close savechanges:=False
Set excelWb = Nothing
excelApp.Quit
End If
Set excelApp = Nothing
End Sub
As explained in comments, add this line on top of the modules : Public ClosingFromWord As Boolean and set this boolean to False when you start your code execution.
As you are working between apps, the easiest way will be to write the value of the boolean in a cell in Excel from Word and read/laod this value in the Workbook_BeforeClose to avoid going through the whole code of that routine.
And modify you code to look like this :
Sub closeExcelApp()
ClosingFromWord = True
excelApp.Workbooks(1).Sheets(1).Cells(1,1) = ClosingFromWord
If Not excelApp Is Nothing Then
excelApp.DisplayAlerts = False
excelWb.Close savechanges:=False
Set excelWb = Nothing
excelApp.Quit
End If
Set excelApp = Nothing
ClosingFromWord = False
excelApp.Workbooks(1).Sheets(1).Cells(1,1) = ClosingFromWord
End Sub
So while you execute closeExcelApp, the boolean will be set to True and the Workbook_BeforeClose won't be executed in his totality as it'll be exited with If ClosingFromWord Then Exit Sub :
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ClosingFromWord = Workbooks(1).Sheets(1).Cells(1,1)
If ClosingFromWord Then Exit Sub
answer = MsgBox("Are you still working with Word userform?", vbYesNo)
If answer = vbYes Then
Cancel = True
MsgBox "This workbook should not be closed. It will be automatically closed when you finish working with Ms. Word Template Userform."
Else
Application.ThisWorkbook.Saved = True
End If
End Sub

How to disable Auto_Open after first save

When opening up a template a macro that is Auto_Open runs this code:
Sub Auto_Open()
UserForm.Show
End Sub
This then brings up a userform that says please save as and a Ok command button.
When Ok is clicked it has the this code.
Private Sub SaveAs_Click()
Dim bFileSaveAs As Boolean
bFileSaveAs = Application.Dialogs(xlDialogSaveAs).Show
If Not bFileSaveAs Then MsgBox "User cancelled", vbCritical
Unload Me
End Sub
Problem is after the Auto_Open is ran for the first SaveAs i want it to never run again. Because I want to be able to open it later with out the Userform popping up. So how do I disable the Auto_Open once its run and then save it disabled
I cant disable all macros because there are others in the workbook that still need to work.
Thanks
You have to use the Workbook.SaveAs method MSDN Found Here after you get the SaveAsFilename...
As for deleting a sub after it runs (I'd do this before saving) See here... You'll need your Auto Open Sub in a different module so you can delete the module before saving.
Private Sub SaveAs_Click()
Dim x As Object
Set x = Application.VBE.ActiveVBProject.VBComponents
x.Remove VBComponent:=x.Item("TestModule") 'Where TestModule is the module that holds the Auto Open script
Set NewBook = Workbooks.Add
Do
fName = Application.GetSaveAsFilename
Loop Until fName <> False
NewBook.SaveAs Filename:=fName
fName = False
Unload Me
End Sub
Exit auto_open if file name without specific wording.
For example: If file name is not starting from "N", auto_open will be exit.
Sub auto_open()
VBA_CODE = ActiveWorkbook.Name
If Left(VBA_CODE, 1) <> "N" Then Exit Sub

How to get Excel to require user to allow macro else cannot open workbook?

I have a macro in my Excel file that is meant to determine whether a user can open it or not. However, it seems like, depending on the settings of the user's machine, Excel by default disables the macro. This ended up opening and revealing the contents in the xls file.
How can I make sure that the user has to accept running the macro or Excel will close the workbook?
UPDATED the code as it was not doing exactly what it was meant to...
This is pretty much the only way you can do this WITH a macro (thanks to #OlleSjögren for the insight :p)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim Current As Worksheet
Worksheets.Add(Before:=Worksheets(1)).Name = "Protection"
Worksheets("Protection").Cells(1, 1) = "Please activate macros to view this workbook."
For Each Current In Worksheets
If Current.Name <> "Protection" Then
Current.Visible = xlSheetVeryHidden
End If
Next Current
End Sub
Private Sub Workbook_Open()
Dim Current As Worksheet
For Each Current In Worksheets
Current.Visible = xlSheetVisible
Next Current
Application.DisplayAlerts = False
Worksheets("Protection").Delete
Application.DisplayAlerts = True
End Sub
The property xlSheetVeryHidden means that it cannot be made visible through the UI (VBA code only can change it).
I think you can't do it. But we can make a workaround.
First of all you need to hide all your worksheet and prevent user to unhide it. Link. Following the link you will see that you can make a sheet veryHidden. As the link shows, you need to add a password to vba code too.
Then you can to create a macro that adds an InputBox with password
Sub CheckPassword()
Dim password As String
password = InputBox("Enter the password") 'You can use a Form with Textbox [PasswordChar] to put ****
If password = "myPass" Then
Sheets(3).Visible = xlSheetVisible
Sheets(3).Select
End If
End Sub
Finally you can attach a sub in the close event.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Sheets(3).Visible = xlSheetVeryHidden
End Sub

Open a workbook (mode automatic) by VBA command without recalculating it

In my VBA addin.xlam, I use workbooks.Open("C:\f.xlsm") to open workbook f.xlsm. The workbook calculation mode of f.xlsm is Automatic, thus I realize that everything in f.xlsm is recalculated automatically, after calling workbooks.Open("C:\f.xlsm"). But this is not what I want.
Is it possible to open a workbook by VBA command without refreshing it, even though the mode of the workbook is Automatic?
Edit 1:
I tried the idea #Ripster suggested:
1) I created a class model CExcelEvents in addin.xlam:
Private WithEvents App As Application
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
Application.Calculation = xlCalculationManual
End Sub
Private Sub Class_Initialize()
Set App = Application
End Sub
2) I linked CExcelEvents to the code in addin.xlam which opens f.xlsm:
Private XLApp As CExcelEvents
Sub try()
Set XLApp = New CExcelEvents
workbooks.Open ("C:\f.xlsm")
End Sub
Then, what try() does turns out to be first opening f.xlsm (which triggers automatic recalculation), then changing its calculation mode to manual. The workbook has been already re-calculated before changing the mode --- it is too late! Does anyone have any idea?
Try setting XLCalculation to Manual immediately before you open the workbook:
Sub try()
Application.Calculation = xlCalculationManual
workbooks.Open ("C:\f.xlsm")
End Sub