Post

Automate STAAD model from Excel using OpenSTAAD

Use OpenSTAAD API to generate/modify staad models

Automate STAAD model from Excel using OpenSTAAD

Overview

  • In this tutorial, I’ll show you how to generate or modify a STAAD model using Excel VBA and OpenSTAAD
  • What is OpenSTAAD?
    • It’s a STAAD API library which allows you to access STAAD internal functions using VBA/C#/Python.
  • Why OpenSTAAD API?
    • You can read data from the active model and modify it
    • Quick visual feedback - you will be able to see or verify all changes live
    • It’s very hard to manipulate *.std files for complex models. OpenSTAAD allows us to break automation into multiple parts, allowing users to make minor adjustments as per project requirements
  • I am assuming that:
    • You have basic knowledge of VBA and know how to add modules and create new subs.

Setup

  • STAAD Model
    • For this tutorial, we’re just going to generate a single-span fixed beam
    • You’re free to use any model you like but make sure that you can verify output results to simplify your testing.
  • Excel
    • Create a macro-enabled Excel file.

Generate New STAAD Model

Create New Model

  • Make sure that your STAAD Application is open before running this macro
  • The code below basically creates a new Model.std file in the active Excel sheet folder with specified units
  • Additionally, we also need to close any existing STAAD file if a model is already open
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
Sub GenerateModel()

    'Create OpenStaad Object
    Dim objOpenSTAAD As Object
    Set objOpenSTAAD = GetObject(, "StaadPro.OpenSTAAD")
    
    'Check if model is open
    Dim stdFilePath As String
    objOpenSTAAD.GetSTAADFile stdFilePath, True
    
    'If model is open close model
    If stdFilePath <> "" Then
        objOpenSTAAD.CloseSTAADFile
    End If
 
    'Create New model
    stdFilePath = ThisWorkbook.Path & "\Model.std"
 
    '(0- Inch, 1- Feet, 2- Feet, 3- Centimeter, 4- Meter, 5- Millimeter, 6- Decimeter, 7 � Kilometer)
    Dim intInputUnitForLength As Integer
    intInputUnitForLength = 4                    ' 4 for meters

    '(0- Kilopound, 1- Pound, 2- Kilogram, 3- Metric Ton, 4- Newton, 5- Kilonewton, 6- Meganewton, 7- Decanewton)
    Dim intInputUnitForForce As Integer
    intInputUnitForForce = 3                     ' 3 for Metric Ton

    objOpenSTAAD.NewSTAADFile stdFilePath, intInputUnitForLength, intInputUnitForForce

    'Wait for 3 seconds for staad to create new model
    'modify this as per your system or staad version
    Dim waitTime As Double
    waitTime = Timer + 3
    Do While Timer < waitTime
        DoEvents
    Loop
    
    '<<< Add your remaining model code here >>>

    'Save model without any user prompt
    objOpenSTAAD.SaveModel 1
End Sub

Add Nodes and Beams

1
2
3
4
5
6
'Add Nodes with node id 1 and 2
objOpenSTAAD.Geometry.CreateNode 1, 0, 0, 0
objOpenSTAAD.Geometry.CreateNode 2, 3#, 0#, 0#

'Add Beam with id 1 connecting the node 1 and 2
objOpenSTAAD.Geometry.CreateBeam 1, 1, 2

Add Material Properties

  • This code will only work with the Connect Edition
  • I can’t find an API for the older version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'Create material concrete
Dim materialName As String
Dim elasticity As Double
Dim poissonRatio As Double
Dim shearModulus As Double
Dim density As Double
Dim alpha As Double
Dim criticalDamp As Double
Dim fcu As Double
Dim bPhysical As Integer
materialName = "CONCRETE"
elasticity = 2214670
poissonRatio = 0.17
shearModulus = 0.06
density = 2.40262
alpha = 5e-05
criticalDamp = 0.05
fcu= 2812.28
bPhysical = 0
objOpenStaad.Property.CreateIsotropicMaterialConcrete  materialName, elasticity, poissonRatio, shearModulus, density, alpha, criticalDamp, fcu, bPhysical

Add Sections

Create Rectangular Section

