Dynamisch zichtbaar maken van CommandButtons

Status
Niet open voor verdere reacties.

masala09

Gebruiker
Lid geworden
6 aug 2012
Berichten
886
Beste Allen,

Toch even terugkomend op de For Each.

Ditmaal bedoelt om de Captions van de CommandButtons dynamisch volgens een lijst te benoemen.

Waar ik uitkom is alsvolgt:

Code:
        For Each ctrl In .Frame1.Controls
            With ctrl
                For i = 12 To 21
                    If .Name = ("CommandButton" & i) Then
                            .Visible(i) = False

                        Select Case TypeGebruiker
                            Case Is = "Beheerder_1"
                                    .Visible(i) = True

                            Case Is = "Gebruiker_1"
                                For i = 12 To 16
                                    .Visible = True
                                Next i
                        End Select
                    End If
                Next i
            End With
        Next ctrl


Per gebruiker geld dezelfde lijst, alleen bepaald de autorisatie welke knoppen zichtbaar moeten zijn. Totaal zijn er 5 verschillende gebruikers met iedere een eigen autorisatie en set knoppen.

Beheerder heeft bijvoorbeeld Knoppen 1 tot en met 10. Dus eigenlijk alles. Terwijl bijvoorbeeld Gebruiker weer enkel de knoppen 1 tot en met 5 heeft. Bij deze zijn de andere 5 dus niet zichtbaar.

Nu ontvang ik een fout dat ik de For i al in gebruik heb (waar ik kan inkomen). Zou ik deze, bij Case Gebruiker, middels een ' uitschakelen dan volgt er een fotmelding: "Property Let-procedure is niet gedefinieerd en Property Get-procedure heeft geen object als resultaat gegeven (Fout 451)".
 
Laatst bewerkt:
Maak eens gebruik van de <F8> toets en de andere hulpmiddelen die je in de VB editor hebt. Je kan i niet meerdere keren aanroepen binnen verschillende lussen.

Op de gok
Code:
For Each ctrl In .Frame1.Controls
    With ctrl
        For i = 12 To 21
            If .Name = ("CommandButton" & i) Then
                .Visible(i) = False
                Select Case TypeGebruiker
                Case Is = "Beheerder_1"
                    .Visible(i) = True
                    Case Is = "Gebruiker_1"
                        For ii = 12 To 16
                            .Visible = True
                            Next ii
                    End Select
                End If
            Next i
        End With
    Next ctrll
 
Laatst bewerkt:
Voor de "i" had ik al aangegeven dat dit mij niet zo bevreemd. Daar was ik namelijk al achter.

<F8> heb ik ook al geprobeerd. Had ik overigens al aangegeven dat dit een module buiten het userform betreft. In het userform ondervond ik ook al het probleem dat ik bijvoorbeeld Controls niet kon gebruiken buiten het userform en in een aparte module.

Bovenstaande code draai ik in de module buiten het userform.

Zo is mijn verhaal denk ik wel compleet. Even afgezien van het plaatsen van een voorbeeld. Wegens drukte met mijn werk etc. kom ik hier telkens niet aan toe en dus doe ik het echt in uiterste noodzaak. Ik blijf namelijk ook proberen buiten jullie antwoorden om. Ook als jullie antwoorden, zoals toevallig nu bij jou, niet de oplossing bieden. Beste leerweg zeg ik altijd maar. ;)

Tevens is er ook een Klassemodule. Nu weet ik niet of dit er mee te maken kan hebben. Deze is voor mij gemaakt om het userform volledig te dekken naar schermformaat.
 
Mijn oplossing. Al vind ik het een vreemde.

Code:
For Each ctrl In .Frame1.Controls
            With ctrl
                For i = 12 To 21
                    If .Name = ("CommandButton" & i) Then
                        .Visible = False

                        Select Case TypeGebruiker
                            Case Is = "Beheerder_1"
                                    .Visible = True

                            Case Is = "Gebruiker_1"
                                For ii = 12 To 16
                                    If .Name = ("CommandButton" & ii) Then
                                        .Visible = True
                                    End If
                                Next ii
                        End Select
                    End If
                Next i
            End With
        Next ctrl
 
Is dit ook vreemd?
Code:
For Each ctrl In .Frame1.Controls
  If TypeOf ctrl Is msforms.commandbutton and TypeGebruiker = "Gebruiker_1" Then
         y = y +1
         If y > 11 and y < 17 Then ctrl.Visible = True
  End If
Next ctrl

of:
Code:
For Each ctrl In .Frame1.Controls
  If TypeOf ctrl Is msforms.commandbutton and TypeGebruiker = "Gebruiker_1" Then
         y = y +1
        ctrl.Visible = y > 11 and y < 17
  End If
Next ctrl
 
Laatst bewerkt:
Je blijft leren...:)

Vreemd of niet. Een oplossing is een oplossing. Het gaat er alleen om hoe de oplossing wordt geformuleerd. Met andere woorden, kan het korter, is het te uitgebreid, doe ik nu niets dubbel. Dat soort dingen.

Het is wat ik al eens eerder aangaf. Een for in een for en daar weer een for in etc... daar ben ik niet helemaal in thuis. Ik ben dat al een beetje aan het doorgronden door er over te lezen etc.

Jij gebruikt hier geen for zie ik en ms.forms.commandbutton ken ik al helemaal niet. Daarom schreef ik dus ook.... je blijft leren.

Wat ik alleen niet snap... Ik geef nog aan CommandButton & i. De i heb ik vooraf al bepaald. Hiermee maakte ik het voor mij leesbaar. Wat jij doet is meteen de CommandButton en dan daarna y = y + 1. Komt dit vanwege het gebruiken van msforms?
 
De y gebruik is als teller doordat ik geen for i lus gebruik.
Het heeft niets met de naam van de commandbutton van doen.

Onderstaande moet je nog even aanpassen.....
Code:
 If y > 11 and y < 17 Then ctrl.Visible = True
...naar
Code:
   if y <11 or y > 17 then ctrl.visible = true
Anders zou je ze eerst moeten verbergen zoals in jouw code, wat hierdoor overbodig is.
 
Dat "foutje" had ik al gespot, maar bedankt voor de info op dat punt. Dat het stukje "eerst verbergen" hiermee kan worden weggelaten dat wist ik niet, want inderdaad daarom had ik eerst de zaken laten verbergen, omdat er anders geen verandering in het zichtbaar maken kwam, zodra er minder knoppen op het scherm moeten staan. Dat is mooi. :thumb:

Dat de y hier wordt gebruikt als teller dat had ik ook door. Wat ik ook begrijp is dat de code refereert naar de commandbuttons. Wat ik niet in de code zie, is dat er hier ook gekeken wordt naar het volgnummertje van de commandbutton. In mijn code geef ik dit "duidelijk" aan. Nu snap ik wel dat die teller y hierin een rol speelt, maar hoe dat zie ik niet.

Soms moet je zaken nemen zoals ze gewoon zijn, maar soms kan hier uitleg in gegeven worden. Dit had ik vroeger ook al met wiskunde. Soms is iets gewoon een gegeven.
 
Laatst bewerkt:
Ervan uitgaande dat je veertig controls hebt waarvan 20 commandbuttons.
Misschien dat dit iets beter te begrijpen is.

Als ctr een commandbutton is, dan y = y + 1
als y = 20 dan ctr.visible = false
 
Hmmm @HSV.

Ik ben jou code eens aan het proberen, maar die werkt bij mij niet hoor. Tenminste niet in mijn opzet.

Iedere code is voor een programma uniek. Tenminste dat heb ik ooit geleerd van ik meen snb.

Ter herinnering. De code wordt in een module buiten het userform aangeroepen zodra er een aanmelding is gedaan. De code staat dus niet onder het userform zelf. Wellicht dat het hiermee te maken heeft ?

De volledige code tot nu toe, omdat er nog meer autoriteit levels bestaan welke nog moeten worden toegevoegd. Deze code staat in een Module genaamd: "Mod_Frm_Hoofd". Deze had ik hier geplaatst en vond ik "vreemd" in opstelling, maar werkt wel.

Code:
Sub Welkom()
    With Frm_Hoofd
        If InlogOk Then
            .Label2.BackColor = vbGreen
            
            With .Label9
                .Font.Size = 8
                .Caption = "Welkom " & Gebruiker & vbCr & "Ingelogd als " & Left(TypeGebruiker, Len(TypeGebruiker) - 2) _
                                & " [ Autorisatieniveau " & Right(TypeGebruiker, 1) & " ]"
            End With
                        
            .Cmb_Log.Caption = "Uitloggen"
            
            .Frame1.Visible = True ''''''''
            '.Frame2.Visible = True ''''''''
            
            For Each ctrl In .Frame1.Controls
                With ctrl
                    For i = 12 To 21
                        If .Name = ("CommandButton" & i) Then
                            .Visible = False
    
                            Select Case TypeGebruiker
                                Case Is = "Beheerder_1"
                                        .Visible = True
    
                                Case Is = "Gebruiker_1"
                                    For ii = 12 To 16
                                        If .Name = ("CommandButton" & ii) Then
                                            .Visible = True
                                        End If
                                    Next ii
                            End Select
                        End If
                    Next i
                End With
            Next ctrl
        Else
            .Label2.BackColor = vbRed
            
            With .Label9
                .Font.Size = 14
                .Caption = "Log in om verder te gaan ---->"
            End With
            
            .Cmb_Log.Caption = "Inloggen"
            
            
            .Frame1.Visible = False ''''''''
            '.Frame2.Visible = False ''''''''
        End If
    End With

End Sub
 
