374 Aufrufe
Gefragt in Tabellenkalkulation von peters Mitglied (323 Punkte)

Hallo zusammen!

Mich beschleicht das Gefühl, irgendwo einen mehr oder minder verdeckten Hirnschaden zu haben ... angry

Also, ich habe dieses Makro:

Private Sub neuerTest2()

    Sheets("Rabatte").Select
    Range("A1:M200").Select
    Range("A1").Activate
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Range("A3").Select
    Application.CutCopyMode = False

End Sub

Wenn ich das im VBA-Projekt der Tabelle im Modul2 laufen lasse, funzt es problemlos.
Nehme ich den Code aber und kopiere den Code ins Codefenster eines Tabellenblattes und führe ihn dort aus, crasht das Ding jedesmal mit einem Laufzeitfehler-1004 "Anwendungs- oder objektdefinierter Fehler"!

Dabei ist es egal, ob ich das Makro als Private Sub oder einfach als Sub definiere.

Kleiner Exkurs zum Hintergrund:
Ich habe in der Entwicklungsumgebung ein Blatt mit verschiedentlichen Makros, die nicht mit ausgeliefert werden nach Fertigstellung bzw. dann auch nicht mehr benötigt werden. Dann wird nur dieses Blatt mit den Schaltflächen und den zugehörigen (also eben im Code des Blattes enthaltenen) Makros gelöscht.

Hat jemand eine Idee, welchen selten dämlichern Stolperpunkt ich übersehe?
Ich vermute ja mal wieder einen echten Stirnklatscher, aber ich komme einfach nicht drauf...!

Gruß

Peter

9 Antworten

+1 Punkt
Beantwortet von m-o Profi (16.3k Punkte)

Hallo Hans,

wenn ich das richtig sehe, kopierst du im Tabellenblatt "Rabatte" den Bereich A1:M200 und fügst die Werte im selben Tabellenblatt in A3 wieder ein.

Bei mir funktioniert der Code sowohl in einem Modul, als auch im Tabellenblatt.

Ich habe dir den Code mal etwas verkürzt:

Sub neuerTest()

With Worksheets("Rabatte")
    .Range("A1:M200").Copy
    .Range("A3").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End With
    
Application.CutCopyMode = False

End Sub

Auf Select kannst du größtenteils verzichten. Im Tabellenblatt würde ich den Code nicht als Private deklarieren.

Gruß

M.O.

0 Punkte
Beantwortet von
Hallo .-)

Select und Activate ist wie das fünfte Rad am Wagen!

In Zukunft kostet dich jedes genutzte Select oder Activate,ein Schoko Muffin (Die mit den großen Schoko krümeln)!

Gruß Michael
+1 Punkt
Beantwortet von
Bearbeitet

Hallo,

das Problem liegt hier:

Sheets("Rabatte").Select
Range("A1:M200").Select

Die Select Methode des Range Objekts funktioniert nur im aktiven Fenster. Mit der ersten Zeile aktivierst  Du das Tabellenblatt Rabatte. Mit der zweiten Zeile willst du dort ein Range Selektieren. Das Range-Objekt ohne Sheets Angabe vorneweg bezieht sich aber auf das Tabellenblatt in dem der Code steht. Da dieses nun nicht mehr aktiv ist, kommt es zu einem Fehler, weil nix sichtbar ist, das selektiert werden könnte. 

In einem normalen Modul bezieht sich das Range Objekt ohne Sheets-Angabe immer auf das aktive Tabellenblatt, daher kommt es dort zu keinem Fehler.

Am besten du verzichtest auf die Select Methode und nimmst M.Os verkürzte Version. Obwohl sich dort ein kleiner Fehler eingeschlichen hat (sorry M.O.) Es muss heißen .Range("A1").PasteSpecial sonst verschieben sich die Zeilen mit jedem Ausführen um 2 nach unten. Das ist so sicher nicht gewollt.

Merke: Es ist nicht egal in welchem Modul sich ein Code befindet. Du musst den Code an die entsprechende Modulart anpassen. Wenn du also am Ende unbedingt mit Select eine bestimmte Zelle anspringen willst, dann so:

Sheets("Rabatte").Select
Sheets("Rabatte").Range("A1").Select

oder so:

With Sheets("Rabatte")
.Select
.Range("A1").Select
End With

Gruß Mr. K.

0 Punkte
Beantwortet von peters Mitglied (323 Punkte)

Guten Morgen,

ich danke Euch für die Erklärungen. Und im Nachhinein betrachtet: Ein echter Strinklatscher!  wink

Durch Eure Erklärungen bin ich mal wieder ein gutes Stück schlauer geworden. Danke!

Gruß

Peter

0 Punkte
Beantwortet von m-o Profi (16.3k Punkte)

Hallo Mr. K,

kein Problem wegen des Fehlers; nobody is perfect smiley.

Gruß

M.O.

0 Punkte
Beantwortet von peters Mitglied (323 Punkte)

M.O. hatte einen "guten Tag" - er hat mich ja auch "Hans" getauft wink

(nehme ich aber nicht krumm smiley)

0 Punkte
Beantwortet von peters Mitglied (323 Punkte)

Nun "hänge" ich schon wieder...! angry

Ich habe den Code nun nach Euren Tips wie folgt eingebaut:

    With Worksheets("Rabatte")
    .Range("A1:A200").Copy

    .Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    .Range("A2").Select
    End With

Die ersten beiden Zeilen, Kopieren und Einfügen, werden einwandfrei erledigt, beim Select auf A2 kommt wieder die Fehlermeldung '1004 - objektorientiert blabla'

Ich dachte, dass ich mich innerhalb des With-Bereiches quasi wie aktiv auf dem Blatt "Rabatte" befinde?

Ich möchte halt in die Zelle A2 gehen, da sonst nach dem Makro der Bereich A1:A200 markiert bleibt, das sieht unschön/halbherzig aus...

Gruß

Peter

0 Punkte
Beantwortet von

Hallo Peter,

nochmal langsam: Das Worksheet Rabatte muss zuerst aktiviert werden, bevor du dort etwas selektieren kannst. Das erzeugst du z.B. in dem du vor .Range("A2").Select einfach noch die Zeile .Select oder alternativ die Zeile .Activate hinzufügst. So wie in meinem zweiten Beispiel gezeigt. Wichtig ist dabei der Punkt vornedran, der anzeigt, dass man sich auf den With Block bezieht. In diesem Fall ist Select oder Activate also ausnahmsweise zwingend erforderlich. 

Mit dem letzten Activate, ohne Punkt davor, aktivierst du dann wieder das Ausgangsblatt sodass dein Abstecher nach Blatt 2 kaum auffällt. Du kannst stattdessen auch Me.Activate schreiben. Das ist gängiger. Ich lass das Me einfach gern weg um zu zeigen, dass man ohne Punkt vornedran immer zunächst die gleichnamigen Eigenschaften und Methoden des Tabellenmoduls aufruft, in dem der Code steht, bevor ein Hauptobjekt aufgerufen wird - gilt auch für das Modul DieseArbeitsmappe, sowie für Userforms und Klassenmodule. Das ist der Unterschied zum normalen Modul.

Sub Kopieren()

    With Worksheets("Rabatte")
    .Range("A1:A200").Copy
    .Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    .Activate
    .Range("A2").Select
    End With

    Application.CutCopyMode = False
    Activate
    
End Sub

Gruß Mr. K.

0 Punkte
Beantwortet von m-o Profi (16.3k Punkte)

Hallo Peter,

was soll ich sagen? Das ist wohl schon meine Alterssenilität blush.

Gruß

M.O.

...