11-16-2016 09:53 AM
Hi,
I am trying to write an API that lets the user write a user selectable number of vectors (e.g. stresses) in user selectable load cases for a (large) number of elements to the data table and save that into a .csv file.
I can write the information to the message pane by using feAppMessage but I cannot write the same information to the data table. For some reason I am unable to get the arrays (C0 up to C6) to provide the information to the .AddColumn command of the data table.
I have put the code I have so far below.
Sub Main
' FEMAP itself
Dim App As femap.model
Set App = feFemap()
' The data table
Dim data As femap.DataTable
Set data = App.feDataTable
' Clear the data table as a precaution
Dim rc As Long
rc = data.Clear
' Create a set to contain the selected elements
Dim elmSet As femap.Set
Set elmSet = App.feSet
' Create a set to contain the output set and vector(s)
Dim OutputSet As femap.Set
Dim VectorSet As femap.Set
Dim OutputVector As femap.Output
Set OutputVector = App.feOutput
' Some other variables
Dim C0 As Variant
Dim C1 As Variant
Dim C2 As Variant
Dim C3 As Variant
Dim C4 As Variant
Dim C5 As Variant
Dim C6 As Variant
Dim minID As Long
Dim maxID As Long
Dim minVal As Double
Dim maxVal As Double
Dim LocPath As String
Dim CsvFile As String
Dim fName As String
'Get the filename and local path of the csv file
fName = ""
App.feFileGetName ("Export maximum vector", "Comma Seperated File","*.csv", False, fName)
' Extract the filename and the save directory
CsvFile = Mid(fName, InStrRev(fName, "\") + 1)
LocPath = Left(fName, Len(fName)-Len(NastFile))
' Catching if the user has not selected a filename or pressed cancel
If Len(fName) = 0 Then
App.feAppMessage(3,"Process cancelled!")
GoTo Jumping_Out
End If
' Set the counter to 0
count = 0
' Get the maximum vector values
If App.feSelectOutput( "Select Output Vectors", -1, FOT_ANY, FOC_ANY, FT_ELEM, False, OutputSet, VectorSet ) = FE_OK Then
If elmSet.Select( FT_ELEM, True, "Select Elements" ) = FE_OK Then
OutputCount =OutputSet.Count * VectorSet.Count - 1
App.feAppManagePanes ( "Data Table", 1)
data.Lock ( False )
ReDim C0(OutputCount) As Long
ReDim C1(OutputCount) As Long
ReDim C2(OutputCount) As Long
ReDim C3(OutputCount) As Long
ReDim C4(OutputCount) As Double
ReDim C5(OutputCount) As Long
ReDim C6(OutputCount) As Double
' Go to the next output set
While OutputSet.Next()
VectorSet.Reset()
' Go to the next output vector
While VectorSet.Next()
OutputVector.GetFromSet( OutputSet.CurrentID(), VectorSet.CurrentID() )
OutputVector.FindMaxMin(elmSet.ID, True, minID, minVal, maxID, maxVal)
App.feAppMessage( FCM_NORMAL, Str$(OutputSet.CurrentID)+";"+Str$(VectorSet.CurrentID)+";"+Str$(minID)+";"+Format$(minVal/1000000, "0.00")+";"+Str$(maxID)+";"+Format$(maxVal/1000000, "0.00"))
' Fill the array for the datatable
C0(count) = count
C1(count) = OutputSet.CurrentID()
C2(count) = VectorSet.CurrentID()
C3(count) = minID
C4(count) = minVal
C5(count) = maxID
C6(count) = maxVal
count = count + 1
Wend
Wend
' Write the data to the data table
Dim newColID As Long
rc = data.AddColumn( False, False, FT_ELEM, 0, "Output Set ID", FCT_DOUBLE, OutputCount, C0, C1, newColID )
rc = data.AddColumn( False, False, FT_ELEM, 0, "Output Vector ID", FCT_DOUBLE, OutputCount, C0, C2, newColID )
rc = data.AddColumn( False, False, FT_ELEM, 0, "Minimum element ID", FCT_DOUBLE, OutputCount, C0, C3, newColID )
rc = data.AddColumn( False, False, FT_ELEM, 0, "Minimum value", FCT_DOUBLE, OutputCount, C0, C4, newColID )
rc = data.AddColumn( False, False, FT_ELEM, 0, "Maximum element ID", FCT_DOUBLE, OutputCount, C0, C5, newColID )
rc = data.AddColumn( False, False, FT_ELEM, 0, "Maximum value", FCT_DOUBLE, OutputCount, C0, C6, newColID )
End If
End If
'Exporting the data table to a txt file
rc = data.Save(True, fName, FSF_CSV)
' Notify the user that the process is finished.
App.feAppMessage(3,"The maximum stresses have been exported to " & fName & ".")
' Specifying the goto point for exiting the sub
Jumping_Out:
' Clear the data table
'rc = data.Clear
End Sub
Can anyone see what is wrong here?
Thanks in advance.
Gertjan
Solved! Go to Solution.
11-22-2016 02:51 AM
All,
By bypassing the data table and directly outputting to Excel I have made my API work how I want.
For anyone looking for a similar solution here is my code.
Sub Main
' This API lets the user export the maximum and minimum vector (user selectable)
' per load case (also user selectable) for a (large) number of selected elements and put them
' in a new excel file.
'
'-------------------------------------- The declarations --------------------------------------
' FEMAP itself
Dim App As femap.model
Set App = feFemap()
' Create a set to contain the selected elements
Dim elmSet As femap.Set
Set elmSet = App.feSet
' Create a set to contain the output set and vector(s)
Dim LoadCaseSet As femap.Set
Dim VectorSet As femap.Set
Dim OutputVector As femap.Output
Set OutputVector = App.feOutput
Dim SetName As Results
Set SetName = App.feResults
' Some other variables
Dim minID As Long
Dim maxID As Long
Dim minVal As Double
Dim maxVal As Double
Dim Row As Long
Dim Col As Long
Dim SNListTitle As String
Dim VNListTitle As String
'Dimension an Excel Application, Workbook and Worksheet. Be sure to activate the Microsoft Excel 12.0 Obeject Library in References
Dim appExcel As Excel.Application
Set appExcel = New Excel.Application
Dim wbkReport As Excel.Workbook
Set wbkReport = appExcel.Workbooks.Add
Dim wksReport As Excel.Worksheet
Set wksReport = wbkReport.Worksheets(1)
' Get the maximum vector values
If App.feSelectOutput( "Select Output Vectors", -1, FOT_ANY, FOC_ANY, FT_ELEM, False, LoadCaseSet, VectorSet ) = FE_OK Then
If elmSet.Select( FT_ELEM, True, "Select Elements" ) = FE_OK Then
'Ask the API to create the titles in the first row of the worksheet
wksReport.Cells( 1, 1 ) ="Output Set ID"
wksReport.Cells( 1, 2 ) ="Output Set Name"
wksReport.Cells( 1, 3 ) ="Output Vector ID"
wksReport.Cells( 1, 4 ) ="Output Vector Name"
wksReport.Cells( 1, 5 ) ="Maximum element ID"
wksReport.Cells( 1, 6 ) ="Maximum value"
wksReport.Cells( 1, 7 ) ="Minimum element ID"
wksReport.Cells( 1, 8 ) ="Minimum value"
' Set the row counter to 1
Row = 1
' Go to the next output set
While LoadCaseSet.Next()
VectorSet.Reset()
' Go to the next output vector
While VectorSet.Next()
' Get the set and vector ID's
OutputVector.GetFromSet( LoadCaseSet.CurrentID(), VectorSet.CurrentID() )
' Get the set and vector names
SetName.SetTitle( LoadCaseSet.CurrentID , SNListTitle )
SetName.VectorTitle( LoadCaseSet.CurrentID, VectorSet.CurrentID, VNListTitle )
' Determine the max and min values per set and per loadcase
OutputVector.FindMaxMin(elmSet.ID, True, minID, minVal, maxID, maxVal)
Row = Row + 1
' Write the data to the Excel
wksReport.Cells( Row, 1 ).value = LoadCaseSet.CurrentID
wksReport.Cells( Row, 2 ).value = SNListTitle
wksReport.Cells( Row, 3 ).value = VectorSet.CurrentID
wksReport.Cells( Row, 4 ).value = VNListTitle
wksReport.Cells( Row, 5 ).value = maxID
wksReport.Cells( Row, 6 ).value = maxVal
wksReport.Cells( Row, 7 ).value = minID
wksReport.Cells( Row, 8 ).value = minVal
Wend
Wend
'Make the Excel spreadsheet visible
appExcel.Visible = True
End If
End If
' Cleaning up
Set App = Nothing
Set elmSet = Nothing
Set OutputVector = Nothing
Set SetName = Nothing
Set appExcel = Nothing
Set wbkReport = Nothing
Set wksReport = Nothing
End SubRegards,
Gertjan
05-08-2017 10:25 AM
Hi Gertjan,
did u manage to get a *.csv output as well?
regards,
der Rechenschieber
05-16-2017 05:51 AM
05-16-2017 11:35 AM
I think I've found the issue with your original API that could not write to the Data Table, and subsequently gave nothing to write to the .csv. Your method to save to to a .csv was correct.
When you were populating the array "C0", your method of "C0(count) = count" resulted in "C0( 0 ) = 0 ". This is not valid. I simply changed it to "C0(count) = count + 1" in order to allow the ID column to start at 1.
In addition, I changed how you dimensioned "OutputSet" to oSet. Your oringial was creating an object with the exact same string name as the object definition. This could not only be confusing, but lead to errors in your program.
When populating the .csv, this API will output everything in a straight line, comma-separated. There are additional techniques such as copying the Data Table by each row or column, or using tools such as "Chr(10)" to get cariage return while writing strings.
Modified API below.
The HTML Clipboard
Sub Main ' FEMAP itself Dim App As femap.model Set App = feFemap() ' The data table Dim data As femap.DataTable Set data = App.feDataTable ' Clear the data table as a precaution Dim rc As Long rc = data.Clear ' Create a set to contain the selected elements Dim elmSet As femap.Set Set elmSet = App.feSet ' Create a set to contain the output set and vector(s) Dim oSet As femap.OutputSet Set oSet = App.feOutputSet Dim VectorSet As femap.Set Set VectorSet = App.feSet Dim OutputVector As femap.Output Set OutputVector = App.feOutput ' Some other variables Dim C0 As Variant Dim C1 As Variant Dim C2 As Variant Dim C3 As Variant Dim C4 As Variant Dim C5 As Variant Dim C6 As Variant Dim minID As Long Dim maxID As Long Dim newColID As Long Dim OutputCount As Long Dim minVal As Double Dim maxVal As Double Dim LocPath As String Dim CsvFile As String Dim fName As String 'Get the filename and local path of the csv file fName = "" App.feFileGetName ("Export maximum vector", "Comma Seperated File","*.csv", False, fName) ' Extract the filename and the save directory CsvFile = Mid(fName, InStrRev(fName, "\") + 1) LocPath = Left(fName, Len(fName)-Len(NastFile)) ' Catching if the user has not selected a filename or pressed cancel If Len(fName) = 0 Then App.feAppMessage(3,"Process cancelled!") GoTo Jumping_Out End If ' Set the counter to 0 count = 0 ' Get the maximum vector values If App.feSelectOutput( "Select Output Vectors", -1, FOT_ANY, FOC_ANY, FT_ELEM, False, oSet, VectorSet ) = FE_OK Then If elmSet.Select( FT_ELEM, True, "Select Elements" ) = FE_OK Then OutputCount =oSet.Count * VectorSet.Count - 1 App.feAppManagePanes ( "Data Table", 1) data.Lock ( False ) ReDim C0(OutputCount) As Long ReDim C1(OutputCount) As Double ReDim C2(OutputCount) As Double ReDim C3(OutputCount) As Double ReDim C4(OutputCount) As Double ReDim C5(OutputCount) As Double ReDim C6(OutputCount) As Double ' Go to the next output set While oSet.Next() VectorSet.Reset() ' Go to the next output vector While VectorSet.Next() rc = OutputVector.GetFromSet( oSet.CurrentID(), VectorSet.CurrentID() ) rc = OutputVector.FindMaxMin(elmSet.ID, True, minID, minVal, maxID, maxVal) App.feAppMessage( FCM_NORMAL, Str$(oSet.CurrentID)+";"+Str$(VectorSet.CurrentID)+";"+Str$(minID)+";"+Format$(minVal/1000000, "0.00")+";"+Str$(maxID)+";"+Format$(maxVal/1000000, "0.00")) ' Fill the array for the datatable C0(count) = count+1 C1(count) = oSet.CurrentID() C2(count) = VectorSet.CurrentID() C3(count) = minID C4(count) = minVal C5(count) = maxID C6(count) = maxVal count = count + 1 Wend Wend ' Write the data to the data table rc = data.AddColumn( False, False, FT_ELEM, 0, "Output Set ID",FCT_DOUBLE, OutputCount, C0, C1, newColID ) rc = data.AddColumn( False, False, FT_ELEM, 0, "Output Vector ID", FCT_DOUBLE, OutputCount, C0, C2, newColID ) rc = data.AddColumn( False, False, FT_ELEM, 0, "Minimum element ID", FCT_DOUBLE, OutputCount, C0, C3, newColID ) rc = data.AddColumn( False, False, FT_ELEM, 0, "Minimum value", FCT_DOUBLE, OutputCount, C0, C4, newColID ) rc = data.AddColumn( False, False, FT_ELEM, 0, "Maximum element ID", FCT_DOUBLE, OutputCount, C0, C5, newColID ) rc = data.AddColumn( False, False, FT_ELEM, 0, "Maximum value", FCT_DOUBLE, OutputCount, C0, C6, newColID ) End If End If 'Exporting the data table to a txt file rc = data.Save(True, fName, FSF_CSV) ' Notify the user that the process is finished. App.feAppMessage(3,"The maximum stresses have been exported to " & fName & ".") ' Specifying the goto point for exiting the sub Jumping_Out: ' Clear the data table 'rc = data.Clear End Sub
06-15-2017 08:54 AM - edited 06-15-2017 09:46 AM
Sorry for bringing up an old thread, I had similar code with the same issue when exporting into a table. The IDs for all stress values aren't shown and only a handful are displayed. For example, 15 stress IDs selected but only 10 are shown with their values. Any idea for a possible solution?
Thank you!
Edit: Fixed the code and followed the same approach. A problem with the code above would be not outputting the final von mises stress. I guess this is an issue with the output counter stopping before counting the last ID. A simple work around would be changing the addcolumn statements to:
The HTML Clipboard
rc = data.AddColumn( False, False, FT_ELEM, 0, "Output Set ID",FCT_DOUBLE, OutputCount+1, C0, C1, newColID )