1
2
3
4
5
6
7
8
Dim width As Double, depth As Double
Dim beamNo as Long
Dim sectionPropertyNo as Long
width = 0.3  
depth = 0.3  
beamNo = 1
sectionPropertyNo = objOpenSTAAD.Property.CreatePrismaticRectangleProperty(depth, width) 
objOpenSTAAD.Property.AssignBeamProperty beamNo, sectionPropertyNo

Create Circular Section

1
2
3
4
5
6
7
Dim sectionDia As Double
Dim beamNo As Long
Dim sectionPropertyNo As Long
sectionDia = 0.3
beamNo = 1
sectionPropertyNo = objOpenSTAAD.Property.CreatePrismaticCircleProperty(sectionDia)
objOpenSTAAD.Property.AssignBeamProperty beamNo, sectionPropertyNo

Create Prismatic Section

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Dim prismaticProperty(0 To 9) As Double
prismaticProperty(0) = 1.037 ' Ax
prismaticProperty(1) = 0#  ' Ay
prismaticProperty(2) = 0#  ' Az
prismaticProperty(3) = 0.102 ' Ix
prismaticProperty(4) = 0.041 ' Iy
prismaticProperty(5) = 0.25 ' Iz
prismaticProperty(6) = 0#  ' YD
prismaticProperty(7) = 0#  ' ZD
prismaticProperty(8) = 0#  ' YB
prismaticProperty(9) = 0#  ' ZB

Dim beamNo As Long
Dim sectionPropertyNo As Long
beamNo = 1
sectionPropertyNo = objOpenSTAAD.Property.CreatePrismaticGeneralProperty(prismaticProperty)
objOpenSTAAD.Property.AssignBeamProperty beamNo, sectionPropertyNo

Add Supports

Fixed Support

1
2
3
4
5
6
Dim supportNo As Long
supportNo=objOpenSTAAD.Support.CreateSupportFixed

'Assign Support at node 1 and 2
objOpenSTAAD.Support.AssignSupportToNode 1, supportNo
objOpenSTAAD.Support.AssignSupportToNode 2, supportNo

Pinn Support

1
supportNo=objOpenSTAAD.Support.CreateSupportPinned

Spring Support

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Dim release(5) As Double
release(0) = 0   'FX
release(1) = 0   'FY
release(2) = 0   'FZ
release(3) = 1   'MX
release(4) = 1   'MY
release(5) = 1   'MZ

Dim stiffness(5) As Double
stiffness(0) = 100'KFX
stiffness(1) = 200'KFY
stiffness(2) = 100'KFZ
stiffness(3) = 0'KMX
stiffness(4) = 0'KMY
stiffness(5) = 0'KMZ

Dim supportNo As Long
supportNo = objOpenSTAAD.Support.CreateSupportFixedBut(release, stiffness)

Add Loads

Create empty load case

1
2
3
4
objOpenSTAAD.Load.CreateNewPrimaryLoad "Dead Load"

'<<Add your load code here>>
'<<You can use single load or multiple>>

Add UDL Load

1
2
3
4
5
6
7
8
9
10
11
12
objOpenSTAAD.Load.CreateNewPrimaryLoad "UDL Load"
dim beamNo as Long
beamNo = 1
dim Direction as Integer
Direction = 5 ' 1 for Y direction
Dim udlForce As Double
udlForce = -2.0 ' use negative value for downward force
dim d1, d2, d3 as Double
d1 = 0.0
d2 = 0.0
d3 = 0.0
objOpenSTAAD.Load.AddMemberUniformForce beamNo, Direction, udlForce,d1, d2, d3

Add Nodal Load

1
2
3
4
5
6
7
8
9
10
11
12
objOpenSTAAD.Load.CreateNewPrimaryLoad "Nodal Load"
dim nodeId as Long
nodeId = 1
dim fx as Double, fy as Double, fz as Double, mx as Double, my as Double, mz as Double
fx = 0.0
fy = -2.0
fz = 0.0
mx = 0.0
my = 0.0
mz = 0.0

objOpenSTAAD.Load.AddNodalLoad nodeId, fx, fy, fz,  mx, my, mz

Add Load Combinations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Dim loadCombTitle as String
Dim loadCombNo as Long
loadCombTitle = "ULTIMATE LOAD"
loadCombNo = 101
objOpenSTAAD.Load.CreateNewLoadCombination loadCombTitle, loadCombNo

Dim loadCaseNo as Long
Dim loadFactor as Double
loadCaseNo = 1 ' Load Case ID for UDL Load
loadFactor = 1.5 ' Factor for UDL Load
'Add Load to Load Combination
objOpenSTAAD.Load.AddLoadAndFactorToCombination loadCombNo, loadCaseNo, loadFactor
loadCaseNo = 2 ' Load Case ID for Nodal Load
loadFactor = 1.2 ' Factor for Nodal Load
objOpenSTAAD.Load.AddLoadAndFactorToCombination loadCombNo, loadCaseNo, loadFactor

Optional code to check if STAAD Application is open

  • This code is not essential but it will add a nice touch for new users
  • This code will check if the STAAD Application is open before running the OpenSTAAD Macro
  • This will prevent unnecessary confusion for new users
1
2
3
4
5
6
7
8
9
10
11
12
Dim objShell As Object
Set objShell = CreateObject("WScript.Shell")

Dim isStaadRunning As Boolean
On Error Resume Next
isStaadRunning = objShell.AppActivate("STAAD.Pro") Or objShell.AppActivate("STAAD.Pro CONNECT Edition")
On Error GoTo 0

If Not isStaadRunning Then
    MsgBox "Please start STAAD.Pro before running this macro.", vbExclamation
    Exit Sub
End If

Final Version with Excel inputs

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
Sub GenerateModel()

    'Check if staad is running
    Dim objShell As Object
    Set objShell = CreateObject("WScript.Shell")

    Dim isStaadRunning As Boolean
    On Error Resume Next
    isStaadRunning = objShell.AppActivate("STAAD.Pro") Or objShell.AppActivate("STAAD.Pro CONNECT Edition")
    On Error GoTo 0

    If Not isStaadRunning Then
        MsgBox "Please start STAAD.Pro before running this macro.", vbExclamation
        Exit Sub
    End If

    'Create OpenStaad Object
    Dim objOpenSTAAD As Object
    Set objOpenSTAAD = GetObject(, "StaadPro.OpenSTAAD")
    
    'Check if model is open
    Dim stdFilePath As String
    objOpenSTAAD.GetSTAADFile stdFilePath, True
    
    'If model is open close model
    If stdFilePath <> "" Then
        objOpenSTAAD.CloseSTAADFile
    End If
 
    'Create New model
    stdFilePath = ThisWorkbook.Path & "\Model.std"
 
    '(0- Inch, 1- Feet, 2- Feet, 3- Centimeter, 4- Meter, 5- Millimeter, 6- Decimeter, 7 ? Kilometer)
    Dim intInputUnitForLength As Integer
    intInputUnitForLength = 4                    ' 4 for meters

    '(0- Kilopound, 1- Pound, 2- Kilogram, 3- Metric Ton, 4- Newton, 5- Kilonewton, 6- Meganewton, 7- Decanewton)
    Dim intInputUnitForForce As Integer
    intInputUnitForForce = 3                     ' 3 for Metric Ton

    objOpenSTAAD.NewSTAADFile stdFilePath, intInputUnitForLength, intInputUnitForForce

    'Wait for 3 seconds for staad to create new model
    'modify this as per your system or staad version
    Dim waitTime As Double
    waitTime = Timer + 3
    Do While Timer < waitTime
        DoEvents
    Loop
    
    'Add Nodes with node id 1 and 2
    objOpenSTAAD.Geometry.CreateNode 1, 0, 0, 0
    objOpenSTAAD.Geometry.CreateNode 2, 3#, 0#, 0#

    'Add Beam with id 1 connecting the node 1 and 2
    objOpenSTAAD.Geometry.CreateBeam 1, 1, 2

    'Create material concrete
    Dim materialName As String
    Dim elasticity As Double
    Dim poissonRatio As Double
    Dim shearModulus As Double
    Dim density As Double
    Dim alpha As Double
    Dim criticalDamp As Double
    Dim fcu As Double
    Dim bPhysical As Integer
    materialName = "CONCRETE"
    elasticity = 2214670
    poissonRatio = 0.17
    shearModulus = 0.06
    density = 2.40262
    alpha = 0.00005
    criticalDamp = 0.05
    fcu = 2812.28
    bPhysical = 0
    objOpenSTAAD.Property.CreateIsotropicMaterialConcrete materialName, elasticity, poissonRatio, shearModulus, density, alpha, criticalDamp, fcu, bPhysical
    
    'Create Rectangular Section
    Dim width As Double, depth As Double
    Dim beamNo As Long
    Dim sectionPropertyNo As Long
    width = 0.3
    depth = 0.3
    beamNo = 1
    sectionPropertyNo = objOpenSTAAD.Property.CreatePrismaticRectangleProperty(depth, width)
    objOpenSTAAD.Property.AssignBeamProperty beamNo, sectionPropertyNo

    'Create Fixed Support
    Dim supportNo As Long
    supportNo = objOpenSTAAD.Support.CreateSupportFixed

    'Assign Support at node 1 and 2
    objOpenSTAAD.Support.AssignSupportToNode 1, supportNo
    objOpenSTAAD.Support.AssignSupportToNode 2, supportNo

    'Add Primary Loads

    'Add Nodal Load
    objOpenSTAAD.Load.CreateNewPrimaryLoad "Nodal Load"
    Dim nodeId As Long
    nodeId = 1
    Dim fx As Double, fy As Double, fz As Double, mx As Double, my As Double, mz As Double
    fx = 0#
    fy = -2#
    fz = 0#
    mx = 0#
    my = 0#
    mz = 0#
   
    objOpenSTAAD.Load.AddNodalLoad nodeId, fx, fy, fz, mx, my, mz

    'Add Member Load
    objOpenSTAAD.Load.CreateNewPrimaryLoad "UDL Load"
   
    beamNo = 1
    Dim Direction As Integer
    Direction = 5 ' 1 for Y direction
    Dim udlForce As Double
    udlForce = -2#  ' use negative value for downward force
    Dim d1, d2, d3 As Double
    d1 = 0#
    d2 = 0#
    d3 = 0#
    objOpenSTAAD.Load.AddMemberUniformForce beamNo, Direction, udlForce, d1, d2, d3

    objOpenSTAAD.Load.CreateNewPrimaryLoad "UVL Load"
     Direction = 2 ' X direction = 1, Y direction = 2, Z direction = 3.
     Dim uvlForce As Double
    objOpenSTAAD.Load.AddMemberLinearVari beamNo, Direction, 2#, 0#, 0#

    'AddLoad Combination
    Dim loadCombTitle As String
    Dim loadCombNo As Long
    loadCombTitle = "ULTIMATE LOAD"
    loadCombNo = 101
    objOpenSTAAD.Load.CreateNewLoadCombination loadCombTitle, loadCombNo

    Dim loadCaseNo As Long
    Dim loadFactor As Double
    loadCaseNo = 1 ' Load Case ID for UDL Load
    loadFactor = 1.5 ' Factor for UDL Load
    'Add Load to Load Combination
    objOpenSTAAD.Load.AddLoadAndFactorToCombination loadCombNo, loadCaseNo, loadFactor
    loadCaseNo = 2 ' Load Case ID for Nodal Load
    loadFactor = 1.2 ' Factor for Nodal Load
    objOpenSTAAD.Load.AddLoadAndFactorToCombination loadCombNo, loadCaseNo, loadFactor

    'Save model without any user prompt
    objOpenSTAAD.SaveModel 1
End Sub

Conclusion

  • This is more than enough to get you started with automating your STAAD model using OpenSTAAD
  • I’ll try to keep this updated with more samples, and also add sample code for models using plate elements
  • This is just the most commonly used functions for OpenSTAAD; you’ll need to read STAAD docs to find missing parts
  • Also, you can automate this even further by linking all values with your design sheet, so you only have to enter all input in a single place
This post is licensed under CC BY-NC-ND 4.0 by the author.