Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1876to1880
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

Aktualisiert nicht innerhalb Schleife

Aktualisiert nicht innerhalb Schleife
08.04.2022 11:25:42
Cel
Hallo zusammen,
im Rahmen meiner Abschlussarbeit habe ich eine Excel Tabelle mit Makro erstellt, um für eine Liste an Dachflächen berechnen zu können, wie viele PV Module auf das Dach passen und mit welchen Erträgen man im Jahresverlauf rechnen kann.
Die Berechnung einer Dachfläche befindet sich in den verschiedenen Tabellenblättern in der Datei.
Damit für jede Dachfläche die Berechnung durchgeführt wird habe ich ein Makro erstellt. Dazu möchte ich noch sagen, ich habe vor der Arbeit noch nie mit VBA programmiert, somit bin ich hier ein Anfänger.
Das VBA Programm soll die Liste der Gebäudeinformationen durch gehen und jeweils in die Eingabe geben, dann soll der Ertrag berechnet werden und jenachdem ob es ein Flach oder ein Schrägdach ist soll der jeweilig mögliche Ertrag im Jahresverlauf in ein gemeinsames Tabellenblatt kopiert werden. Wenn weniger als drei Module auf das Dach passen, soll das Dach übersprungen werden und das nächste angeschaut werden.
Ich habe ein Quellcode mit dem das ganze problemlos funktioniert, allerdings braucht die Tabelle mehrere Stunden um zu berechnen, da ich die automatische Berechnung usw. nicht ausgeschaltet hatte. (Wie gesagt, Anfänger) (siehe Quellcode 1)
Nun habe ich das ganze versucht zu verbessern (Quellcode 2). Damit braucht die Berechnung bei 11.000 Dachflächen noch ca. 20 Minuten, was denke ich okay ist.
Allerdings habe ich hier das Problem, dass zwischendurch einfach die Berechnungen nicht aktualisiert werden, und ich verstehe nicht, wo es herkommt.
Ich habe ja die Neuberechnung in die For-Schleife gepackt,..
Teilweise stimmt hier also die erste Berechnung, aber die folgenden Dachflächen erhalten den gleichen Jahresverlauf an Ertrag, was nicht möglich ist.
Ich hoffe mein Problem ist klar geworden und dass mir jemand helfen kann :-)
Vielen Dank!
QUELLCODE 1

Sub Geb_ertrag()
Application.ScreenUpdating = False
''Gebäude Ids kopieren
Sheets("Gebäudeinformationen").Range("A:A").Copy
Sheets("Erträge je Gebäude").Range("A:A").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
'Berechnung der Anzahl der geeigneten Dachflächen
Anzahl_Flächen = Sheets("Gebäudeinformationen").Cells(Rows.Count, 1).End(xlUp).Row - 1
'Ausrichtung eingeben
Sheets("Gebäudeinformationen").Cells(2, 13).Copy
Sheets("Eingabe").Cells(10, 3).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
For i = 1 To Anzahl_Flächen
vorprüfung = Sheets("Gebäudeinformationen").Cells(i + 1, 14) * 0.75 / 1.676675
If vorprüfung  12 Then
GoTo Line1
ElseIf vorprüfung / 3  12 Then
Sheets("Ertrag").Range("I2:I8761").Copy
Sheets("Erträge je Gebäude").Cells(i + 1, 3).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
zeile = i + 1
spalte = "b"
cells_beginn = spalte & zeile
ERTRAG = Sheets("Ertrag").Range(cells_beginn)
Sheets("Ertrag").Cells(16, 13).Copy
Sheets("Erträge je Gebäude").Cells(i + 1, 8763).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Else
Sheets("Ertrag").Range("T2:T8761").Copy
Sheets("Erträge je Gebäude").Cells(i + 1, 3).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
zeile = i + 1
spalte = "b"
cells_beginn = spalte & zeile
ERTRAG = Sheets("Ertrag").Range(cells_beginn)
Sheets("Ertrag").Cells(16, 24).Copy
Sheets("Erträge je Gebäude").Cells(i + 1, 8763).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
End If
End If
Line1:
Next i
'Summenbildung
range_summe = "C" & Anzahl_Flächen + 2 & ":LXZ" & Anzahl_Flächen + 2
Sheets("Erträge je Gebäude").Range(range_summe).Copy
range_einfuegen = "h3:h" & Anzahl_Flächen + 2
Sheets("Ertrag Summe").Range(range_einfuegen).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
'Ertrag des Gebäudes Übertragen
Sheets("Erträge je Gebäude").Range("LYB2:LYB1695").Copy
Sheets("Ertrag Gebäude").Range("h2:h1695").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Application.ScreenUpdating = True
End Sub

