noc06
Goto Top

Makro für die Bennenung von Arbeitsblättern (mit Überprüfung, ob der gewählter Name schon vorhanden ist)

Guten Morgen!

Ich habe folgendes Problem und hoffe, daß mir diesbzgl. jemand den entscheidenden Hinweis geben kann (leider funktioniert die SF heute morgen nicht bzw. das System ist überlastet).

Über ein Makro soll ein bestehendes Tabellenblatt ausgewertet und die Auswertung in ein noch neu zu erstellendes Blatt eingetragen werden. Dieses neue Blatt soll den Namen des Blattes bekommen, aus dem das Makro ausgelöst wurde, zzgl. eines Zusatzes (in meinem Fall wäre dies "Auswertung Blatt 1", wenn das Makro aus Blatt 1 gestartet worden ist).

Die Erstellung des neuen Blattes inkl. der erstmaligen Benennung funktioniert auch genau wie geplant, allerdings ergibt sich dabei ein Problem, welches ich bisher nicht lösen konnte.

Löst man das Makro nämlich weitere Male aus, ergibt sich logischerweise eine Fehlermeldung, da der gewählte Blattname bereits vorhanden ist. Mein Ziel wäre an dieser Stelle eine Überprüfung, ob der gewählte Blattname bereits existiert und wenn dies der Fall ist, der neue Name noch mit einem Zahlenzusatz, i.e. (2),... , versehen wird, entsprechend der bereits vorhanden Blätter mit dem identischen Namen (m.E. ist das einfache Zählen der allg. vorhandenen Blätter und hieraus den numerischen Zusatz zu bilden keine Option, da eine Auswertung mit verschiedenen Parametern erfolgen kann und somit die Übersichtlichkeit verloren gehen würde).

Es wäre klasse, wenn mir jemand bezüglich meines Problems helfen könnte, da ich selbst von der Makroprogrammierung nicht wirklich viel Ahnung habe und das meiste per trail-and-error umsetze.

Eine kleine Zusatzfrage hätte ich dann auch noch: wie muß der Code aussehen, um die, in diesem Fall Auswertungsblätter, alle hinter einem bestimmten Blatt (ein leeres Blatt soll "Auswertungen >>>" genannt werden und dahinter werden alle getätigten Auswertungen entsprechend aufgelistet) einzufügen?

Vielen Dank und schönen Gruß
Noc06
Kommentar vom Moderator Biber am Nov 01, 2010 um 16:41:24 Uhr
Zitat von @Noc06:
Makro für die Bennenung von Arbeitsblättern..
Set rgc+=1
#711

Content-Key: 154097

Url: https://administrator.de/contentid/154097

Printed on: April 27, 2024 at 03:04 o'clock

Member: bastla
bastla Nov 01, 2010 at 11:17:22 (UTC)
Goto Top
Hallo Noc06!

Etwa so:
Sub AddSheet()
Pre = "Auswertung " 'Präfix für neue Tabellennamen  
After = "Auswertungen >>>" 'Blatt, nach dem das neue Blatt eingefügt werden soll  

NewSheet = Pre & ActiveSheet.Name
Counter = 1
LNew = Len(NewSheet) 'Länge des neuen Tabellennamens (wird mehrfach benötigt und daher hier nur einmal ermittelt)  
For Each Sheet In Sheets 'alle Blätter durchgehen  
    ThisName = Sheet.Name 'Name des betrachteten Blattes  
    If Left(ThisName, LNew) = NewSheet Then 'beginnt der Name dieses Blattes so wie jener des neu zu erstellenden Blattes?  
        If ThisName <> NewSheet Then 'ja, ist aber nicht gleich (daher bereits mit Laufnummer)  
            Nr = Val(Evaluate(Mid(Sheet.Name, LNew + 1))) 'Laufnummer ermitteln ...  
            If Nr >= Counter Then Counter = Nr + 1 '... und erhöhen  
        Else 'Blatt mit dem selben Namen wie das neu zu erstellende Blatt existiert  
            If Counter < 2 Then Counter = 2 'Laufnummer nur auf 2 setzen, wenn noch noch nicht mindestens 2  
        End If
    End If
Next
Worksheets.Add After:=Sheets(After) 'Blatt nach dem vorgegebenen Blatt einfügen ...  
'... und benennen (nur wenn Laufnummer > 1 auch mit Zusatz)  
If Counter > 1 Then ActiveSheet.Name = NewSheet & " (" & CStr(Counter) & ")" Else ActiveSheet.Name = NewSheet  
End Sub
Anmerkung: Es wird vorausgesetzt, dass es keine fehlerhaften Namen bestehender Auswertungsblätter (etwa aufgrund manueller Änderungen) gibt - ein Blatt "Auswertung Blatt 1 ()" etwa würde einen Fehler verursachen, der über "On Error" abgefangen werden müsste ...

Grüße
bastla
Mitglied: 76109
76109 Nov 01, 2010 at 12:16:26 (UTC)
Goto Top
Hallo Noc06!

Wenn's nur darum geht einen neuen Tabellennamen zu generieren, dann in etwa so:
Sub test()
    Dim s As String
    
    s = GetSheetName("Tabelle1")  
End Sub

Private Function GetSheetName(ByRef SheetName) As String
    Dim Wks As Worksheet, aName As Variant, sName As String
    
    sName = "Auswertung " & SheetName & ".0"  
    
    On Error Resume Next
    
    Do
        aName = Split(sName, ".")  
        sName = aName(0) & "." & CInt(aName(1)) + 1  
        Set Wks = Nothing
        Set Wks = Sheets(sName)
    Loop While Not Wks Is Nothing
    
    GetSheetName = sName
End Function
Wobei ich aufgrund der nicht bekannten Stellenzahl (1...1000?) der Einfachheit halber einen Punkt plus Ziffer verwendet habe z.B.
wird "Tabelle" zu "Auswertung Tabelle.1", "Auswertung Tabelle.2" ...
oder "Tabelle1" zu "Auswertung Tabelle1.1", "Auswertung Tabelle1.2" ...

Gruß Dieter
Member: Noc06
Noc06 Nov 01, 2010 at 12:52:07 (UTC)
Goto Top
Hallo bastla!

Vielen Dank für Deine schnelle und detaillierte Antwort! Ich habe allerdings gerade noch Probleme, Deinen Code vernünftig in meinem unterzubringen. Um die Erklärungen nicht ins Unnötige ausarten zu lassen, poste ich mal einen Teil meines Ursprungscodes in gekürzter Fassung (sicherlich nicht die beste Schreibweise, ist aber wie gesagt fast alles via trail-and-error entstanden - Unsauberkeiten bitte ich zu entschuldigen face-wink ):

' Benötigte Variablen festlegen  
 
    Dim NewTableName As String
    Dim Quelle, Ziel As Worksheet
    
    Set Quelle = ThisWorkbook.ActiveSheet
   
    If ActiveSheet.Name <> Range("B8") Then                'Abfrage stellt sicher, daß das Arbeitsblatt  
    ActiveSheet.Name = Range("B8")                           'den Projektnamen enthält und keinen  
    End If                                                                             'beliebigen Text  
   
    Set Ziel = ThisWorkbook.Worksheets.Add(After:=Sheets(Sheets.Count))
    
    NewTableName = Quelle.Range("$B$8").Value     'Das neue Blatt bekommt einen festen Namen aus dem Quellblatt  
    
    
 ' Neues Blatt mit weißem Hintergrund versehen  
    
    
    Ziel.Cells.Select
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
    
    Ziel.Name = "Auswertung " & NewTableName  
    
    On Error Resume Next        '*** Falls Blattname bereits existiert ***  

'Kopieraufträge aus Ursprungsblatt [...]  

Wenn ich jetzt versuche, Deinen Code bei mir einzubauen (so wie ich glaube, daß es richtig sein könnte...), kommt folgendes dabei heraus:

    Dim NewTableName As String
    Dim Quelle, Ziel As Worksheet
    
    Pre = "Auswertung " 'Präfix für neue Tabellennamen  

    After = "Auswertungen >>>" 'Blatt, nach dem das neue Blatt eingefügt werden soll  

    NewSheet = Pre & ActiveSheet.Name
    
    
    Set Quelle = ThisWorkbook.ActiveSheet
   
    If ActiveSheet.Name <> Range("B8") Then 'Abfrage stellt sicher, daß das Arbeitsblatt  
    ActiveSheet.Name = Range("B8")          'den Projektnamen enthält und keinen  
    End If                                  'beliebigen Text  
    


Counter = 1

LNew = Len(NewSheet) 'Länge des neuen Tabellennamens (wird mehrfach benötigt und daher hier nur einmal ermittelt)  



For Each Sheet In Sheets 'alle Blätter durchgehen  

    ThisName = Sheet.Name 'Name des betrachteten Blattes  

    If Left(ThisName, LNew) = NewSheet Then 'beginnt der Name dieses Blattes so wie jener des neu zu erstellenden Blattes?  

        If ThisName <> NewSheet Then 'ja, ist aber nicht gleich (daher bereits mit Laufnummer)  

            Nr = Val(Evaluate(Mid(Sheet.Name, LNew + 1))) 'Laufnummer ermitteln ...  

            If Nr >= Counter Then Counter = Nr + 1 '... und erhöhen  

        Else 'Blatt mit dem selben Namen wie das neu zu erstellende Blatt existiert  

            If Counter < 2 Then Counter = 2 'Laufnummer nur auf 2 setzen, wenn noch noch nicht mindestens 2  

        End If

    End If

Next



Set Ziel = Worksheets.Add(After:=Sheets(After))   'Blatt nach dem vorgegebenen Blatt einfügen ... (=> von mir noch als "Ziel" definiert, damit die Kopieraufträge entsprechend ausgeführt werden können)  

 ' Neues Blatt mit weißem Hintergrund versehen  
    Ziel.Cells.Select
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With


'... und benennen (nur wenn Laufnummer > 1 auch mit Zusatz)  



If Counter > 1 Then ActiveSheet.Name = NewSheet & " (" & CStr(Counter) & ")" Else ActiveSheet.Name = NewSheet  


On Error Resume Next '*** Falls Blattname bereits existiert ***  

Das ganze funktioniert nach ersten Testläufen auch soweit ganz gut, allerdings wird, wenn man den Namen (welcher in der Zelle B8 eingetragen wurde) ändert, dieser erst im übernächsten Auswertungslauf entsprechend in den Blattnamen übernommen und es zeitweise (ich kann Dir allerdings nicht 100%ig sagen warum, es scheint mit den Laufnummern zusammenzuhängen) zu Fehlermeldungen kommt.

Danke und schönen Gruß
Member: Noc06
Noc06 Nov 01, 2010 at 13:09:49 (UTC)
Goto Top
Hallo Dieter,

Danke für Deinen Tipp - werde den auch gleich mal ausprobieren. Muß ich bzgl. der "Private Function" etwas grundlegendes beachten oder kann ich den Code theoretisch direkt einbauen?

Danke und schönen Gruß
Noc06
Mitglied: 76109
76109 Nov 01, 2010 at 13:36:05 (UTC)
Goto Top
Hallo Noc06!

Nö, Du kannst das Private auch weglassen. Das bewirkt im Grunde nur, dass die Funktion nur innerhalb des aktuellen Code-Blattes von einer anderen Sub oder Funktion aufgerufen werden.

Stünde die Funktion z.B. in einem Modul mit Private-Angabe, dann kann die Funktion nicht aus anderen Modulen, Formularen... aufgerufen werden. Und in der Excel-Ansicht unter Makros, wäre sie auch nicht sichtbar.

Gruß Dieter
Member: bastla
bastla Nov 01, 2010 at 13:44:28 (UTC)
Goto Top
Hallo Hallo Noc06!
erst im übernächsten Auswertungslauf
... ist relativ einfach zu erklären, da in Zeile 8 der Name des neuen Blattes ausgehend vom (zu diesem Zeitpunkt gültigen) Namen des aktuellen Blattes festgelegt wird und erst in Zeile 14 das aktuelle Blatt umbenannt wird ...

... daher könntest Du die Zeilem 1 bis 15 auf
    Dim NewTableName As String
    Dim Quelle, Ziel As Worksheet

    Set Quelle = ThisWorkbook.ActiveSheet
    ActiveSheet.Name = Range("B8")          ' aktuelles Blatt hat nach dieser Zeile sicher den Projektnamen  
    
    Pre = "Auswertung " 'Präfix für neue Tabellennamen  
    After = "Auswertungen >>>" 'Blatt, nach dem das neue Blatt eingefügt werden soll  

    NewSheet = Pre & ActiveSheet.Name
 
ändern ...

Grüße
bastla
Member: Noc06
Noc06 Nov 01, 2010 at 15:45:20 (UTC)
Goto Top
Hallo bastla,

Danke für die Hilfe - jetzt funktioniert es genauso wie es soll!

Gruß
Noc06
Member: bastla
bastla Nov 01, 2010 at 16:32:27 (UTC)
Goto Top
Hallo Noc06!
jetzt funktioniert es genauso wie es soll!
Na dann könnten wir uns noch ja noch einigen Kleinigkeiten widmen - vor allem:
Wenn Du Variablendeklarationen (mit "Dim") vornimmst, dann aber konsequent für alle verwendeten Variablen - dazu ist es sinnvoll, vorweg "Option Explicit" zu setzen, da Du so keine Deklaration vergessen kannst und außerdem Schreibfehler bei Variablennamen leicht entdeckst ...

Die Zeile
Dim Quelle, Ziel As Worksheet
erzeugt übrigens (da in VBA und nicht in einem aktuellen VB verwendet) die Variable "Quelle" nicht mit dem Type "Worksheet", sondern als "Variant" (was sich aber erfreulicher Weise nicht weiter auswirkt) - exakt wäre:
Dim Quelle As Worksheet, Ziel As Worksheet
Weiters könntest Du auf das Auswählen der Zellen verzichten und anstelle von
Ziel.Cells.Select
With Selection.Interior
gleich
With Ziel.Cells.Interior
schreiben.
Die Zeile 69 schließlich ist so auch nicht sinnvoll - das würde übersetzt etwa bedeuten: "Wenn ich die Augen zumache, kann mich keiner sehen ..." face-wink - also entweder ein vernünftiges Errorhandling (mit "On Error Goto" oder zumindest einer Abfrage (in der nächsten Zeile)
If Err.Number <> 0 Then
oder (in der Testphase auf jeden Fall zu bevorzugen) den Fehler und den resultierenden den Abbruch des Makros "zulassen". Abgesehen davon wäre der Fehler im Fall des Falles schon nach Zeile 33 abzufangen, denn wenn diese Zeile fehlerfrei bleibt, kann es eigentlich keine Namenskollision mehr geben ...

Grüße
bastla
Member: Noc06
Noc06 Nov 02, 2010 at 09:01:24 (UTC)
Goto Top
Na dann könnten wir uns noch ja noch einigen Kleinigkeiten widmen - vor allem:
Wenn Du Variablendeklarationen (mit "Dim") vornimmst, dann aber konsequent für alle verwendeten Variablen -
dazu ist es sinnvoll, vorweg "Option Explicit" zu setzen, da Du so keine Deklaration vergessen kannst und
außerdem Schreibfehler bei Variablennamen leicht entdeckst ...

Wieder etwas dazugelernt - Danke!


Die Zeile
Dim Quelle, Ziel As Worksheet
> 
erzeugt übrigens (da in VBA und nicht in einem aktuellen VB verwendet) die Variable "Quelle" nicht mit dem Type
"Worksheet", sondern als "Variant" (was sich aber erfreulicher Weise nicht weiter auswirkt) - exakt
wäre:
Dim Quelle As Worksheet, Ziel As Worksheet
> 

Erledigt...

----
Weiters könntest Du auf das Auswählen der Zellen verzichten und anstelle von
Ziel.Cells.Select
> With Selection.Interior
> 
gleich
With Ziel.Cells.Interior
> 
schreiben.

Erledigt...

Die Zeile 69 schließlich ist so auch nicht sinnvoll - das würde übersetzt etwa bedeuten: "Wenn ich die Augen
zumache, kann mich keiner sehen ..." face-wink

Womit doch genau erreicht wäre, was gewünscht war: ich sehe die Fehler nicht - also sind auch keine vorhanden ;-P

- also entweder ein vernünftiges Errorhandling (mit "On ErrorGoto" oder zumindest einer Abfrage (in der nächsten Zeile)
If Err.Number <> 0 Then
> 

Werde ich noch einbauen.

Jetzt muß ich nur noch einen Weg finden, wie, für den Fall, daß die Makrosicherheit bei Excel zu hoch eingestellt ist, ein Hinweisfenster (bzgl. "zu hoher" Makrosicherheit) eingeblendet wird, welches nach Bestätigung eines OK Buttons das ganze Worksheet wieder schließt (so daß alle anderen Blätter erst gar nicht sichtbar sind).

Bekommt man das über AutoOpen, eine Function und eine entsprechende Schleife hin? Fange einfach ein wenig an zu basteln, mal schauen, wie weit ich komme...

Danke und schönen Gruß
Noc06
Member: bastla
bastla Nov 02, 2010 at 09:18:55 (UTC)
Goto Top
Hallo Noc06!
das ganze Worksheet wieder schließt (so daß alle anderen Blätter erst gar nicht sichtbar sind)
... erschiene mir umgekehrt sinnvoller: Die Blätter müssten beim Beenden versteckt und vom AutoOpen-Makro wieder sichtbar gemacht werden (--> kein Makro - keine Blätter); habe ich so allerdings auch noch nicht umgesetzt ...

Grüße
bastla
Member: Noc06
Noc06 Nov 02, 2010 at 14:07:28 (UTC)
Goto Top
Hallo bastla,

ich bleibe vorerst in meinem Ursprungsthread (auch wenn das jetzt mit meinem alten Problem nichts mehr zu tun hat).

Ich habe mit meinen Makro Kenntnissen mal versucht, das ganze inkl. Deinem letzten Tipp umzusetzen (mit einer hoffentlich auch etwas übersichtlicheren Schreibweise).

Herausgekommen ist dabei folgendes (alles in "DieseArbeitsmappe" verfrachtet):


Option Explicit

'*** Definition der benötigten Variablen  

Dim i As Integer   '*** Zählervariable  
Dim Anz As Integer '*** Anzahl der vorhandenen Blätter  
Dim s As Boolean   '*** Speichervariable  
Dim Hinweis As Byte
Dim Cancel As Boolean



'********************************************************************************************  

'*** Was muss beim bzw. vor dem Öffnen der Arbeitsmappe passieren?  
'***  
'*** Es werden alle Blätter der Arbeitsmappe ausgeblendet und der zu bestätigende Disclaimer  
'*** aufgerufen - erst nach dessen Bestätigung werden die restlichen Blätter sichtbar.  
'***  
'*** Das Blatt "MakroHinweis" enthält einen Warntext, der nur erscheint, wenn die Makro-  
'*** sicherheit von Excel zu hoch eingestellt ist und somit eine korrekte Ausführung  
'*** der Arbeitsmappe nicht gewährleistet ist. In diesem Fall erscheint ausschließlich  
'*** das Blatt "MakroHinweis", alle anderen Blätter sollen über [xlVeryHidden] aus-  
'*** geblendet werden.  

'********************************************************************************************  


Private Sub Workbook_Open()

Anz = ActiveWorkbook.Sheets.Count

Application.ScreenUpdating = False

'*** Alle vorhandenen Arbeitsblätter werden gezählt und anschließend in einer Schleife vom   
'*** letzten Blatt bis zum ersten Blatt (in -1 Schritten) heruntergezählt - es gibt zunächst   
'*** keine Begrenzung nach oben (die Anzahl der Blätter betreffend), alle werden mit eingeschlossen.  

For i = Sheets.Count To 1 Step -1  
Sheets(i).Visible = False  
Next i  


'*** Dieses Arbeitsblatt wird ausgeblendet, wenn die Makrosicherheit ausgeschaltet ist.  
Sheets("MakroHinweis").Visible = False   

Sheets(Anz).Visible = False

'*** Diese Blatt enthält einen separat zu bestätigenden Disclaimer - erst danach werden die restlichen Blätter eingeblendet.  
Sheets("Disclaimer").Select         

Application.ScreenUpdating = True

End Sub



'********************************************************************************************  

'*** Was muss vor dem Schließen der Arbeitsmappe passieren?  
'***  
'*** Vor dem Schließen der Arbeitsmappe müssen erst alle enthaltenen Blätter wieder mit  
'*** [xlVeryHidden] versehen werden , so dass diese nicht versehentlich ohne den Sichtschutz  
'*** abgespeichert werden.  
'*** Einzige Ausnahme ist das Blatt "MakroHinweis", welches sichtbar sein soll, falls die  
'*** Excel das Ausführen von Makros nicht zuläßt.  

'*** aufgerufen - erst nach dessen Bestätigung werden die restlichen Blätter sichtbar.  
'***  
'*** Das Blatt "MakroHinweis" enthält einen Warntext, der nur erscheint, wenn die Makro-  
'*** sicherheit von Excel zu hoch eingestellt ist und somit eine korrekte Ausführung  
'*** der Arbeitsmappe nicht gewährleistet ist. In diesem Fall erscheint ausschließlich  
'*** das Blatt "MakroHinweis", alle anderen Blätter sollen über [xlVeryHidden] aus-  
'*** geblendet werden.  

'********************************************************************************************  


Private Sub Workbook_BeforeClose()

If ActiveWorkbook.Saved Then

    Sheets("MakroHinweis").Visible = True  

        For i = Sheets.Count To 1 Step -1

            If Sheets(i).Name <> "MakroHinweis" Then Sheets(i).Visible = xlVeryHidden  

        Next i

    s = True

    ThisWorkbook.Close True

Else

    If s = True Then Exit Sub

    Hinweis = MsgBox("Wollen Sie Ihre Änderungen vor dem Schließen der Arbeitsmappe abspeichern", _  
    vbYesNo + vbQuestion + vbExclamation, "Änderungen abspeichen?", "", 0)  

        If Hinweis = 6 Then ' Die Abfrage des Hinweisfensters wurde "Ja" beantwortet  

            Application.ScreenUpdating = False

            Sheets("MakroHinweis").Visible = True  

             For i = Sheets.Count To 1 Step -1

                If Sheets(i).Name <> "MakroHinweis" Then Sheets(i).Visible = xlVeryHidden  
    
             Next i

            Application.ScreenUpdating = True

            s = True

            ThisWorkbook.Save

        Else

            s = True

            ThisWorkbook.Close False

        End If

End If

End Sub

Sieht zwar schön aus, funktioniert nur leider noch nicht so ganz.... Any ideas?

Gruß
Noc06
Mitglied: 76109
76109 Nov 02, 2010 at 18:26:06 (UTC)
Goto Top
Hallo Noc06!

Ich fange mal bei Workbook_Open an. Und da hast Du ja schon einige Denkfehler drinnenface-wink

1. Codezeile 39-41: Es können nicht alle Tabellenblätter mit Visible = False unsichtbar gemacht werden. Es muss immer mindestens 1 Tabellenblatt sichtbar sein.
2. Codezeile 45-47: Würden sich erübrigen, wenn 1. funktionieren würde
3. Codezeile 50: unsichtbare Sheet's können nicht selektiert werden.

Bei Workbook_BeforeClose erspare ich mir das kommentieren...

Sorry, aber insgesamt ziemlich sinnloser Code, von daher dann das Ganze eher so:
Option Explicit

Const MsgSave = "Wollen Sie Ihre Änderungen vor dem Schließen der Arbeitsmappe abspeichern"  

Private Sub Workbook_Open()
    Sheets("Disclaimer").Visible = True  
    Sheets("MakroHinweis").Visible = xlVeryHidden  
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If ActiveWorkbook.Saved = True Then
        Call WorkbookCleanUp
    ElseIf MsgBox(MsgSave, vbYesNo Or vbQuestion, "Änderungen abspeichen...") = vbNo Then  
        ActiveWorkbook.Saved = True
    Else
        Call WorkbookCleanUp
    End If
End Sub
    
Private Sub WorkbookCleanUp()
    Dim Wks As Worksheet
        
    Application.ScreenUpdating = False

    Sheets("MakroHinweis").Visible = True  
        
    For Each Wks In Sheets
        If Wks.Name <> "MakroHinweis" Then Wks.Visible = xlVeryHidden  
    Next
            
    ActiveWorkbook.Save
        
    Application.ScreenUpdating = True
End Sub
Wobei die Arbeitsmappe inklusive Code mindestens 1 mal abgespeichert werden mussface-wink

Gruß Dieter
Member: Noc06
Noc06 Nov 03, 2010 at 11:27:33 (UTC)
Goto Top
Hallo Dieter,

erstmal Danke, daß Du Dir die Zeit genommen hast, das ganze anzuschauen - ich war mir im Vorfeld bereits durchaus darüber im Klaren, daß der von mir zusammengeschusterte Code sicherlich nicht der Weisheit letzter Schluß sein würde, da sich, wie ich im Vorfeld bereits erwähnt hatte, meine VBA Programmierkenntnisse auf trail-and-error beschränken (abgesehen von ein paar ganz marginalen Grundkenntnissen).

Sicherlich keine saubere Art des Programmierens, aber immerhin habe ich damit bisher immer das erreicht, was ich umsetzen wollte - und da die Programme nicht für die Allgemeinheit bestimmt sind, waren mir etwaige Unsauberkeiten im Regelfall relativ egal.

Aber ich bin ja nicht beratungsresistent und immer dankbar für neue Tipps und Hinweise.

Zu den von Dir angemerkten Punkten 1 bis 3:

1. Codezeile 39-41: Es können nicht alle Tabellenblätter mit Visible = False unsichtbar gemacht werden. Es muss immer
mindestens 1 Tabellenblatt sichtbar sein.

Vollkommen richtig. Ich hatte vorher mit den True/False Werten experimentiert und vergessen, diese wieder richtig zu setzen - so wie von mir geschrieben macht das natürlich wirklich wenig Sinn.

2. Codezeile 45-47: Würden sich erübrigen, wenn 1. funktionieren würde

Danke für den Tipp - ich bin davon ausgegangen, daß man das nochmal separat abbilden müßte.

3. Codezeile 50: unsichtbare Sheet's können nicht selektiert werden.

Auch richtig, siehe Kommentar zu Punkt 1.


Bei Workbook_BeforeClose erspare ich mir das kommentieren...


So schlimm? face-wink


Sorry, aber insgesamt ziemlich sinnloser Code, von daher dann das Ganze eher so:

In diesem Fall Sorry für den Krampf und Danke für Deinen Vorschlag.

Schönen Gruß
Noc06
Member: Noc06
Noc06 Nov 04, 2010 at 14:02:06 (UTC)
Goto Top
Hallo Dieter,

der von Dir vorgeschlagene Code funktioniert super! Danke hierfür.

Ich bin allerdings an einer anderen Stelle gerade mit meinem VBA Latein etwas am Ende und stehe vor folgendem Problem:

Auf dem "Disclaimersheet", welches bei aktivierten Makros angezeigt wird, ist eine Checkbox vorhanden, welche zwingend bestätigt werden muss, bevor die restlichen vorhandenen Blätter angezeigt werden. Wenn ich beispielsweise nach Deiner Zeile 7

 For Each wks In Sheets
        Application.ScreenUpdating = False
        If wks.Name <> "MakroHinweis" Then wks.Visible = True  
Next

einfüge, werden zwar alle Blätter wieder eingeblendet, allerdings führt das natürlich den Disclaimer ad absurdum.

Bisher hatte ich das ganze wie folgt gelöst, was auch problemlos funktionierte:

1.) In "DieseArbeitsmappe":

Option Explicit

Private Sub Workbook_Open()
Dim Anz, i
Anz = ActiveWorkbook.Sheets.Count

For i = Sheets.Count To 2 Step -1     'Blatt 1 ist der Disclaimer und von der Schleife ausgenommen.  

   Application.ScreenUpdating = False
   Sheets(i).Visible = False
   
Next i

Sheets(Anz).Visible = False

Sheets("Sheet_Disclaimer").Select  

End Sub

2.) Im Disclaimer Sheet:

