.Select-Methode und .Unprotect funktioniert nicht

  • Excel

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Skorpion79.

    .Select-Methode und .Unprotect funktioniert nicht

    Hallo Mitglieder,
    ich habe eine recht komplexe Excel-Datei, zu der ich auch viele Makros programmiert habe.
    Grundlage dieser Makros ist das auswählen von Objekten, also z. B.:

    Visual Basic-Quellcode

    1. Sheets(1).Select


    oder:

    Visual Basic-Quellcode

    1. Range("A1").Select


    Wenn das angegebene Objekt nicht existiert, gibt er mir die Fehlermeldung "Index ausserhalb des gültigen Bereichs" aus.
    Existiert es allerdings, führt er die .Select-Anweisung einfach nicht aus, ohne dass es einen Fehler gibt.
    Gleiches passiert bei

    Visual Basic-Quellcode

    1. Sheets.Unprotect
    und

    Visual Basic-Quellcode

    1. Sheets.Protect

    Als ich die Makros erstellt habe, funktionierte alles einwandfrei und der Fehler kam erst jetzt.

    Vielen Dank im Voraus,
    vatbub


    Edit by Manschula:Ich vermute, dieses Thema passt besser in dieses Unterforum --> Thema aus dem Hauptforum verschoben

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manschula“ ()

    Erstmal Willkommen im Forum :thumbup:

    Zu deinem Schutzproblem: Du musst VBA schon sagen welches Tabellenblatt geschützt werden soll und welches nicht.
    Möglichkeiten:

    Visual Basic-Quellcode

    1. Worksheets(1).Unprotect
    2. ' bzw
    3. Worksheets(1).Protect

    oder:

    Visual Basic-Quellcode

    1. Activesheet.Unprotect
    2. ' bzw
    3. Activesheet.Protect


    führt er die .Select-Anweisung einfach nicht aus


    Wie wäre es, wenn Du Deine Anwendung so umbaust, das Du Select gar nicht erst brauchst? Select ist eine "böse" VBA Funktion und sollte, bis auf wenige Ausnahmen, aus dem Code verbannt werden.

    Skorpion79 schrieb:

    Du musst VBA schon sagen welches Tabellenblatt geschützt werden soll und welches nicht.


    Schon klar, dass ich nen Index angeben muss, aber im Beispiel hab ich drauf verzichtet.


    Skorpion79 schrieb:

    Wie wäre es, wenn Du Deine Anwendung so umbaust, das Du Select gar nicht erst brauchst? Select ist eine "böse" VBA Funktion und sollte, bis auf wenige Ausnahmen, aus dem Code verbannt werden.


    Jap, habe ich auch dran gedacht, aber dann bleibt halt noch des Problem mit .Protect und .Unprotect

    Gruss,
    vatbub
    So, hier ist jetzt beispielhaft der Code, der eine Sicherungsdatei importiert, der wenn die Daten in der Datei kaputt gegangen sind, sie aus einer Sicherung importiert.

    Ich habe ihn bereits so überarbeitet, dass .Select und .Activate nur am Schluss vorkommen.
    SicherungDatenPrüfen ist eine UserForm, die dazu dient, die Daten, wie Schuljahr, Schulfach etc., die in der Sicherungsdatei gefunden wurden, vom Nutzer überprüfen zu lassen.
    Sämtliche Sub-Funktionen, die mit 'Call' aufgerufen werden, haben das gleiche Problem mit .Protect und .Unprotect


    Visual Basic-Quellcode

    1. Sub SicherungImportieren()
    2. Dim MsgBoxR As VbMsgBoxResult
    3. On Error GoTo Fehler 'Importiert Daten aus einer Sicherungsdatei
    4. Dim DateinameStamm, DateinameImport As String
    5. Start:
    6. DateinameStamm = ActiveWorkbook.Name
    7. If Range("A1").Value = "Notenverwaltung - Sicherung" Then
    8. ActiveWorkbook.Save
    9. Application.DisplayAlerts = False
    10. ActiveWorkbook.Close
    11. Application.DisplayAlerts = True
    12. GoTo Start
    13. End If
    14. MsgBox Prompt:="Herzlich Willkommen zum Assistenten zum Wiederherstellen einer Sicherungsdatei! Bitte wählen Sie die Sicherungsdatei aus.", Title:="Sicherung Wiederherstellen"
    15. DateiWaehlen:
    16. On Error GoTo Windows7
    17. Application.Dialogs(xlDialogOpen).Show ("C:\Dokumente und Einstellungen\" & Application.UserName & "\Eigene Dateien")
    18. DateinameImport = ActiveWorkbook.Name
    19. If DateinameImport = DateinameStamm Then
    20. Exit Sub
    21. End If
    22. On Error GoTo DateiUngeeignet
    23. With Workbooks(DateinameImport).Sheets("Persdaten")
    24. If Not .Range("A1").Value = "Notenverwaltung - Sicherung" Then GoTo DateiUngeeignet
    25. On Error GoTo Fehler
    26. Dim Klasse2, Jahr2, Fach2, VersionSicherung, VersionStamm As String
    27. Klasse2 = .Range("B5").Value
    28. Jahr2 = .Range("B6").Value
    29. Fach2 = .Range("B7").Value
    30. VersionSicherung = .Range("B8").Value
    31. End With
    32. Datenprüfung:
    33. With SicherungDatenPrüfen
    34. .Klasse = Klasse2
    35. .Jahr = Jahr2
    36. .Fach = Fach2
    37. .Show
    38. End With
    39. Application.ScreenUpdating = False
    40. 'Schreibt Daten in die Originaldatei
    41. With Workbooks(DateinameStamm).Sheets(1)
    42. .Range("J10").Value = SicherungDatenPrüfen.Klasse
    43. .Range("J12").Value = SicherungDatenPrüfen.Fach
    44. .Range("J14").Value = SicherungDatenPrüfen.Jahr
    45. End With 'Kopiert die Klassenliste
    46. Workbooks(DateinameImport).Sheets(2).Range("B4:C38").Copy Workbooks(DateinameStamm).Sheets(2).Range("B4").PasteSpecial Paste:=xlPasteValues, SkipBlanks:=False
    47. 'Kopieren der Arbeiten
    48. Dim BlattName As String
    49. Dim Vorhanden As Boolean
    50. Dim AlterName As String
    51. For Z = 3 To Sheets.Count
    52. With Workbooks(DateinameImport)
    53. BlattName = .Sheets(Z).Name
    54. .Sheets(Z).Range("C5:R7").Copy
    55. End With
    56. With Workbooks(DateinameStamm)
    57. Vorhanden = False
    58. For i = 3 To Sheets.Count
    59. If .Sheets(i).Name = BlattName Then
    60. Vorhanden = True
    61. End If
    62. Next i
    63. If Vorhanden = False Then
    64. Call NeueArbeitEinfügen
    65. AlterName = ActiveSheet.Name
    66. Sheets(ActiveSheet.Name).Name = BlattName
    67. Call NeueArbeitSchreiben3(BlattName)
    68. End If
    69. With .Sheets(BlattName)
    70. On Error Resume Next
    71. .Unprotect
    72. .Range("C5").PasteSpecial Paste:=xlPasteValues, SkipBlanks:=True
    73. End With
    74. End With
    75. Set SheetImport = Workbooks(DateinameImport).Sheets(Z)
    76. Set SheetStamm = Workbooks(DateinameStamm).Sheets(BlattName) SheetImport.Range("C9:R43").Copy
    77. SheetStamm.Range("C9").PasteSpecial Paste:=xlPasteValues, SkipBlanks:=False
    78. SheetImport.Range("D1:J1").Copy
    79. SheetStamm.Range("D1").PasteSpecial Paste:=xlPasteValues, SkipBlanks:=False
    80. SheetImport.Range("A47:A48").Copy
    81. SheetStamm.Range("A47").PasteSpecial Paste:=xlPasteAll, SkipBlanks:=False
    82. SheetStamm.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
    83. SheetStamm.Name = BlattName
    84. Next Z
    85. On Error GoTo Fehler
    86. Workbooks(DateinameStamm).Sheets("Über").Range("E4").Value = Workbooks(DateinameImport).Path & "\" & Workbooks(DateinameImport).Name
    87. Application.DisplayAlerts = False
    88. Workbooks(DateinameImport).Close
    89. Application.DisplayAlerts = True
    90. Workbooks(DateinameStamm).Sheets(1).Select
    91. Application.ScreenUpdating = True
    92. MsgBox "Die Sicherung wurde erfolgreich importiert, ohne dass Arbeiten, die nicht in der Sicherungsdatei erwähnt waren gelöscht wurden. Die Registerkarten wurden nicht geordnet."
    93. Call ArbeitenAktualisieren
    94. Call Speichern
    95. Exit Sub
    96. Fehler:
    97. Application.ScreenUpdating = True
    98. MsgBoxR = MsgBox("Währrend des Vorgangs trat folgender Fehler auf: " & Err.Description & " (Fehler-Nr.: " & Err.Number & ")", vbCritical, "Fehler")
    99. Resume Next
    100. Windows7:
    101. Application.Dialogs(xlDialogOpen).Show ("C:\Users\" & Application.UserName & "\Documents")
    102. GoTo DateiWaehlen
    103. DateiUngeeignet:
    104. With Application
    105. .DisplayAlerts = False
    106. Workbooks(DateinameImport).Close
    107. .DisplayAlerts = True
    108. .ScreenUpdating = True
    109. End With
    110. MsgBoxR = MsgBox("Die gewählte Datei ist keine Sicherungsdatei von Notenverwaltung oder wurde nicht als solche erkannt! Bitte wählen Sie eine entsprechende Sicherungsdatei aus!", vbCritical, "Keine Sicherungsdatei erkannt")
    111. GoTo DateiWaehlen
    112. End Sub
    In Zeile 67 übergibts Du das Blatt an eine Prozedur, hebst den Blattschutz aber erst in Zeile 71 auf. Also kommt Unprotect zu spät. Erst den Blattschutz aufheben und dann mit den Zellen arbeiten. Den Blattschutz erst wieder reinmachen, wenn alles erledigt ist. Das Select kannst Du erstmal so lassen.

    BTW: Auch GoTo ist mittlerweile eine böse Funktion und sollte, bis auf wenige Ausnahmen (On Error GoTo Fehler), nicht mehr verwendet werden. Heißt das Du Deine Anwendung nochmal grundlegend überdenken solltest. Jetzt hast Du Spaghetti Code und das macht man heute nicht mehr.
    Das ist kein Fehler, denn in Zeile 58 ff. wird überprüft, ob das Blatt vorhanden ist. Ist es nicht vorhanden, erstellen die Prozenduren NeueArbeitEinfuegen und NeueArbeitSchreiben3 ein neues, das automatisch geschützt wird, da die Prozeduren auch durch den Nutzer einzeln aufgerufen werden können und danach nichts mehr passiert.

    Jetzt liegt also auf jeden Fall ein geschütztes Blatt vor, egal ob es schon davor da war oder neu erstellt wurde, das entsperrt wird und in das dann etwas geschrieben wird.

    Die Reihenfolge ist hier also nicht das Problem, sondern, dass .Unprotect ohne Fehlermeldung nicht ausgeführt wird.
    Füge zwischen das einfügen in Zelle C5 und dem Unprotect Befehl mal folgendes ein:

    Visual Basic-Quellcode

    1. MsgBox .ProtectContents

    Steht in der MsgBox "Falsch" wurde Unprotect ausgeführt. Bei "Wahr" wurde Unprotect ignoriert (aus welchen Gründen auch immer)
    Das On Error Resume Next solltest Du testweise auch mal entfernen. Das unterdrückt eine eventuelle Fehlermeldung.