QUELLCODE 2:

Sub Geb_ertrag()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
ActiveSheet.DisplayPageBreaks = False
Application.EnableEvents = False
'Berechnung der Anzahl der geeigneten Dachflächen
Anzahl_Flächen = Sheets("Erträge je Gebäude").Cells(Rows.Count, 1).End(xlUp).Row - 1
'Gebäude-IDs kopieren
Sheets("Erträge je Gebäude").Range("A:A") = Sheets("Gebäudeinformationen").Range("A:A").Value
'Gebäude-Ausrichtung kopieren
Sheets("Erträge je Gebäude").Range("B:B") = Sheets("Gebäudeinformationen").Range("C:C").Value
For i = 1 To Anzahl_Flächen Step 1
vorprüfung = Sheets("Gebäudeinformationen").Cells(i + 1, 4) * 0.75 / 1.6
If vorprüfung  12 Then
GoTo Line1
ElseIf vorprüfung / 3  12 Then
Sheets("Ertrag").Range("I2:I8761").Copy
Sheets("Erträge je Gebäude").Cells(i + 1, 3).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Erträge je Gebäude").Cells(i + 1, 8763) = Sheets("Ertrag").Cells(16, 13).Value
Else
Sheets("Ertrag").Range("T2:T8761").Copy
Sheets("Erträge je Gebäude").Cells(i + 1, 3).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Erträge je Gebäude").Cells(i + 1, 8763) = Sheets("Ertrag").Cells(16, 24).Value
End If
End If
Line1:
Next i
Sheets("Erträge je Gebäude").Calculate
'Summenbildung
range_summe = "C" & Anzahl_Flächen + 2 & ":LXZ" & Anzahl_Flächen + 2
Sheets("Erträge je Gebäude").Range(range_summe).Copy
range_einfuegen = "b3:b" & Anzahl_Flächen + 2
Sheets("Ertrag Summe").Range(range_einfuegen).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
'Ertrag des Gebäudes Übertragen
For t = 2 To Anzahl_Flächen + 1 Step 1
range_gebäude = "b" & t
range_kopieren = "LYB" & t
Sheets("Ertrag Gebäude").Range(range_gebäude) = Sheets("Erträge je Gebäude").Range(range_kopieren).Value
Next t
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
Application.DisplayStatusBar = True
ActiveSheet.DisplayPageBreaks = True
Application.EnableEvents = True
End Sub

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Aktualisiert nicht innerhalb Schleife
08.04.2022 11:33:14
onur
Der Code ist nur die halbe Miete - ohne die dazugehörige Datei fast nix Wert.
AW: Aktualisiert nicht innerhalb Schleife
08.04.2022 15:50:02
GerdL
Hallo C.!
Warum überschreibst du
im Blatt "Eingabe" die Zellen C8 und C18 in der Schleife x-mal ?
Hast du ein Mischsystem zwischen Übertragung und Formelberechnung?
Gruß Gerd
AW: Aktualisiert nicht innerhalb Schleife
08.04.2022 18:06:08
Cel
Hallo Gerd!
Ja es ist ein Mischsystem.
Vielleicht zur Erklärung, ich kann die Datei nicht einfach hochladen, da dort sensible Daten enthalten sind, die ich nicht löschen kann. Sonst funktioniert die Rechnung nicht.
Aber ich versuche es mal darzustellen:
Folgende Tabellenblätter dienen zur Berechnung des Ertrags einer einzelnen Fläche:
Tabellenblatt Eingabe:
Hier soll eingegeben werden, welche Ausrichtung, Neigung und Fläche das Dach aufweist. Daraufhin wird berechnet, wie viele Module Platz finden.
Tabellenblatt Einstrahlung auf Modul:
Berechnet unter Nutzung der Ausrichtung und Neigung die Einstrahlungsstärke auf solch eine ausgerichtete und geneigte Fläche pro Quadratmeter. Die Berechnung ist die komplexeste in der Datei. Ich habe hierbei schon versucht alle Formeln durch konstante Werte zu ersetzen um die Berechnung so unaufwändig wie möglich zu halten.
Tabellenblatt Ertrag:
Berechnet unter Nutzung der zuvor berechneten Einstrahlung und Modulfläche, welchen Ertrag man je Stunde erwarten kann.
Diese Tabellenblätter bzw. Berechnungen finden in der Excel Tabelle an sich statt und sollen für jede Dachfläche, welche in Tabellenblatt Gebäudeinformationen zu finden ist wiederholt werden.
Das Ziel des Makros ist, diese Rechnung eben gezielt zu wiederholen.
Sprich:
1. ) Infos über die jeweilige Dachfläche aus "Gebäudeinformationen" ziehen
2.) Modulfläche, Einstrahlung und Ertrag neu berechnen
3.) Ertrag in neues Tabellenblatt kopieren.
Tabellenblatt Erträge je Gebäude:
Soll den Jahresverlauf an PV-Ertrag jeder Dachfläche enthalten.
Tabellenblatt Ertrag Gebäude:
Soll die Jahressumme je Gebäude enthalten. Also die Summe aller Erträge auf allen Teildachflächen des Gebäudes.
Das Ganze funktioniert an sich auch.
Allerdings immer nur für ein paar Schleifendurchläufe.
Wenn ich dort nur 50 Dachflächen durchgehe kommen auch die richtigen Ergebnisse heraus. Aber zwischendurch oder ab einem gewissen Punkt, mir ist da kein Schema aufgefallen werden egal welche Dachfläche es ist die gleichen Jahresverläufe und Jahressummen rüberkopiert.
Ich habe nach dem heutigen Tag das Gefühl, das Excel die Rechnung einfach nicht packt und hinterherhinkt. Aber dazu fehlen mir die Erfahrungswerte, welche Datenmengen für so eine Konstruktion noch okay sind.
Grüße
Anzeige
AW: Aktualisiert nicht innerhalb Schleife
08.04.2022 20:19:45
Yal
Hallo Cel,
Achte auf das Einrücken, es ist eine wichitige Hilfsmittel für die Lesbarkeit (und somit für das Herausfinden von Fehler).
Wenn Du innerhalb eines For-Schleife überall i + 1 schreiben muss, dann nicht

For i = 1 To Anzahl_Flächen 
sondern

For i = 2 To Anzahl_Flächen + 1 
und dafür überall i anstatt i + 1.
Lieber eine Wert-Übertragung (Ziel = Quelle.Value) anstatt Quelle.Copy + Ziel.PasteValue: Zeitfaktor ca. 450!
Dafür brauchst Du nur sicherstellen, dass das Ziel die gleiche Anzahl an Zeilen/Spalten wie die Qeelle. Kann man mit Resize gut steuern.
Das Application.Calculate kann innerhalb der For-Schleife sehr teuer sein, falls 11.000 Durchläufe! Würde vielleicht Worksheets("Eingabe").Calculate reichen? Zwar optimiert Excel in dem es sich merkt, was zu aktualisiern ist, aber manche Formeln werden grundsätzlich immer neuberechnet, auch wenn sie für dein Ergebnis nicht notwendig sind. Und durch die mögliche Verschiebung der letzte verwendete Zelle durch das Einfügen von 8763 Werte wird Excel auch ge-challenged!
Nicht nachvollziehbar für mich ist, warum ein Block von 8763 Zellen immer wieder rüberkopiert wird. Da gäbe es vielleicht eine andere Weg, die Berechnung zu machen (auch wenn es durch die Value-Übertragung schneller geht).
Auch nicht klar: es wird entweder I2:I8761 oder T2:T8761, also eine Spalte und 8761 Zeilen. Dann anschliessend eine Wert in Cells(i, 8763), also AKteulel Zeile, aber Spalte 8763. Füllt sich für mcih nicht richtig an.
Das Coding hier ist nichts anderes als dein Coding, nur um die oberen Punkten "optimiert". Es wird dazu führen, dass es nicht 20 Minuten rechnet, sodass Du mehr Test durchlaufen kannst. Es empfielt sich auch mit einem reduzierten Umfang an Daten zu arbeiten, um das Coding fertig z ustellen, und dann mit dem gesamten Umfang nur am Ende zu rechnen.
Viel Erfolg damit:

