MS-Office-Forum

Zurück   MS-Office-Forum > Microsoft Office > Microsoft Excel
Registrieren Forum Hilfe Alle Foren als gelesen markieren

Banner und Co.

Antworten
Ads
Themen-Optionen Ansicht
Alt 12.04.2018, 10:17   #16
losgehts
MOF User
MOF User
Standard

Hallo allerseits,

ich kann nicht verstehen, wie man mit diesem Ergebnis aus Post #13 zufrieden sein kann:
Ursprungsdaten:
12:26:10 17,79
12:26:16 0
13:07:33 11,24

Ergebnis:
12:45:00 23,584

Ich habe das im Eingangspost so verstanden, dass die Messdaten folgendermaßen zu interpretieren sind:
12:26:10 bis 12:26:15 konstant 17,79
12:26:26 bis 13:07:32 konstant 0
Meine Erwartung für einen Mittelwert über einen Zeitraum von 15 Minuten so ungefähr gegen 12:45 Uhr ist daher exakt 0 !



Da die Messerte konstant in den Zeiträumen zwischen der jeweiligen Erhebung sind, fände ich es völlig hirnverbrannt, für jede Sekunde eine Zahl zu erzeugen und diese in ein Tabellenblatt zu schreiben. Das Signal ist mit den Daten ja vollständig reproduzierbar!

Wenn du nun 15-Minuten Intervalle und deren Mittelwerte generieren möchtest, dann würde ich das einfach mit einem Makro erledigen, ähnlich wie ebs17 das ja schon lange vorschlägt (nur nicht jede Sekunde in das Tabellenblatt ablegen!).
Irgendwo habe ich gelesen, dass es um einen Datensatz geht, der ein Jahr repräsentiert (~32 Mio Sekunden ~ 36000 Viertelstunden). Darauf ist mein Code ausgelegt und beötigt auf meinem Rechner eine Laufzeit von unter 9 Sekunden.
Grundsätzlich addiert der Code für jede Sekunde einen Wert auf und berechnet daraus die Mittelwerte für 15 Minuten.
Code:

Sub machMittelwert()
'ein bisschen dumm, der Algorithmus: anzahl ist bei der Berechnung des Mittelwertes (fast) immer konstant!
Dim dt As Long, t0 As Date, t As Date, i As Long, Abtastung As Double
Dim data() As Variant, MW(1 To 40000, 1 To 2) As Double
Dim ld As Long, lmw As Long
Dim summe As Double, anzahl As Long, wert As Double

'Bereich einlesen, in dem die Daten sind:
'Spalte1: Datum mit Uhrzeit
'Spalte2: Werte
data = Range("B1:C18").Value  ' <<== noch anzupassen !

dt = 15 '[min], 60 sollte durch dt teilbar sein  'es wird der Mittelwert über dt gebildet
t0 = CDate(data(1, 1))                           ' erster Zeitpunkt
t0 = DateSerial(Year(t0), Month(t0), Day(t0)) + _
      TimeSerial(Hour(t0), Int(Minute(t0) / dt) * dt, 0)
Abtastung = TimeSerial(0, 0, 1)                 'Intervall, in dem Signal abgefragt wird

summe = 0
anzahl = 0
ld = 1                                          'erste Zeile, in der ein Wert steht (Index für data)
lmw = 0                                         'Index für MW()
i = 0                                           'Laufwariable
wert = data(ld, 2)                              'erster Wert aus Tabellenblatt

For i = 1 To 32000000#                          'Schleife auf ca 1 Jahr ausgelegt
    t = t0 + Abtastung * i                      'Zeitpunkt
    
    If t >= data(ld, 1) Then
        wert = data(ld, 2)                      'neuer Wert aus Tabellenblatt
        ld = ld + 1                             'Tabellenblattindex +1
        If ld > UBound(data) Then Exit For      'fertig!
    End If
    
    summe = summe + wert                        'addieren für Mittelwert
    anzahl = anzahl + 1
    
    If Second(t) = 0 Then
        If Minute(t) Mod dt = 0 Then            'Mittelwert berechnen
            lmw = lmw + 1                       'Index ("Zeile")
            MW(lmw, 2) = summe / anzahl         'Mittelwert
            MW(lmw, 1) = t                      'Zeitpunkt
            summe = 0
            anzahl = 0
        End If
    End If
    
Next
MW(1, 2) = 0                                    'erster Wert ist nicht zwingend richtig (Extrapolation!)

'Ausgabe in ein Tabellenblatt
With Range("E1")  ' <<== anpassen!
    .Resize(lmw, 2).Value = MW             ' Ausgabe
    .Offset(0, 1).Value = ""               ' ersten Wert löschen
    .EntireColumn.NumberFormat = "dd/mm/yyyy hh:mm:ss"
End With

End Sub
Achtung, die Zeitachse ist leicht verschoben (hängt von der Anfangszeit ab).

Den Code habe ich übrigens nicht für mich so überausführlich kommentiert. Ich hoffe, es hilft dir die Vorgehensweise zu verstehen und zu bewerten.

Der Code geht von folgendem Tabellenaufbau aus:
eine Spalte mit vollständigem Datum, mit dem Excel auch rechnen kann *) (das ist Datum + Uhrzeit, z.B. "01.01.2000 12:32:12")
daneben eine Spalte mit den Werten.
den Bereich musst du im Code anpassen.

Ebenfalls muss der Bereich im Makro angepasst werden, wo das Ergebnis hingeschrieben werden soll (linke, obere Zelle).

Bitte an Testdaten testen, da das Makro Zellen überschreibt.

Was hälst du davon, was haltet ihr davon?
Grüße, Ulrich

*) ein solches Datum ist für dich leicht zu erzeugen über "Daten" => "Text in Spalten" und ein paar Formeln mit denen man Texte verknüpft. Hast du mit Formeln einen Datumsstring erzeugt, mit dem dein Excel klar kommt, kannst du den gesamten String mit 1 multiplizieren, dann verwandelt Excel das als Zahl. (Ob das 20 Zeilen oder 800000 sind, spielt keine Rolle, da du die Formeln ja "runterziehen kannst).
So etwas mache ich einmalig, und speicher das Ergebnis (das Datum) ohne Formel (Copy und "Inhalte einfügen" => "Werte") und lösche sämtliche Hilfsspalten.

Geändert von losgehts (12.04.2018 um 10:27 Uhr).
losgehts ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 15.04.2018, 17:30   #17
Andreas9202
Threadstarter Threadstarter
Neuer Benutzer
Neuer Benutzer
Standard Rückmeldung Lösungsvorschläge

Hallo zusammen,

gerne würde ich eine Rückmeldung zu den Lösungsvorschlägen ohne und mit VBA geben.
Da ich bei dem Lösungsweg ohne VBA auf unten stehende Probleme stoße,
würde ich die VBA-Lösung bevorzugen.

Dennoch würde ich gerne meine Gedanken zu diesem Lösungsweg äußern:
ohne VBA-Lösung:
nachdem ich mich durch die Beiträge von simpsonsfan (Computer Base Forum) und ebs17 (MS Office Forum)
orientieren konnte, stelle ich mir einen optimalen Workflow wie folgt vor:
1) Anlegen eines Wunsch-Stempels in Sekunden
2) Umformung des originalen Zeitstempels in gewünschtes Format
3) Zuordnung der Messwerte über S-Verweis
4) Auffüllen der leeren Felder über Excelbefehl, bspw. =wenn(F5="";F4;F5)
5) Mittelwertbildung

Ein Muster könnte ich mir so vorstellen:
(siehe kesselwaerme.png)

Hierbei stoße ich auf folgende Probleme:
zu 1)
Wenn ich über Excel
23.12.2014 11:45:00
23.12.2014 11:45:01
23.12.2014 11:45:02
vorgebe und die Zeile automatisch füllen lasse, werden manche Datumsangaben doppelt ausgegeben, bspw.
richtig: 11:46:39 Excel: 23.12.2014 11:46:39
richtig: 11:46:40 Excel: 23.12.2014 11:46:39

Wenn ich meine Tabelle mit sekündlichen Werten fülle und am 23.12.2014 11:45:00 starte, erreiche ich bereits am 04.01.2015 13:33:52 die maximale Zeilenanzahl von Excel.

zu 5)
Wie erreiche ich, dass nur die letzten 15 Werte zur Mittelwertberechnung verwendet werden und
diese Berechnung nur um bspw. 12:15:00, 12:30:00, 12:45:00 in die Zellen geschrieben werden?


VBA-Lösung:

Zitat:

Ich habe das im Eingangspost so verstanden, dass die Messdaten folgendermaßen zu interpretieren sind:
12:26:10 bis 12:26:15 konstant 17,79
12:26:26 bis 13:07:32 konstant 0
Meine Erwartung für einen Mittelwert über einen Zeitraum von 15 Minuten so ungefähr gegen 12:45 Uhr ist daher exakt 0 !

Ja, das ist korrekt. In dieser Form hätte ich es auch gerne. Bin in meinen Rückmeldungen allerdings davon abgewichen, sorry.

Leider bekomme ich den Fehler 400 angezeigt und eine Berechnung findet nicht statt.
Das Datumsformat ist: TT.MM.JJJJ hh:mm:ss

Glücklichweise kann man VBA Befehle und Funktionen sehr gut googeln,
sodass diese einzeln für sich verstehe, den gesamten Zusammenhang durchblicke ich noch nicht.

Die noch anzupassenden Zeilen deines Codes, habe ich so angepasst:
Code:

data = Range("A1:B7612").Value  
With Range("C1")  (Diese Zeil habe ich als Ausgabespalte verstanden, korrekt?)
Wieso wird hier durch anzahl geteilt? Wird anzahl nicht bis 7612 hochgerechnet?
Code:

MW(lmw, 2) = summe / anzahl 'Mittelwert
Vielen Dank für die Unterstützung.


PS: Sollte ich in Zukunft ein neues Thema/Thread erstellen, dann werde ich mir bereits vorab zu meiner Fragestellung ausführliche Gedanken machen und einen möglichen, detaillierteren Lösungsweg präsentieren, der dann natürlich gerne optimiert werden kann.
Angehängte Grafiken
Dateityp: png kesselwaerme.PNG (28,8 KB, 5x aufgerufen)
Andreas9202 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 16.04.2018, 23:03   #18
losgehts
MOF User
MOF User
Standard

Hallo,

vielen Dank für dein Feedback. Wenn ich VBA Fehlermeldung 400 google, dann erfahre ich, dass der Fehler 400 für die verschiedensten Arten von Fehlern herhalten muss. Das hilft mir also nicht weiter, dir zu helfen.
Der Code ist an einem kleinen Datensatz getestet und hat dort funktioniert.

Jetzt liegt es an dir, eine (Excel-)Datei zur Verfügung zu stellen, an der ich testen kann, was schief läuft.
Bilder sind in diesem Fall völlig nutzlos: von einem Bild muss ich mir einen Datensatz abschreiben und dann funktioniert es wieder ...
Ah, etwas fällt mir am Bild doch auf:
In deinem Bild stehen die Daten im Bereich B5:C7000. Du hast im Code aber angepasst:

Zitat:

data = Range("A1:B7612").Value



Zitat:

Wieso wird hier durch anzahl geteilt? Wird anzahl nicht bis 7612 hochgerechnet?

Grundsätzlich berechnet sich ein Mittelwert ja aus einer Summe, die durch eine Anzahl geteilt wird. Die Variable "anzahl" wird nicht stupide hochgezählt, sondern ab und an (hoffentlich zum richtigen Zeitpunkt) auch wieder auf null gestellt. Bei genauem betrachten des Codes wirst du in der Schleife eine Zeile finden, in der
anzahl = 0
steht. Außerdem repräsentiert die Variable "anzahl" nicht die Zeilenanzahl, sondern die Anzahl an Sekunden:

Die Schleife läuft über alle Sekunden. Zunächst wird abgefragt, ob für die aktuelle Zeit ein neuer Messwert in den Daten der Tabelle steht:

Zitat:

If t >= data(ld, 1) Then

das größergleich - Zeichen kannst du dir als Gleichheitszeichen denken.
Wenn es einen neuen Wert in den Daten gibt, dann wird er in die Variable "wert" geschrieben:

Zitat:

wert = data(ld, 2)

gibt es keinen neuen Wert, hat die Variable "wert" ja noch den von der vorherigen Sekunde (zwischen den Messwerten in der Tabelle soll der Wert ja konstant bleiben).

Um später einen Mittelwert bilden zu können wird also aufsummiert und die Anzahl gezählt
Code:

    summe = summe + wert                        'addieren für Mittelwert
    anzahl = anzahl + 1

Und wenn es dann soweit ist, dass das Ende eines Zeitraums, für den der Mittelwert gesucht wird, erreicht ist, dann wird der Mittelwert gespeichert:
Code:

            MW(lmw, 2) = summe / anzahl         'Mittelwert
und die Variablen für den nächsten Mittelwert vorbereitet:
Code:

            summe = 0
            anzahl = 0
Falls du einwendest, dass es doch bisschen bekloppt ist, die Anzahl zu zählen, wo doch das Zeitintervall für den Mittelwert konstant ist und damit zur Mittelwertberechnung die Anzahl konstant und vorher berechenbar ist (15 Min = 900 Sekunden), dann hast du völlig recht.



Vielleicht bereitet es dir Schwierigkeiten, den Code zu verstehen, weil du auf das Tabellenblatt fokussiert bist.
Der Denkansatz des Codes ist anders:
stell dir vor, du hättest eine mathematische Funktion, die exakt deine Messwerte für jeden Zeitpunkt angibt:
wert(t) = 12*t^2+cos(t*pi+2.34)+42 ...
Einen Mittelwert für die ersten zehn Sekunden berechnest du dann so:
Code:

summe = 0
for t = 1 to 10
   summe = summe + wert(t)
next
Mittelwert = summe / 10
Und das Tabellenblatt ist einfach die Funktion wert(t).


Oder wenn sich dir beim Begriff "Funktion" die Nackenhaare streuben:
Es gibt eine Datenbasis (Tabellenblatt), aus der geht für jeden Zeitpunkt hervor, welcher Wert gemessen wurde.
Um nun Mittelwerte für ein Zeitintervall zu berechnen, muss ich mich für ein Raster entscheiden (hier: jede Sekunde) und dann entnehme ich der Datenbasis für jeden Rasterpunkt innerhalb des Zeitintervalls den entsprechenden Wert, addiere die auf und teile durch die Anzahl. Das ergibt den Mittelwert.


Hat dir das geholfen?
Grüße, Ulrich
losgehts ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 22.04.2018, 20:09   #19
Andreas9202
Threadstarter Threadstarter
Neuer Benutzer
Neuer Benutzer
Standard

Guten Abend Ulrich,

deine Erklärung zum VBA-Code ist top! Das hat mir sehr geholfen, vielen Dank für die ausführliche Erklärung.

Mittlerweile wird mir auch der Fehlercode 400 nicht mehr angezeigt und die Berechnung läuft.

Aus meiner Sicht ist das Thema/Thread dann abgeschlossen

Vielen Dank allerseits.
Andreas9202 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Ads
Antworten


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Besucher: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge anzufügen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

vB Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist An.
Gehe zu


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:19 Uhr.


Partner und Co.
Access-Paradies -Alles rund um die Datenbank Microsoft Access -Code -Programme-Tools -Tipps   Kostenlose Tipps & Tricks, Downloads und Programme   www.kulpa-online.com - Tipps - Tricks - Tutorials - Meinungen - Downloads uvm...   vb@rchiv · Willkommen in der Welt der VB Programmierung   Access-Garhammer - Hier finden Sie jede Menge Beispiel-Datenbanken zu Access und mehr ...   mcseboard.de   Die Top Seite für Excel-VBA-Makros uvm.

Powered by: vBulletin Version 3.6.2 (Deutsch)
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

Copyright ©2000-2018 MS-Office-Forum. Alle Rechte vorbehalten.
Copyright ©Design: Manuela Kulpa ©Rechte: Günter Kramer
Eine Verwendung der Inhalte in anderen Publikationen, auch auszugsweise,
ist ohne ausdrückliche Zustimmung der Autoren nicht gestattet.