RAM Structural System provides a wealth of built-in reporting functionality. However, users often times have requested the ability to have a custom report of all the beam designs in one big table that is beyond the default reporting functionality. We can achieve this and much more by using RAM DataAccess API.
RAM DataAccess API allows programmatic input/ouput of a RAM Database file. The following is an outline of the steps involved to produce an Excel design report of all the steel beams in a RAM Structural System database file.
For an in-depth discussion about RAM DataAccess API see http://communities.bentley.com/products/structural/structural_analysis___design/m/structural_analysis_and_design_gallery/141899
If you are VBA inclined, search for a document on your computer entitled “RAM DATAAccess Developers Guide.pdf”. It is included in the RAM Structural System installation and details the entire RAM DataAccess API for input and ouput.
User Story:
- In Microsoft Excel, the user clicks a button, a file selection dialog is displayed and prompts the user to select the source RAM Structural System (*.rss) file.
- Once a RAM Structural System file is selected, the program outputs the design result of each beam into a “outputTbl”, with each row being 1 beam, and each column being the design value of interest
See it in action:
(Please visit the site to view this video)
Steps:
Setting up your Excel Workbook for VBA Development
- Ensure the “Developers” Ribbon is displayed. File->Options->Customize Ribbon, and check “Developers”
- Save your blank workbook as “*.xlsm” macro enabled spreadsheet
- In the developer tab go to “Visual Basic”, and your should see the VBA Code Editor
- Right click “ThisWorkbook” and insert a new module
2. Our code will reside in this new module. Go to Tools – References and select ‘RAMDataAccess 2.0 Type Library’ from the ‘References – VBAProject’ dialog box. Adding this reference to your application creates a library of the functions and constants that are available in RAM DA. Also select Microsoft Scripting Runtime, as this will allow us to use “Dictionaries”. Dictionaries are a handy Key Value Pair storage system.
3. With “Module 1” selected, copy and paste the following code:
'''''''''''''''''''''''
'''' CODE START '''''''
'''''''''''''''''''''''
Dim RamDataAcc1 As RAMDATAACCESSLib.RamDataAccess1
Dim RamDataAccIDBIO As RAMDATAACCESSLib.IDBIO1
Dim IModel As RAMDATAACCESSLib.IModel
Dim ISteelCriteria As RAMDATAACCESSLib.ISteelCriteria
Dim IModelData1 As RAMDATAACCESSLib.IModelData1
Dim IStories As RAMDATAACCESSLib.IStories
Dim IStory As RAMDATAACCESSLib.IStory
Dim IBeams As RAMDATAACCESSLib.IBeams
Dim IBeam As RAMDATAACCESSLib.IBeam
Dim IProperties As RAMDATAACCESSLib.IProperties
Dim IProperty As RAMDATAACCESSLib.IProperty
Dim ISteelBeamDesignResult As RAMDATAACCESSLib.ISteelBeamDesignResult
Dim prop As Props
Dim pStartPoint As RAMDATAACCESSLib.SCoordinate
Dim pEndPoint As RAMDATAACCESSLib.SCoordinate
Dim dVersion As Double
Dim dVMin As Double
'Long
Dim R As Long
Dim lNumMems As Long
Dim lNumStories As Long
Dim lStory As Long
Dim lMem As Long
Dim lNumCants As Long
Dim lMemberID As Double
Dim plNumStudSegments As Long
Dim lSizeOfArrayOfStuds As Long
Dim lTotalStuds As Long
Dim lStudSeg As Long
Dim i As Long
Dim lNumPoints As Long
Dim lPoint As Long
Dim lStoryUID As Long
Dim NumFinalPolygons As Long
Dim lFinalPolygon As Long
Dim NumFinalDiaphragms As Long
Dim lHole As Long
Dim lFirstSpace As Long
Dim j As Long
Dim lNumWebOpenings As Long
Dim lBasePlate As Long
Dim lFixity As Long
Dim lAboveUID As Long
Dim lSplice As Long
Dim lLoadDB As Long
Dim palNumStuds() As Long
'Double
Dim dMemLength As Double
Dim pdArea As Double
Dim pdBfTop As Double
Dim pdBfBot As Double
Dim pdTfTop As Double
Dim pdTfBot As Double
Dim pdDepth As Double
Dim pdWebT As Double
Dim dSectionPerimeter As Double
Dim dX1 As Double
Dim dY1 As Double
Dim dZ1 As Double
Dim dX2 As Double
Dim dY2 As Double
Dim dZ2 As Double
Dim dPerimeterLength As Double
Dim dConcThick As Double
Dim dPolygonArea As Double
Dim dHoleArea As Double
Dim dP1X As Double
Dim dP2X As Double
Dim dP3X As Double
Dim dP1Y As Double
Dim dP2Y As Double
Dim dP3Y As Double
Dim dP1Z As Double
Dim dP2Z As Double
Dim dP3Z As Double
Dim dP1P2 As Double
Dim dP2P3 As Double
Dim dP1P3 As Double
Dim dTemp As Double
Dim dWeight As Double
Dim dUnitsFactor As Double
Dim dDesignCamber As Double
Dim A As Double
Dim B As Double
Dim C As Double
Dim dAngle As Double
Dim dM1 As Double
Dim dM2 As Double
'Enumerators
Dim eBeamCoordLoc As eBeamCoordLoc
Dim peBeamStatus As model_status
Dim peColumnStatus As model_status
Dim peFrameStatus As model_status
Dim peShape As ESTEEL_SEC
'Strings
Dim frameType As String
Type Props
strDesig As String
strRollFlg As String
dDepth As Double
dTw As Double
dBfTop As Double
dTfTop As Double
dBfBot As Double
dTfBot As Double
dKTop As Double
dKBot As Double
dArea As Double
dPerimeter As Double
strShape As String
End Type
Private Function GetSectionProps() As Props
Dim SectionProps As Props
Set IMemberData1 = RamDataAcc1.GetDispInterfacePointerByEnum(IMemberData_INT)
IMemberData1.GetSteelMemberSectionDimProps lMemberID, peShape, 1, pdBfTop, pdBfBot, pdTfTop, pdTfBot, 1, 1, pdDepth, pdWebT, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, pdArea
If peShape = EStlWF Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = 2 * pdBfTop + 2 * pdDepth + 2 * pdBfBot - 2 * pdWebT
SectionProps.dBfTop = pdBfTop
SectionProps.strShape = "ISection"
End If
If peShape = EStlChannel Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = 2 * pdBfTop + 2 * pdDepth + 2 * pdBfBot - 2 * pdWebT
SectionProps.dBfTop = pdBfTop
SectionProps.strShape = "Channel"
End If
If peShape = EStlTube Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = 2 * pdBfTop + 2 * pdDepth
SectionProps.dBfTop = pdBfTop
SectionProps.strShape = "Tube"
End If
If peShape = EStlDoubleL Then
SectionProps.dArea = 2 * pdArea
SectionProps.dPerimeter = 4 * pdDepth + 4 * pdWebT
SectionProps.dBfTop = 0
SectionProps.strShape = "DoubleAngle"
End If
If peShape = EStlFlatBar Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = pdBfTop * 2 + pdTfTop * 2
SectionProps.dBfTop = 0
SectionProps.strShape = "Bar"
End If
If peShape = EStlLSection Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = 2 * pdDepth + 2 * pdWebT
SectionProps.dBfTop = 0
SectionProps.strShape = "Angle"
End If
If peShape = EStlNone Then
SectionProps.dArea = 0
SectionProps.dPerimeter = 0
SectionProps.dBfTop = 0
SectionProps.strShape = "NA"
End If
If peShape = EStlPipe Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = pdDepth * 3.14159
SectionProps.dBfTop = 0
SectionProps.strShape = "Pipe"
End If
If peShape = EstlRoundBar Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = pdDepth * 3.14159
SectionProps.dBfTop = 0
SectionProps.strShape = "Rod"
End If
If peShape = EStlTSection Then
SectionProps.dArea = pdArea
SectionProps.dPerimeter = 2 * pdBfTop + 2 * pdDepth
SectionProps.dBfTop = 0
SectionProps.strShape = "Tee"
End If
GetSectionProps = SectionProps
End Function
Sub runThis()
' Define Variables
'Set version developed
dVMin = 14.5
'Get Model path
Dim OpenFile As String
Dim strVMin As String
Dim iNumStories As Long
Dim strStoryID As String
Dim lNumBeams As Long
Dim member_num As String
OpenFile = Application.GetOpenFilename("RAM SS Database (*.ram; *.rss), *.ram; *.rss")
If OpenFile = "" Or OpenFile = False Then
Exit Sub
End If
'Initialize DataAccess
Set RamDataAcc1 = New RAMDATAACCESSLib.RamDataAccess1
'Set RamDataAcc1 = CreateObject("RAMDATAACCESSLib.RamDataAccess1")
'Initialize IO interface
Set RamDataAccIDBIO = RamDataAcc1.GetDispInterfacePointerByEnum(IDBIO1_INT)
'Check to see if compatible version
RamDataAccIDBIO.GetDatabaseVersion OpenFile, dVersion
dVersion = Round(dVersion, 1)
If dVersion < dVMin Then
strVMin = dVMin
MsgBox "This tool was written for Ram Structural System version " + strVMin + " or later. Please update."
Exit Sub
End If
lLoadDB = RamDataAccIDBIO.LoadDataBase2(OpenFile, "DA")
If lLoadDB <> 0 Then
MsgBox "The model appears to be in use or is not consistent with the version of RAM Structural System on this machine."
Exit Sub
End If
'Initialize the Object Model Interface
Set IModel = RamDataAcc1.GetDispInterfacePointerByEnum(IModel_INT)
' get Storeis
Set IStories = IModel.GetStories
iNumStories = IStories.GetCount
ClearTable "outputTbl"
For lStory = 0 To (iNumStories - 1)
Set IStory = IStories.GetAt(lStory)
strStoryID = IStory.strLabel
'Get member ID lists on Story
Set IBeams = IStory.GetBeams
IBeams.Filter eBeamFilter_Material, ESteelMat
lNumBeams = IBeams.GetCount
Dim lBeam As Long
For lBeam = 0 To lNumBeams - 1
Set IBeam = IBeams.GetAt(lBeam)
lMemberID = IBeam.lUID
member_num = IBeam.lLabel
' If member_num = 1 Then
sect_lbl = IBeam.strSectionLabel
camber = IBeam.dCamber
prop = GetSectionProps
IBeam.GetCoordinates eBeamEnds, pStartPoint, pEndPoint
Set ISteelBeamDesignResult = IBeam.GetSteelDesignResult
Dim numStudsDAArray As RAMDATAACCESSLib.DAArray
Set numStudsDAArray = ISteelBeamDesignResult.GetNumStudsInSegments
Dim designedCamber
Dim pSize As Long
' determin frame type
If IBeam.eFramingType = MemberIsGravity Then
frameType = "Gravity"
Set IGravitySteel1 = RamDataAcc1.GetDispInterfacePointerByEnum(IGravitySteelDesign_INT)
If IBeam.bComposite = 1 Then
ReDim palNumStuds(0 To 4) As Long
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetSize pSize
For lStudSeg = 0 To pSize - 1
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetAt lStudSeg, k
lTotalStuds = lTotalStuds + k
palNumStuds(lStudSeg) = k
Next
For onWards = pSize To UBound(palNumStuds)
palNumStuds(onWards) = 0
Next
Else
lTotalStuds = 0
End If
ElseIf IBeam.eFramingType = MemberIsLateral Then
frameType = "Lateral"
If IBeam.bComposite = 1 Then
ReDim palNumStuds(0 To 4) As Long
lTotalStuds = 0
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetSize pSize
For lStudSeg = 0 To pSize - 1
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetAt lStudSeg, k
lTotalStuds = lTotalStuds + k
palNumStuds(lStudSeg) = k
Next
For onWards = pSize To UBound(palNumStuds)
palNumStuds(onWards) = 0
Next
Else
lTotalStuds = 0
End If
End If
dMemLength = Sqr((pStartPoint.dXLoc - pEndPoint.dXLoc) ^ 2 + (pStartPoint.dYLoc - pEndPoint.dYLoc) ^ 2 + (pStartPoint.dZLoc - pEndPoint.dZLoc) ^ 2)
Dim dict As New scripting.dictionary
dict.Add "Floor", strStoryID
dict.Add "BeamNo", member_num
dict.Add "FrameType", frameType
dict.Add "SectionLbl", sect_lbl
dict.Add "SectionShp", prop.strShape
dict.Add "SectArea", prop.dArea
dict.Add "SectTop", prop.dBfTop
dict.Add "SectPerimeter", prop.dPerimeter
dict.Add "BeamLength", dMemLength
dict.Add "StartX", pStartPoint.dXLoc
dict.Add "StartY", pStartPoint.dYLoc
dict.Add "StartZ", pStartPoint.dZLoc
dict.Add "EndX", pEndPoint.dXLoc
dict.Add "EndY", pEndPoint.dYLoc
dict.Add "EndZ", pEndPoint.dZLoc
dict.Add "Camber", IBeam.dCamber
dict.Add "StudDiameter", IBeam.dStudDiameter
dict.Add "StudLength", IBeam.dStudLength
dict.Add "StudSegmentLength1", IBeam.dStudSegment1Length
dict.Add "StudSegmentLength2", IBeam.dStudSegment2Length
dict.Add "StudSegmentLength3", IBeam.dStudSegment3Length
dict.Add "StudSegmentLength4", IBeam.dStudSegment4Length
dict.Add "StudSegmentLength5", IBeam.dStudSegment5Length
dict.Add "NumOfStud1", palNumStuds(0)
dict.Add "NumOfStud2", palNumStuds(1)
dict.Add "NumOfStud3", palNumStuds(2)
dict.Add "NumOfStud4", palNumStuds(3)
dict.Add "NumOfStud5", palNumStuds(4)
AddToTable dict, "outputTbl"
Set dict = Nothing
'End If
Next
Next
For Each ws In ThisWorkbook.Worksheets
For Each lstobj In ws.ListObjects
If lstobj.Name = "outputTbl" Then
lstobj.ListColumns(1).Delete
End If
Next
Next
RamDataAccIDBIO.CloseDatabase
End Sub
Sub ClearTable(tblName)
For Each ws In ThisWorkbook.Worksheets
For Each lstobj In ws.ListObjects
If lstobj.Name = tblName Then
lstobj.Delete
End If
Next
Next
Dim wsh As Worksheet
Set wsh = ThisWorkbook.Worksheets(1)
Dim lo As ListObject
Set lo = wsh.ListObjects.Add(xlSrcRange, Range("$A$4"), , xlYes)
lo.Name = "outputTbl"
lo.ListRows.Add AlwaysInsert:=True
End Sub
Sub AddToTable(dict As scripting.dictionary, tblName)
Dim wkBk As Workbook
Dim wksht As Worksheet
Dim lo As ListObject
Dim lstobj As ListObject
Set wkBk = Application.ThisWorkbook
For Each ws In ThisWorkbook.Worksheets
For Each lstobj In ws.ListObjects
If lstobj.Name = tblName Then
AddDictToTbl lstobj, dict
End If
Next
Next
End Sub
Public Function DoesTableExist(ByVal wb As Workbook, _
ByVal tblName As String) As Boolean
On Error GoTo catch
DoesTableExist = False
Dim lstobj As ListObject, ws As Worksheet
For Each ws In wb.Worksheets
For Each lstobj In ws.ListObjects
If lstobj.Name = tblName Then
DoesTableExist = True
Exit Function
End If
Next
Next
Exit Function
catch:
DoesTableExist = False
End Function
Public Function AddDictToTbl(lo As ListObject, dict As scripting.dictionary)
Dim hr As Range
Set hr = lo.HeaderRowRange
For Each k In dict.Keys
If Application.WorksheetFunction.CountIf(hr, k) > 0 Then
Else
lo.ListColumns.Add
lo.HeaderRowRange.End(xlToRight) = k
End If
Next
'lo.ListColumns("Column1").Delete
Dim rowRng As ListRow
'lo.ListRows.Add AlwaysInsert:=True
Set rowRng = lo.ListRows(lo.ListRows.Count)
Dim colRng As Range
Dim tarRng As Range
For Each Key In dict.Keys
' find column no from key
Set colRng = lo.ListColumns(Key).Range
Set tarRng = colRng(lo.ListRows.Count + 1)
tarRng = dict(Key)
Next
lo.ListRows.Add AlwaysInsert:=True
End Function
‘Explanation: In VBA , we work with variables, front portion establishes some commonly used variable to store our values in.
'''''''''''''''''''''''
'''' CODE END '''''''
'''''''''''''''''''''''
4. Select Cell “A4” on Sheet 1 and insert a table. Check "my table has header", and enter “ouputTbl” as the table Name.
5. In Developer Tab, Insert-> Form Controls -> Button. Draw a button above the table you have just added. Right click the button and edit the text to read “Load RSS”. Right click button again and select “Assign Macro”. A dialog will pop up asking which procedure to run when this button is pressed. Select “runThis” Procedure. Save your workbook and try out the program you have just created.
Explanation
1. When you click the "Load RSS" button it will launch the procedure "runThis". Let's drill into the content of "runThis" and see what it is doing.
In runThis, we ask the user to select the RSS database to pull information from using the following code:
OpenFile = Application.GetOpenFilename("RAM SS Database (*.ram; *.rss), *.ram; *.rss")
If OpenFile = "" Or OpenFile = False Then
Exit Sub
End If
OpenFile is the path to the RSS database file selected by the user, if the user did not select a file, it "Exit Sub" <-- or exit the procedure.
Once the user has sucessfully selected a file, the program proceeds with the following lines of code:
'Initialize DataAccess
Set RamDataAcc1 = New RAMDATAACCESSLib.RamDataAccess1
'Set RamDataAcc1 = CreateObject("RAMDATAACCESSLib.RamDataAccess1")
'Initialize IO interface
Set RamDataAccIDBIO = RamDataAcc1.GetDispInterfacePointerByEnum(IDBIO1_INT)
'Check to see if compatible version
RamDataAccIDBIO.GetDatabaseVersion OpenFile, dVersion
dVersion = Round(dVersion, 1)
If dVersion < dVMin Then
strVMin = dVMin
MsgBox "This tool was written for Ram Structural System version " + strVMin + " or later. Please update."
Exit Sub
End If
lLoadDB = RamDataAccIDBIO.LoadDataBase2(OpenFile, "DA")
If lLoadDB <> 0 Then
MsgBox "The model appears to be in use or is not consistent with the version of RAM Structural System on this machine."
Exit Sub
End If
'Initialize the Object Model Interface
Set IModel = RamDataAcc1.GetDispInterfacePointerByEnum(IModel_INT)
The above block of code establishes some pointer variables and checks if the current version is compatible. Once that is done it loads the RSS Database with lLoadDB = RamDataAccIDBIO.LoadDataBase2(OpenFile, "DA") , and sets the Object Model Interface.
' get Storeis
Set IStories = IModel.GetStories
iNumStories = IStories.GetCount
ClearTable "outputTbl"
We then get the number of stories and assign to iNumStories and also run this self explanatory function ClearTable "ouputTbl", which deletes the content of a Table with the name "outputTbl". This clears the table from previously output results.
For lStory = 0 To (iNumStories - 1)
Set IStory = IStories.GetAt(lStory)
strStoryID = IStory.strLabel
'Get member ID lists on Story
Set IBeams = IStory.GetBeams
IBeams.Filter eBeamFilter_Material, ESteelMat
lNumBeams = IBeams.GetCount
Dim lBeam As Long
For lBeam = 0 To lNumBeams - 1
Set IBeam = IBeams.GetAt(lBeam)
lMemberID = IBeam.lUID
member_num = IBeam.lLabel
' If member_num = 1 Then
sect_lbl = IBeam.strSectionLabel
camber = IBeam.dCamber
prop = GetSectionProps
Next we start a nested "for" loop, where we are iterating through each story in the model, and also iterating through each beam in each storey. The current Beam Object we are working is set to IBeam. We assign its properties (e.g beamID and beam No to some intermediary variables), and also run a helper method called GetSection Props, which pushed some properties to the prop variable.
Dim pSize As Long
' determin frame type
If IBeam.eFramingType = MemberIsGravity Then
frameType = "Gravity"
If IBeam.bComposite = 1 Then
ReDim palNumStuds(0 To 4) As Long
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetSize pSize
For lStudSeg = 0 To pSize - 1
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetAt lStudSeg, k
lTotalStuds = lTotalStuds + k
palNumStuds(lStudSeg) = k
Next
For onWards = pSize To UBound(palNumStuds)
palNumStuds(onWards) = 0
Next
Else
lTotalStuds = 0
End If
ElseIf IBeam.eFramingType = MemberIsLateral Then
frameType = "Lateral"
If IBeam.bComposite = 1 Then
ReDim palNumStuds(0 To 4) As Long
lTotalStuds = 0
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetSize pSize
For lStudSeg = 0 To pSize - 1
IBeam.GetSteelDesignResult.GetNumStudsInSegments.GetAt lStudSeg, k
lTotalStuds = lTotalStuds + k
palNumStuds(lStudSeg) = k
Next
For onWards = pSize To UBound(palNumStuds)
palNumStuds(onWards) = 0
Next
Else
lTotalStuds = 0
End If
End If
dMemLength = Sqr((pStartPoint.dXLoc - pEndPoint.dXLoc) ^ 2 + (pStartPoint.dYLoc - pEndPoint.dYLoc) ^ 2 + (pStartPoint.dZLoc - pEndPoint.dZLoc) ^ 2)
Next we check for it framing system type (beam or lateral), and push the design values for these beams to intermediate variables. note the dMemLength is just a simple formula from the beam coordinate outputs.
Dim dict As New scripting.dictionary
dict.Add "Floor", strStoryID
dict.Add "BeamNo", member_num
dict.Add "FrameType", frameType
dict.Add "SectionLbl", sect_lbl
dict.Add "SectionShp", prop.strShape
dict.Add "SectArea", prop.dArea
dict.Add "SectTop", prop.dBfTop
dict.Add "SectPerimeter", prop.dPerimeter
dict.Add "BeamLength", dMemLength
dict.Add "StartX", pStartPoint.dXLoc
dict.Add "StartY", pStartPoint.dYLoc
dict.Add "StartZ", pStartPoint.dZLoc
dict.Add "EndX", pEndPoint.dXLoc
dict.Add "EndY", pEndPoint.dYLoc
dict.Add "EndZ", pEndPoint.dZLoc
dict.Add "Camber", IBeam.dCamber
dict.Add "StudDiameter", IBeam.dStudDiameter
dict.Add "StudLength", IBeam.dStudLength
dict.Add "StudSegmentLength1", IBeam.dStudSegment1Length
dict.Add "StudSegmentLength2", IBeam.dStudSegment2Length
dict.Add "StudSegmentLength3", IBeam.dStudSegment3Length
dict.Add "StudSegmentLength4", IBeam.dStudSegment4Length
dict.Add "StudSegmentLength5", IBeam.dStudSegment5Length
dict.Add "NumOfStud1", palNumStuds(0)
dict.Add "NumOfStud2", palNumStuds(1)
dict.Add "NumOfStud3", palNumStuds(2)
dict.Add "NumOfStud4", palNumStuds(3)
dict.Add "NumOfStud5", palNumStuds(4)
AddToTable dict, "outputTbl"
Set dict = Nothing
We created a new Dictionary Object, this dictionary object stores Key (Beams property NAME), Value (Beams Property VALUE) into one object. We then run a helper function entitled AddToTable that takes a dictionary object as well as the table name to ouput the results to.
AddToTable adds the value according to the column headings for each new beam into a new row.
Next
Next
Closing next statement for our two concentric for loops in the beginning of the code.
The completed macro enabled workbook, along with the example file can be downloaded at
Note that the completed workbook contains additional code that allows the import of not only Beams, but also Columns, Horizontal Braces and also Vertical Braces in the model.
***Important caveats and considerations when replicating this work:
- Make a back up of your target RSS file before testing this out.
- All results output by the API are in Imperial units. Conversions to SI are required on the client side.
- RAM Structural System has to be switched off at the time of running.
- Should it error out at some point, try again and ensure that the “*.usr” file located in the same directory as your “*.rss” file is deleted.