How to Extract Model Data from ETABS to Excel Using VBA
Learn to use the ETABS API to extract model data to Excel
How to Extract Model Data from ETABS to Excel Using VBA
Overview
- In this tutorial, I’ll show you how to extract data from an ETABS model using Excel VBA.
- Why automate this process?
- You can use this approach together with your results extraction code or model generation.
- Integrate your model with your design sheet.
- I am assuming that:
- You have basic knowledge of VBA and know how to add modules and create new subs.
- You’re familiar with ETABS and know how to check results manually to compare them with the code output.
Setup
- We are going to use two files:
- ETABS Model:
- Create a simple ETABS model with a 4x4 grid and 5m spacing, 4 stories.
- Assign elements: Beam, Column, Slab, and supports.
- Apply Loads and Load Combinations: Dead Load, Live Load, Floor Load, Wall Load.
- Excel:
- Create a macro-enabled Excel file.
- We are going to print all results in the active sheet, column A.
Use the sample code below to print your output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Sub GetResults() 'Clear All Previous Results ActiveSheet.Range("A1").CurrentRegion.ClearContents 'You can print your output using GetNextCell() Function GetNextCell().Value = "Hello, My Name is Vivek" GetNextCell().Value = "This is a demo for ETABS API using Excel VBA" End Sub ' Function to get the next empty cell in column A Private Function GetNextCell() As Range If ActiveSheet.Range("A1").CurrentRegion.Rows.Count = 1 And IsEmpty(ActiveSheet.Range("A1")) Then Set GetNextCell = ActiveSheet.Range("A1") Else Set GetNextCell = ActiveSheet.Cells(ActiveSheet.Range("A1").CurrentRegion.Rows.Count + 1, 1) End If End Function
Extract Model Data
Link Excel with ETABS using VBA
- First, you have to add a reference for the ETABS API:
- Open the VBA Editor > Tools > References Dialog.
- Find
ETABS Application Programming Interface (API) v1
and make sure it’s checked.
I am using ETABS v22, but this code should work for ETABS version 18 and above. For older versions, you have to add the reference
ETABS v16 Application Programming Interface (API)
(version specific to your ETABS).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Sub GetResults()
'Clear All Previous Results
ActiveSheet.Range("A1").CurrentRegion.ClearContents
'Get ETABS API Object
Dim etApp As ETABSv1.cOAPI
Set etApp = GetObject(, "CSI.ETABS.API.ETABSObject")
'Get ETAB Model, this is also compatible with ETABS
Dim etModel As ETABSv1.cSapModel
Set etModel = etApp.sapModel
'Commonly Used Variables
'Using Long types instead of Integer to use this with OpenSTAAD
Dim i As Long, j As Long
Dim nodeId As Long, beamId As Long, loadCaseName As String
'<<< Add Remaining Code Here >>>
End Sub
Load Patterns
1
2
3
4
5
6
7
8
'Get list of all load patterns
Dim numberOfLoadPatterns As Long, LoadPatterns() As String
etModel.LoadPatterns.GetNameList numberOfLoadPatterns, LoadPatterns
'Loop through all load patterns and print load pattern name
For i = 0 To numberOfLoadPatterns - 1
GetNextCell().Value = LoadPatterns(i)
Next i
Load Combinations
1
2
3
4
5
6
7
8
'Get list of all load combinations
Dim numberOfLoadCombinations As Long, LoadCombinations() As String
etModel.RespCombo.GetNameList numberOfLoadCombinations, LoadCombinations
'Loop through all load combinations and print load combination name
For i = 0 To numberOfLoadCombinations - 1
GetNextCell().Value = LoadCombinations(i)
Next i
Story Data
Get the number and names of all stories:
1
2
3
4
5
6
7
8
'Get All story data
Dim NumberOfStories As Long, StoryNames() As String
etModel.SapModel.GetStoryList NumberOfStories, StoryNames
'Loop through all stories and print story name
For i = 0 To NumberOfStories - 1
GetNextCell().Value = StoryNames(i)
Next i
Get story data with each story name, elevation, and height
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'Get All story data
Dim BaseElevation As Double
Dim NumberStories As Long
Dim StoryNames() As String
Dim StoryElevations() As Double
Dim StoryHeights() As Double
Dim IsMasterStory() As Boolean
Dim SimilarToStory() As String
Dim SpliceAbove() As Boolean
Dim SpliceHeight() As Double
Dim color() As Long
etModel.Story.GetStories_2 BaseElevation, NumberStories, StoryNames, StoryElevations, StoryHeights, IsMasterStory, SimilarToStory, SpliceAbove, SpliceHeight, color
'Print all story data
For i = 0 To NumberStories - 1
GetNextCell().Value = StoryNames(i) ' name
GetNextCell().Value = StoryElevations(i) ' elevation
GetNextCell().Value = StoryHeights(i) ' height
Next i
Joints
1
2
3
4
5
6
7
8
'Get All Joint Node Id for Base Story
Dim NumberOfJointNodes As Long, JointNodeNames() As String
etModel.PointObj.GetNameListOnStory "Base", NumberOfJointNodes, JointNodeNames
'Loop through all joint nodes and print joint node name
For i = 0 To NumberOfJointNodes - 1
GetNextCell().Value = JointNodeNames(i)
Next i
Frame Elements
Get all frame element IDs
1
2
3
4
5
6
7
8
9
10
'Get All Frame Objects
Dim numberOfFrameElements As Long, frameElements() As String
'Get all frame object names
etModel.FrameObj.GetNameList numberOfFrameElements, frameElements
'Loop through all object and print their IDs
For i = 0 To numberOfFrameElements - 1
GetNextCell().Value = frameElements(i)
Next i
Get column elements
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'Get All Frame Objects
Dim numberOfFrameElements As Long, frameElements() As String
Dim frameType As eFrameDesignOrientation
'Get all frame object names
etModel.FrameObj.GetNameList numberOfFrameElements, frameElements
'Loop through all object and print their IDs if it's column
For i = 0 To numberOfFrameElements - 1
'Get frame type to check if it's a column
etModel.FrameObj.GetDesignOrientation frameElements(i), frameType
'Check if frame is vertical (column)
If frameType = eFrameDesignOrientation.eFrameDesignOrientation_Column Then
GetNextCell().Value = frameElements(i)
End If
Next i
Get beam elements
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'Get All Frame Objects
Dim numberOfFrameElements As Long, frameElements() As String
Dim frameType As eFrameDesignOrientation
'Get all frame object names
etModel.FrameObj.GetNameList numberOfFrameElements, frameElements
'Loop through all object and print their IDs if it's beam
For i = 0 To numberOfFrameElements - 1
'Get frame type to check if it's a column
etModel.FrameObj.GetDesignOrientation frameElements(i), frameType
'Check if frame is beam
If frameType = eFrameDesignOrientation.eFrameDesignOrientation_Beam Then
GetNextCell().Value = frameElements(i)
End If
Next i
Shell Elements
1
2
3
4
5
6
7
'Get all shell element names
etModel.AreaObj.GetNameList numberOfSlabs, SlabNames
'Loop through all shell elements and write their names/IDs
For i = 0 To numberOfSlabs - 1
GetNextCell().Value = SlabNames(i)
Next i
Selected objects
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
'Get selected frame objects
Dim numberOfSelectedObjects As Long
Dim ObjectType() As Long, ObjectName() As String
' Get all selected objects
etModel.SelectObj.GetSelected numberOfSelectedObjects, ObjectType, ObjectName
'Loop through all joint objects in the model
GetNextCell().Value = "Joint Objects"
For i = 0 To numberOfSelectedObjects - 1
If ObjectType(i) = 1 Then ' 1 = Joint object
GetNextCell().Value = ObjectName(i)
End If
Next i
' Loop through all selected objects and filter for frame objects
GetNextCell().Value = "Frame Objects"
For i = 0 To numberOfSelectedObjects - 1
If ObjectType(i) = 2 Then ' 2 = Frame object
GetNextCell().Value = ObjectName(i)
End If
Next i
' Loop through all selected objects and filter for slab objects
GetNextCell().Value = "Slab Objects"
For i = 0 To numberOfSelectedObjects - 1
If ObjectType(i) = 5 Then ' 5 = Slab object
GetNextCell().Value = ObjectName(i)
End If
Next i
Section Data
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
'Extract Section Data
Dim elementID As Long, sectionName As String, materialName As String
elementID = 1
GetNextCell().Value = elementID
'Get section name from elementID
etModel.FrameObj.GetSection elementID, sectionName, ""
GetNextCell().Value = sectionName
'Get material name from section
etModel.PropFrame.GetMaterial sectionName, materialName
GetNextCell().Value = materialName'Material
'Section Type and Size
Dim sectionType As eFramePropType, sectionSize As String
Dim t3 As Double, t2 As Double, Color As Long, Notes As String, GUID As String
'Get Section Type
etModel.PropFrame.GetTypeOAPI sectionName, sectionType
'If rectangular section then width and depth
If sectionType = eFramePropType.eFramePropType_Rectangular Then
'Get rectangle section size
etModel.PropFrame.GetRectangle sectionName, "", materialName, t3, t2, Color, Notes, GUID
GetNextCell().Value = t2'Width
GetNextCell().Value = t3'Depth
'Get rectangle frame length
Dim elementLength As Double
Dim iNode As String, jNode As String
Dim x1 As Double, y1 As Double, z1 As Double
Dim x2 As Double, y2 As Double, z2 As Double
'Get element end nodes
etModel.FrameObj.GetPoints elementID, iNode, jNode
'Get coordinates of frame end points
etModel.PointObj.GetCoordCartesian iNode, x1, y1, z1
etModel.PointObj.GetCoordCartesian jNode, x2, y2, z2
'Calculate length using distance formula
elementLength = Sqr((x2 - x1) ^ 2 + (y2 - y1) ^ 2 + (z2 - z1) ^ 2)
GetNextCell().Value = elementLength 'Element Length
End If
Conclusion
- Extracting data from ETABS is a perfect way to integrate your model with your design sheet.
- Additionally, this approach works perfectly with code for extracting results.
This post is licensed under CC BY-NC-ND 4.0 by the author.