Private Sub chkAccept_Click()
  On Error Resume Next
  Call DisclaimerAccept(chkAccept.Value)
End Sub

Private Sub CheckBox1_Click()

End Sub

3.) Modul "AutoStart"

Private Sub Auto_Open()
Sheets("Disclaimer").Activate  
Sheet_Disclaimer.[b3] = False    'Der Disclaimer wird beim Laden der Arbeitsmappe zurückgesetzt und muss nach jedem Start neu bestätigt werden, bevor alle Arbeitsblätter eingeblendet werden.  

End Sub

4.) Modul "Disclaimer"

Option Explicit

Sub DisclaimerAccept(blnAccepted As Boolean)

Dim sh As Variant
  
  Application.ScreenUpdating = False

  For Each sh In ThisWorkbook.Sheets
    If blnAccepted Then
      sh.Visible = xlSheetVisible
    Else
      If sh.CodeName <> "Sheet_Disclaimer" Then sh.Visible = xlSheetVeryHidden  
    End If

  Next sh
  
End Sub

Versuche ich meine bestehende Lösung mit Deinem Ansatz zu verknüpfen, funtkioniert das ganze leider nicht. Vorgegnagen bin ich wie folgt:

Den Teil aus 4.)

 For Each sh In ThisWorkbook.Sheets
    If blnAccepted Then
      sh.Visible = xlSheetVisible
    Else
      If sh.CodeName <> "Sheet_Disclaimer" Then sh.Visible = xlSheetVeryHidden  
    End If

  Next sh
  

habe ich durch

Dim wks As Worksheet

 For Each wks In Sheets
        Application.ScreenUpdating = False
        If wks.Name <> "MakroHinweis" Then wks.Visible = True  
Next

ersetzt, allerdings funktioniert das ganze so nicht. Es erscheint zwar keine Fehlermeldung, allerdings passiert auch sonst nichts.

Nach meinem Verständnis funktioniert die Übergabe der Variablen nach dem Bestätigen der Checkbox nicht richtig, zumindest schafft der Debugg-Modus es nicht von 2.) Zeile 3 auf 4.) Zeile 3 zu springen. Per F8 bleibt man die ganze Zeit in

Private Sub chkAccept_Click()
  On Error Resume Next
  Call DisclaimerAccept(chkAccept.Value)
End Sub

hängen.

Da ich allerdings nur über rudimentäre VBA Kenntnisse verfüge, vermute ich eher, daß ich bei der "Verschmelzung" nicht richtig vorgegangen bin und es deswegen nicht funktioniert.

Ich wäre Dir sehr dankbar, wenn Du mir bzgl. der Umsetzung nochmal ein wenig unter die Arme greifen könntest.

Danke und schönen Gruß
Noc06
Member: Noc06
Noc06 Nov 04, 2010 at 16:49:02 (UTC)
Goto Top
Die ganze Problematik hat sich gerade erledigt - die Definition der Checkbox war fehlerhaft... Jetzt funktioniert alles wie gewollt.

Nochmals Danke an bastla und didi1954 für die Hilfe!

Gruß
Noc06
Mitglied: 76109
76109 Nov 04, 2010 at 16:51:20 (UTC)
Goto Top
Hallo Noc06!

Ganz schön verwirrendface-wink

Ich schlage folgende Lösung vor:

In meinem Code in Codezeile 24 diese Codezeile einfügen:
    Sheets("Disclaimer").CheckBox1 = False  

Und im Sheet "Disclaimer" diesen Code einfügen:
Private Sub CheckBox1_Click()
    Dim Wks As Worksheet
    
    If CheckBox1 = True Then
        Application.ScreenUpdating = False

        For Each Wks In Sheets
            If Wks.Name <> "MakroHinweis" Then Wks.Visible = True  
        Next
    
        Application.ScreenUpdating = True
    End If
End Sub

Das war's eigentlich schonface-wink

Gruß Dieter

[edit] Mhm, war ich wohl etwas zu langsamface-smile [/edit]
Member: Noc06
Noc06 Nov 05, 2010 at 11:29:53 (UTC)
Goto Top
Hallo Dieter,

Dein Lösungsvorschlag ist programmiertechnisch sicherlich die sauberere Lösung - ich werde es noch entsprechend bei mir anpassen.

Danke für Deine Zeit und Unterstützung!

Schönen Gruß und ein erholsames WE,
Noc06