<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://communities.bentley.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Dustin Powell's Communities Activities</title><link>https://communities.bentley.com/members/5ac7ce84_2d00_7988_2d00_4294_2d00_8357_2d00_f90577e8fecc</link><description>Recent activity for people in Dustin Powell's community</description><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>VBA to interface with civil reports?</title><link>https://communities.bentley.com/products/programming/civil_programming/f/civil_programming_forum/229399/vba-to-interface-with-civil-reports</link><pubDate>Thu, 05 May 2022 20:08:35 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:fc418c4c-abfc-4b06-a456-d4bb7a4fcb23</guid><dc:creator>Dustin Powell</dc:creator><description>&lt;p&gt;i&amp;#39;m wanting to pull some values from the civil reports to be used in a VBA program inside OpenRoads. i know the files are routed to the appdata\local\temp but i cant track the latest file name other than actually looking into the folder.&lt;/p&gt;
&lt;p&gt;is there a way i can capture the .xml file name as its created or is there a means for me to redirect the save folder for the report when my code runs?&lt;/p&gt;
&lt;p&gt;if i can redirect it only when the code runs i can have it delete the file at the end of the code run&lt;/p&gt;
&lt;p&gt;.&lt;img src="/resized-image/__size/320x240/__key/communityserver-discussions-components-files/343635/5873.pastedimage1651781249749v1.png" alt=" " /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>VBA feature macros in OpenSite Designer</title><link>https://communities.bentley.com/products/programming/civil_programming/f/civil_programming_forum/236585/vba-feature-macros-in-opensite-designer</link><pubDate>Thu, 06 Oct 2022 08:31:09 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:16b0585a-3925-4799-8e61-87f728003336</guid><dc:creator>Jan Šalom</dc:creator><description>&lt;p&gt;The same question as &lt;a href="/products/programming/civil_programming/f/civil_programming_forum/168912/vba-feature-macros-in-ord"&gt;https://communities.bentley.com/products/programming/civil_programming/f/civil_programming_forum/168912/vba-feature-macros-in-ord&lt;/a&gt; but for OpenSite Designer. Is it possible to work with terrain model objects in OpenSite Designer and if so where is the library file.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Ask A Question II</title><link>https://communities.bentley.com/achievements/cd3cd235-25c1-476e-bb88-33a5705ca45a</link><pubDate>Thu, 01 Sep 2022 18:06:05 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:fd94e8eb-367e-4f05-9a2d-dc40af7430b8</guid><dc:creator /><description>Ask 10 questions in a forum.</description></item><item><title>Discussion Starter I</title><link>https://communities.bentley.com/achievements/21025ab1-febb-4fb4-a872-d32a921cb45c</link><pubDate>Thu, 21 Jul 2022 21:53:37 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:bece2a71-1e08-4bfc-9e93-73d3eb01c7c5</guid><dc:creator /><description>Start a discussion in a forum that receives 5 replies.</description></item><item><title>ORD 2021 R1 VBA  DLL Reference for Trace Slope Command or Any Terrain point command?</title><link>https://communities.bentley.com/products/programming/civil_programming/f/civil_programming_forum/231056/ord-2021-r1-vba-dll-reference-for-trace-slope-command-or-any-terrain-point-command</link><pubDate>Thu, 09 Jun 2022 18:35:50 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:6fb38dca-c41d-4810-a2c1-5eaf94dc60ce</guid><dc:creator>Dustin Powell</dc:creator><description>&lt;p&gt;So i am unfortunately unable to use the SDK to read or program in C due to the company i work for.&lt;/p&gt;
&lt;p&gt;I have been using VBA to try to make the trace slope command more automated the hangup is getting a point from the boundary of the surface or getting a command state return from the trace slope command to make sure a terrain has been selected.&lt;/p&gt;
&lt;p&gt;i could potentially work around this by patterning the border and getting vertices back but that seems like a resource intensive means.&lt;/p&gt;
&lt;p&gt;Attempts to use locate element by scanning are somewhat successful but limited in returning a value thats actually on the border of the terrain. i can get range.low and range.high but thats about it.&lt;/p&gt;
&lt;p&gt;prerequisite for code is a station offset report to have been run prior to use.&lt;/p&gt;
&lt;p&gt;Special thanks to LA Solutions for the scanbylevel i modified here.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;Option Explicit
Option Compare Text
Public Sub ItterativeTraceSlope()
Call GetArrayData
End Sub

Private Sub GetArrayData()

&amp;#39;requires microsoft scripting runtime library reference
&amp;#39;requires microsoft excel 16.0 object library reference
&amp;#39;this section gets the station offset report and saves it to an array removing unneeded text

    Dim MyArray() As Variant
    Dim Data As Variant
    Dim userresult As Variant
    Dim myPath, myFile, DGNFile, NewestFile, PointText, Trackr, Tailend As String
    Dim c As Long, N, erCatch, intval As Integer
    Dim LatestDate As Date, OLDDate As Date
    Dim LMD As Date, maxd As Long
    
    
  DGNFile = &amp;quot;*&amp;quot; &amp;amp; ActiveDesignFile.Path &amp;amp; &amp;quot;*&amp;quot; &amp;#39;get the folder path for the project from the dgn
  OLDDate = DateAdd(&amp;quot;m&amp;quot;, -3, Date) &amp;#39;skip files older than 90 days
    myPath = Environ$(&amp;quot;TEMP&amp;quot;) &amp;#39;file path of xml report
    &amp;#39;Debug.Print myPath &amp;amp; &amp;quot;is this where xml file is?&amp;quot;
    If Right(myPath, 1) &amp;lt;&amp;gt; &amp;quot;\&amp;quot; Then myPath = myPath &amp;amp; &amp;quot;\&amp;quot;
    myFile = Dir(myPath &amp;amp; &amp;quot;*.xml&amp;quot;, vbNormal) &amp;#39;limit to xml only files
    If Len(myFile) = 0 Then &amp;#39;no xmls in that folder
        MsgBox &amp;quot;No files were found! Please Run Station Offset Report&amp;quot;, vbExclamation
        Exit Sub
    End If
Do While Len(myFile) &amp;gt; 0
        LMD = FileDateTime(myPath &amp;amp; myFile)
    If LMD &amp;lt; OLDDate Then &amp;#39;skip files older than 90 days
     GoTo LP:
     End If
        &amp;#39;check file for tag
        Open myPath &amp;amp; myFile For Input As #1 &amp;#39;open and read the first three lines of each xml file
    For N = 1 To 3 &amp;#39;this section checks the xml file to make sure it matches the command station offset and is from the same project as the dgn.
   
       Line Input #1, Data
        
            Select Case True
            &amp;#39;is file a station offset report?
            Case Data Like &amp;quot;*Station Offset Report*&amp;quot;
            &amp;#39;go to next line of file then
            Line Input #1, Data
           &amp;#39;Debug.Print Data &amp;#39;does file tag match dgnfile path
            If Data Like DGNFile Then
            If LMD &amp;gt; LatestDate Then &amp;#39;check the date
            NewestFile = myFile
            LatestDate = LMD
            End If
            End If
            End Select
    Next
   Close #1
        myFile = Dir
LP:
   
Loop
    
     If Len(NewestFile) = 0 Then &amp;#39;no file matching end process
        MsgBox &amp;quot;No files were found for this project. Please Run Station Offset Report&amp;quot;, vbExclamation
        Exit Sub
    End If

    Open myPath &amp;amp; NewestFile For Input As #1
    &amp;#39;Debug.Print &amp;quot;file opened&amp;quot; &amp;amp; NewestFile
    erCatch = 0
    c = 1
    Do Until EOF(1)
        Line Input #1, Data
        Select Case True
            &amp;#39;use trackr to find values to pass to array
            Case Data Like &amp;quot;*&amp;lt;offsetLinePoint*&amp;quot; &amp;#39;change this to the line just before your desired capture
                Trackr = &amp;quot;Process&amp;quot; &amp;#39;value to make sure we are only getting the areas we want in each loop
                erCatch = 1 &amp;#39;value to see if data exists
            
            Case Data Like &amp;quot;*&amp;lt;point*&amp;quot; And Trackr = &amp;quot;Process&amp;quot;
                                &amp;#39;remove and replace text ; delineated
                PointText = excel.WorksheetFunction.Substitute(Data, &amp;quot;&amp;lt;point&amp;quot;, &amp;quot;&amp;quot;)
                PointText = excel.WorksheetFunction.Substitute(PointText, &amp;quot;&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)
                PointText = excel.WorksheetFunction.Substitute(PointText, &amp;quot;northing=&amp;quot;, &amp;quot;;&amp;quot;) &amp;#39;ycoordinate
                PointText = excel.WorksheetFunction.Substitute(PointText, &amp;quot;easting=&amp;quot;, &amp;quot;;&amp;quot;) &amp;#39;xcoordinate
                PointText = excel.WorksheetFunction.Substitute(PointText, &amp;quot;elevation=&amp;quot;, &amp;quot;;&amp;quot;) &amp;#39;zcoordinate
                &amp;#39;locate and replace pointless text at end of string
                Tailend = Mid(PointText, InStr(1, PointText, &amp;quot;pointType&amp;quot;), Len(PointText) + 1 - InStr(1, PointText, &amp;quot;pointType&amp;quot;))
                PointText = excel.WorksheetFunction.Substitute(PointText, Tailend, &amp;quot;&amp;quot;)
                &amp;#39;&amp;#39;Debug.Print PointText
                PointText = excel.WorksheetFunction.Substitute(PointText, Chr(34), &amp;quot;&amp;quot;) &amp;#39;remove quotes
                PointText = Trim(PointText)
                If IsNumeric(PointText) Then PointText = Val(PointText)
                ReDim Preserve MyArray(1, 1 To c) &amp;#39;expand the array for each new point
                &amp;#39;Debug.Print PointText
                MyArray(1, c) = PointText &amp;#39;save each point to the array
                &amp;#39;reset or continue counting
                Trackr = &amp;quot;&amp;quot;
                c = c + 1
           
        End Select
    Loop
    
    Close #1 &amp;#39;close the file
    &amp;#39;Debug.Print &amp;quot;file closed&amp;quot;
    If erCatch = 0 Then  &amp;#39;didnt find anything
    MsgBox &amp;quot;No data Found&amp;quot;
    Exit Sub
    End If
 
  maxd = MAXd2POINT(MyArray) &amp;#39;call maxd function and get largest distance
  
RESTRT:
userresult = excel.Application.InputBox(&amp;quot;Enter Distance Interval (25&amp;#39;Min)(&amp;quot; &amp;amp; maxd &amp;amp; &amp;quot;Max):&amp;quot;, &amp;quot;Trace Slope Iterations&amp;quot;, &amp;quot;25&amp;quot;, , , , , 1) &amp;#39;change &amp;quot;25&amp;quot; if you want a new default

If userresult = &amp;quot;False&amp;quot; Then
Exit Sub &amp;#39;user hit cancel end program

ElseIf Not IsNumeric(userresult) Or userresult &amp;lt; 25 Then &amp;#39;change this section if you want a different minimum
MsgBox &amp;quot;Value must be a number and no less than 25&amp;quot;
GoTo RESTRT:
ElseIf userresult &amp;gt; 25 Then &amp;#39;user input is greater than 25 we will round and use 5&amp;#39; intervals because i said so.
userresult = userresult / 5
userresult = excel.WorksheetFunction.Floor_Math(userresult, 1) * 5
intval = userresult
End If
   &amp;#39;pass variables to next sub command
    &amp;#39;&amp;#39;SaveArrayToTextFile myPath, MyArray&amp;#39;uncomment to save text file
    TraceSlopeArray MyArray, intval
    &amp;#39;MyArray = Application.WorksheetFunction.Transpose(MyArray)
        &amp;#39;Range(&amp;quot;A1&amp;quot;).Resize(UBound(MyArray, 1), UBound(MyArray, 2)) = MyArray &amp;#39;excel output
End Sub
Private Sub TraceSlopeArray(MyArray2 As Variant, DistInt As Integer)
&amp;#39;this section takes the previous array and passes it to the command trace slope
&amp;#39;debug.print &amp;quot;Made it to TraceSlopeArray&amp;quot;
    Dim startpoint, point1 As Point3d
    Dim point2, pointP As Point3d
    Dim SPArray() As String, N, L As Integer
    Dim lngTemp, distcal As Long, Tim, lvlName As String
    Dim Vi, Fi As Integer
&amp;#39;loop check for 3d if not 3d call 3d
Fi = 0
Vi = 0
 While Fi = 0 And Vi &amp;lt; 9
 Vi = Vi + 1
    If ActiveDesignFile.Views(Vi).IsOpen = True Then
     ActiveDesignFile.Views(Vi).Select
     If ActiveModelReference.Is3D = True Then
     Fi = 1
     Debug.Print Vi &amp;amp; &amp;quot;is 3d&amp;quot;
     End If
    End If

Wend

If Fi = 0 Then
    &amp;#39;no 3d found call 3d command
    CadInputQueue.SendKeyin &amp;quot;vba Run TwoView3DF9&amp;quot;
    Vi = 2
End If
 
 &amp;#39;send levels to scanner functions to find the terrain model and get startpoint
lvlName = &amp;quot;SV_DTM_TERRAIN MODEL&amp;quot;
startpoint = ScanByLevelGetSurfacePoint(lvlName)

&amp;#39;   Coordinates are in master units
 &amp;#39;get start point from user cause i couldnt find anything
&amp;#39;Call GETUSERPNT(startPoint)
If startpoint.X = &amp;quot;&amp;quot; Then
Exit Sub
End If

&amp;#39;   Send a keyin to start traceslope and set feature definition
    CadInputQueue.SendKeyin &amp;quot;DMSG ACTIVATETOOLBYPATH Terrain Model Tools\Analyze Trace Slope&amp;quot;
     CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE FeatureDefinition=&amp;lt;FeatureDefinition&amp;gt;Bentley.CifNET.GeometryModel.ContentManagement.SlopeTraceObjectSettings, Bentley.CifNET.GeometryModel.4.0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bf6c96a266e58d4|TraceSlope\Roadway\Trace Slope\Trace Slope|False&amp;lt;/FeatureDefinition&amp;gt; &amp;quot;

    &amp;#39;CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE FeatureDefinition=&amp;lt;FeatureDefinition&amp;gt;Bentley.CifNET.GeometryModel.ContentManagement.SlopeTraceObjectSettings, Bentley.CifNET.GeometryModel.4.0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bf6c96a266e58d4|No Feature Definition|False&amp;lt;/FeatureDefinition&amp;gt; &amp;quot;

    CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE NamePrefix=&amp;lt;NamePrefix&amp;gt;VAByAGEAYwBlACAAUwBsAG8AcABlAA==,False&amp;lt;/NamePrefix&amp;gt; &amp;quot;

    &amp;#39;CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE FeatureDefinition=&amp;lt;FeatureDefinition&amp;gt;Bentley.CifNET.GeometryModel.ContentManagement.SlopeTraceObjectSettings, Bentley.CifNET.GeometryModel.4.0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bf6c96a266e58d4|TraceSlope\Roadway\Trace Slope\Trace Slope|False&amp;lt;/FeatureDefinition&amp;gt; &amp;quot;

&amp;#39;   Send the start point to the current command
    point1.X = startpoint.X
    point1.Y = startpoint.Y
    point1.Z = startpoint.Z
    CadInputQueue.SendDataPoint point1, Vi
    
    
&amp;#39;   lets get points from the array
     For N = 1 To UBound(MyArray2, 2)
    &amp;#39;preserve each previous point for distance calcs
    pointP.X = point1.X
    pointP.Y = point1.Y
  
    &amp;#39;split that array to points and segment x,y,z
    Tim = MyArray2(1, N)
    SPArray = Split(Tim, &amp;quot;;&amp;quot;)
    point1.X = Trim(SPArray(2)) &amp;#39;x coordinate is 2nd value
    point1.Y = Trim(SPArray(1)) &amp;#39;y coordinate is 1st value
    point1.Z = Trim(SPArray(3)) &amp;#39;z is elevation and doesnt really matter
    &amp;#39;figure out the distance between points
    distcal = ((pointP.X - point1.X) ^ 2 + (pointP.Y - point1.Y) ^ 2) ^ 0.5
    If distcal &amp;lt; DistInt And N &amp;lt; UBound(MyArray2, 2) Then
     L = N &amp;#39;pass N number to L
    Do Until distcal &amp;gt; DistInt &amp;#39;loop until the distance is greater than the minimum interval
    Tim = MyArray2(1, L)
    SPArray = Split(Tim, &amp;quot;;&amp;quot;)
    point1.X = Trim(SPArray(2))
    point1.Y = Trim(SPArray(1))
    point1.Z = Trim(SPArray(3))
    distcal = ((pointP.X - point1.X) ^ 2 + (pointP.Y - point1.Y) ^ 2) ^ 0.5
    L = L + 1
    If L &amp;gt; UBound(MyArray2, 2) Then &amp;#39;reached the end of the array go back 1 and leave the loop
    N = L - 1
    Exit Do
    End If
    Loop
    N = L &amp;#39;Pass L to N number

    End If
    
    point1.X = Trim(SPArray(2))
    point1.Y = Trim(SPArray(1))
    point1.Z = Trim(SPArray(3))
    
    &amp;#39;send point to command in 3d view
    CadInputQueue.SendDataPoint point1, Vi
    &amp;#39;Debug.Print point1.X

    CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE FeatureDefinition=&amp;lt;FeatureDefinition&amp;gt;Bentley.CifNET.GeometryModel.ContentManagement.SlopeTraceObjectSettings, Bentley.CifNET.GeometryModel.4.0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bf6c96a266e58d4|TraceSlope\Roadway\Trace Slope\Trace Slope|False&amp;lt;/FeatureDefinition&amp;gt; &amp;quot;

    CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE NamePrefix=&amp;lt;NamePrefix&amp;gt;VAByAGEAYwBlACAAUwBsAG8AcABlAA==,False&amp;lt;/NamePrefix&amp;gt; &amp;quot;

    Next
    
    

&amp;#39;   Send a reset to the current command
    CadInputQueue.SendReset

    CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE FeatureDefinition=&amp;lt;FeatureDefinition&amp;gt;Bentley.CifNET.GeometryModel.ContentManagement.SlopeTraceObjectSettings, Bentley.CifNET.GeometryModel.4.0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4bf6c96a266e58d4|TraceSlope\Roadway\Trace Slope\Trace Slope|False&amp;lt;/FeatureDefinition&amp;gt; &amp;quot;

    CadInputQueue.SendKeyin &amp;quot;CIVILCMD SETVALUE NamePrefix=&amp;lt;NamePrefix&amp;gt;VAByAGEAYwBlACAAUwBsAG8AcABlAA==,False&amp;lt;/NamePrefix&amp;gt; &amp;quot;

    CadInputQueue.SendReset

    CommandState.StartDefaultCommand
    &amp;#39;debug.print &amp;quot;traceSlopeArray Successful&amp;quot;
    
End Sub
Public Function ScanByLevelGetSurfacePoint(levelName As String) As Point3d
&amp;#39;this section checks the current dgn levels for a terrain surface
&amp;#39;debug.print &amp;quot;Made it to ScanByLevelGetSurfacePoint&amp;quot;
    Dim nElements As Long
    Dim idf2, crp2 As String, pnt2 As Point3d
    Dim oLevel As Level
    Dim lvlres1 As Boolean

nElements = 0

crp2 = &amp;quot;Coversheet&amp;quot;
    
CH2:

&amp;#39;Debug.Print OAtt.AttachName
lvlres1 = IsValidLevelName(levelName, ActiveModelReference)
If lvlres1 = False Then
GoTo OtherLevels1:
End If
    Set oLevel = ActiveModelReference.Levels(levelName)
    &amp;#39;check if level exists
    
    &amp;#39;   Set up scan criteria
    Dim oScanCriteria   As ElementScanCriteria
    Set oScanCriteria = New ElementScanCriteria
    oScanCriteria.ExcludeAllLevels
    oScanCriteria.IncludeLevel oLevel &amp;#39;only the level named
    oScanCriteria.ExcludeNonGraphical
    &amp;#39;   Perform the scan
    Dim oEnumerator As ElementEnumerator
    Set oEnumerator = ActiveModelReference.Scan(oScanCriteria)
Do While oEnumerator.MoveNext
    If oEnumerator.Current.IsGraphical Then &amp;#39;redundant but if not something is wrong
        oEnumerator.Current.Redraw msdDrawingModeHilite
        idf2 = DLongToString(oEnumerator.Current.ID)
    If Not idf2 = &amp;quot;&amp;quot; Then &amp;#39;no ID no Entry
        pnt2 = oEnumerator.Current.Range.Low
        nElements = nElements + 1
        crp2 = &amp;quot;have you seen my stapler?&amp;quot;
    End If
    End If
Loop

OtherLevels1:
      &amp;#39;if at first you dont succeed try a few more levels
    If crp2 = &amp;quot;Coversheet&amp;quot; And Not levelName Like &amp;quot;RDY_*&amp;quot; Then
    levelName = &amp;quot;RDY_Existing Ground&amp;quot;
    GoTo CH2:
    ElseIf crp2 = &amp;quot;Coversheet&amp;quot; And Not levelName Like &amp;quot;RDY_DTM_PERIMETER&amp;quot; Then
    levelName = &amp;quot;RDY_DTM_PERIMETER&amp;quot;
    GoTo CH2:
    ElseIf crp2 = &amp;quot;Coversheet&amp;quot; And levelName = &amp;quot;RDY_DTM_PERIMETER&amp;quot; Then
    &amp;#39;Debug.print &amp;quot;Couldnt find anything in the DGN Check References&amp;quot;
    levelName = &amp;quot;SV_DTM_TERRAIN MODEL&amp;quot;
    pnt2 = ScanByLevelGetSurfPointAttach(levelName)
    
    End If
    
    ScanByLevelGetSurfacePoint = pnt2
    &amp;#39;&amp;#39;Debug.Print idf2 &amp;amp; &amp;quot;;&amp;quot; &amp;amp; crp2 &amp;amp; &amp;quot;;&amp;quot;
    &amp;#39;debug.print &amp;quot;ScanByLevelGetSurfacePoint Successful&amp;quot;
End Function
Public Function ScanByLevelGetSurfPointAttach(levelName2 As String) As Point3d
&amp;#39;this section checks attachment references will only use files whose names are Existing or Terrain
    &amp;#39;debug.print &amp;quot;made it to ScanByLevelGetSurfPointAttach&amp;quot;
    Dim nElements As Long
    Dim idf2, crp2 As String, pnt2 As Point3d
      Dim lvlres2 As Boolean
nElements = 0
    
    Dim oLevel2 As Level
crp2 = &amp;quot;Coversheet&amp;quot;
    
CH2:
Dim OAtt As Attachment
&amp;#39;loop though all attachments
For Each OAtt In ActiveModelReference.Attachments
&amp;#39;can we find attachement names
If OAtt.AttachName Like &amp;quot;*Exist*&amp;quot; Or OAtt.AttachName Like &amp;quot;*Terrain*&amp;quot; Then
&amp;#39;Debug.Print OAtt.AttachName
lvlres2 = IsValidLevelName(levelName2, OAtt)
If lvlres2 = False Then
GoTo OtherLevels2:
End If
    Set oLevel2 = OAtt.Levels(levelName2)
    &amp;#39;check if level exists
   
    &amp;#39;   Set up scan criteria
    Dim oScanCriteria   As ElementScanCriteria
    Set oScanCriteria = New ElementScanCriteria
    oScanCriteria.ExcludeAllLevels
    oScanCriteria.IncludeLevel oLevel2
    oScanCriteria.ExcludeNonGraphical
    &amp;#39;   Perform the scan
    Dim oEnumerator As ElementEnumerator
    Set oEnumerator = OAtt.Scan(oScanCriteria)
Do While oEnumerator.MoveNext
    If oEnumerator.Current.IsGraphical Then &amp;#39;redundant but if not something is wrong

 
        oEnumerator.Current.Redraw msdDrawingModeHilite
        idf2 = DLongToString(oEnumerator.Current.ID)
    If Not idf2 = &amp;quot;&amp;quot; Then &amp;#39;no ID no Entry
        pnt2 = oEnumerator.Current.Range.Low
        nElements = nElements + 1
        crp2 = &amp;quot;have you seen my stapler?&amp;quot;
    End If
    End If
Loop

OtherLevels2:
    &amp;#39;if at first you dont succeed try a few more levels
    If crp2 = &amp;quot;Coversheet&amp;quot; And Not levelName2 Like &amp;quot;RDY_*&amp;quot; Then
    levelName2 = &amp;quot;RDY_Existing Ground&amp;quot;
    GoTo CH2:
    ElseIf crp2 = &amp;quot;Coversheet&amp;quot; And Not levelName2 Like &amp;quot;RDY_DTM_PERIMETER&amp;quot; Then
    levelName2 = &amp;quot;RDY_DTM_PERIMETER&amp;quot;
    GoTo CH2:
    ElseIf crp2 = &amp;quot;Coversheet&amp;quot; And levelName2 = &amp;quot;RDY_DTM_PERIMETER&amp;quot; Then
    MsgBox &amp;quot;NO Terrain Model Found, Check Terrain Feature Definition&amp;quot;
    &amp;#39;debug.print &amp;quot;what the hey we checked references and didnt find it either?&amp;quot;
    Exit Function
    End If
    
End If
Next

    ScanByLevelGetSurfPointAttach = pnt2
    &amp;#39;Debug.Print pnt2.X &amp;amp; &amp;quot;;&amp;quot; &amp;amp; crp2 &amp;amp; &amp;quot;;&amp;quot;
    &amp;#39;debug.print &amp;quot;ScanByLevelGetSurfPointAttach Sucessful&amp;quot;
End Function

Public Function MAXd2POINT(Myarray3 As Variant) As Long
&amp;#39;checks the max distance between first and last entry of array
&amp;#39;debug.print &amp;quot;made it to MAXd2POINT&amp;quot;
    Dim Pmin As Point2d, Pmax As Point2d
    Dim PArray() As String, TinyT As String
    Dim c As Integer, mxd As Double
c = UBound(Myarray3, 2)
TinyT = Myarray3(1, 1)
    PArray = Split(TinyT, &amp;quot;;&amp;quot;)
    Pmin.X = Trim(PArray(2))
    Pmin.Y = Trim(PArray(1))
  TinyT = Myarray3(1, c)
    PArray = Split(TinyT, &amp;quot;;&amp;quot;)
    Pmax.X = Trim(PArray(2))
    Pmax.Y = Trim(PArray(1))
 mxd = Point2dDistance(Pmin, Pmax) / 5
 mxd = excel.WorksheetFunction.Floor_Math(mxd, 1) * 5
MAXd2POINT = mxd
&amp;#39;debug.print &amp;quot;MAXd2POINT Sucessful &amp;quot; &amp;amp; mxd
End Function
Public Function IsValidLevelName(ByVal lvlName2 As String, omodref As ModelReference) As Boolean
    IsValidLevelName = False
    On Error GoTo err_IsValidLevelName
    Dim oLevel3                              As Level
    Set oLevel3 = omodref.Levels(lvlName2)
    If oLevel3 Is Nothing Then
        IsValidLevelName = False
    Else
        IsValidLevelName = True
    End If
    Set oLevel3 = Nothing
    Exit Function

err_IsValidLevelName:
    Select Case Err.Number
    Case 5:
        &amp;#39;   Level not found
        Resume Next
    Case Else
        MsgBox &amp;quot;IsValidLevelName failed&amp;quot;
    End Select
End Function
Sub SaveArrayToTextFile(myPath2 As String, MyArray2 As Variant)
&amp;#39;this is fairly obvious write array to text
    Dim FSO As New FileSystemObject
    Dim filetocreate As Object
    Dim N As Integer
    Set FSO = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)
 
    Set filetocreate = FSO.CreateTextFile(myPath2 &amp;amp; &amp;quot;test.txt&amp;quot;)
 &amp;#39;&amp;#39;Debug.Print MyArray2(1, 23)
    For N = 1 To UBound(MyArray2, 2)
        filetocreate.WriteLine MyArray2(1, N)
    Next
    
    filetocreate.Close
 
End Sub
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Exporting Terrain Model</title><link>https://communities.bentley.com/products/programming/civil_programming/f/civil_programming_forum/226741/exporting-terrain-model</link><pubDate>Tue, 08 Mar 2022 07:20:53 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:29626791-c315-4214-af72-f3c48612dacd</guid><dc:creator>Juho Selenius</dc:creator><description>&lt;p&gt;&lt;span&gt;Hi&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;we have a localized xml standard for road models that is based on LandXML. That means the LandXML exported from ORD isn&amp;#39;t applicable to our clients standards and we need to make our own work-intensive adjustments after exporting the terrain model.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I haven&amp;#39;t found a way in OpenRoads Designer to export terrain models in xml with schema other than LandXML only by making changes to some setting in the software. Is the only way to try to create something with the SDK or could there be more of a lighter way to do this (maybe without the SDK)?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>linking in permits and other construction documents?</title><link>https://communities.bentley.com/products/digital-twin-cloud-services/itwin-services/f/itwin-services-forum/228994/linking-in-permits-and-other-construction-documents</link><pubDate>Tue, 26 Apr 2022 19:41:33 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:6998bae6-5a04-4bbf-a431-cc60e3889ea3</guid><dc:creator>Dustin Powell</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;we are currently in the process of migrating our plans to digital submission. mainly I work in OpenRoads but we have permit applications such as for environmental impacts and i was wondering if theres a way to link these to the model. yes i know we can use the insert object to create a clickable linked image but im wondering if theres something like a documents folder that can &amp;quot;hold&amp;quot; all the required permits?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>Let me Help You</title><link>https://communities.bentley.com/achievements/687f4b6d-e18a-4e55-836c-49926ca2c9d9</link><pubDate>Mon, 01 Nov 2021 07:53:59 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:4374199e-37e7-4aea-bc4a-b0d11295ede7</guid><dc:creator /><description>Answer a question that is verified as helpful or correct.</description></item><item><title>Ask A Question I</title><link>https://communities.bentley.com/achievements/460ac7df-7ccc-4c42-a204-9e05eef3be09</link><pubDate>Fri, 29 Oct 2021 01:16:52 GMT</pubDate><guid isPermaLink="false">6dad98f5-dbc9-4c4d-a9ba-e9da8dc6aa8e:56317b84-1dcf-4349-abe6-b126fe96df86</guid><dc:creator /><description>Ask a question in a forum.</description></item></channel></rss>