Laatst bewerkt:
Oke dan. Met anders denken, ben ik op iets heel anders uitgekomen en heb ik de IIF functie ingepast.
Deze wijze vind ik op zich mooier, netter, duidelijker en minder vreemd overkomen.

Volgens mij maak ik hiermee de code ook sneller daar alles meteen in 1 coderegel wordt opgepakt.

Code:
For Each ctrl In .Frame1.Controls
                With ctrl
                    For i = 12 To 21
                        If .Name = ("CommandButton" & i) Then
                            
                            Select Case TypeGebruiker
                                
                                Case Is = "Beheerder_1"
                                    .Visible = IIf(i >= 12 And i <= 21, True, False)
                                
                                Case Is = "Gebruiker_1"
                                    .Visible = IIf(i >= 12 And i <= 19, True, False)
                                
                                Case Is = "Gebruiker_2"
                                    .Visible = IIf(i >= 12 And i <= 16, True, False)
                            
                            End Select
                        End If
                    Next i
                End With
            Next ctrl

Of is dit nog omslachtig door het gebruik van IIF.

Volgens mij en als ik de .Visible = False om alle knoppen onzichtbaar te maken, boven de Select Case plaats en enkel een IF gebruik om de benodigde knoppen zichtbaar te maken, duurt dat langer daar dan eerst alles 1 voor 1 onzichtbaar wordt gemaakt en daarna meteen wordt gekeken of deze knop weer zichtbaar moet worden gemaakt of niet.

Naar mijn gevoel gaat de code nu alles af en maakt deze meteen zichtbaar of onzichtbaar.
 
Laatst bewerkt:
Sorry, omdat ik niet weet of dit uitmaakt, heb ik op een andere wijze de code opgezet en verplaatst naar helemaal onder de module. Zo worden na iedere uitlog alle knoppen meteen onzichtbaar gemaakt en hoef ik geen IIF te gebruiken.

Nu gebruik ik slechts de IF wat het meer leesbaar maakt. Ook heb ik alle levels nu geplaatst.

Wel blijven die paar vragen in #11 staan.

Code:
        For Each ctrl In .Frame1.Controls
            With ctrl
                For i = 12 To 21
                    If .Name = ("CommandButton" & i) Then
                        Select Case TypeGebruiker
                            Case Is = vbNullString
                                .Visible = False
                            Case Is = "Beheerder_1"
                                If i >= 12 And i <= 21 Then .Visible = True
                            Case Is = "Beheerder_2"
                                If i >= 12 And i <= 20 Then .Visible = True
                            Case Is = "Beheerder_3"
                                If i >= 12 And i <= 19 Then .Visible = True
                            Case Is = "Gebruiker_1"
                                If i >= 12 And i <= 18 Then .Visible = True
                            Case Is = "Gebruiker_2"
                                If i >= 12 And i <= 16 Then .Visible = True
                            Case Is = "Gebruiker_3"
                                If i >= 12 And i <= 15 Then .Visible = True
                        End Select
                    End If
                Next i
            End With
        Next ctrl
 
@Mas

zet alle commandbuttons in ontwerpmodus op visible =false

Dan hoef je daarna alleen per gebruiker de knopnummers in te lezen en die vervolgens zichbaar te maken.
Omdat iedere gebruiker de inititialize -gebeurtenis moet doorlopen, hoef je de zichtbare knoppen niet weer op onzichtbaar te zetten.
Dan is deze code voldoende:

Code:
Private sub userform_initialize()
   select case environ("username") 
   case "GB_001"
      sn=array(12,13,14,16,17)
   case "GB_002", GB_003"
      sn=array(14,16,19)
   next

   for each it in sn
     me("Commandbutton" & it).visible=true
   next
End Sub
 
Laatst bewerkt:
Hmmm @HSV.
Ik ben jou code eens aan het proberen, maar die werkt bij mij niet hoor. Tenminste niet in mijn opzet.

Tja, jij ziet beren waar ik ze niet zie.
 
Snb.

Dank je, maar dit formulier blijft na geopend te zijn, open staan. Het is het hoofdscherm. Vanaf hier kun je inloggen, uitloggen, andere menu's ingaan etc.

HSV, Heb ik je beledigd met dat zinnetje... nee toch?
 
Nee hoor, hier werkt het prima, alleen jammer dat we alles tig keer moeten herhalen voordat het doordringt hoe het werkt.
 
@ HSV. Ja ik ken dat. Ik word daar met sommigen in mijn omgeving ook moe van. Mij zelf in hetzelfde groepje plaatsend. Vaak zie ik dingen niet of begrijp ik de logica niet helemaal of helemaal niet waarna ik ga proberen etc. Dan gaat er weer van alles in mijn hoofd spelen en word ik soms chaotisch ("Daar bestaan pillen voor", ik weet het.)

Dus kort door de bocht... sorry!
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan