Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1968to1972
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

VBA - Leerzeilen einfügen mit Bedingung

VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 15:56:20
Schneider, Franz
Hallo,

in eine Tabelle füge ich eine Leerzeile ein, wenn ab der Startzeile in der Spalte L (mit Zahlen) die Zahl gleich oder größer ist, als die Zahl in der Folgezeile. In der Tabelle existieren bei Beginn ab der Startzeile keine Leerzeilen. Diese Prozedur funktioniert auch wie gewünscht, wenn es auch einige Sekunden dauert. Leider steigt die Ablaufdauer auf über eine Minute, je häufiger ich untenstehende Prozedur aufrufe:



Sub Leerzeilen_einfügen_01()
Dim altPl As String
Dim anzLZ As Long
Dim letzteZeile As Long
Dim neuNam As String
Dim startZeile As Long
Dim ws As Worksheet
Dim zeile As Long
startZeile = 9
anzLZ = 1
Set ws = ActiveSheet
altPl = ws.Cells(startZeile, "L")
zeile = startZeile
Do Until IsEmpty(ws.Cells(zeile, "L"))
neuPl = ws.Cells(zeile, "L")
If neuPl = altPl Then
ws.Rows(zeile).Resize(anzLZ).Insert
zeile = zeile + anzLZ
altPl = neuPl
End If
zeile = zeile + 1
Loop
Set ws = Nothing
End Sub


Ich muss erwähnen, dass diese Prozedur innerhalb einer übergeordneten umfangreichen Prozedur über eine Call-Anweisung aufgerufen wird. Wenn ich diese Call-Anweisung "abschalte", dann läuft diese Prozedur wunschgemäß in ca. 1 Sekunde ab.

Das gleiche Problem tritt bei der folgenden Prozedur auf:



Sub Leerzeilen_Einfügen_02()
Dim Zei As Long
For Zei = Cells(Rows.Count, 2).End(xlUp).Row To 9 Step -1
If Cells(Zei, 12).Value = Cells(Zei - 1, 12).Value Then
Rows(Zei & ":" & Zei).Insert
End If
Next Zei
End Sub


Hat jemand eine Idee, warum das so ist und wie ich die Prozedur gestalten muss, damit die Ablaufzeit wieder auf "Normal" fällt?

Viele Grüße
Franz

16
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 16:04:08
schauan
Hallöchen,

ich vermute, dass da Berechnungen oder Eventmakros laufen?
Schalte mal temporär Events auf False und Berechnungen auf manuell, falls das nix durcheinander bringt ...
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 18:39:43
Schneider, Franz
Hallo schauan,
danke für deine Antwort. Leider kann ich deine Ratschläge nicht testen, da ich wegen meiner wenigen VBA-Kenntnisse nicht weiß, wie ich das anstellen muss. Die Originaldatei ist sehr umfangreich und untereinander verknüpft. Hochladen kann ich sie auch nicht, da Personaldaten enthalten sind. Ich versuche erst einmal den Vorschlag von Daniel umzusetzen.
Gruß Franz
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 19:03:42
daniel
Hi
google mal "GetMoreSpeed"
wenn du was in Excel machst, führt Excel immer auch bestimmte Aktionen im Hintergrund durch, die u.U. Zeit kosten.
mit den Befehlen, die du dort findest, kannst du einige dieser Hintergrundaktionen temporär deaktivieren, was das Makro beschleunigen kann
(allerdings lassen sich nicht alle dieser Hintergrundaktionen ausschalten)

Gruß Daniel
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 16:10:28
daniel
Hi
lade mal die Datei hoch.
vielleicht gibt es auch schnellere Methoden, um Leerzeilen einzufügen
"Insert" ist für Excel ein aufwendiger Vorgang.
Wesentlich schneller ist Sortieren.
Wenn man "schnell" viele Zeilen einfügen will, dann kann man das so machen:
1. man fügt am ende der Daten eine Spalte an, die alle Zeilennummern enthält.
2. unterhalb dieser Spalte fügt man dann alle Zeilennummern ein, nach denen eine Leerzeile eingefügt werden muss.
3. man sortiert die ganze Liste (inklusive der neuen Zeilen) nach dieser Spalte und löscht die Spalte.

Gruß Daniel
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 18:30:13
Schneider, Franz
Hallo Daniel,

danke für die schnelle Antwort. Meine sehr umfangreiche Originaldatei kann ich nicht hochladen, weil sie als Vereinsdatei persönliche Daten enthält. Ggf. müsste ich eine Musterdatei erstellen. Da ich jedoch alles andere als ein Profi bin, brauche ich dazu freie Zeit, die knapp ist. Zunächst versuche ich erst einmal deine Alternative mit dem Sortieren. Wenn ich damit zurechtgekommen bin (oder auch nicht), melde ich mich wieder.

Noch eine Anmerkung: Wenn ich die Datei schließe und den PC ab- und nach kurzer Zeit wieder einschalte, dann beträgt die Ablaufdauer wieder nur einige Sekunden. Es scheint mir, als wenn beim Ablauf Daten im Hintergrund gespeichert werden (aber wo?), sich dort festsetzen und den nächsten Durchlauf zeitlich hinauszögern. Wenn man den Speicherort kennt, dann müsste man ihn auch wieder zurückstellen können - ohne Neustart des PC.

Gruß Franz
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 18:40:07
daniel
naja, um das zu beantworten, müsste man schon wissen, was du in der Datei alles machst.
da bringt raten nichts. Ist wie beim Arzt. Diagnose ohne Patient = schwierig.
wenn persönliche Daten drin sind, dann halt abändern.
am einfachsten die Namen: Vorname1, Vorname2, Nachname1, Nachname2 usw tuts ja auch. und wenn die alle im Musterort plz 99999 wohnen, tut das der funktionaltät des Makros keinen abbruchl.
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 18:51:26
Schneider, Franz
Ich werde mal sehen, was ich in der mir zur Verfügung stehenden Zeit zustande bringe.
AW: VBA - Leerzeilen einfügen mit Bedingung
12.03.2024 19:09:08
Schneider, Franz
Hallo Daniel,

vielleicht hast du schon gelesen, dass sich mein Problem mit dem verzögerten Programmablauf durch meine Prozedur für das Einfügen von Leerzeilen vermutlich in Wohlgefallen aufgelöst hat und ich diesbezüglich nicht weiter experimentieren werde. Aber dein Vorschlag mit den Zeilennummern in einer Hilfsspalte reizt mich, ihn mit deiner Hilfe umzusetzen. Ich verspreche mir davon einen höheren Zeitgewinn.

Per VBA eine Spalte einzusetzen oder eine vorhandene freie Spalte zu nutzen und die Zeilennummern als Werte einzufügen, das traue ich mir zu. Aber wie bekomme ich mit VBA die Zeilennummer, nach der eine freie Zeile eingefügt werden soll, für eine Sortierung (vermutlich ergänzt um ein weiteres Kennzeichen) unter die bereits vorhandenen Zeilennummern und das mit einer Schleife? Die freien Zeilen sollen da eingefügt werden, wo die in der Spalte vorher stehende Zahl größer oder gleich ist als die darunter stehende Zahl.

Ich hoffe, du kannst mir da weiter helfen oder mir einen Beispielcode geben. Vielen Dank.

Gruß Franz
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
12.03.2024 19:41:23
daniel
Hi

nein, das macht man NICHT per schleife, sondern per Formel
also im Prinzip so am ende der Tabelle

Sub test()

With ActiveSheet.UsedRange 'genutzter Tabellenbereich
With .Columns(.Columns.Count + 1).Resize(.Rows.Count - 1, 2).Offset(1, 0) ' zwei spalten am ende des genutzten Bereichs, ab Zeile 2 (0hne Überschrift)
.Columns(1).FormulaR1C1 = "=Row()" 'zeilennummer in der ersten Spalte
.Columns(2).FormulaR1C1 = "=IF(RC1>=R[1]C1,row(),"""")" 'Formel, die kennzeichnet, wo Zeilen eingefügt werden müssen
.Formula = .Value 'formeln eleminieren
.Columns(2).Cut Destination:=.Columns(1).Offset(.Rows.Count) 'Zweite Spalte unter die erste verschieben
With .Columns(1).Resize(.Rows.Count * 2) 'neuen bereich (doppelte Zeilen) für das Sortieren festlegen
.EntireRow.Sort Key1:=.Cells(1, 1), order1:=xlAscending, Header:=xlNo 'sortieren
.ClearContents 'Aufräumen
End With
End With
End With

End Sub


das wäre mal ein Beispielcode, der zeigt wie dich das gemeint habe.
die formel zum Kennzeichen der stellen, wo zeilen eingefügt werden sollen, musst du ggf noch anpassen (aber das kannst du ja auch in der Tabelle selbst ausprobieren, ist ja ne normale Excelformel) Ich habe versucht, das was du beschrieben hast für die Spalte A umzusetzen (wie gesagt, ich habe keine Datei von dir , daher ist der Code immer nur beispielhaft und muss von dir wahrscheinlich noch angepasst werden)

Gruß Daniel

Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
13.03.2024 13:27:56
Schneider, Franz
Hallo Daniel,

das ist genau das, was ich mir vorgestellt habe. Danke.

Um festzustellen, an welchen Stellschrauben ich drehen muss, um deine Test-Prozedur an meine Bedingungen anzupassen, habe ich die Tabelle um eine Spalte nach rechts gerückt und drei Überschriftszeilen eingefügt. Da bei einigen Tabellen zwei oder mehr Leerzeilen (für das spätere Einfügen von Text) eingefügt werden müssen, habe ich auch das nach meiner Art umgesetzt und es funktioniert:



Sub test_02()

' *** Verschieben der Tabelle um 1 Spalte mit 3 Überschriftszeilen und Einfügen von 2 Leerzeilen ***

With ActiveSheet.UsedRange
With .Columns(.Columns.Count + 1).Resize(.Rows.Count - 3, 3).Offset(3, 0)
.Columns(1).FormulaR1C1 = "=Row()"
.Columns(2).FormulaR1C1 = "=IF(RC2>=R[1]C2,row(),"""")"
.Columns(3).FormulaR1C1 = "=IF(RC2>=R[1]C2,row(),"""")"
.Formula = .Value
.Columns(2).Cut Destination:=.Columns(1).Offset(.Rows.Count)
.Columns(3).Cut Destination:=.Columns(1).Offset(.Rows.Count * 2)
With .Columns(1).Resize(.Rows.Count * 3)
.EntireRow.Sort Key1:=.Cells(1, 1), order1:=xlAscending, Header:=xlNo
.ClearContents
End With
End With
End With


Ich könnte mir vorstellen, dass es auch anders/besser umgesetzt werden kann. Hast du eventuell hinsichtlich der Zahl der einzufügenden Leerzeilen einen Verbesserungsvorschlag?

Gruß Franz
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
13.03.2024 13:40:29
daniel
Hi
du könntest, anstatt 2x dieselbe Formel einzufügen, auch den Bereich kopieren (nicht Cut, sondern Copy) und dann beim Einfügen die Zeilenanzahl verdoppeln, wenn der Einfügebreich größer ist als die kopierten Daten, wiederholt Excel die Daten um den Bereich zu füllen

.Columns(2).Cut Destination:=.Columns(1).Offset(.Rows.Count).Resize(.Rows.Count * 2)


da so die kopierten Daten bleiben, musst du sie dann beim Aufräumen mitlöschen:

.Resize(, 2).ClearContents


Gruß Daniel
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
18.03.2024 22:30:28
Schneider, Franz
Hallo Daniel,

sorry, dass ich mich erst jetzt wieder melde. Ich habe lange daran gebastelt, bis es funktionierte.

Den Code habe ich deinem Vorschlag entsprechend umgestellt und in meine Originaldatei eingearbeitet. Der Code funktioniert auch - eigentlich.



Sub Leerzeilen_einfügen()
' *** Tabelle mit 8 Überschriftszeilen, 12 Spalten und Einfügen von 2 Leerzeilen ***
With ActiveSheet.UsedRange
With .Columns(.Columns.Count + 1).Resize(.Rows.Count - 8, 12).Offset(8, 0)
.Columns(1).FormulaR1C1 = "=Row()"
.Columns(2).FormulaR1C1 = "=IF(RC12>=R[1]C12,row(),"""")"
.Formula = .Value
.Columns(2).Copy Destination:=.Columns(1).Offset(.Rows.Count).Resize(.Rows.Count * 2)
With .Columns(1).Resize(.Rows.Count * 3)
.EntireRow.Sort Key1:=.Cells(1, 1), order1:=xlAscending, Header:=xlNo
.Resize(, 2).ClearContents
End With
End With
End With
End Sub


Nach dem Einfügen der Hilfsspalte mit der Formel war zu erkennen, dass sich die Spalte nach jedem Start der Prozedur (mit Löschen der Spalte danach) nicht nur um das Dreifache füllte, sondern sich das Dreifache bis zum Excel-Zeilenende (über 1 Mio.) potenzierte und die Prozedur dann mit einer Fehlermeldung abbrach. An irgendeiner Stelle speichert Excel die zuletzt genutzte Zelle in der Spalte und setzt dann beim erneuten Start mit dem Dreifachen dort wieder auf.

Nach sehr vielen vergeblichen Versuchen und Umstellungen mit meinen wenigen VBA-Kenntnissen habe ich mich dazu entschlossen, eine neue Tabelle aufzurufen, sie mit den fixen Daten händisch bis zur Zeile 8 ebenso zu füllen, wie die "Problemtabelle" (ohne Daten daraus durch Kopieren zu übernehmen) und alle Prozesse ohne Änderungen darauf anzuwenden. Und siehe da, die Leerzeilen wurden ordnungsgemäß eingefügt. Der beschriebene Fehler trat auch bei vielen Durchläufen nicht auf. Eigentlich müsste ich jetzt zufrieden sein, bin ich auch, aber ich wüsste schon gerne, wo das Problem liegt. Hast du darauf eine Antwort?

Leider kann ich dir die problematische Excel-Datei (1,5 MB) auch mit Dummydaten nicht zur Verfügung stellen, da sie auch nach starkem Schrumpfen sinnvoll nicht auf die Größe reduziert werden kann, die für ein Hochladen erforderlich ist.

Danke für deine Unterstützung und Geduld mit mir. Jetzt kann ich an der Datei mit den anderen Anforderungen weiterarbeiten.

Viele Grüße
Franz
Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
19.03.2024 07:42:22
Daniel
Hi

Vermutlich hast du in der Originaltabelle Formatierungen für ganze Zeilen. Fornatierungen sind ebenso für die Größe des genutzten Bereichs relevant, außer sie gelten für ganze Zeilen oder für ganze Spalten.

Das Problem besteht jetzt darin, das du dann die Formate mit kopierst, und sie jetzt speicherrelevant werden, weil sie im unteren Bereich nicht mehr für die ganze Zeile gelten.

Ersetze mal das einzeilige
x.Copy Destination:= y 
durch das zweizeilige
x.copy

y.PasteSpecial xlpastevalues
, da dieses nur Werte einfügt.

Gruß Daniel

Anzeige
AW: VBA - Leerzeilen einfügen mit Bedingung
19.03.2024 20:24:06
Schneider, Franz
Hallo Daniel,

leider funktioniert dein vorgeschlagener Code nur in der von mir neu eingerichteten Tabelle. In der "alten" Originaltabelle füllt sich die 1. Hilfsspalte weiter bis über 1 Mio. Zeilen und bricht dann nach weiteren Durchläufen mit einer Fehlermeldung ab. Ich habe diese Tabelle jetzt gelöscht, um mir weiteren Ärger zu ersparen.

Nochmals vielen Dank. Für mich ist dieser Fall nun mit einem Erfolgserlebnis beendet.

Viele Grüße
Franz
AW: VBA - Leerzeilen einfügen mit Bedingung
11.03.2024 19:16:48
schauan
Hallo Franz,

ok.

1)
Aber Du kannst z.B. mal schauen, ob da was berechnet wird - steht ja unten links in der Statuszeile von Excel.

2)
Ob da Eventmakros zumindest vorhanden sind, siehst Du z.B. in den Codemodulen der Tabellenblätter, z.B. gbt's da zuweilen Worksheet_Change u.a.

3)
Du kannst z.B. mal am Anfang des Einfügemakros diese Zeilen einfügen:

Application.EnableEvents=False
Application.ScreenUpdating=False
Application.Calculation=xlCalculationManual

und am Ende

Application.Calculation=xlCalculationAutomatic
Application.EnableEvents=True
Application.Calculate
Application.ScreenUpdating=True

AW: VBA - Leerzeilen einfügen mit Bedingung
12.03.2024 18:05:05
Schneider, Franz
Hallo schauan,

es ist schon erstaunlich. Beim Versuch, auf Basis eurer Vorschläge eine Lösung für mein Problem der langen Verarbeitungsdauer zu finden, taucht dieser Fehler nicht mehr auf. Die Verarbeitung dauert nach vielmaligem Durchlauf genauso lange (oder kurz) wie nach einem PC-Neustart. Von einer schleichenden Verlängerung ist bislang nichts zu spüren.

Dein Tipp mit "GetMoreSpeed" hat mir nichts gebracht. Im Gegenteil. Teilweise wurden die Ergebnisse verfälscht. Deshalb habe ich deinen anderen Vorschlag mit

Application.EnableEvents=False
Application.Calculation=xlCalculationManual
und am Ende
Application.Calculation=xlCalculationAutomatic
Application.EnableEvents=True
Application.Calculate

in die Problem-Prozedur eingefügt. ScreenUpdating hatte ich vorher schon berücksichtigt. Ich hoffe, dass die lange Laufzeit somit kein Thema mehr ist. Jetzt kann ich mein Programm weiter entwickeln. Vielleicht komme ich dann später mit einem neuen Problem in dieses Forum zurück.

Vielen Dank für deine Unterstützung.

Gruß Franz

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige