Unload issue

Status
Niet open voor verdere reacties.

masala09

Gebruiker
Lid geworden
6 aug 2012
Berichten
886
Ik heb een klein dingetje met Unload Me.

Deze kan niet in een code worden uitgevoerd als de code verder nog loopt. Er volgt dan een automatiseringsfout met de mededeling dat de verbindingen met het aangeroepen object met clients is verbroken, waarna Exel 2007 en VBA vastloopt.

Na wat uitzoekwerk bleek de automatiseringsfout in TextBox_AfterUpdate te zitten en daar ben ik in gaan aanpassen. Let even niet op al die msgboxen die er verder in staan, want die staan er hooguit in om uit te zoeken wat er precies gebeurd en om even niet verdwaald te raken in het heen en weer springen van sub naar sub.

Vanuit mijn inlogscherm en na het invoeren van het wachtwoord wordt met de knop enter meteen de code achter TExtBox_ AfterUpdate uitgevoerd. Ik heb dus geen knop meer voor inloggen of annuleren. Dit om onnodig OK klikken etc te voorkomen.

Nu kan ik, omdat ik de Unload Me in TextBox_Exit heb geplaatst, wel het formulier zonder probleem van het scherm laten verdwijnen en werkt de Unload Me dus wel. Echter wat mij opvalt is dat TextBox_AfterUpdate en TextBox_Exit procedure 2 maal wordt aangesproken.

Mijn gedachten is dat zodra ik in Exit de opdracht Unload me geef er bij het ontladen van het formulier eerst een wijziging in de textboxen plaatsvindt. Dit zou dan het voor de tweede maal aanspreken van AfterUpdate en Exit verklaren. Zodra ik de msgboxen, wat de bedoeling is, verwijder of uitschakel, dan merk ik niet van het 2 maal aanspreken en wordt het formulier direct gesloten.

Klopt mijn gedachtegang en dus dat dit normaal is en slechts wordt ontdekt vanwege de msgboxen?

Code:
Private Sub Tb_Wachtwoord_AfterUpdate()
'----------------------------------------------
'Vergelijking vermoedelijk niet nodig
    
    'If Tb_Wachtwoord = vbNullString Then
    'MsgBox "AFTERUPDATE: Geen waarde. U verlaat de sub" 'Tijdelijke melding. Verwijderen na juist lopen code
    'Exit Sub
    'End If

'----------------------------------------------
    
'Call log moet blijven staan

    MsgBox "naar log" 'Tijdelijke melding. Verwijderen na juist lopen code
    
    Call log
    
    
'----------------------------------------------
'Indien bovenstaande vergelijking niet nodig dan is onderstaand ook niet nodig
    
    'MsgBox "wis gebruiker en wachtwoord"'Tijdelijke melding. Verwijderen na juist lopen code
    'Tb_Gebruiker = vbNullString
    'Tb_Wachtwoord = vbNullString
'----------------------------------------------

End Sub

Private Sub Tb_Wachtwoord_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    MsgBox "EXIT: Dit formulier wordt uit het geheugen gewist" 'Tijdelijke melding. Verwijderen na juist lopen code

    Unload Me

End Sub



Edit:

Om de code nog meer te laten inzien, volgt sub Log onderstaand. Wellicht niet nodig, maar dan is er op deze wijze meer te volgen. En ook hierin volgen er nog een paar kleine wijzigingen.

Code:
Private Sub log()
    Dim LastRow As Long
    Dim Logregel As Long
    Dim GebruikerOk As Boolean
    Dim WachtwoordOk As Boolean
    Dim LogTijd As Date
    Dim InlogTijd As Date
    Dim UitlogTijd As Date
    Dim SessieDuur As Double
    Dim i As Long
    Dim j As Long

    With Sheets("Gebruikers")
        LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
                      
        For i = 2 To LastRow
            If Trim(Tb_Gebruiker) = Trim(.Cells(i, 1)) Then
                GebruikerOk = True
                
                If Trim(Tb_Wachtwoord) = Trim(.Cells(i, 2)) Then
                    WachtwoordOk = True
                                        
                    For j = 1 To 12
                        If InlogOk Then
                            .Cells(i, j).Interior.ColorIndex = -4142 'Standaard
                        Else
                            .Cells(i, j).Interior.ColorIndex = 43 'Groen
                        End If
                    Next j
                    
                End If
            End If
                
            If GebruikerOk = True And WachtwoordOk = True Then
                LogTijd = Now
                
                If Not InlogOk Then 'INLOGGEN
                    InlogOk = True
                    Logregel = Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Row
                    Gebruikersnaam = .Cells(i, 1)
                    Gebruiker = .Cells(i, 3)
                    
                    'If .Cells(i, 8) <> vbNullString Then
                    '    LaatsteInlog = .Cells(i, 8)
                    'Else
                        'LaatsteInlog = "01-01-1900 00:00:00"
                    'End If
                    
                    Sheets("Gebruikers").Select
                    .Cells(i, 7) = .Cells(i, 7) + 1 'Aantal maal login
                    .Cells(i, 8) = LogTijd
                    .Cells(i, 8).NumberFormat = "dd-mm-yyyy hh:mm:ss"
                    .Cells(i, 10) = "1" 'Status: Gebruiker Ingelogd
                                   
                    Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Offset(1).Resize(, 6) = Array(Logregel, .Cells(i, 1), .Cells(i, 3), _
                        .Cells(i, 4), .Cells(i, 5), LogTijd)
                    Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Cells(, 6).NumberFormat = "dd-mm-yyyy hh:mm:ss"
                    
                    'MsgBox .Cells(i, 4).Interior.Color
                    'Frm_InlogID.Show
                    
                Else 'UITLOGGEN
                    .Cells(i, 9) = LogTijd
                    .Cells(i, 9).NumberFormat = "dd-mm-yyyy hh:mm:ss"
                    .Cells(i, 10) = "0" 'Status: Gebruiker Uitgelogd
                    
                    With Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp)
                        .Cells(, 7) = LogTijd
                        .Cells(, 7).NumberFormat = "dd-mm-yyyy hh:mm:ss"
                        
                        InlogTijd = Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Cells(, 6)
                        UitlogTijd = Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Cells(, 7)
                        SessieDuur = UitlogTijd - InlogTijd
                        
                        .Cells(, 8) = SessieDuur
                        .Cells(, 8).NumberFormat = "[hh]:mm:ss"
                    End With
                    
                    InlogOk = False
                    Gebruiker = vbNullString
                    Gebruikersnaam = vbNullString
                    LaatsteInlog = vbNullString
                    'Call Logscherm
                    'Me.Hide
                    
                    UserForm1.Show 'Userform geeft de melding dat men is uitgelogd en verdwijnt automatisch weer na 3 seconden om door te gaan
                                                'met de procedure
                End If
            Me.Hide
            Exit Sub
            End If
        Next i

        If Not GebruikerOk Then
            MsgBox ("U heeft een ongeldige gebruikersnaam ingevoerd." _
                & vbNewLine & vbNewLine & "Probeer opnieuw"), vbInformation
        Else
            If Not WachtwoordOk Then
                MsgBox ("U heeft een ongeldig wachtwoord ingevoerd." _
                    & vbNewLine & vbNewLine & "Probeer opnieuw."), vbInformation
            End If
        End If
            
        If Not InlogOk Then
            Tb_Gebruiker = vbNullString
            Tb_Wachtwoord = vbNullString
            Tb_Gebruiker.SetFocus
        Else
            Tb_Wachtwoord = vbNullString
            Tb_Wachtwoord.SetFocus
        End If
    End With

End Sub
 
Laatst bewerkt:
Kan je niet veel beter het bestandje uploaden?
 
Ja kan wel, maar dat gaat nu even niet lukken. Op dit moment namelijk geen tijd voor en omdat de Unload issue naar mijn idee is opgelost en het slechts in de Exit en AfterUpdate zit, heb ik het voor nu even zo gedaan. Als je zegt van dat het heen en weer springen niet hoort, dan zal ik morgen het bestandje scheiden en hier plaatsen.

Wel heb ik een Editje gemaakt zodat Sub Log ook is in te zien.

Had eigenlijk gehoopt dat het antwoord op mijn vraag wel bekend zou zijn namelijk. Nogmaals Unload werkt wel, maar hij triggert 2 maal AfterUpdate en 2 maal Exit.
 
Laatst bewerkt:
Even tijd voor gemaakt en dan naar bed.

Bekijk bijlage TestMapLog.xlsm

Trouwens meteen nog een klein probleempje ontdekt.

Zodra er een verkeerd wachtwoord of gebruikersnaam is ingetoetst dan zou deze normaal gesproken de textboxen moeten legen en dan de focus op textbox Gebruikersnaam zetten, maar ja.... hier heb je het weer... er volgt een wijziging in TextBox_AfterUpdate met als gevolg dat de procedure doorloopt, het formulier wordt ontladen en dan wilt er een setfocus plaats vinden naar een textbox van een formulier die er niet meer is en dus worden de verbindingen weer verbroken.

Even ter verduidelijking. De code was eerst opgezet met commandbuttons inloggen en uitloggen. Toen werkte het allemaal wel.
 
Laatst bewerkt:
Waarom gebruik je niet gewoon de environ("username"), eventueel gecombineerd met de environ("computername")

Code:
Sub Workbook_open()
  if sheet1.columns(1).find(environ("Username")) is nothing then actvieworkbook.close 0
End Sub
 
Beste SNB. Ik snap wat jij bedoelt, maar omdat er geen gebruik wordt gemaakt van een dergelijke opzet, heeft dit geen nut. Niemand hoeft zich op het systeem in te loggen of uit te loggen. Slechts voor bepaalde programma's of bestanden is dit noodzakelijk, zodat er dan gezien kan worden wat er is gedaan en door wie. Het systeem hoeft, buiten bepaalde bestanden, niet zo gesloten te zijn. Iedereen heeft gewoon overal toegang toe daar dit nodig is. Echter sommige bestanden hoeven niet voor iedereen toegankelijk te zijn en voor die bestanden bestaat er gewoon een log in.

Wij hebben dit al eens overwogen en overlegd met onze netwerkbeheerder. Zijn mening is dat met onze opzet van systeem jouw wijze in deze voor ons geen enkel toegevoegde waarde heeft. Het is voor ons niet interessant genoeg en het verschil weegt niet op tegen de vele bewerkingen die dan gemaakt moeten worden. Zodoende dat er bewust voor deze wijze is gekozen en die enkele bestanden of programma's te voorzien van een username en login. Dit heeft tot op heden altijd zijn werk goed gedaan.

Wel houd ik deze wijze beslist in mijn achterhoofd, want het scheelt in die zin dan wel een hoop gedoe en wordt de toegang geregeld direct bij het inloggen van een bepaalde user.
 
Laatst bewerkt:
Wat is bij jou dan het resultaat van:

Code:
Sub M_Marcel()
   msgbox environ("computername")
   MsgBox Environ("userdomain")
End Sub
 
Laatst bewerkt:
1 En de zelfde naam. Mijn bedrijfsnaam: . ...& Elektrotechniek-PC.
 
En dat geldt voor alle gebruikers ?
 
Vermoedelijk weet niemand het antwoord?? Dan haal ik de test-msgboxen gewoon weg en is het hierdoor slechts zichtbaar geworden.

Weet iemand dan wel of het mogelijk is om de focus op een textbox te laten staan zodra je een checkbox aanklikt. Of is dit enkel mogelijk middels een commandbutton en deze dan op Take Focus On Click = False.
 
Als al die gebruikers een eigen instantie van Excel starten kun je gebruik maken van Application.username.

Desnoods kun je dit bestand in een verborgen map zetten en alle geautoriseerde gebruikers een snelkoppeling daarnaar sturen.
 
Laatst bewerkt:
Ik heb al eerder lopen rommelen met een variabele op boolean.. Maar het lukt mij niet of ik plaats hem verkeerd en als ik zo de tekst lees dan begrijp ik er niet zo heel veel van.
De daarin gestelde Me.EnableEvents bestaat niet. In ieder geval niet in Excel 2007 met VBA 6.3.

Dus hoe jij dit dan zou invoegen weet ik niet. Voel je vrij als je dat wilt. Ik zie het dan graag tegemoet anders laat ik die vraag zo en houd ik de msgboxen die nergens op slaan weg. Dan heb ik er ook geen last van.
 
Je maakt 'm zelf bovenaan in de code van jouw form: Public EnableEvents As Boolean
vervolgens handig in jouw code verwerken...
Die Unload me in de exit van de textbox zal op deze manier mi altijd twee maal triggeren,

Jouw andere vraag "Weet iemand dan wel of het mogelijk is om de focus op een textbox te laten staan zodra je een checkbox aanklikt."

Nee niet mogelijk, of zoals je nu doet, meteen de focus weer terug (ik snap dat je dat niet wilt) of bijv. een 'workaroundje'

Plaats een Image (leeg) over de checkbox en zet de Backstyle op transparant

Voeg onderstaande code toe:

Code:
Private Sub Image1_Click()'de naam van jouw ingevoerde transparante Image
 Chk_Tekens = Not Chk_Tekens
End Sub
Private Sub Chk_Tekens_Change()
    If Chk_Tekens = True Then
        Tb_Wachtwoord.PasswordChar = ""
    Else
        Tb_Wachtwoord.PasswordChar = "*"
    End If
    
    If Tb_Gebruiker <> vbNullString Then
        Tb_Wachtwoord.SetFocus
    Else
        Tb_Gebruiker.SetFocus
    End If
        
End Sub

en haal de code van Private Sub Chk_Tekens_Click weg
 
Dat met die checkbox heb ik al opgelost. Ik heb een commandbutton geplaatst met daaroverheen een checkbox. Vervolgens heb ik de commandbutton naar achteren geplaatst en in diens eigenschappen de Focus On Click op False gezet. In de eigenschappen van checkbox heb ik Enabled op False gezet.

Ik zie nu dus een commandbutton met daarin een checkbox. Zodra ik op de commandbutton druk dan verschijnt het vinkje in de checkbox of verdwijnt deze en werkt de code zonder dat de focus van de textbox af gaat.

Code:
Private Sub Cb_Tekens_Click()
    Select Case Chk_Tekens
        Case Is = False
            Chk_Tekens.Value = True
        Case Is = True
            Chk_Tekens.Value = False
    End Select
    
End Sub

Private Sub Chk_Tekens_Change()
    If Chk_Tekens = True Then
        Tb_Wachtwoord.PasswordChar = ""
    Else
        Tb_Wachtwoord.PasswordChar = "*"
    End If
    
    If Tb_Gebruiker <> vbNullString Then
        Tb_Wachtwoord.SetFocus
    Else
        Tb_Gebruiker.SetFocus
    End If
        
End Sub

Voor dat andere stukje.... Ik ben er mee bezig, maar ik heb geen idee waar ik de code EnableEvents=False moet plaatsen. Waar ik hem ook plaats.... hij blijft opnieuw worden getriggerd. Wat ik al aangaf ik had een soortgelijk met andere naam ook al uitgeprobeerd.
 
Laatst bewerkt:
Jouw commandbutton en mijn Image verhaal zijn bijna gelijk, (ik zou enkel gaan voor een Image omdat je die niet ziet)

je moet uiteraard zelf nog wel wat code toevoegen, deze EnableEvents is enkel een naam voor een variabele en had elke naam kunnen hebben, wellicht ben je daardoor in de war ;)

aanzetje, code in jouw form:

Code:
[B]Public EnableEvents As Boolean[/B]

Private Sub UserForm_Initialize()
      With Me
       [B] .EnableEvents = True[/B]
        'Controleren op een eventuele inlog
        If Not Inl........en verder.....

Code:
Private Sub Tb_Wachtwoord_AfterUpdate()
 [B]If Not Me.EnableEvents Then Exit Sub[/B]
   [B] Me.EnableEvents = False[/B] 
   MsgBox "naar log" 'Tijdelijke melding. Verwijderen na juist lopen code
       Call log
     [B]Me.EnableEvents = True[/B]
End Sub
 
Laatst bewerkt:
Hmm die image zet mij in deze wel aan het denken. Ik ga er eens mee goochelen en kijken hoe dit eruit gaat zien. Ik bedoel als je hem dan niet ziet......:thumb:

Verder die code voor enableevents ga ik straks nog even proberen uit te werken. Bedankt voor de aanzet. Al begrijp ik niet 1,2,3. Ik had hem ook al in de Initialize geplaatst. Alleen boven de with. Misschien maakt het verschil als ik hem in de With zet.

Echter de Me.EnableEvents=True of False wordt volgens mij niet herkend. Immers in Me. komt enkel Enable voor. Desalniettemin ik ga het wel even uit proberen. Wellicht dat de Me. nu wel werkt in deze.
 
E v R. Bedankt voor je voorzet.

De reden dat ik Me.EnableEvents dus niet zag, was wegens het verkeerd declareren. Deze staat nu goed als Public EnableEvents as Boolean helemaal bovenin. (Oorzaak was typefoutje in de variabele). De eerste keer dat ik een dergelijk iets probeerde had ik hem gedeclareerd als Dim. Dacht dat dit zou werken en dat Public voor alleen in een Module en hierdoor voor heel het project was. Maar nu snap ik dan toch 1 ding niet. Hoewel dit weer een mooie leer is, vraag ik mij toch af wat dan het verschil is tussen Dim helemaal bovenin de code of Public. Immers beide gelden zij voor over heel het userform.

In ieder geval.

De initialize staat nu op deze manier:

Code:
Private Sub UserForm_Initialize()
    With Me
        .EnableEvents = True
        'Controleren op een eventuele inlog
        If Not InlogOk And Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Cells(, 7) = vbNullString Then InlogOk = True
        
        'Indien er een inlog bestaat
        If InlogOk Then
            .Caption = "Uitlogscherm"
            '.Tb_Gebruiker.PasswordChar = "*"
            
            'Instellen ingelogde Gebruikersnaam
            If Gebruikersnaam <> vbNullString Then
                .Tb_Gebruiker.Value = Gebruikersnaam 'Als het bestand nog in bedrijf is
            Else
                .Tb_Gebruiker.Value = Sheets("LogFile").Cells(Rows.Count, 1).End(xlUp).Cells(, 2) 'Als het bestand opnieuw wordt of is opgestart            End If
            End If
            
            .Tb_Gebruiker.Enabled = False
            .Tb_Wachtwoord.SetFocus
            
        'Indien er geen inlog bestaat
        Else
            .Caption = "Inlogscherm"
        End If
        
    End With

End Sub

De Tb_Gebruiker_AfterUpdate() en Tb_Gebruiker_Exit zijn als volgt:

Code:
Private Sub Tb_Wachtwoord_AfterUpdate()
    If Me.EnableEvents = False Then Exit Sub
    MsgBox "naar log" 'Tijdelijke melding. Verwijderen na juist lopen code
    Call log

End Sub

Private Sub Tb_Wachtwoord_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If Me.EnableEvents = False Then Exit Sub
    Me.EnableEvents = False
    MsgBox "EXIT: Dit formulier wordt uit het geheugen gewist" 'Tijdelijke melding. Verwijderen na juist lopen code
    Unload Me
    
End Sub

Tevens jouw beoogde oplossing met Image.Click gebruikt. Staat een stuk netter en geeft via een omweg, maar met een ander object toch mijn eerste bedoeling weer.

Echter nu rest er een probleem bij als er een verkeerde gebruikersnaam en of wachtwoord wordt ingevoerd. De eerder gestelde Automatiseringsfout komt dan ook naar voren toe. Ik ga dat eerst eens nu zelf oplossen met de Me.EnableEvents. Als het niet lukt dan kom ik er op terug. Lukt het wel dan plaats ik mijn oplossing.

Thanks. :thumb:

Voor nu naar bedje toe. Morgen weer vroeg dag. Even naar het buitenland voor werkzaamheden. Kijken hoe een project daar loopt.
 
Laatst bewerkt:
vraag ik mij toch af wat dan het verschil is tussen Dim helemaal bovenin de code of Public. Immers beide gelden zij voor over heel het userform.

Dim is hetzelfde als Private dwz enkel 'zichtbaar' voor jouw Userform, Public is 'zichtbaar' in jouw gehele project (overigens in het geval van het plaatsen in jouw Userform, dien je deze wel specifiek te vermelden ==> UserForm1.EnableEvents)
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan