BeforeClose will not close my Excel-Sheet VBA - vba

So I have been trying to put together a little Excel sheet, that has an entry Log in it. So whenever the sheet is closed, Name, Date and Time are added.
So basically I have three macro running, I will only mention two. The main macro will ask if I want to close the sheet and I will have to answer with yes or no. This works fine. If I press yes the main macro will call a sub macro, that will ask me to enter a string. If this Inputbox is empty or the entry is canceled, I want the main sub to stop running and cancel the Close process. Which won't seem to work. The error in the code to me seems pretty clear, but I don't know how to prevent it and find a better solution. If you could help me come up with a solution I would really appreciate it.
This line of code seems to be the problem:
If Cancel_Button_LOG = False Then Cancel = True
Here I will add compressed versions of the two macros
Public Sub Add_Entry_to_Log()
Dim i As Integer
Dim response As Variant
Cancel_Button_LOG = True
response = InputBox("Please enter your Name", "Name")
If response <> "" Then
Else
Cancel_Button_LOG = False
MsgBox "Please enter your name", vbExclamation + vbOKOnly, "Name"
End If
Worksheets("Log").Protect "secret"
ThisWorkbook.Save
End Sub
Now I will want to use the Cancel_Button_log Variable to cancel the main sub:
Dim answer As Variant
answer = MsgBox("Are your sure you want to close the workbook?", vbYesNo) Cancel = False
Select Case answer
Case Is = vbYes
Worksheets("Log").Unprotect "secret"
Call Test
Call Add_Entry_to_Log
If Cancel_Button_LOG = False Then Cancel = True
Worksheets("Log").Protect "secret"
Case Is = vbNo
Cancel = True
End Select
ThisWorkbook.Save
End Sub

I think you're doing this in the most complicated way possible. If I understand your requirements correctly - you can replace all your code in your ThisWorkbook module with something like this:
Const WB_LOG As String = "Log" '// name of sheet that the log is in
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If MsgBox("Do you really want to close the workbook?", vbYesNo) = vbYes Then
With Sheets(WB_LOG)
.Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Resize(1, 2).Value = Array(Environ$("USERNAME"), Now)
End With
ThisWorkbook.Save
Else
Cancel = True
End If
End Sub
Private Sub Workbook_Open()
With Sheets(WB_LOG)
.Protect Password:="secret", UserInterfaceOnly:=True
.Range("A1:B1").Value = Array("USERNAME", "TIMESTAMP")
End With
End Sub
This would negate the need for the user to manually insert their name (assuming their system username would suffice*) and also negate the need to unprotect the worksheet each time as I've used the UserInterfaceOnly option.
* Environment variables such as %USERNAME% can be falsified if a user wishes to do so and knows how - however someone typing their name into a textbox is even easier to falsify...

Related

AutoClose macro..ending closing action based on answer without save prompt

