Post

How to Extract Results from ETABS to Excel Using VBA

Learn to use the ETABS API to extract results to Excel

How to Extract Results 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 extract multiple results from different sections.
    • You can perform post-processing on the original results to convert them into your desired format.
    • Integrate the results extraction code with your design sheet for a simpler workflow.
  • 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 Results

  • 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

Support Reactions

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
'Deselect all cases and combos
etModel.Results.Setup.DeselectAllCasesAndCombosForOutput

'Select Load Case
loadCaseName = "Dead"
etModel.Results.Setup.SetCaseSelectedForOutput loadCaseName

'Get joint reactions
Dim itemType As eItemTypeElm
Dim numberResults As Long
Dim objectIds() As String, elementIds() As String, loadCase() As String
Dim stepType() As String, stepNum() As Double
Dim fx() As Double, fy() As Double, fz() As Double, mx() As Double, my() As Double, mz() As Double

nodeId = 20
itemType = eItemTypeElm_Element
'This retrieves the reaction forces and moments at the specified joint for all selected load cases
etModel.Results.JointReact nodeId, itemType, numberResults, objectIds, elementIds, loadCase, stepType, stepNum, fx, fy, fz, mx, my, mz

'Print Joint Reactions
'Divide results by 1000 to convert N to KN
GetNextCell().Value = fx(0) / 1000
GetNextCell().Value = fy(0) / 1000
GetNextCell().Value = fz(0) / 1000
GetNextCell().Value = mx(0) / 1000
GetNextCell().Value = my(0) / 1000
GetNextCell().Value = mz(0) / 1000

Section Forces

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
'Deselect all cases and combos
etModel.Results.Setup.DeselectAllCasesAndCombosForOutput

'Select Load Case
loadCaseName = "Dead"
etModel.Results.Setup.SetCaseSelectedForOutput loadCaseName
    
'Get beam section forces
Dim itemType As eItemTypeElm
Dim numberResults As Long
Dim objectIds() As String, objectDistances() As Double, elementIds() As String, elementDistances() As Double, loadCase() As String
Dim stepType() As String, stepNum() As Double
Dim p() As Double, v2() As Double, v3() As Double, t() As Double, m2() As Double, m3() As Double

beamId = 63
itemType = eItemTypeElm_Element

'This retrieves the section forces for the specified element and all selected load cases
etModel.Results.FrameForce beamId, itemType, numberResults, objectIds, objectDistances, elementIds, elementDistances, loadCase, stepType, stepNum, p, v2, v3, t, m2, m3

'Loop through All points and print results
For i = 0 To numberResults - 1
    'Location from Beam Start i
    GetNextCell().Value = "Location @ " & elementDistances(i) / 1000
    'Print the results for each beam
    GetNextCell().Value = p(i) / 1000    'Axial Force (kN)
    GetNextCell().Value = v2(i) / 1000   'Shear Force V2 (kN)
    GetNextCell().Value = v3(i) / 1000   'Shear Force V3 (kN)
    GetNextCell().Value = t(i) / 1000000    'Torsional Moment (kN-m)
    GetNextCell().Value = m2(i) / 1000000   'Bending Moment M2 (kN-m)
    GetNextCell().Value = m3(i) / 1000000   'Bending Moment M3 (kN-m)
Next

Node Displacement

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
'Deselect all cases and combos
etModel.Results.Setup.DeselectAllCasesAndCombosForOutput

'Select Load Case
loadCaseName = "Dead"
etModel.Results.Setup.SetCaseSelectedForOutput loadCaseName
    
'Get Joint displacement
Dim itemType As eItemTypeElm
Dim numberResults As Long
Dim objectIds() As String, elementIds() As String, loadCase() As String
Dim stepType() As String, stepNum() As Double
Dim ux() As Double, uy() As Double, uz() As Double, rx() As Double, ry() As Double, rz() As Double

nodeId = 64
itemType = eItemTypeElm_Element
etModel.Results.JointDispl  nodeId, itemType, numberResults, objectIds, elementIds, loadCase, stepType, stepNum, ux, uy, uz, rx, ry, rz

'Print displacement in mm
GetNextCell().Value= ux(0)
GetNextCell().Value= uy(0)
GetNextCell().Value= uz(0)
GetNextCell().Value= rx(0)
GetNextCell().Value= ry(0)
GetNextCell().Value= rz(0)

Conclusion

  • Using a VBA macro to extract results is one of the most popular use cases.
  • There is no major downside to this automation.
  • The only downside I can think of is that you’ll need a good system to identify each element and load.
This post is licensed under CC BY-NC-ND 4.0 by the author.