Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel VBA - always show worksheet on open

Tags:

excel

vba

How can the following conditions be met with VBA code?

  1. A particular worksheet is always displayed on open, even if the worbook is opened without enabling macros.
  2. A workbook user may save the workbook while working on any worksheet.
  3. The save must not interfere with the user - no navigating away to a different sheet, no messageboxes, etc.
  4. The regular save functions (Ctrl-S, clicking Save) must remain available and when used must obey the criteria above.

I'd like to avoid the attempted solutions I've listed at the bottom of this question.

Details:
The workbook is created using Office 2007 on a Windows 7 machine. It is an .xlsm workbook with 2 worksheets, "Scheduler" and "Info." Sheet tabs are not visible. Not all users will enabled macros when the workbook is opened.

Upon opening the workbook, a user will only be exposed to one sheet as follows:

  • "Info" shows up if macros are disabled, and basically tells anyone who opens the workbook that macros need to be enabled for full workbook functionality. If macros are enabled at this point, "Scheduler" is activated.
  • "Scheduler" is where data is stored and edited, and is automatically shown if macros are enabled. It is not presented to the user when the workbook is opened without macros enabled.

"Info" must show up first thing if the workbook is opened and macros are disabled.

Attempted Solutions (I'm looking for better solutions!):

  • Placing code in the Workbook.BeforeSave event. This saves with "Info" activated so it shows up when the workbook is opened. However, if the user is in "Scheduler" and not done, I cannot find a way in this event to re-activate "Scheduler" after the save.
  • Using Application.OnKey to remap the Ctrl-s and Ctrl-S keystrokes. Unfortunately this leaves out the user who saves using the mouse (clicking File...Save or Office Button...Save).
  • Checking during every action and if needed activating "Scheduler". In other words, inserting code in something like the Workbook.SheetActivate or .SheetChange events to put "Scheduler" back into focus after a save with "Info" activated. This runs VBA code constantly and strikes me as a good way to get the other code in the workbook into trouble.
  • Placing code in the Worksheet("Info").Activate event, to change focus back to "Scheduler". This leads to the result of "Scheduler", not "Info", showing when the workbook is opened, even with macros disabled.
like image 688
Aaron Thomas Avatar asked Dec 16 '22 05:12

Aaron Thomas


2 Answers

Will this not work? Updated to handle Saving gracefully

Private Sub Workbook_Open()
    ThisWorkbook.Worksheets("Scheduler").Activate
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    ThisWorkbook.Worksheets("Info").Activate
    If (ShouldSaveBeforeClose()) Then
        Me.Save
    Else
        Me.Saved = True ' Prevents Excel Save prompt.
    End If
End Sub

Private Function ShouldSaveBeforeClose() As Boolean
    Dim workbookDirty As Boolean
    workbookDirty = (Not Me.Saved)
    If (Not workbookDirty) Then
        ShouldSaveBeforeClose= False
        Exit Function
    End If

    Dim response As Integer
    response = MsgBox("Save changes to WorkBook?", vbYesNo, "Attention")
    ShouldSaveBeforeClose= (response = VbMsgBoxResult.vbYes)
End Function
like image 142
nunzabar Avatar answered Dec 30 '22 14:12

nunzabar


I don't have time to test this out, but you might be able to do this using Application.OnTime in your BeforeSave event handler. Something like:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    Dim objActiveSheet
    Set objActiveSheet = Me.ActiveSheet
    If objActiveSheet Is InfoSheet Then Exit Sub
    If Module1.PreviousSheet Is Nothing Then
        Set Module1.PreviousSheet = objActiveSheet
        InfoSheet.Activate
        Application.OnTime Now, "ActivatePreviousSheet"
    End If
End Sub

Then in Module1:

Public PreviousSheet As Worksheet

Public Sub ActivatePreviousSheet()
    If Not PreviousSheet Is Nothing Then
        PreviousSheet.Activate
        Set PreviousSheet = Nothing
    End If
End Sub
like image 20
Joe Avatar answered Dec 30 '22 15:12

Joe