IntroductionGetting StartedAll PostsNotesAbout The Author
Requesting, Storing, And Retrieving User Settings
Friday, October 02, 2009 - 3:44 PM

This particular code was written for use in an email attachment that was essentially part of the UI for a larger application, but it can also be used for a main UI. Externally storing settings for a main UI makes it possible for mutliple users to use the same file or copies of the same file to ease development. Some developers prefer to store settings in the registry, but having had bad experiences with registries, I prefer to store settings in a workbook located in a hidden folder.



This goes in a Module (mine is called 'mWorkbook'):

Option Explicit
Option Base 1


Public Sub myWBBeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
 If (Left(ActiveSheet.Name, 5) = "Sheet") Then ShowUI (True): Exit Sub 'blank form, opened by main ss
 Dim subN&:  subN = SubStart(Updating, Events, , , , PrimaryCall)
   
    'check if this is the blank form, opened by main ss
    If (Left(ActiveSheet.Name, 5) = "Sheet") Then GoTo ExitNow
   
    If ThisWorkbook.Sheets("UserNames").Range("PathAvailable") Then SaveComments

'    'this is for sending file as an attachment
'    With ThisWorkbook.Sheets("UserNames").Range("PathAvailable")
'        'test comments path again
'        If Not .Value Then TestCommentsPath
'        'save comments if path is available
'        If .Value Then Call SaveComments
'    End With
   
    'if saved to temporary directory
    With ThisWorkbook.Sheets("UserNames")
        If Not SaveAsUI Then
            If Not .[PromptUserSave_ReturnValue] Then
                If (Left(ThisWorkbook.Path, 7) = "C:\Temp") Then
                    'user canceled SaveAs, so don't prompt again
                    If Not fPromptUserSave Then .[PromptUserSave_ReturnValue] = True
                ElseIf (Left(ThisWorkbook.Path, Len(.[MainPath])) = .[MainPath]) Then
                    'user canceled SaveAs, so don't prompt again
                    If Not fPromptUserSave Then .[PromptUserSave_ReturnValue] = True
                End If
            End If
        End If
    End With
   
ExitNow:
 SubEnd (subN)
End Sub


Public Sub myWBOpen()
 If (Left(ActiveSheet.Name, 5) = "Sheet") Then ShowUI (True): Exit Sub 'blank form, opened by main ss
 Dim subN&:  subN = SubStart(Updating, Events, Warnings, , , (Left(ActiveSheet.Name, 5) <> "Sheet")) 'events should be supressed when this is opened by main wb, but testing sheet name just to be sure
   
    'hide comments column if path not accessible
    TestCommentsPath 'not necessary when file accessed directly via a link rather than as attachment
   
    Dim tempStr$:  tempStr = GetStoredPath
   
    If TestLen(tempStr) Then
        If (ThisWorkbook.Path <> tempStr) Then
            If (MsgBox("Save to your default directory (" & tempStr & ")?", vbYesNo, "") = vbYes) Then
                If FileFolderExists(tempStr) Then
                    ThisWorkbook.SaveAs tempStr & "\" & ThisWorkbook.Name
                Else
                    MsgBox ("Your default path (" & tempStr & ") is not available.")
                    DeleteHiddenFile
                    fPromptUserSave
                End If
            ElseIf (MsgBox("Reset your default directory (" & tempStr & ")" & Chr(10) & _
                    "(Answer 'No' if you wish to opt out of using a default directory)", vbYesNo, "") = vbYes) Then
                DeleteHiddenFile
            ElseIf (MsgBox("Do you wish to opt out of using a default directory?", vbYesNo, "") = vbYes) Then
                MsgBox ("If you wish to undo this action in the future, please let us know.")
                StoreUserPath ("")
            End If
        End If
    Else
        fPromptUserSave
    End If

    Dim Region$, RegionMap, ws, i&, tempStr$, tempPath$, tempVar
    Set RegionMap = CreateObject("Scripting.Dictionary")

    With RegionMap
        .Add "0", "ALL Regions"
        .Add "1", "Region 1"
        .Add "2", "Region 2"
        .Add "3", "Region 3"
        .Add "4", "Region 4"
        .Add "5", "Region 5"
        .Add "6", "Region 6"
        .Add "7", "Region 7"
    End With
    tempStr = vbNullString
    For i = 0 To RegionMap.Count - 1
        tempStr = tempStr & i & " = " & RegionMap(CStr(i)) & Chr(10)
    Next

    tempPath = GetMyDocumentsPath & "\My Program Data"
    If Not FileFolderExists(tempPath) Then MkDir tempPath
    tempPath = tempPath & "\HiddenFile.xls"

    If FileFolderExists(tempPath) Then
        Workbooks.Open Filename:=tempPath
        If Not IsNumeric(Cells(1, 1)) Then
InputAgain1:
            Cells(1, 1) = InputBox("Please input your region:" & Chr(10) & tempStr & Chr(10) & Chr(10) & _
                "This is a permanent selection. To reset your selection later, ask us for assistance.", "", 0)
            If Not IsNumeric(Cells(1, 1)) Then
                MsgBox ("Please enter a numeric value between 0 and " & RegionMap.Count - 1 & ".")
                GoTo InputAgain1
            ElseIf (Cells(1, 1) > RegionMap.Count - 1) Or (Cells(1, 1) < 0) Then
                MsgBox ("Please enter a numeric value between 0 and " & RegionMap.Count - 1 & ".")
                GoTo InputAgain1
            ElseIf ((Cells(1, 1) \ 1) <> Cells(1, 1)) Then 'not a whole number - backslash with 1 is equivalent to rounding to integer
                MsgBox ("Please enter a numeric value between 0 and " & RegionMap.Count - 1 & ".")
                GoTo InputAgain1
            End If
        End If
    Else
        Workbooks.Add
InputAgain2:
        Cells(1, 1) = InputBox("Please input your region:" & Chr(10) & tempStr, "", 0)
        If Not IsNumeric(Cells(1, 1)) Then
            MsgBox ("Please enter a numeric value between 0 and " & RegionMap.Count - 1 & ".")
            GoTo InputAgain2
        End If
        ActiveWorkbook.SaveAs tempPath
    End If
    Region = RegionMap(CStr(Cells(1, 1)))
    ActiveWorkbook.Close

    If Not (Region = "ALL Regions") Then
        Region = UCase(Left(Region, InStr(Region, " ") - 1))
        For Each ws In ThisWorkbook.Sheets
            If (InStr(ws.Name, Region) = 0) And (InStr(UCase(ws.Name), "BREAKS") = 0) Then
                If (Left(ws.Name, 5) = "Sheet") Then GoTo ExitNow 'must be editting the form (EmailForm.xls)
                ws.Visible = 0
            End If
        Next
    End If

    ShowUI (False)

ExitNow:
 SubEnd (subN)
End Sub


Private Function fPromptUserSave(Optional inPath$) As Boolean
 Dim subN&:  subN = SubStart(NoWarnings:=Warnings)
   
    Dim sPath$, StoredPath$, RetVal As Boolean
   
    Dim tempStr$, OriginalDir$:  OriginalDir = CurDir
    If TestLen(inPath) Then sPath = inPath Else StoredPath = GetStoredPath: sPath = StoredPath
    'use your own path here
    If Not TestLen(sPath) Then sPath = "C:\Desktop"
    tempStr = Left(sPath, 1)
    ChDrive tempStr
    sPath = sPath & "\" '& ThisWorkbook.Name
    ChDir sPath
   
    sPath = sPath & ThisWorkbook.Name
           
    On Error Resume Next
    If (ThisWorkbook.Path & "\" & ThisWorkbook.Name <> sPath) Then
        If FileFolderExists(sPath) Then SetAttr sPath, vbNormal:  Kill sPath
    End If
    ThisWorkbook.SaveAs sPath
    RetVal = Application.Dialogs(xlDialogSaveAs).Show(sPath)
    If (ThisWorkbook.Path & "\" & ThisWorkbook.Name <> sPath) Then
        If FileFolderExists(sPath) Then SetAttr sPath, vbNormal:  Kill sPath
    End If
    On Error GoTo 0

    If Not TestLen(StoredPath) And RetVal Then
        If (Left(sPath, Len(Sheets("UserNames").[MainPath])) <> Sheets("UserNames").[MainPath]) Then
            If (Len(CurDir) > 3) Then
                If (MsgBox("Do you want to store this path (" & CurDir & _
                            ") as your default directory for this report?", vbYesNo, "") = vbYes) Then
                    StoreUserPath (CurDir)
                ElseIf (MsgBox("Do you wish to opt out of using a default directory?", vbYesNo, "") = vbYes) Then
                    MsgBox ("If you wish to undo this action in the future, please let us know.")
                    StoreUserPath ("")
                End If
            End If
        End If
    End If
    fPromptUserSave = RetVal

    ChDir OriginalDir

 SubEnd (subN)
End Function


Private Function DeleteHiddenFile()

    Dim sPath$:  sPath = GetMyDocumentsPath & "\T+1 Report Data\HiddenFile.xls"
    If FileFolderExists(sPath) Then
        SetAttr sPath, vbNormal:  Kill sPath
    End If
   
End Function


Private Function GetStoredPath$()
'cells(1,1) = region
'cells(2,1) = path

    Dim sPath$:  sPath = GetMyDocumentsPath & "\T+1 Report Data\HiddenFile.xls"
   
    If FileFolderExists(sPath) Then
        Workbooks.Open sPath
        GetStoredPath = Cells(2, 1)
        ActiveWorkbook.Close
    Else
        GetStoredPath = ""
    End If

End Function


Private Sub StoreUserPath(SelectedPath$)
'cells(1,1) = region
'cells(2,1) = path

    Dim tempPath$:  tempPath = GetMyDocumentsPath & "\T+1 Report Data"
    If Not FileFolderExists(tempPath) Then MkDir tempPath
    tempPath = tempPath & "\HiddenFile.xls"

    If FileFolderExists(tempPath) Then
        Workbooks.Open Filename:=tempPath
        Cells(2, 1) = SelectedPath
    Else
        Workbooks.Add
        Cells(2, 1) = SelectedPath
        ActiveWorkbook.SaveAs tempPath
    End If
    ActiveWorkbook.Close

End Sub


Private Sub TestCommentsPath()

    On Error Resume Next
   
    With ThisWorkbook.Sheets("UserNames")
        If FileFolderExists(.Range("MainPath")) Then
            'path for comment CSV file is available
            .Range("PathAvailable") = True
        Else
            'path not accessible from user's account or location
            HideNewCommentsCol
            .Range("PathAvailable") = False
        End If
    End With
   
End Sub


Private Sub HideNewCommentsCol()
'this is called if comments path is not accessilbe, bc user won't be able to enter new comments

    Dim ws, tempVar, ActiveWS$:  ActiveWS = ActiveSheet.Name
    For Each ws In ThisWorkbook.Sheets
        If ws.Visible And (ws.Name <> "SUMMARY") Then
            With ws
                tempVar = cMatch("NEW COMMENT", .Name)
                If IsNumeric(tempVar) Then
                    .Columns(tempVar).Hidden = 1
                End If
            End With
        End If
    Next
    If (ActiveSheet.Name <> ActiveWS) Then Sheets(ActiveWS).Select

End Sub


Private Sub ShowUI(Show As Boolean)
'hide/show some of Excel's UI

    If (ActiveWorkbook.Name = ThisWorkbook.Name) Then
        With ActiveWindow
            If (CountVisibleSheets = 1) Then
'optional:
''                .DisplayWorkbookTabs = 0
            Else
                .DisplayWorkbookTabs = 1
            End If
            .DisplayHorizontalScrollBar = Show
            .DisplayVerticalScrollBar = Show
        End With
    End If
    With Application
'optional:
''        .DisplayFullScreen = Not Show
''        .DisplayFormulaBar = Show
'        .DisplayStatusBar = Show
        .ShowStartupDialog = Show
        .ShowWindowsInTaskbar = Show
        .CommandBars("Reviewing").Visible = 0
        .CommandBars(2).Visible = Show
    End With

End Sub


Private Function CountVisibleSheets() As Byte
    Dim ws
    For Each ws In ThisWorkbook.Sheets
        If ws.Visible Then CountVisibleSheets = CountVisibleSheets + 1
    Next
End Function


Private Function GetMyDocumentsPath$()
    On Error GoTo NotFound
    GetMyDocumentsPath = Environ("UserProfile") & "\My Documents" 'use hidden "my documents" folder
    Exit Function
NotFound:
    'set path here
    GetMyDocumentsPath = "C:\" 'use regular "my documents" folder instead
End Function



This goes in the Workbook object:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    Call myWBBeforeSave(SaveAsUI, Cancel)
End Sub

Private Sub Workbook_Open()
    Call myWBOpen
End
Sub

Private Sub Workbook_WindowActivate(ByVal Wn As Window)
    ShowUI (False)
End Sub
 
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
    If Range("ShowNumbersAsTextErrors") Then Application.ErrorCheckingOptions.NumberAsText = 1
    ShowUI (True)
End Sub

<< Navigate to Friday, October 02, 2009 Add New Comment
No records found        
Add New Comment
Your name   
Subject   
Content   
*Required fields

January, 2009
February, 2009
March, 2009
April, 2009
May, 2009
June, 2009
July, 2009
August, 2009
September, 2009
October, 2009
November, 2009
December, 2009
IntroductionGetting StartedAll PostsNotesAbout The Author