4. Oktober 2019

Table-Objekte anwenden

Table-Objekte in INOSIM sind indexierte Tabellen. Sie können mit der Zeilen- und Spaltenüberschrift direkt auf den Inhalt einer Zelle zugreifen, ohne per For-Loop zunächst die richtige Zeile und Spalte zu suchen.

Um in einer Parametersteuerung die Dauer der Operation mit einem Wert aus der Tabelle zu überschreiben, könnte man diesen Code verwenden:

Sub Drying_Duration(cop As OrderOperation, mop As RecipeOperation)
    cop.Duration = t_process(cop.Unit.Name, "Drying [h]") * 3600
End Sub

Um die Daten aus einem Excel-Sheet als Table-Objekt in der Simulation verwenden zu können, müssen die Daten zunächst aus dem Excel-Sheet in das Table-Objekt eingelesen werden, z. B. in der Simulation_Init-Prozedur. Im ersten Teil dieses Tipps wird daher kurz die Read_Table-Funktion vorgestellt, die Sie einfach in Ihren Projekten verwenden können. Table-Objekte sind auch sinnvoll, um große Mengen von benutzerdefinierten Ergebnissen während der Simulation zu speichern, z. B. wie folgt:

i = t_results.ColumnCount
t_results(cop.Unit.Name,i+1) = cop.OrderProcedure.CustomAttribute("CIP Delay")

Dieses Table-Objekt könnte nun beispielsweise in der End_Sim-Prozedur zellenweise mit Hilfe der CellYX-Eigenschaft in Excel geschrieben werden. Allerdings benötigt ein aktueller Rechner etwa 1 s, um 1000 Zellen zu schreiben. Bei großen Datenmengen können so lange Wartezeiten entstehen. Im zweiten Teil dieses Tipps wird die Write_Table-Funktion vorgestellt, mit der das Schreiben etwa 100mal schneller erfolgt als das Schreiben einzelner Zellen.

Read_Table-Funktion

Die Funktion erwartet die Eingabeparameter

  • XLS_Sheet (der String-Name des Excel-Sheets),
  • VBA_Table (das zuvor deklarierte Table-Objekt),
  • rs und cs (erste Zeile und erste Spalte),
  • re und ce (letzte Zeile und letzte Spalte, 0 für alle),
  • ri und ci (Aktivierung Zeilen-/Spaltenindex des Table-Objekts). Bei Aktivierung des Zeilenindex wird die erste Zeile als Index verwendet (Spalten analog).

Verwenden Sie beispielsweise in der Simulation_Init-Prozedur folgenden Code:

Read_Table("Input", t_input,1,1,0,0,1,1)

Mit diesem Code wird das gesamte Excel-Sheet eingelesen, da re = 0 von INOSIM als „alle verfügbaren Zeilen“ interpretiert wird (analog für ce). Sie können selbstverständlich auch erst ab Zeile 2 nur die Spalten 3 bis 8 einlesen und nur den Zeilenindex aktivieren mit Read_Table(„Input“, t_input,2,3,0,8,1,0). Achten Sie darauf, dass keine doppelten Zeilen- oder Spaltenindizes erstellt werden können, die als Index verwendete Zeile (bzw. Spalte) darf keine doppelten Einträge haben.

Function Read_Table(XLS_Sheet As String, VBA_Table As Table, rs As Integer, cs As Integer, re As Integer, ce As Integer, ri As Boolean, ci As Boolean)
    'Support function for reading excel sheets into VBA table objects

    'XLS_Sheet = sheet name of excel sheet
    'VBA_Table = table object in VBA
    'rs and cs = first row(rs)/first column (cs) to be used in sheet
    're and ce = last row(re)/last column (ce) to be used in sheet. re = 0 or ce = 0 results in all rows/columns of sheet to be used
    'ri and ci = settings, whether first row/column should be used as an index in table object

    Set VBA_Table = New Table
    Dim s As Sheet
    Set s = Parameters.Sheets(XLS_Sheet)
    Dim ro As Integer, co As Integer   'Offset für Zeilen-/Spaltenindex

    s.BufferEnabled = True
    Dim r,c As Integer
    If re = 0 Then
        re = s.UsedRows
    End If
    If ce = 0 Then
        ce = s.UsedColumns
    End If
    If ri Then
        'Switch row index on and set offset for first column = 0
        VBA_Table.RowIndex = True
        co = 0
    Else
        'Set offset for first column = 0
        co = 1
    End If
    If ci Then
        'Switch column index on and set offset for first row = 0
        VBA_Table.ColumnIndex = True
        ro = 0
    Else
        'Set offset for first row = 0
        ro = 1
    End If

    'pre dimension the table-object to reduce memory usage for large tables
    VBA_Table.ColumnCount = ce-cs
    VBA_Table.RowCount = re-rs

	'write data from sheet into Table
    For r = 0 To re-rs
        For c = 0 To ce-cs
            If r + ro = 0 Or c + co = 0 Then
                If s.CellYX(r+rs,c+cs) <> "" Then
                    VBA_Table(r+ro,c+co) = CStr(s.CellYX(r+rs,c+cs))
                End If
            Else
                If IsDate(s.CellYX(r+rs,c+cs)) Then
                    VBA_Table(r+ro,c+co) = CStr(s.CellYX(r+rs,c+cs))
                Else
                    VBA_Table(r+ro,c+co) = s.CellYX(r+rs,c+cs)
                End If
            End If
        Next
    Next
End Function

Write_Table Funktion

Die Funktion erwartet die Eingabeparameter

  • VBA_Table (ein Table-Objekt mit Ergebnissen),
  • t_rs und t_cs (erste Zeile und erste Spalte des Table-Objekts),
  • t_re und t_ce (letzte Zeile und letzte Spalte des Table-Objekts, 0 für alle),
  • XLS_Sheet (der String-Name des Excel-Sheets),
  • s_rs und s_cs (erste Zeile und erste Spalte des Sheets, in das geschrieben werden soll).

Verwenden Sie beispielsweise in der End_Sim-Prozedur folgenden Code:

Write_Table(t_results,0,0,0,0,"Results",1,1)

Mit diesem Code wird das gesamte Table-Objekt in das Sheet t_results geschrieben. Zu beachten ist, dass die Indexzeile bzw. die Indexspalte die Nummer 0 hat. Soll der Zeilenindex mit ausgegeben werden, ist 0 die erste Zeile. Mit t_re = 0 werden alle verfügbaren Zeilen gewählt (analog für ce). Sie können selbstverständlich auch das Table-Objekt ohne Indizes und nur die Spalten 3 bis 8 ausgeben lassen und die Spalten 1-3 des Sheets nicht überschreiben mit:

Write_Table(t_results,1,3,0,8,"Results",1,4)
Function Write_Table(VBA_Table As Table, t_rs As Long, t_cs As Long, t_re As Long, t_ce As Long, XLS_Sheet As String, s_rs As Long, s_cs As Long) ', ri As Boolean, ci As Boolean)
    'Support function for writing VBA table objects into an Excel Sheet using RangeYX method

	'VBA_Table = VBA table object 
	't_rs and t_cs = first row(rs)/first column (cs) of table object. Use t_rs = 0 and t_cs = 0 to include the index
	't_re and t_ce = last row(re)/last column (ce) of table object. t_re = 0 or t_ce = 0 results in all rows/columns of sheet to be used 
	'XLS_Sheet = sheet name of excel sheet as string
	's_rs and t_cs = first row/first column of the excel sheet to be used

	'set re, ce
    Dim r As Long, c As Long
    If t_re = 0 Then
        t_re = VBA_Table.RowCount
    End If
    If t_ce = 0 Then
        t_ce = VBA_Table.ColumnCount
    End If

    'set array dimensions
	Dim a() As Variant
	ReDim a(t_re-t_rs,t_ce-t_cs)

	'writing into array
    For r = t_rs To t_re
        For c = t_cs To t_ce
			If Not IsNull(VBA_Table(r,c)) Then
				a(r-t_rs,c-t_cs) = VBA_Table(r,c)
			End If
        Next
    Next

	'writing array to sheet
    Dim s As Sheet
    Set s = Parameters.Sheets(XLS_Sheet)

	'(first row, first column, first row + number of rows, first column + number of columns)
	s.RangeYX(s_rs, s_cs, s_rs+t_re-t_rs, s_cs+t_ce-t_cs) = a()

End Function

Demo-Projekt

Experiment General Understanding

Im Demo-Projekt wird in der Simulation_Init-Prozedur ein Excel-Sheet mit 10000 Werten mit der Read_Table-Funktion in das Table-Objekt t_input überführt. Während der Simulation wird das Table-Objekt t_results erzeugt und in der End_Sim-Prozedur durch Verwendung der Write_Table-Funktion in das Excel-Sheet Results geschrieben. Zur Veranschaulichung wird t_results auch zellenweise in das Excel-Sheet Results cell wise geschrieben, und zum Vergleich wird die jeweils benötigte Rechenzeit auf der Konsole ausgegeben.

Experiment Process Example

Gegeben sind 3 Trockner mit unterschiedlichen Trocknungsdauern und unterschiedlichem Reinigungsbedarf (nach 2-5 Batches).

Die Trocknungsdauer wird in der Parametersteuerung Drying_Duration aus dem Table-Objekt t_process gelesen und der Operation zugewiesen.

In der Verknüpfungsbedingung Dryer_Clean wird das benutzerdefinierte Attribut BatchCounter mit dem Wert CleanAfterXBatches aus t_process verglichen, um zu entscheiden, ob der Trockner gereinigt werden muss. Erfolgt eine Reinigung, wird der Wert in der Zelle t_process([Trocknername], CleanedXTimes) um 1 hochgezählt.

In der End_Sim-Prozedur wird mit der Write_Table-Funktion die Spalte 3 (CleanedXTimes) in das Excel-Sheet zurückgeschrieben.

Downloads

(Nur für angemeldete INOSIM Nutzer)

  • Beispiel-Projekt
  • VBA Funktion Read_Table
  • VBA Funktion Write_Table

Fragen?

Möchten Sie mehr über dieses Thema erfahren oder haben weitere Fragen? Bitte kontaktieren Sie uns.

Array ( [posts_per_page] => 3 [post_type] => [category__in] => Array ( [0] => 171 ) [orderby] => rand [order] => ASC )

Mehr Tipps & Tricks

Die Frameworks für die Steuerungstypen Teilanlagenpoolbelegung und Transfer in/aus Teilanlagenpool haben sich in der neuen INOSIM Version 13 geändert. Die Änderungen bieten einige neue Möglichkeiten,…

In diesem Tipp & Trick geht es um den Einsatz eines VBA Timers zur Messung der Ausführungsdauer von VBA Steuerungen. Um die Perfomance eines Modells…

4. Oktober 2019

Table-Objekte anwenden

Table-Objekte in INOSIM sind indexierte Tabellen. Sie können mit der Zeilen- und Spaltenüberschrift direkt auf den Inhalt einer Zelle zugreifen, ohne per For-Loop zunächst die richtige Zeile und Spalte…

mehr

INOSIM Kontakt

Zu den lokalen Geschäftszeiten

Deutschland +49 231 97 00 250

USA +1 214 663 3101

Indien +91 9766 331 092