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.
(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.
Mehr Tipps & Tricks
INOSIM 13 – WWB.NET vs. WWB-COM
Mit der neuen INOSIM 13 Version wurde der Basic-Editor umgestellt. So unterstützt dieser nun zusätzlich zu der WWB-COM auch die WWB.NET Sprachvariante, welche mit Visual…
Auswertung von Tankfüllständen
INOSIM stellt eine Reihe vordefinierter Ergebnisse und Auswertungen zur Verfügung, entweder im Gantt-Diagramm oder als Excel-Report. Insbesondere die Excel-Reports können für weitere Auswertungen genutzt werden.…
Benutzerdefinierte Farben im INOSIM Gantt-Diagramm
Das INOSIM Gantt-Diagramm bietet die Möglichkeit, Belegungsbalken auf Basis verschiedener vordefinierter Attribute zu färben. In der Auftragssicht ist es möglich, das Farbschema sowohl mit dem…