Diagrammdarstellung auf einem Formular

23.04.2021

Dieses Beispiel demonstriert eine Visualisierung von gemessenen oder berechneten, niederfrequenten Daten.

Einmal pro Sekunde wird einem Signal ein neues Wertepaar (Zeit, gemessener Wert) hinzugefügt. Anschließend wird ein Diagramm, das dieses Signal als Kurvenzug beinhaltet aktualisiert und im Formular aktualisiert. Solange der Datensatz mit den erfassten Werten weniger als 100 Werte enthält wird das komplette Signal angezeigt, ansonsten werden nur die letzten 100 Werte dargestellt.

Den Beispielcode und die zugehörigen FlexPro-Objekte sind in der Datenbank Visualize.fpd abgelegt. Der Pfadname der Projektdatenbank lautet normalerweise C:\Users\Public\Documents\Weisang\FlexPro\2021\Examples\VBA\Visualize\Visualize.fpd bzw. C:>Benutzer>Öffentlich>Öffentliche Dokumente>Weisang>FlexPro>2021>Examples>VBA>Visualize>Visualize.fpd.

Anlegen eines Formulars für die Diagrammanzeige

Das benötigte Formular enthält lediglich ein Anzeige-Kontrollfeld, das in der Folge die Diagrammdarstellung übernimmt, sowie eine Schaltfläche zum Schließen des Formulars.

In der Initialisierungsphase des Formulars wird mit Hilfe der API-Funktion SetTimer ein Intervalltimer initialisiert, der einmal pro Sekunde die Prozedur UpdateProc aufruft. In der Terminierungsphase des Formulars wird der angelegte Timer mit Hilfe der API-Funktion KillTimer wieder aufgegeben.

Private Sub UserForm_Initialize()

    '   init random number generator (needed for the sample data)

    Randomize

    nTimerID = SetTimer(0, 0, 1000, AddressOf UpdateProc)

End Sub

Private Sub UserForm_Terminate()

    KillTimer 0, nTimerID

End Sub

Einfügen und Aktualisieren des Diagramms

In der Prozedur UpdateProc wird zunächst mit

On Error Resume Next

verhindert, dass die Prozedur im Fehlerfall abgebrochen wird. Dies ist aufgrund der Verwendung der SetTimer-API erforderlich, damit sichergestellt wird, dass der Prozeduraufruf immer zu Windows zurückkehrt. Anschließend wird geprüft, ob das Zielsignal für die Daten im Wurzelordner der Datenbank bereits vorhanden ist. Ist dies nicht der Fall ist, wird es angelegt und initialisiert, ansonsten wird eine neue Reihe in das Signal eingefügt.

If oSignal Is Nothing Then

    Set oSignal = ActiveDatabase.RootFolder.Add("Signal", fpObjectTypeDataSet)

    oSignal.DataStructure = fpDataStructureSignal

    oSignal.DataType(fpDataComponentX)= fpDataTypeCalendarTime

    oSignal.DataType(fpDataComponentY) = fpDataTypeFloat64

    ' we now have a signal with one value

Else ' increase the rows of the signal

    oSignal.NumberOfRows = oSignal.NumberOfRows + 1

End If

Daraufhin wird der neue Wert berechnet und mit Hilfe des Range-Objektes an das existierende Signal angehängt (siehe auch Arbeiten mit Datensätzen).

' you could acquire the data here, in this sample we calculate

' the new value pair

oSignal.Value(fpDataComponentX, , oSignal.NumberOfRows) = Now

oSignal.Value(fpDataComponentY, , oSignal.NumberOfRows) = (fMax - fMin + 1)_

                                                          * Rnd + fMin

Am Ende der Funktion wird das Diagramm, das im Formular angezeigt werden soll aktualisiert und die Picture-Eigenschaft des Diagramms wird der Picture-Eigenschaft des Anzeige-Kontrollfelds im Formular zugewiesen.

Set oDiag = ActiveDatabase.RootFolder.Object("2D-Diagramm.2D")

oDiag.Update

Display.DiagramImage.Picture = oDiag.Picture

Für die Visualisierung benötigte FlexPro-Objekte

Um die Visualisierung in der oben beschriebenen Form realisieren zu können, wurden ein Diagramm- und ein Formel-Objekt im Wurzelordner der Datenbank angelegt. Das Diagramm dient als Grundlage für die Darstellung im Formular. Es enthält genau einen Kurvenzug, der aus dem Signal, das die Formel LastValuesOfSignal liefert, besteht. Die Formel prüft, ob die Anzahl der Werte im Signal größer als ein frei wählbares Maximum (im Beispiel: 100) ist. Wenn dies der Fall ist, liefert die Formel lediglich die letzten 100 Werte des Signals, ansonsten das vollständige Signal.

nMax = 100

nCount = NumberOfRows(Signal)

if nCount < nMax then

 return Signal

else

 return Signal[-nMax, -1]

end

Artikel teilen oder als Email versenden:

Diese Beiträge könnten Sie ebenfalls interessieren