Sub Geb_ertrag()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
ActiveSheet.DisplayPageBreaks = False
Application.EnableEvents = False
'Berechnung der Anzahl der geeigneten Dachflächen
Anzahl_Flächen = Sheets("Erträge je Gebäude").Cells(Rows.Count, 1).End(xlUp).Row - 1
'Gebäude-IDs kopieren
Sheets("Erträge je Gebäude").Range("A1").Resize(Anzahl_Flächen, 1) = Sheets("Gebäudeinformationen").Range("A1").Resize(Anzahl_Flächen, 1).Value
'Gebäude-Ausrichtung kopieren
Sheets("Erträge je Gebäude").Range("B1").Resize(Anzahl_Flächen, 1) = Sheets("Gebäudeinformationen").Range("C1").Resize(Anzahl_Flächen, 1).Value
For i = 2 To Anzahl_Flächen + 1
vorprüfung = Sheets("Gebäudeinformationen").Cells(i, "D") * 0.75 / 1.6
If vorprüfung  12 Then
GoTo SpringZuNext
ElseIf vorprüfung  12 Then
Sheets("Erträge je Gebäude").Cells(i, "C").Resize(8761, 1) = Sheets("Ertrag").Range("I2").Resize(8761, 1).Value
Sheets("Erträge je Gebäude").Cells(i, 8763) = Sheets("Ertrag").Cells(16, 13).Value
Else
Sheets("Erträge je Gebäude").Cells(i, "C").Resize(8761, 1) = Sheets("Ertrag").Range("T2").Resize(8761, 1).Value
Sheets("Erträge je Gebäude").Cells(i, 8763) = Sheets("Ertrag").Cells(16, 24).Value
End If
End If
SpringZuNext:
Next i
Sheets("Erträge je Gebäude").Calculate
'Summenbildung
range_summe = "C" & Anzahl_Flächen + 2 & ":LXZ" & Anzahl_Flächen + 2
range_einfuegen = "B3:B" & Anzahl_Flächen + 2
Sheets("Ertrag Summe").Range(range_einfuegen) = Sheets("Erträge je Gebäude").Range(range_summe).Value
'Ertrag des Gebäudes Übertragen
range_gebäude = "B2:B" & Anzahl_Flächen + 1
range_kopieren = "LYB2:LYB" & Anzahl_Flächen + 1
Sheets("Ertrag Gebäude").Range(range_gebäude) = Sheets("Erträge je Gebäude").Range(range_kopieren).Value
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
Application.DisplayStatusBar = True
ActiveSheet.DisplayPageBreaks = True
Application.EnableEvents = True
End Sub
VG
Yal
Anzeige
AW: Aktualisiert nicht innerhalb Schleife
11.04.2022 09:59:14
Cel
Hallo Yal,
danke auf jeden Fall. Damit ist mir schon ein wenig geholfen, ein paar Struddelfehler hast du aufgeklärt und läuft auch viel schneller.
Jetzt habe ich nurnoch ein anderes Problem.
Im Abschnitt (Quellcode ist eigentlich noch genauso wie du ihn geschickt hast):
'Übertragung der Rechenwerte in Erträge je Dachfläche
'Unterscheidung zwischen Schrägdach und Flachdach nach Dachneigung

Wenn ich im Debug Modus Schleifendurchgänge durchgehe sind immer alle richtigen Werte in der Ertrag-Tabelle. Sowohl im Jahresverlauf als auch in der Jahressumme. Allerdings werden nur die Jahressummen korrekt in die "Erträge je Gebäude" Tabelle gepackt! Bei dem Jahresverlauf wird für jede Stunde der Wert 0 rüber geschrieben.
Vielleicht hast du dazu auch eine Lösung?
Anzeige
AW: Aktualisiert nicht innerhalb Schleife
11.04.2022 10:30:56
Yal
Hallo Cel,
ich kann leider wenig dazu sagen, weil es an zu viele Parametern hängt, die Situation-spezifisch sind. Also nur in deiner Datei.
Prinzipiell ist aber, dass diese Vermischung Daten-Kopiererei per VBA, Berechnung durch Excel und Ergebnis-Kopiererei bei deiner Mengen an Berechnungen selten zu einem zufriedenstellenden Ergebnis führt.
Bei solcher Komplexität (wobie ich keine Einblick habe) nimmt man entweder eine komplette "Excel"- (dann sollte esweniger Kopierei geben) oder eine komplette VBA-Lösung (dann sollten alle Berechnungen in VBA nachgebildet werden). Es ist natürlich schwarz-weiss übertrieben :-) Man benutzt Excel, um diese Rechenweg zu finden, dann überträgt alles in VBA. Excel ist dann nur noch Eingabe- und Ergebnisdarstellung-Träger.
Was man versuchen könnte, ist um den Application Calculate rumzutricksen:

Application.EnableEvents = True
Application.Calculate
Application.ScreenUpdating = True
Application.EnableEvents = False
Application.ScreenUpdating = False
Da zerschiess man ein Teil der Performance, die wir gerade rausgeholt hatten. Einfach rumspielen. Vielleicht ist der ScreenUpdating nicht notwendig.
Und ganz schön ist es auch nicht.
VG
Yal
Anzeige
AW: Aktualisiert nicht innerhalb Schleife
11.04.2022 10:27:42
Cel
Hallo nochmal Yal,
ich habe nun herausgefunden, warum immer nullen rübergeschrieben werden.
Es wird immer nur der erste Wert des Arrays in den gesamten gewünschten Bereich übertragen. Wenn ich den Bereich auf "I11" stelle wie in dem Quellcode zu sehen, so wird nur der 11. Wert des Arrays übertragen. :
'Übertragung der Rechenwerte in Erträge je Dachfläche
'Unterscheidung zwischen Schrägdach und Flachdach nach Dachneigung
If Sheets("Gebäudeinformationen").Cells(i, "B") > 12 Then
Sheets("Erträge je Gebäude").Cells(i, "C").Resize(8760, 1) = Sheets("Ertrag").Range("I11").Resize(8760, 1).Value
Sheets("Erträge je Gebäude").Cells(i, 8763) = Sheets("Ertrag").Cells(16, 13).Value
Else
Sheets("Erträge je Gebäude").Cells(i, "C").Resize(8760, 1) = Sheets("Ertrag").Range("T11").Resize(8760, 1).Value
Sheets("Erträge je Gebäude").Cells(i, 8763) = Sheets("Ertrag").Cells(16, 24).Value
End If

Das ist mir aber auch sehr unklar, wieso das passiert. Vielleicht kannst du mir da weiterhelfen?
Grüße
Anzeige
AW: Aktualisiert nicht innerhalb Schleife
11.04.2022 10:58:53
Yal
Hallo Cel,
es gibt keinen Array, sondern einen Bereich. Es würde ausserdem nicht erklären, warum es im Schritt-Modus funtkioniert, aber nicht im normalen Lauf.
Der Form

Sheets("Erträge je Gebäude").Cells(i, "C").Resize(8761, 1) = Sheets("Ertrag").Range("T2").Resize(8761, 1).Value
besagt nur: die Zelle Ci und den 8760 Zellen darunter (row) bekommen die Werte aus dem Berich T2 und den 8760 Zellen darunter.
Wenn Du T2 durch T11 ersetzst, dann nimmt es die Werte aus T11 und 8760 Zellen datunter.
Versuch in der Linke Teil nach dem Resize mit einem ".Value"

Sheets("Erträge je Gebäude").Cells(i, "C").Resize(8761, 1).Value = Sheets("Ertrag").Range("T2").Resize(8761, 1).Value
VG
Yal
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige