Supportnet Computer
Planet of Tech

Supportnet / Forum / Tabellenkalkulation

Einfügen von Tabellenblättern per VBA u.a.





Frage

Hallo allerseits, ich habe einige Fragen im Zusammenhang mit dem Einfügen von Tabellenblättern per VBA: Dazu will ich per CommandButton, wenn es nicht schon vorhanden ist, ein Tabellenblatt erstellen lassen und dorthin Zelleninhalte von einem anderen Blatt in die erste freie Zeile kopieren. Dazu will ich wissen: 1.) Wie stelle ich fest ob es ein Blatt mit einem bestimmten Namen schon gibt? Geht das auch mit "Find"? 2.) Den Befehl zum Einfügen eines Tabellenblatts kenne ich. Problem ist, wie bennne ich es mit einem Namen (Bsp. "Neues Blatt"), wenn ich nicht weiß wie es heißt nachdem es eingefügt worden ist. (Je nachdem wieviele Blätter es schon in der Mappe gibt, benennt Excel das Blatt Tabelle5, Tabelle6 usw.) Der Befehl Sheets.add.name("Neues Blatt") ginge, allerdings steht das Blatt dann vor dem zuletzt aktiven. Will ich dem neuen Blatt eine bestimmte Position (in diesem Fall hinter dem Blatt "Daten") zuweisen lautet der Befehl: Sheets.Add after:=Worksheets("Daten") Das läßt die gleichzeitige Benennung nicht mehr zu, soweit ich weiß. Um es zu aktivieren muss ich wiederrum seinen Namen kennen... 3.) Wie spreche ich einen Zellbereich an, wenn die Zeilennummern der Anfangs- und Endzeile durch eine Variable definiert ist? Sprich, wenn ich den Bereich von ("Zeile1", Spalte 1) bis ("Zeile2", Spalte 10) kopieren will und eine andere Prozedur bspw. Zeile1 und Zeile2 folgendermaßen belegt: Zeile1 = 175 Zeile2 = 185 Worksheets("Daten").Range(Cells(Zeile1,1),Cells(Zeile2,10)).copy Bin ich da auf der richtigen Spur? Vielen Dank für alle Bemühungen! Es dient einem guten Zweck - meine Diplomarbeit! ;-) Hannes

Antwort 1 von coros

Hallo Hannes,

ich habe Dir mal ein Makro erstellt, welches prüft, ob es bereits ein Blatt mit dem Namen „Neues Blatt“ existiert. Wenn nicht, wird ein neues Blatt an 2. Stelle mit dem Namen „Neues Blatt“ eingefügt. Kopiere das nachfolgende Makro in ein StandardModul und starte es mit einer Startfläche.

Option Explicit

Sub Blatt_einfügen()
Dim Wiederholungen As Integer, Blatt_vorhanden As Boolean
For Wiederholungen = 1 To Worksheets.Count
If Sheets(Wiederholungen).Name = "Neues Blatt" Then Blatt_vorhanden = True
Next
If Blatt_vorhanden = False Then
With Worksheets.Add(Sheets(2))
.Name = "Neues Blatt"
End With
End If
End Sub


Soll ein anderer Blattname geprüft werden, muss überall, wo der Text „Neues Blatt“ vorkommt, der zu prüfende Blattname eingetragen werden. Soll das Blatt an anderer Stelle als 2 eingefügt werden muss in der Zeile

With Worksheets.Add(Sheets(2))

die Zahl 2 gegen die Stellenzahl, an der das Blatt eingefügt werden soll, geändert werden.

Ich hoffe, dass ich Dich richtig verstanden habe und Frage 1 und 2 damit beantwortet sind. Zu Frage 3, da bist auf dem richtigen Weg. Wobei ich da noch nicht so ganz verstehe, was Du vorhast.

Bei Fragen melde Dich bitte.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du ein
Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 2 von Hanso

Hallo Oliver,

auf Dich hatte ich gehofft! ;-) Du hattest Dir letztens schon mit den Steuerelementen große Mühe gegeben! Dafür vielen Dank nochmal! (Ich hatte übrigens, allerdings erst einige Zeit später, die aus meiner Problemstellung heraus abschließende Antwort angefügt)
Zum aktuellen Problem: Das ist genau das was ich brauche! Den Befehl als With... und dann "add" und "name" auszuführen ist eine gute Idee. Kannte ich in diesem Zusammenhang nicht. Das bereits vorhandenes Tabellenblatt mit einer Schleife zu suchen - da hätte ich eigentlich selber drauf kommen sollen! Wie doof auch - ich war zu sehr auf einen expliziten "Such"-Befehl fixiert.
Die Frage 3 kriege ich auch selbst hin sobald ich endlich meine Excel Bücher habe die, momentan im Institut liegen. Ich will halt einen Zellbereich definieren, wobei die Zeilen durch Variablen benannt werden. Aber dafür find ich schon noch die richtige Syntax.
Also vielen Dank nochmal!!!

Hannes

Antwort 3 von coros

Hi Hannes,

freut mich, dass Dir das Makro geholfen hat. Danke auch für die Rückmeldung.

Zu 3. hatte ich ja schon geschrieben, dass das der richtige Weg ist. Den Befehl den Du da aufführst, kopiert Dir den Wert in Tabellenblatt „Daten“ aus dem Bereich A175 bis J185. Wenn es das ist, was Du erreichen wolltest, ist der Syntax richtig.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du ein
Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 4 von Hanso

Jetzt muss ich doch nochmal nachfragen:

Ich möchte, dass das neue Blatt als letztes eingefügt wird. Mit dem Count Befehl wird es aber vor dem letzten eingefügt. Möchte ich die Option "After" ähnlich wie im Beispiel der Excel Hilfe (s.u.) einfügen funktioniert die "With"-Methode nicht. Kannst Du mir da nochmal einen Hinweis geben? Danke!
ActiveWorkbook.Sheets.Add Before:=Worksheets(Worksheets.Count)

Hannes

Antwort 5 von coros

Hi Hannes,

dann muss das Makro in der With-Anweisung um die Zeile

.Move After:=Sheets(Worksheets.Count)

erweitert werden. Somit lautet das Makro dann

Option Explicit

Sub Blatt_einfügen()
Dim Wiederholungen As Integer, Blatt_vorhanden As Boolean
For Wiederholungen = 1 To Worksheets.Count
If Sheets(Wiederholungen).Name = "Neues Blatt" Then Blatt_vorhanden = True
Next
If Blatt_vorhanden = False Then
With Worksheets.Add
.Name = "Neues Blatt"
.Move After:=Sheets(Worksheets.Count)
End With
End If
End Sub


Viel Spaß mit dem Makro.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du ein
Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 6 von Hanso

Hallo nochmal,
ich weiß zwar nicht ob jemand einen so langen Thread noch bis zum Ende liest, aber ich probiers trotzdem nochmal hier.

Irgendwie scheinen die einfachsten Dinge heute die schwierigsten zu sein.... Die oben empfohlenden Vorgehensweisen funktionieren aber! :-)
Hier meine Prozedur soweit:

Private Sub cobt_zwischen_Click()

Dim i As Integer, Anfang As Integer, Ende As Integer
Dim Blatt_vorhanden As Boolean
Dim Leere_Zeile As Range

Anfang = 173 ´Hier zu Testzwecken benannt. Wird später aus einer anderen Prozedur beigesteuert
Ende = 192

For i = Worksheets.Count To 1 Step -1
If Sheets(i).Name = "Zwischenergebnisse" Then
Blatt_vorhanden = True
Exit For
End If
Next i

If Blatt_vorhanden = False Then
With Worksheets.Add
.Name = "Zwischenergebnisse"
.Move After:=Sheets(Worksheets.Count)
End With
End If

Set Leere_Zeile = Worksheets("Zwischenergebnisse").Range("A:A").Find("")

Worksheets("Daten").Range(Cells(Anfang, 1), Cells(Ende, 9)).Copy_
Destination:=Worksheets("Zwischenergebnisse").Range("A1")
´An dieser Stelle kommt die Meldung: "Anwendungs- oder objektdefinierter Fehler" Was ist falsch??? :-(
´Statt Range("A1") soll hier die erste leere Zeile, benannt durch "Leere_Zeile" eingesetzt werden. Aber erstmal muss der Rest funktionieren!!!

Worksheets("Zwischenergebnisse").Activate
End Sub

Auch die "Find" Funktion liefert eine Fehlermeldung, wenn das Tabellenblatt noch völlig leer ist... Die Kopier Methode habe ich in einem Handbuch als auch in der Excel-Hilfe nachgeschlagen und verschiedene Varianten ausprobiert. U.a. auch in der Art

worksheets("Daten").activate
Range((Cells(180,1),cells(190,10).select
selection copy
usw...
Also alles ganz brav nacheinander, wie es mitgeschrieben wird, wenn man es als Makro aufzeichnet.
Vielleicht sehe ich ja heute auch den Wald vor lauter Bäumen nicht...

Viele Grüße,

Hannes

Antwort 7 von coros

Moin Hannes,

nachfolgend Dein Code so abgeändert, dass er auch bei Dir funktionieren sollte.

Private Sub cobt_zwischen_Click()

Dim i As Integer, Anfang As Integer, Ende As Integer
Dim Blatt_vorhanden As Boolean
Application.ScreenUpdating = False
Rem:Hier zu Testzwecken benannt. Wird später aus einer anderen Prozedur beigesteuert
Ende = 192
Anfang = 173

For i = Worksheets.Count To 1 Step -1
If Sheets(i).Name = "Zwischenergebnisse" Then
Blatt_vorhanden = True
Exit For
End If
Next i


If Blatt_vorhanden = False Then
With Worksheets.Add
.Name = "Zwischenergebnisse"
.Move After:=Sheets(Worksheets.Count)
End With
End If

Sheets("Daten").Activate
Sheets("Daten").Range(Cells(Anfang, 1), Cells(Ende, 9)).Copy
Worksheets("Zwischenergebnisse").Cells(Worksheets("Zwischenergebnisse") _
.Range("A65536").End(xlUp).Offset(1, 0).Row, 1).PasteSpecial Paste:=xlPasteValues
Worksheets("Zwischenergebnisse").Activate
End Sub


Teste den mal und melde Dich, wenn etwas nicht stimmt.

Was Du mit der Zeile

Set Leere_Zeile = Worksheets("Zwischenergebnisse").Range("A:A").Find("")

erreichen wolltest, weiß ich nicht so ganz, aber die erste leere Zeile findest Du damit nicht. Der richtige Code dazu lautet für eine Spalte

Set Leere_Zeile = Worksheets("Zwischenergebnisse").Range("A65536").End(xlUp).Offset(1, 0).Row

Wobei Du auf das Set verzichten kannst, denn Du willst der Variablen „Leere_Zeile“ keinen Objektverweis oder so zuweisen, sondern lediglich die ermittelte Zeilennummer übergeben, so dass diese an anderer Stelle in dem Code oder in VBA noch mal herangezogen werden kann. Ich habe allerdings auf das übergeben des Wertes an eine variable verzichtet, sondern den Syntax zum ermitteln der Zeile mit in den Befehl zum Einfügen des Bereiches in Blatt „Zwischenergebnisse“ mit integriert.

Übrigens, Du musst mir nicht immer den gleichen Beitrag, den Du hier schreibst auch in den Pager schreiben. Ich schaue mehrfach am Tag hier vorbei und beantworte dann auch die Fragen. Mir fällt weniger auf, wenn im Pager etwas steht, als dass eine neue Antwort auf einen Beitrag, an dem ich beteiligt bin, vorhanden ist.

So, das war’s für den Moment. Bis dann.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du ein
Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 8 von nighty

hi hanso :)

benutze fuer die findmethode diese abfrage

gruss nighty

If Not Leere_Zeile Is Nothing Then

else

end if

Antwort 9 von Hanso

Hallo Oliver,

ich habe jetzt Deinen Code kopiert und ausprobiert. Leider bleibt er immer noch an der Zeile

Sheets("Daten").Range(Cells(Anfang, 1), Cells(Ende, 9)).Copy


mit der Meldung "Laufzeitfehler 1004, Anwendungs- oder objektdefinierter Fehler" hängen.
Wenn ich Sheets("Daten") weglasse und nur

Range(Cells(Anfang, 1), Cells(Ende, 9)).Copy


schreibe, wird der Bereich aus dem ersten Tabellenblatt der Mappe kopiert, obwohl vorher ja das richtige Blatt ("Daten") aktiviert wird.
Statt mit Sheets mit

Worksheets("Daten").Range(Cells(Anfang, 1), Cells(Ende, 9)).Copy


den Bereich anzusprechen hilft auch nicht.
Soweit ich das verstehe ist der einzige Unterschied zwischen Sheets und Worksheets der, dass Sheets Blätter im allgemeinen und Worksheets Tabellenblätter anspricht, was hier aber keinen Unterschied machen dürfte.
Was nu?
Vielen Dank für Deine Geduld! Ich habe selbst auch meine Bücher gewälzt, aber leider nichts aufschlussreiches gefunden. Die "Find"-Methode kommt übrigens wörtlich aus Said Baloui, "Excel 2002 Kompendium", funktioniert aber nicht. :-(

Hannes

Antwort 10 von coros

Hallo Hannes,

führe den Code mal nicht in einem Ereignis der Schaltfläche aus, sondern kopiere den Code in Makro in einem StandarModul. Also z.B.

Sub Daten_kopieren()
Dim i As Integer, Anfang As Integer, Ende As Integer
Dim Blatt_vorhanden As Boolean
Application.ScreenUpdating = False
Rem:Hier zu Testzwecken benannt. Wird später aus einer anderen Prozedur beigesteuert
Ende = 192
Anfang = 173

For i = Worksheets.Count To 1 Step -1
If Sheets(i).Name = "Zwischenergebnisse" Then
Blatt_vorhanden = True
Exit For
End If
Next i


If Blatt_vorhanden = False Then
With Worksheets.Add
.Name = "Zwischenergebnisse"
.Move After:=Sheets(Worksheets.Count)
End With
End If

Sheets("Daten").Activate
Sheets("Daten").Range(Cells(Anfang, 1), Cells(Ende, 9)).Copy
Worksheets("Zwischenergebnisse").Cells(Worksheets("Zwischenergebnisse") _
.Range("A65536").End(xlUp).Offset(1, 0).Row, 1).PasteSpecial Paste:=xlPasteValues
Worksheets("Zwischenergebnisse").Activate
End Sub


Starte das Makro mit der Schaltfläche, über das Du vorher den Code gestartet hast. Also, z.B.

Private Sub cobt_zwischen_Click() 
Daten_kopieren
End Sub


Dann sollte es funktionieren. Wobei bei mir auch der von mir gepostetet Code funktioniert hatte. Aber auch auf diese Weise sollte es funktionieren.

MfG,
Oliver
Da hier der einzige Lohn für die Helfer eine Rückmeldung ist, wäre es nett, wenn Du ein
Feedback abgeben könntest, ob der Lösungsvorschlag Dein Problem gelöst hat.

Antwort 11 von Hanso

Jau!!!!!!!!!!! Das hat funktioniert!!!! :-D

Super riesen vielen großen Dank!!!!

Weshalb das vorher nicht ging bleibt mir zwar schleierhaft, aber jetzt ist erstmal wichtig dass es vorwärts geht!
Ich habe sowieso den Verdacht dass bei VBA nicht immer alles völlig eindeutig funktioniert... Aber vielleicht waren es dann auch meine Fehler. Beispielsweise funktionierte mal ein Code bei schrittweiser Abarbeitung (F8), aber nicht bei schnellem vollständigem Ablauf.

Also vielen Dank nochmal und viele Grüße,

Hannes

Ich möchte kostenlos eine Frage an die Mitglieder stellen:


Ähnliche Themen:


Suche in allen vorhandenen Beiträgen: