Consulting

Results 1 to 6 of 6

Thread: Force User to enable macro and still save

  1. #1

    Post Force User to enable macro and still save

    Hi everyone,


    I'm currently doing a timesheet module for work and am struggling with a bit of code.

    I have found here a bit of code which is perfect for what I want and need done but unfortunately it's interfering with other part of my code.

    I am using the following code to make people enable the macro:

    Option Explicit
    
    Const WelcomePage = "Macros"
    Private Sub Workbook_BeforeClose(Cancel As Boolean)
    'Turn off events to prevent unwanted loops
    Application.EnableEvents = False
    
    'Evaluate if workbook is saved and emulate default propmts
    With ThisWorkbook
    If Not .Saved Then
    Select Case MsgBox("Do you want to save the changes you made to '" & .Name & "'?", _
    vbYesNoCancel + vbExclamation)
    Case Is = vbYes
    'Call customized save routine
    Call CustomSave
    Case Is = vbNo
    'Do not save
    Case Is = vbCancel
    'Set up procedure to cancel close
    Cancel = True
    End Select
    End If
    
    'If Cancel was clicked, turn events back on and cancel close,
    'otherwise close the workbook without saving further changes
    If Not Cancel = True Then
    .Saved = True
    Application.EnableEvents = True
    .Close savechanges:=False
    Else
    Application.EnableEvents = True
    End If
    End With
    End Sub
    Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    'Turn off events to prevent unwanted loops
    Application.EnableEvents = False
    
    'Call customized save routine and set workbook's saved property to true
    '(To cancel regular saving)
    Call CustomSave(SaveAsUI)
    Cancel = True
    
    'Turn events back on an set saved property to true
    Application.EnableEvents = True
    ThisWorkbook.Saved = True
    End Sub
    Private Sub Workbook_Open()
    'Unhide all worksheets
    Application.ScreenUpdating = False
    Call ShowAllSheets
    Application.ScreenUpdating = True
    End Sub
    Private Sub CustomSave(Optional SaveAs As Boolean)
    Dim ws As Worksheet, aWs As Worksheet, newFname As String
    'Turn off screen flashing
    Application.ScreenUpdating = False
    
    'Record active worksheet
    Set aWs = ActiveSheet
    
    'Hide all sheets
    Call HideAllSheets
    
    'Save workbook directly or prompt for saveas filename
    If SaveAs = True Then
    newFname = Application.GetSaveAsFilename( _
    fileFilter:="Excel Files (*.xls), *.xls")
    If Not newFname = "False" Then ThisWorkbook.SaveAs newFname
    Else
    ThisWorkbook.Save
    End If
    
    'Restore file to where user was
    Call ShowAllSheets
    aWs.Activate
    
    'Restore screen updates
    Application.ScreenUpdating = True
    End Sub
    Private Sub HideAllSheets()
    'Hide all worksheets except the macro welcome page
    Dim ws As Worksheet
    
    Worksheets(WelcomePage).Visible = xlSheetVisible
    
    For Each ws In ThisWorkbook.Worksheets
    If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVeryHidden
    Next ws
    
    Worksheets(WelcomePage).Activate
    End Sub
    Private Sub ShowAllSheets()
    'Show all worksheets except the macro welcome page
    
    Dim ws As Worksheet
    
    For Each ws In ThisWorkbook.Worksheets
    If Not ws.Name = WelcomePage Then ws.Visible = xlSheetVisible
    Next ws
    
    Worksheets(WelcomePage).Visible = xlSheetVeryHidden
    End Sub
    ------


    When using this, unfortunately, it's then stopping my worksheet from being saved with the name I want it to have.

    When not using the veryhidden code it does it by using the following code:

    Public Sub Send_Email()
    On Error Resume Next
    Application.DisplayAlerts = False
    MkDir ("C:\Timesheets\")
    ActiveWorkbook.SaveAs "C:\Timesheets\" & Range("A3").Value & " " & Replace(Range("B3"), "/", "-") & ".xlsm"
    
    Dim linsOutlookApp As Object
    Dim linsMailItem As Object
    Dim lstrFileName As String
    Dim lstrOldFileName As String
    Dim MailAddress As String
    Dim CCMailAddress As String
    Dim MailSubject As String
    Dim EmailComments As Variant
    
    Sheets("Time Entry").Activate
    ActiveWorkbook.Save
    
    
    If MsgBox("Press OK to send email", vbOKCancel, "Email Confirmation") = vbOK Then
    
    
    Set linsOutlookApp = CreateObject("Outlook.Application")
    linsOutlookApp.Session.Logon
    Set linsMailItem = linsOutlookApp.CreateItem(0)
    
    linsMailItem.Attachments.Add ActiveWorkbook.FullName
    
    linsMailItem.Recipients.Add "myemail"
    
    linsMailItem.Subject = "Timesheet for " & Range("A3").Value & " for w/c " & (Range("B3").Value)
    linsMailItem.Body = "This file was sent automatically from Excel. " & _
    linsMailItem.DeleteAfterSubmit = False
    linsMailItem.Send
    
    Else: End
    End If
    End Sub
    ------

    I guess what I'm trying to get out of the help is:

    1 - I want to keep using my initial code "Veryhidden" so that the users must enable macros to use this spreadsheet other it will not do what's meant to
    2 - when I use the "veryhidden" bit of cade, my spreadsheet is using whatever name the spreadsheet has instead of renaming it according to the user that has input it's name and the date.



    Could someone please help me tie these two up?

    I need the veryhidden code to let my macro save the spreadsheet so it can then be sent with the right name and date.

    Thank you for all your help!

    Regards,

    Andre Bessa
    Last edited by SamT; 05-23-2015 at 09:06 AM.

  2. #2
    VBAX Mentor
    Joined
    Feb 2015
    Posts
    395
    Location
    I sense that you are in real danger of tying yourself up in knots if you are not careful.
    This all looks a bit too complicated and convoluted to me, so let's take a step back and find out what you are trying to achieve (ignoring all code for the moment)

    1. In very broad terms what is the user expected to do?
    Inputting time into a worksheet?

    2. What is it that you are trying to prevent them from doing?
    Amending the structure of the worksheet?
    Putting invalid entries into the worksheet?

    3. What is your concern about saving the file at the end of the process?
    Saving the file as the incorrect name?

    Is this close to the mark?

  3. #3
    Hi,

    Thank you so much for your reply Yondle!

    1. In very broad terms what is the user expected to do?

    The user is expected to open the workbook, enable macros e then fill in a timesheet with their name, date, customer name, time and whether this is chargeable work or not.

    Inputting time into a worksheet?

    Yes, the end-user will also be inputting time into the timesheet.

    2. What is it that you are trying to prevent them from doing?

    Previously the users have been inputting worng dates, misspelling their own names and various other things. This macro looks to do a spot check before it then send it to an email box with a reference to the name of the person that has filled this in and the date that they have chosen on the first input cell.

    Amending the structure of the worksheet?

    No, I can prevent this by protecting the sheet.

    Putting invalid entries into the worksheet?

    Yes, the above mentioned but more specific than just only dates here and text there...

    3. What is your concern about saving the file at the end of the process?

    The file needs to be saved so that when the user presses the send button, this contains the name of the person and the date (both taken from the spreadsheet the person filled in)

    Saving the file as the incorrect name?

    Currently it's not saving the file with any name as the "Veryhidden" code is cancelling regular saving and if I turn that off, the veryhidden code stops working.....

    HELP!!!

  4. #4
    VBAX Mentor
    Joined
    Feb 2015
    Posts
    395
    Location
    A few ideas for you to consider:

    Quick Summary
    My understanding is that the same master workbook format is used by lots of different users but it takes a unique name when saved by each user every day. There is a concern over the quality of the input, which in turn may affect the name of the file. In fact it is likely that users frequently over-write the masterfile and keep sending the same filename by email (ouch!)

    Suggestions
    On opening the file you could prevent access to any sheets (hide them) etc until a button is pressed (unhides them), and this will not work until macros are enabled.
    Userforms are the best way to tighten the quality of data entry by multiple users. You can make behaviour more predictable and force ALL the boxes to be completed - but you need to spend a bit of time creating them.
    If you do not want to create userforms then you can build a lot of control into the worksheets themselves.
    Comments below apply equally to userforms or direct input into worksheets.
    Obviate a lot of your difficulties by using the power of Excel to monitor input (and prevent invalid data)

    Validate data entry - HOW?
    Add a (protected and hidden) Control Sheet in the workbook with key validation data such as
    - List of user names
    - List of customer names
    and use dropdown boxes permitting only these values in cells where input required
    (But what if a new customer after workbook sent out: drop-down includes CUSTOMER NOT LISTED - and allow entry in cell below where they can type in any name, same approach would apply to a new employee)
    - The date box could default to the current day, or perhaps drop-down with word "Today" (which Excel would interpret as today's date), "Yesterday" and a list of all other recent dates to allow input if not done on correct day - here I would ask user enter the date at the beginning of the input and again further down and put an error message to screen if the 2 answers differ - wakes them up!)
    - dropdown options Yes/No in "chargeable " box

    Time input
    - a bit more difficult to control quality of input here, especially if allocating time between various boxes
    - start and finish times better than hours worked
    - perhaps some idiot checks such as maximum number of hours etc or force user to confirm anything that looks peculiar based on logic checks

    Saving the file
    - if the user name has been correctly "validated" and the date made as idiot-proof as possible, then the name that is auto-generated should also be valid (most of the time) and by putting the appropriate code into a "before close" sub - this can be used to force the file to be saved in the manner you want with the name you want. You can also prevent the masterfile name being used to save the file - thus making it impossible to overwrite.

    Hopefully that has provided some "food for thought".
    Last edited by Yongle; 05-22-2015 at 10:11 AM.

  5. #5
    VBAX Mentor
    Joined
    Feb 2015
    Posts
    395
    Location
    Attached is a file which illustrate some of the above (the basic stuff) - nothing fancy.
    As I said previously, I would use UserForms but for the moment this will give you an idea of how easy it is to improve accuracy

    Controls are exercised via mixture of hidden worksheets, data validation checks, and macros to take user to next step. To avoid confusion you need unique user and customer numbers - duplicate name problems otherwise.

    Various input boxes have DropDowns - change a few (I have not cleared them out, but the user would just see blanks to start with)
    See what happens when you change Customer to New Customer
    See what happens when you select any customer other than New Customer and try to type a name in the new customer box

    First time just open the file and just follow the instructions (amend a couple of fields) including closing the file (it will fail to save unless you have a D drive, but there is a message box that tells you where it wants to save to, and you can change the path etc after first run!)

    This macro (which acts when workbook is opened every time) hides all sheets except one which leaves the user in no doubt what he must do
    Private Sub Workbook_Open()
    Worksheets("Welcome").Visible = True
    Worksheets("DirectEntry").Visible = False
    Worksheets("Control").Visible = False
    End Sub
    This macro controls things when user finishes inputting
    Sub CloseFile()
    Dim FilePath As String
    Dim FileName As String
    Dim FullPath As String
    
    
    With Sheets("DirectEntry")
    FileName = .Range("B2").Value & " " & .Range("D4").Value & ".xlsm"
    End With
    
    
    FilePath = "D:\Documents\"
    FullPath = FilePath & FileName
    MsgBox "File will be saved as " & FullPath
    ActiveWorkbook.SaveAs FullPath
    
    
    Application.DisplayAlerts = False
    ActiveWorkbook.Close
    Application.DisplayAlerts = True
    End Sub
    Attached Files Attached Files

  6. #6
    Moderator VBAX Sage SamT's Avatar
    Joined
    Oct 2006
    Location
    Near Columbia
    Posts
    7,814
    Location
    Note that I have not read all the code, questions, or responses in the entire thread. However, in re, Hidden code...

    Why not just put all the code possible* in modules, then protect the Project with a password.

    *By using Application level Events, you might put all the code in one or more modules.
    I expect the student to do their homework and find all the errrors I leeve in.


    Please take the time to read the Forum FAQ

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •