Arbeiten mit Datensätzen

23.08.2021

Die Datensätze von FlexPro werden wesentlich durch die vier Eigenschaften DataStructure, DataType, NumberOfRows und NumberOfColumns bestimmt. Die Eigenschaft DataStructure bestimmt die Datenstruktur des Datensatzes. FlexPro unterstützt neun Datenstrukturen, wobei sechs davon aus bis zu drei Komponenten X, Y, und Z zusammengesetzt sind. Die Eigenschaft DataType bestimmt den Datentyp des Datensatzes bzw., wenn dieser eine zusammengesetzte Datenstruktur hat, die Datentypen der einzelnen Komponenten darin. FlexPro unterstützt eine Vielzahl Datentypen für Zahlen, Texte, Boolesche Werte, Zeiten und Zeitdauern. Nicht alle Datentypen sind für alle Komponenten eines Datensatzes erlaubt. So sind z. B. Zeichenketten nicht als Datentyp für einen Datensatz erlaubt, der eine zusammengesetzte Datenstruktur hat. Die beiden Eigenschaften NumberOfRows und NumberOfColumns bestimmen die Größe eines Datensatzes. NumberOfRows kann bei allen Datenstrukturen außer dem Einzelwert verwendet werden und bestimmt die Anzahl der Datenzeilen. NumberOfColumns ist nur bei den zweidimensionalen Datenstrukturen Datenmatrix und Signalreihe von Relevanz und bestimmt die Anzahl der Spalten. Bei allen anderen Datenstrukturen hat diese Eigenschaft den Wert Eins und kann nicht geändert werden. Ein Ändern von NumberOfRows oder NumberOfColumns wirkt sich u. U. auf mehrere Komponenten eines Datensatzes aus. Wenn Sie z. B. die Anzahl der Zeilen eines Signals vergrößern, wird dessen X- und Y-Komponente vergrößert.

Anlegen eines Datensatzes

Den passenden Code zum Anlegen eines Datensatzes lassen Sie sich am einfachsten von FlexPro erstellen, indem Sie den Makrorekorder einschalten und dann einen Datensatz mit dem Assistenten anlegen. Der erzeugte Code sieht z. B. für eine Signalreihe mit drei Spalten zu je 100 Werten ungefähr so aus:

With ActiveDatabase.RootFolder.Add("SignalSeries", fpObjectTypeDataSet)

    .DataStructure = fpDataStructureSignalSeries

    .DataType(fpDataComponentY) = fpDataTypeFloat64

    .DataType(fpDataComponentX) = fpDataTypeFloat64

    .NumberOfColumns = 3

    .NumberOfRows = 100

    .FillColumns "(NumberOfRows(i), FloatingPoint64 0, FloatingPoint64 0)"_

           , fpDataComponentY

    .FillColumns "(NumberOfRows(i), FloatingPoint64 0, FloatingPoint64 1)"_

           , fpDataComponentX

    .Update

End With

Wichtig für ein effizientes Anlegen des Datensatzes ist die korrekte Reihenfolge bei der Verwendung der Eigenschaften DataStructure, DataType, NumberOfRows und NumberOfColumns. Da bei jedem Schreibzugriff auf eine dieser Eigenschaften der vorhandene Datensatz umgebaut wird, sollte der Datensatz erst mit dem letzten Zugriff auf seine volle Größe gebracht werden. Der Assistent verwendet die richtige Reihenfolge. Zunächst wird die Datenstruktur des Datensatzes festgelegt. Nun sind die Komponenten des Datensatzes vorhanden und deren Datentypen können bestimmt werden. Anschließend wird die Anzahl der Spalten eingestellt. Der Datensatz hat danach erst eine Zeile mit drei Spalten, also drei Werte. Erst mit dem Festlegen der Zeilenanzahl wächst der Datensatz auf insgesamt 300 Werte. Anschließend werden die Inhalte der Spalten initialisiert. Dieser Schritt kann entfallen, wenn anschließend Daten in den Datensatz geschrieben werden sollen.

Schreiben und Lesen der Daten eines Datensatzes

Wenn Sie die Value-Methode des DataSet-Objektes ohne Angabe von Argumenten verwenden, können Sie auf den kompletten Inhalt des Datensatzes zugreifen. Dieses Vorgehen empfiehlt sich jedoch nur für kleinere Datensätze, da der komplette Inhalt zur Übertragung in ein Variant-Datenfeld, d. h. in den Hauptspeicher kopiert werden muss. Wenn der Datensatz eine zusammengesetzte Datenstruktur hat, dann übergibt Value alle Komponenten als Signal-Objekt. Bei der Zuweisung an eine Variable in Visual Basic müssen Sie dann die Set-Anweisung verwenden. Folgendes Beispiel liest ein Signal aus und berechnet anschließend das Delta-t aus der X-Komponente.

Dim S As Signal

Set S = SignalDataSet.Value

Dim Delta As Double

Delta = S.X(1) - S.X(0)

Bitte beachten Sie auch, dass der erste X-Wert in S.X den Index Null hat. Auch beim Schreibzugriff auf die Value-Eigenschaft müssen Sie berücksichtigen, dass der Wert mit Index Null im Datenfeld enthalten ist.

Dim V(2) As Double

V(0) = 1

V(1) = 2

V(2) = 3

DataSet.Value = V

Ein Datenfeld, das in Basic mit (n) dimensioniert wird, hat also n + 1 Werte!

FlexPro kann Datensätze von mehreren Gigabytes Größe effektiv verarbeiten. Dies wird dadurch möglich, dass Datensätze ab einer wählbaren Größe als Dateien auf der Festplatte verwaltet werden, also nicht komplett in den Hauptspeicher geladen werden. Beim Zugriff auf die Daten eines Datensatzes über das Automation Objektmodell werden die zu übertragenden Daten jedoch immer als Variant Datenfeld übertragen und daher komplett in den Hauptspeicher kopiert. Deshalb sollten Sie bei sehr großen Datensätzen nur auf Teile der Daten zugreifen. Indem Sie die optionalen Argumente Row und Column der Value-Eigenschaft verwenden, können Sie gezielt auf einzelne Werte, Zeilen oder Spalten in einem Datensatz zugreifen.

Folgendes Beispiel greift auf die Werte in einem rechteckigen Bereich in der Y-Komponente einer Signalreihe zu und setzt diese auf null.

Dim Row, Col As Long

For Row = 1 To 4

    For Col = 1 To 2

        SignalSeriesDataSet.Value(fpDataComponentY, Col, Row) = 0

    Next

Next

Sie können Daten auch blockweise übertragen. Hierzu steht Ihnen das ValueObjectRange-Objekt zur Verfügung, auf welches Sie mit der Range-Eigenschaft des Datensatzes zugreifen können. Dieses ermöglicht einen Schreib-Lese-Zugriff auf einen Ausschnitt der Daten im Datensatz.

Folgendes Beispiel kopiert die ersten fünf Werte in der Y-Komponente eines Signals an die Positionen 6 bis 10.

SignalDataSet.Value(fpDataComponentY, , 6, , 10).Value = _

    SignalDataSet.Range(fpDataComponentY, , 1, , 5).Value

Bitte beachten Sie folgendes:

Schreib- und Lesezugriffe auf das ValueObjectRange-Objekt werden direkt an den Datensatz weitergeleitet. Das ValueObjectRange-Objekt hält also keine Kopie der Daten des Ausschnittes.

Das ValueObjectRange-Objekt kann auch für Formeln, Datenverknüpfungs- und Analyseobjekte verwendet werden. Allerdings ist dann nur Lesezugriff erlaubt.

Über die Value-Eigenschaft des ValueObjectRange-Objekts können Sie nicht nur auf den kompletten Bereich, sondern auch auf Spalten, Zeilen oder einzelne Werte zugreifen.

Die Laufindizes des ValueObjectRange-Objekts beginnen immer mit Eins, auch wenn der Bereich im Datensatz bei einem höheren Index beginnt.

Dim Range As ValueObjectRange

Set Range = SignalSeriesDataSet.Range(fpDataComponentY, 1, 2, 2, 5)

Dim Data As Variant

Data = Range.Value 'Data ist nun vom Typ variant/double(0 bis 1, 0 bis 3)

Große Datensätze abschnittweise übertragen

Oft stellt sich die Aufgabe, Daten, die kontinuierlich, z. B. während einer Messung, entstehen, in einem Datensatz abzulegen. Die nahe liegende Lösung für dieses Problem ist, den Datensatz zunächst mit der korrekten Datenstruktur und Datentyp anzulegen und die Anzahl der Zeilen zunächst mit Null zu initialisieren. So wie die Daten anfallen wird dann die Anzahl der Zeilen vergrößert und über ein ValueObjectRange-Objekt der jeweils aktuelle Wert in den Datensatz übertragen. Für eine Datenreihe sieht der Code hierfür wie folgt aus:

With DataSeries

    .NumberOfRows = .NumberOfRows + 1

    .Value( , , .NumberOfRows) = NewValue

End With

Dieses Verfahren hat jedoch den Nachteil, dass die Verarbeitungsgeschwindigkeit relativ gering ist. Bei jedem Vergrößern des Datensatzes muss FlexPro intern die Werte umkopieren, was insbesondere bei größeren Datensätzen sehr rechenintensiv ist. Auch ist das Datenvolumen, dass pro Zugriff auf die Automation Schnittstelle von FlexPro übertragen wird, sehr gering. Diese Probleme können Sie vermeiden, indem Sie die anfallenden Daten zunächst in einem Datenfeld sammeln und dann dessen Inhalt als Ganzes übertragen.

Dim Data(1000000 - 1) As Double

For i =  0 to 100000 - 1

    Data(i) = NewValue

Next

With DataSeries

    .NumberOfRows = .NumberOfRows + 1000000

    .Range(fpDataComponentY, , .NumberOfRows - 1000000 + 1, _

           , .NumberOfRows).Value = Data

End With

Artikel teilen oder als Email versenden:

Diese Beiträge könnten Sie ebenfalls interessieren