I have a word document with field in the end of the document to update filepath, last saved date & last save by. I need these to update on the closing of the file.
I am running an Autoclose macro that updates the fields. The problem is that I need the workbook to save BEFORE these fields are updated, so the last save date and the last save by will update.
I am going to recreate the "Would you like to save changes" message box at the start of the macro, with a yes/no/cancel option. I have 2 questions
1- If the user says No or Cancel..how do I suppress the system generated Would you like to save to avoid a repeat of the same question (or pass along their response to my version of the question to the system so they don't see it)
2 - If the pick cancel, how do I stop the system action of closing the file?
What i have below I found online , the sendkeys (ESC) is not stopping the system close.`
Sub AutoClose()
'if the document is already saved
If ActiveDocument.Saved = True Then
'update all fields, save, close without prompt
Else
'which would be the document's status is not saved
answer = MsgBox("Yes No Cancel Example", vbYesNoCancel)
'above is do you want to save
If answer = vbYes Then
MsgBox "Yes"
ElseIf answer = vbNo Then
'dont save, dont update, close file without prompt
Else
'this is the cancel, so dont update, dont close
ActiveDocument.Saved = True
SendKeys "{ESC}"
End If
End If
End Sub
Perhaps:
Sub AutoClose()
Application.ScreenUpdating = False
Dim Rslt
With ActiveDocument
If .Saved = True Then
Call UpdateFields
.Save
Else
Rslt = MsgBox("Save changes and close, or discard changes and close?", vbYesNoCancel)
If Rslt = vbYes Then
Call UpdateFields
.Save
ElseIf Rslt = vbNo Then
.Saved = True
Else
Call UpdateFields
Application.ScreenUpdating = True
Exit Sub
End If
End If
End Sub
Sub UpdateFields()
With ActiveDocument
.Fields.Update
.PrintPreview
.ClosePrintPreview
End With
End Sub

VBA Access Message Box woes

I followed a few simple comments on how to pop a confirmation box before executing a script, but sadly, if I press yes, the script doesn't run.
Private Sub Overwrite_Btn_Click()
If MsgBox("Yes?", vbOKCancel) = ok Then
Me.Product_Quantity = Me.Quantity_Input
Else
Exit Sub
End If
End Sub
I'm trying to set Product_Quantity equaling Quantity_Input, and although it works without the MsgBox command, it doesn't with it.
What am I doing wrong?
Instead of If MsgBox("Yes?", vbOKCancel) = ok Then try: If MsgBox("Yes?", vbOKCancel) = vbOK Then
Typically the interactions with forms will return one constant from a set of several constants. Those are catalogged in enums. In this case you have several constants in the VbMsgBoxResult class, and vbOK is a constant with value 1, which is returned from clicking the ok button.
Actually, If MsgBox("Yes?", vbOKCancel) = 1 Then would work as well, but it is harder to remember that clicking Ok returns 1 then simply stating a constant named vbOK
In object explorer (F2 on the VBE), searching for VbMsgBoxResult will give all possible results that comes from interacting with a message box.
https://www.techonthenet.com/access/constants/msgbox_ret.php
1) Dim a variable as integer.
2) Check for value of integer equal to 6, or check for vbYess
3) ?????
4) Profit
borrowed from link
Dim LResponse As Integer
LResponse = MsgBox("Do you wish to continue?", vbYesNo, "Continue")
If LResponse = vbYes Then
{...statements...}
Else
{...statements...}
End If
Single line:
If MsgBox("Yes?", vbOKCancel) <> vbOk then Exit Sub
'continue code here.
More Information:
MSDN : MsgBox Function (Office/VBA)

VBA excel printing to printer with user form

I have a userform, that when filled out, has a command button at the bottom. When the button is clicked, it copies the data to worksheet2, and then copies the row information into worksheet 4, which is a form, closes the userform.and opens up the welcome userform then i want it to print worksheet4.
Here is the code I have. The print function will not work.
Private Sub SavePrintButton_Click()
EditAdd
Sheet4.Activate
Dim myValue As Variant
myValue = TextBox1.Value
Range("b2").Value = myValue
Unload Me
Function PrintOneSheet()
Sheets("Sheet4").PrintOut
End Function
WelcomeUserForm.Show
End Sub
Your "PrintOneSheet" function is embedded in SavePrintButton_Click. Move the "end sub" after "unload me" and insert "call PrintOneSheet" above "unload me". I've taken the liberty of adding a "Me.Hide" line since you apparently want the current form to go away before you show WelcomeUserForm. It still gets unloaded once it's not needed. Meantime if for any reason you want to go back to it to correct something, you can do so by simply showing it again.
Private Sub SavePrintButton_Click()
Dim myValue As Variant
EditAdd
Sheet4.Activate
myValue = TextBox1.Value
Sheet4.Range("b2").Value = myValue
Call PrintOneSheet
Me.Hide
WelcomeUserForm.Show
Unload Me
End Sub
Function PrintOneSheet()
Sheets("Sheet4").PrintOut
End Function
On another note, is Sheet4 always going to be called "Sheet4"? Sheet4 is a direct call to the object id, "Sheet4" is a call to one of its properties (its name). You should be consistent in your references or someday you'll change something apparently minor and chaos will break loose.
I have reworked the code a bit. Does this look more like it should? I got rid of all unload.me in my vba.
Private Sub SavePrintButton_Click()
EditAdd
Sheet6.Activate
Dim myValue As Variant
myValue = TextBox1.Value
Range("b2").Value = myValue
ClearForm
Me.Hide
Sheet6.PrintOut
WelcomeUserForm.Show
MsgBox "New Run Added"
MsgBox "Run Sent to Printer"
End Sub

Mandatory fields red. Now how to save?

What it does: Requires fields from users. Blocks user from saving if specific fields are missing. Turns those fields red until saved correctly.
What I need: Well, how the hell am I supposed to save this...
What I would like: Since the worksheet is blank. I cannot save. and required fields are red. EVEN if I could save I would LIKE the cells to be on no fill until I roll it out.
View Original Post Here
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim xlSht As Worksheet
Dim cellsNotPopulated As Boolean
cellsNotPopulated = False
Set xlSht = ThisWorkbook.Worksheets("1st Call")
With xlSht
If .Range("F7") = "" Then
.Range("F7").Interior.Color = RGB(255, 0, 0)
cellsNotPopulated = True
Else
.Range("F7").Interior.ColorIndex = xlNone
End If
End With
If cellsNotPopulated = True Then
MsgBox "Please review the highlighted cells and ensure the fields are populated."
Cancel = True
End If
End Sub
If you are in the middle of development and want to "break the rules" and save your current efforts, then in a standard module:
Sub MyPrivateSave()
Application.EnableEvents = False
ThisWorkbook.Save
Application.EnableEvents = True
End Sub
Of course, when you finish development, you would remove this little "save tool" before you send the workbook out to the users.
or add as the first line if environ("Username")=your username then exit sub

How to select certain options from an alert in VBA

I have a macro that calls a number of other macros which work fine, but I would like to make it more automated - at the moment it requires users to click 'Yes' or 'No' or other similar options as the macro runs.
A sample is below:
Sheets("Macro").Select
Sheets("Hidden").Visible = True
Application.ScreenUpdating = False
Application.DisplayAlerts = False
intList = MsgBox("HerpDerp?", vbYesNo + vbQuestion)
If intList = vbNo Then Exit Sub
If (Range("asd").Value = "sdf" Or Range("asd").Value = "dfg") Then
othermacro1
othermacro2
Else
othermacro3
othermacro4
End If
Sheets("Macro").Select
Application.DisplayAlerts = True
Sheets("Hidden").Visible = False
MsgBox "DerpHerp", vbInformation + vbOKOnly, "Save"
End Sub
Through troubleshooting I would have thought that setting alerts to automatically not display this would circumvent the problem, but users need to click more divers buttons than 'yes' or 'no' in order to continue with the macro, which may be why this is occurring (though I would have anticipated that this would just make the alert not appear...).
Any help on this would be greatly appreciated and any additional info required can easily be supplied.
Thanks in advance for the help!
Check this sample code and hope this helps you:
Source Code:
Sub MsgBoxDemo()
Dim Answer As Long
Answer = MsgBox("Select Yes or No", vbExclamation + vbYesNo, "Reply")
If Answer = vbYes Then
MsgBox "Yes"
End If
If Answer = vbNo Then
MsgBox "No"
End If
End Sub