hiding and unhiding columns based on a user

gvanhook
StarLounger
Posts: 67
Joined: 22 Feb 2010, 20:15
Location: Indiana

hiding and unhiding columns based on a user

Post by gvanhook »

Greetings Loungers!
I am working on a project for a colleague and it has me baffled on how to proceed. Basically what I need to do is create a userform that collects log in information (user and password) and based on the user unhide certain columns in a spreadsheet. I have never used a userform before and the examples I have looked at are not quite fitting my needs. For the most part the users will need to only view the column that is theirs, but there are a handful of users that will also need to edit column(s).
I have the following code that I am trying to modify but am being very unsuccessful. The original code was designed to hide or unhide entire sheets, but I just want to hide or unhide specific columns.
Any assistance would be appreciated. I have attached a sanitized copy of the sheet.

Thanks,
Greg

Code: Select all

Private Sub UserForm_Click()
Dim bOK2Use As Boolean

Private Sub btnOK_Click()
    Dim bError As Boolean
    Dim sSName As String
    Dim p As DocumentProperty
    Dim bSetIt As Boolean

    bOK2Use = False
    bError = True
    If Len(txtUser.Text) > 0 And Len(txtPass.Text) > 0 Then
        bError = False
        Select Case txtUser.Text
            Case "user1"
                If txtPass.Text <> "u1pass" Then bError = True _
                Else
                    Columns("D").Hidden = False
            Case "user2"
                sSName = "u2sheet"
                If txtPass.Text <> "u2pass" Then bError = True
            Case Else
                bError = True
        End Select
    End If
    If bError Then
        MsgBox "Invalid User Name or Password"
    Else
'        'Set document property
        bSetIt = False
        For Each p In ActiveWorkbook.CustomDocumentProperties
            If p.Name = "auth" Then
                p.Value = sSName
                bSetIt = True
                Exit For
            End If
        Next p
        If Not bSetIt Then
            ActiveWorkbook.CustomDocumentProperties.Add _
              Name:="auth", LinkToContent:=False, _
              Type:=msoPropertyTypeString, Value:=sSName
        End If

        Columns(sSName).Hidden = False

        bOK2Use = True
      Unload UserForm1
    End If
End Sub

Private Sub UserForm_Terminate()
    If Not bOK2Use Then
        ActiveWorkbook.Close (False)
    End If

End Sub
You do not have the required permissions to view the files attached to this post.

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

You should remove the line "Private Sub UserForm_Click()", it is the first line of a Sub but there is no corresponding End Sub

If the name entered by the user is "user1" and the password is OK, you try to unhide column D but this fails because the worksheet is protected.
And you don't set the value of sSName, so the line

Columns(sSName).Hidden = False

will fail even if the sheet is not protected.

If the name entered by the user is "user2" and the password is OK, you set the value of sSName to "u2sheet". This will also cause the line

Columns(sSName).Hidden = False

to fail even if the sheet is not protected, because "u2sheet" is not a valid column.

Can you explain what exactly you wanted to happen here?

If you want to unhide columns, you must unprotect the sheet first, and reprotect it afterwards.
Best wishes,
Hans

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

One other thing: your userform is not named UserForm1, so the line

Unload UserForm1

will fail. Change it to

Unload Me

Me refers to the userform running the code, regardless of its name.
Best wishes,
Hans

gvanhook
StarLounger
Posts: 67
Joined: 22 Feb 2010, 20:15
Location: Indiana

Re: hiding and unhiding columns based on a user

Post by gvanhook »

I have taken another stab at it.
The results I am looking for are that if the name entered is gvanhook and the password is OK, then unhide column D. I have put code around the unhide line to unprotect and then reprotect the code but now I am getting a compile error "Case without Select Case".

Code: Select all

Private Sub btnOK_Click()
    Dim bError As Boolean
    Dim sSName As String
    Dim p As DocumentProperty
    Dim bSetIt As Boolean
    

    bOK2Use = False
    bError = True
    If Len(txtUser.Text) > 0 And Len(txtPass.Text) > 0 Then
        bError = False
        Select Case txtUser.Text
            Case "gvanhook"
                If txtPass.Text <> "gvanhook" Then bError = True _
                Else
                   Worksheets("Project Progress").Activate
                   If ActiveSheet.ProtectContents Then
                   ActiveSheet.Unprotect ("ross")
                   Columns("D").Hidden = False
                   ActiveSheet.Protect ("ross")
                    
             Case "user2"
                If txtPass.Text <> "u2pass" Then bError = True _
                 Else
                   Worksheets("Project Progress").Activate
                   If ActiveSheet.ProtectContents Then
                   ActiveSheet.Unprotect ("ross")
                   Columns("E").Hidden = False
                   ActiveSheet.Protect ("ross")
            Case Else
                bError = True
        End Select
    End If
    If bError Then
        MsgBox "Invalid User Name or Password"
    Else

        bOK2Use = True
      Unload Me
    End If
End Sub

Private Sub UserForm_Terminate()
    If Not bOK2Use Then
        ActiveWorkbook.Close (False)
    End If

End Sub

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

The error message is somewhat misleading - you're actually missing a few End Ifs.

Here is a slightly streamlined version of btnOK_Click: by reversing the logic for bError, you can omit the Case Else part.

Code: Select all

Private Sub btnOK_Click()
    Dim bError As Boolean
    Dim sSName As String
    Dim p As DocumentProperty
    Dim bSetIt As Boolean

    bOK2Use = False
    bError = True
    If Len(txtUser.Text) > 0 And Len(txtPass.Text) > 0 Then
        Select Case txtUser.Text
            Case "gvanhook"
                If txtPass.Text = "gvanhook" Then
                    bError = False
                    Worksheets("Project Progress").Activate
                    If ActiveSheet.ProtectContents Then
                        ActiveSheet.Unprotect "ross"
                        Columns("D").Hidden = False
                        ActiveSheet.Protect "ross"
                    End If
                End If
            Case "user2"
                If txtPass.Text = "u2pass" Then
                    bError = False
                    Worksheets("Project Progress").Activate
                    If ActiveSheet.ProtectContents Then
                        ActiveSheet.Unprotect "ross"
                        Columns("E").Hidden = False
                        ActiveSheet.Protect "ross"
                    End If
                End If
        End Select
    End If
    If bError Then
        MsgBox "Invalid User Name or Password"
    Else
        bOK2Use = True
        Unload Me
    End If
End Sub
Best wishes,
Hans

gvanhook
StarLounger
Posts: 67
Joined: 22 Feb 2010, 20:15
Location: Indiana

Re: hiding and unhiding columns based on a user

Post by gvanhook »

Hans,
Thank you for the suggestions. I have changed the code as recommended but I am still having one problem. I can see the column unhide but as soon as the userform unloads, the spreadsheet closes. When I stepped through in debug, it got to the Private Sub UserForm_Terminate () and then the workbook closed. Here is the full code as I have it entered.

Code: Select all

Private Sub btnOK_Click()
    Dim bError As Boolean
    Dim sSName As String
    Dim p As DocumentProperty
    Dim bSetIt As Boolean
    

    bOK2Use = False
    bError = True
    If Len(txtUser.Text) > 0 And Len(txtPass.Text) > 0 Then
        Select Case txtUser.Text
            Case "v"
                If txtPass.Text = "v" Then
                    bError = False
                    Worksheets("Project Progress").Activate
                    If ActiveSheet.ProtectContents Then
                        ActiveSheet.Unprotect ("ross")
                        Columns("D").Hidden = False
                        ActiveSheet.Protect ("ross")
                    End If
                End If
             Case "user2"
                If txtPass.Text = "u2pass" Then
                bError = False
                   Worksheets("Project Progress").Activate
                   If ActiveSheet.ProtectContents Then
                    ActiveSheet.Unprotect ("ross")
                    Columns("E").Hidden = False
                    ActiveSheet.Protect ("ross")
                   End If
                End If
        End Select
    End If
    If bError Then
        MsgBox "Invalid User Name or Password"
    Else

        bOK2Use = True
      Unload Me
    End If
End Sub

Private Sub UserForm_Terminate()
    If Not bOK2Use Then
        ActiveWorkbook.Close (False)
    End If

End Sub
I also have a case where I will need to unhide multiple non-contiguous columns. How would I accomplish that?

Thanks!

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

When I try your code, the workbook only closes if I enter an incorrect username/password combination. The variable bOK2Use is set to True if bError has been set to False, which happens if the user enter a correct username and password. The workbook closes if bOK2Use is not True.

To unhide several columns, you can use code like this. In this example, columns D, R through V and Z are unhidden:

Range("D1,R1:V1,Z1").EntireColumn.Hidden = False

BTW, you should try to indent your code consistently, as in the version that I posted; it makes the code much easier to read and to debug.
Best wishes,
Hans

gvanhook
StarLounger
Posts: 67
Joined: 22 Feb 2010, 20:15
Location: Indiana

Re: hiding and unhiding columns based on a user

Post by gvanhook »

Hans,
I am not sure what is different between my running the code and you, but the workbook is closing when I enter a correct user/pass combination. If I enter an invalid combination I get the appropriate message box. I have attached the workbook.
You do not have the required permissions to view the files attached to this post.

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

You have omitted the line

Dim bOK2Use As Boolean

at the top of the userform module. As a consequence, it becomes a local variable within each procedure, and the value of bOK2Use in UserForm_Terminate has nothing to do with the value of bOK2Use in btnOK_Click.

If you had required explicit declaration of variables, you would have been warned of this problem. See A Dim understanding: declaring variables in VB/VBA.
Best wishes,
Hans

gvanhook
StarLounger
Posts: 67
Joined: 22 Feb 2010, 20:15
Location: Indiana

Re: hiding and unhiding columns based on a user

Post by gvanhook »

Hans,
I added the Option Explicit line and also added the dim bOK2Use = Boolean to both the btnOk_Click and Userform_Terminate subs and the workbook is still closing. I added watches to both bOK2Use and bError and stepped through the routines to see if the logic was coming up faulty but the logic looked fine (bOK2Use = True and bError = False) at the unload step. When UserForm_terminate started the statement "if not bOK2Use then ActiveWorkbook.close (False)" I would have expected the code to jump to the end if since bOK2Use = True, but it did not. The ActiveWorkbook.Close event then triggered the workbook_beforeClose(Cancel As Boolean) macro in This Workbook. I don't understand why it is not working. :hairout:
Any ideas?

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

You should NOT add Dim bOK2Use As Boolean to btnOK_Click and to Userform_Terminate. Doing so will create separate, independent local variables in each procedure, and setting the value of bOK2Use in one of the procedures will not have any influence on the value of bOK2Use in the other.

In the original code, you had the line Dim bOK2Use As Boolean correctly placed at the top of the module, so that it was a module-level variable. But you had mistakenly placed an orphan line

Private Sub UserForm_Click()

above it. I wrote that you should remove that line, NOT that you should also remove the line Dim bOK2Use As Boolean. But you did remove the latter too. This caused the problem. The top part of the module should look like this:

Code: Select all

Option Explicit

Dim bOK2Use As Boolean

Private Sub btnOK_Click()
    Dim bError As Boolean

    bOK2Use = False
    bError = True
    ...
See the attached version.
tracker_Lounge.xlsm
You do not have the required permissions to view the files attached to this post.
Best wishes,
Hans

gvanhook
StarLounger
Posts: 67
Joined: 22 Feb 2010, 20:15
Location: Indiana

Re: hiding and unhiding columns based on a user

Post by gvanhook »

Thanks Hans! This is the first time I have seen a variable at the module-level. I did not know it was possible. Thank you for all of your assistance (and patience)!

Everything is working great now and I have begun to populate with real data, but now am getting an error in this section where I am trying to unhide non-contiguous columns. The error is coming on the Range line

Code: Select all

If ActiveSheet.ProtectContents Then
      ActiveSheet.Unprotect "ross"
      Range("D1,F1:H1,M1").EntireColumnHidden = False
End If
This is a run-time error '438': Object doesn't support this property or method

ideas? :scratch:
I have tried this in both excel 2007 & 2010.

User avatar
HansV
Administrator
Posts: 78620
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: hiding and unhiding columns based on a user

Post by HansV »

It should be

Range("D1,F1:H1,M1").EntireColumn.Hidden = False

with a period (dot) between EntireColumn and Hidden.
Best wishes,
Hans