-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDataConvertorGSA.cls
236 lines (204 loc) · 8.72 KB
/
DataConvertorGSA.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "DataConvertorGSA"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
'@Folder "Operation.ImportData"
'********************************************************
'This module read GSA .csv file and write the data to the worksheet
'Arthor: Lucas LEUNG
'Update Log
'05 Jun 2023 - Initial Setup
'*******************************************************
Option Explicit
Implements IDataFormatConvertor
Private wsInteract As clsWorksheetsInteraction
Private genFunc As clsGeneralFunctions
Private UI As clsUIManager
Private ds_sys As DataSheetSystem
Private df_ele As clsDataFrame, df_force As clsDataFrame
Private df_joint As clsDataFrame
Private isVer10_2 As Boolean 'true for version = or after v10.2; false for 10.1 or before
Private isTerminate As Boolean
Private Sub Class_Initialize()
Set wsInteract = New clsWorksheetsInteraction
Set genFunc = New clsGeneralFunctions
Set UI = New clsUIManager
Set ds_sys = New DataSheetSystem
End Sub
Private Function IDataFormatConvertor_GetUserInput() As String
IDataFormatConvertor_GetUserInput = UI.GetFilePath(".csv", "Open GSA .csv output file", ds_sys.prop("ImportLog", "folderPath"))
End Function
Private Function IDataFormatConvertor_ReadData(filePath As String) As Integer
'return -1 if 'cancel' the file picker dialog box
Dim ret As Integer, i As Long
Dim heads_ele As Variant, heads_force As Variant
Dim ws_gsa As Worksheet, gsaWB As Workbook
Dim rCol_table As Long
'Validation of Data
If filePath = vbNullString Then
ret = -1
GoTo TerminateFunc
End If
'1. Open csv File
Workbooks.OpenText fileName:= _
filePath, DataType:=xlDelimited, Semicolon:=True, Local:=True
ds_sys.prop("ImportLog", "folderPath") = ActiveWorkbook.path & "\"
'2. Initialize/ Format Setting
'If Not mLog Is Nothing Then mLog.WriteLog ".csv file is opened."
rCol_table = 1
Set ws_gsa = ActiveSheet
Set gsaWB = ActiveWorkbook
'2B. Determine GSA Version
Dim gsaVerText As Variant
gsaVerText = ws_gsa.Columns("A:A").Find("Oasys")
gsaVerText = Split(Split(gsaVerText, " ")(1), ".")
If CInt(gsaVerText(0)) < 10 Then
isVer10_2 = False
ElseIf CInt(gsaVerText(0)) = 10 And CInt(gsaVerText(1)) <= 1 Then
isVer10_2 = False
Else
isVer10_2 = True
End If
'3. Read Data into dataframe
Set df_ele = ReadGSATableToDF(ws_gsa, "START_TABLE Elements", True)
If isTerminate Then
ret = -1
GoTo TerminateFunc
End If
Set df_force = ReadGSATableToDF(ws_gsa, "START_TABLE Beam and Spring Forces and Moments", True)
Set df_joint = ReadGSATableToDF(ws_gsa, "START_TABLE Nodes", True)
If Not df_joint Is Nothing Then Set df_joint = df_joint.Filter_byHeads(genFunc.CStr_arr(Array("Node", "x", "y", "z", "Restr.")))
With df_joint
For i = 1 To .CountRows
If .idata(i, 5) = "free" Then
.idata(i, 5) = False
Else
.idata(i, 5) = True
End If
Next i
End With
heads_ele = Array("Elem", "Property", "Topology", "Topology 2", "Length/ Area/Volume", "Type", "Orient. Angle")
If isVer10_2 Then
Set df_ele = GSAEleTableToDF_v10_2(df_ele)
Else
Set df_ele = df_ele.Filter_byHeads(genFunc.CStr_arr(heads_ele))
End If
'Set df_ele = df_ele.Filter_str("Type", "Beam")
'4. Modify the force data frame to fit the format of this worksheet
If Not df_force Is Nothing Then
' myArr2 = WSInteract.SetArrayTwoDim(fRow_force, rCol_table, True, lRow_force - fRow_force + 1)
' Set df_force = Factory.NewclsDataFrame(myArr2, True, False)
If df_force.columnNum("Env") = -1 Then df_force.InsertEmptyColumn 4, "Env" 'insert Column if there is no 'Env' Column
heads_force = Array("Elem", "Pos", "Case", "Env", "Fx", "Fz", "Fy", "Mxx", "Mzz", "Myy")
Set df_force = df_force.Filter_byHeads(genFunc.CStr_arr(heads_force))
df_force.AddEmptyColumn ("subElem")
df_force.column("subElem") = df_force.column("Elem")
'Modify the 'Pos' from % to True length
Dim col_pos As Long, col_eleID As Long, col_length As Long
Dim dict_eleLen As Object
col_eleID = df_ele.columnNum("Elem")
col_length = df_ele.columnNum("Length/ Area/Volume")
col_pos = df_force.columnNum("Pos")
Set dict_eleLen = CreateObject("Scripting.Dictionary")
For i = 1 To df_ele.CountRows
dict_eleLen.Add df_ele.idata(i, col_eleID), df_ele.idata(i, col_length)
Next i
For i = 1 To df_force.CountRows
df_force.idata(i, col_pos) = dict_eleLen(df_force.idata(i, col_eleID)) * df_force.idata(i, col_pos)
Next i
End If
gsaWB.Close False
Exit Function
TerminateFunc:
IDataFormatConvertor_ReadData = ret
If Not gsaWB Is Nothing Then gsaWB.Close False
End Function
Private Function GSAEleTableToDF_v10_2(gsaEleDataFrame) As clsDataFrame
Dim tempDF As New clsDataFrame, tempDF2 As New clsDataFrame
Dim heads_ele1 As Variant, heads_ele2() As String
Dim i As Long
heads_ele1 = Array("Elem", "Property", "Topology", "Length/ Area/Volume", "Type", "Orient. Angle")
heads_ele2 = genFunc.CStr_arr(Array("Elem", "Property", "Topology", "Topology 2", "Length/ Area/Volume", "Type", "Orient. Angle"))
Set tempDF = gsaEleDataFrame.Filter_byHeads(genFunc.CStr_arr(heads_ele1))
Set tempDF2 = New clsDataFrame
tempDF2.heads = heads_ele2
tempDF2.column("Elem") = tempDF.column("Elem")
tempDF2.column("Property") = tempDF.column("Property")
tempDF2.column("Length/ Area/Volume") = tempDF.column("Length/ Area/Volume")
tempDF2.column("Type") = tempDF.column("Type")
tempDF2.column("Orient. Angle") = tempDF.column("Orient. Angle")
Dim topoTextArr As Variant
For i = 1 To tempDF2.CountRows
topoTextArr = Split(tempDF.idata(i, 3), " ")
tempDF2.idata(i, 3) = topoTextArr(0)
tempDF2.idata(i, 4) = topoTextArr(1)
Next i
Set GSAEleTableToDF_v10_2 = tempDF2
End Function
Private Function ReadGSATableToDF(ws As Worksheet, tableName As String, Optional isMustRead As Boolean = False) As clsDataFrame
Dim rCol_table As Long, lRow As Long
Dim fRow_table As Long, lRow_table As Long
Dim myRng As Range
Dim errMsg As String
rCol_table = 1
With ws
lRow = .Range("A" & .rows.count).End(xlUp).row
Set myRng = .Range(.Cells(1, rCol_table), .Cells(lRow, rCol_table)).Find(tableName)
If myRng Is Nothing Then
If isMustRead Then
errMsg = "Cannot find the " & tableName & " Table in the file. The Program will be terminated."
isTerminate = True
End If
GoTo TerminateFunc
End If
fRow_table = myRng.row + 2
If .Range(myRng, .Cells(lRow, rCol_table)).Find("Maxima") Is Nothing Then
Set myRng = .Range(myRng, .Cells(lRow, rCol_table)).Find("END_TABLE")
Else
Set myRng = .Range(myRng, .Cells(lRow, rCol_table)).Find("Maxima")
End If
lRow_table = myRng.row - 1
End With
'There if there are empty cells within the table. (apply if 'fully populate' not tick). Only 'force' table applies.
Dim rng As Variant
For Each rng In ws.Range(ws.Cells(fRow_table, 1), ws.Cells(lRow_table, 1))
If rng.Text = vbNullString Then
errMsg = "Wrong Data Format! Please tick the 'Fully Populate Field' option in GSA during export."
isTerminate = True
GoTo TerminateFunc
End If
Next
Dim myArr As Variant, df As clsDataFrame
myArr = wsInteract.SetArrayTwoDim(fRow_table, rCol_table, True, lRow_table - fRow_table + 1)
Set df = New clsDataFrame
df.Init_byArr myArr, True, False
Set ReadGSATableToDF = df
Exit Function
TerminateFunc:
If Not errMsg = vbNullString Then
MsgBox errMsg
End If
End Function
Private Property Get IDataFormatConvertor_DfEle() As clsDataFrame
Set IDataFormatConvertor_DfEle = df_ele
End Property
Private Property Let IDataFormatConvertor_DfEle(value As clsDataFrame)
Set df_ele = value
End Property
Private Property Get IDataFormatConvertor_DfForce() As clsDataFrame
Set IDataFormatConvertor_DfForce = df_force
End Property
Private Property Let IDataFormatConvertor_DfForce(value As clsDataFrame)
Set df_force = value
End Property
Private Property Get IDataFormatConvertor_DfJoint() As clsDataFrame
Set IDataFormatConvertor_DfJoint = df_joint
End Property
Private Property Let IDataFormatConvertor_DfJoint(value As clsDataFrame)
Set df_joint = value
End Property