Friday, January 30, 2009

Point Inquiry - VBA

This post will go through the steps to get point information from a point and send the information to the command line.

The first thing we want to do is to make sure Civil 3D is running. To do this open the SurfacePoints example that comes with Civil 3D and export the Base Objects code. The sample code is located at:

C:\Program Files (x86)\AutoCAD Civil 3D 2009\Sample\Civil 3D API\Vba\SurfacePoints


Next go create a new VBA project through the VBAMAN command and then import the module into the new file.



Now go insert a new module into the ACADProject.


Next make sure the Land references are included, from the Menu: Tools > References


Now add Option Explicit at the top of the newly created module and Sub PointInfo(), the End Sub should automatically be created. The Option Explicit requires you to use DIM all of the variables used in the code, otherwise VBA assumes that value and that may cause problems if you want a specific type of object.


Now go into the subroutines module of the SurfacePointsSample and copy the lines that check to see if Civil 3D is running and gets the Civil 3D application and document.


Now paste it into the PointInfo() sub. This will make sure Civil 3D is running, if it's not the sub will be ended and an error message will be given to the user.

Now that we've done the housekeeping we can start to write the code to get a point using the ThisDrawing.Utility.GetEntity.


The AcadEntity is just a generic AutoCad entity and the vPoint is a variant. A variant is kind of like a junk entity, it will store almost anything, in this case it stores three number values representing the location the user selected. So now that we hopefully have the point from the user we need to make sure the user selected the point using the If/Then and TypeOf to make sure the user selected a point.


If it is we create a variable for an Aeccpoint and set it equal to the oAcadObj. We'll also add an Else to tell the user what he did wrong.


So now have the point we'll send the point information to the command line using the prompt Method of the Utility object.


So that's almost it. Just add some error catching, maybe an "On Error Resume Next" at the top or an "On Error Resume Next" above the GetEntity line and an "On Error Go to 0" to turn it off in case the user doesn't select an object and around the Description line if the point doesn't have a description assigned which will also cause an error.

The completed VBA may be found on this page:

Thursday, January 29, 2009

myvbooks - Autodesk University 2008

I've been working on creating a vBook on using VBA with Civil 3D, which I hope to complete someday. I did notice a few weeks back that the site that someday may contain the vBook has Autodesk University 2008 Power Track sessions for sale on the site. The PowerTrack session for Civil 3D is available along with Inventor, Building Design and a bundle with all of the PowerTracks.

Don't worry the sessions are still available for free on the AU website if you were an attendee, but is an option for you to get the screencasts if for some reason you are unable to get access to them on the AU website.

Monday, January 26, 2009

Extract 3DPolyline From Corridor

This post will show how to extract all of the feature lines from a corridor with a particular code name using VBA programming. Well it won't do all of them, just the ones associated with the Mainline baseline (any offset baselines are not dealt with).


The user is prompted to select a corridor and then to type in the code they want to extract. As you can see in the code each of the baselines, feature line collections and feature lines are looped through to see if they contain contain the code the user provided. At the end a 3DPolyline is added to the drawing and then it loops to the next items. The basic structure for offset baselines is similar and could be added. The completed code may be found on this page:

There is no error catching in the code, so the user will get error messages if something goes wrong. Adding On Error Resume Next near the top of the code will suppress most of the error messages.

Sunday, January 25, 2009

Lighter Side of Civil 3D

The Between the Lines blog recently had a post on AutoCAD Pranks. This post will cover a Civil 3D 2009 prank. The first thing you need to do is down load this VBA file. To run the file type VBALOAD at the command line and select the file. Next type VBARUN and select a subassembly object. Once you select the subassembly object it will go from something that looks like this:


to something that looks like this:


The change won't affect how the corridor is built. To get the subassembly back to the original look, go the Properties of the Subassembly, the Parameters tab and press OK. Civil 3D 2009 should then rebuild the subassembly based on the dll file.

For a more disastrous prank take a look at this post. Instead of importing points, add data to the surface that is large difference from the highest or lowest point on the surface while the surface style doesn't show contours. Then save and close the drawing. Once an unsuspecting person opens the file and sets the surface to show contours it will either crash the program or take a really long time to draw the contours. Since I did the original post Civil 3D 2009 does a much better job of handling the task and will take a larger elevation difference to cause the program to crash.

I personally wouldn't do any of this, but there seems to be some people out there who like to mess with others.

Thursday, January 22, 2009

Labeling Multiple Lines

In Civil 3D it appears you can only label one line at a time. This post will show a way to do label multiple lines using VBA. The first thing that needs to be done is to create a new vba project. The thing I learned while figuring out how to do this is using a selection set to select multiple objects. To create a selection set add it to the drawing's selection set collection. Once I'm done with it I need to delete it in order to be able to run the program again without getting an error that the selection set already has been created.


This is example just does lines, but the same concept could be done with polylines, feature lines, arcs, parcels and alignments.

Wednesday, January 21, 2009

Selecting Uncompleted Objects

Sometimes you go through the steps to create a profile or alignment get everything set to edit it and accidentally imageclose the Layout Tools before creating a segment. At first glance it appears you have to delete the alignment or profile from the Toolspace and start over. Luckily that isn't the case if you use the Quick Select tool. To use the tool just right click in Model space and choose the Quick Select option.

Once the Quick Select dialog comes up pick the Object type you want to select, in this case an alignment or profile. Next choose a property that you know is assigned to it such as the name of the profile or alignment. Using the wildcard option you can use part of the alignment or profile name. Press OK and then you should have the alignment or profile selected.


Now right click in Model space and you should have the option to edit the geometry data. While not a large time saver it may make you feel better not having to do work over again.

Monday, January 19, 2009

Create Point Relative to Elevation

This post is going to build on the Create Points with Elevation post I did last month. Instead of creating the point with elevation at the point selected, this will create a point relative to another point and let the user type in an elevation difference.

The code from the last post is below:


The first thing that needs to be done is to change the "Select Point to something more appropriate, maybe "Select Reference Elevation Point: ". Now we need to ask the user to specify the location where the point needs to be created at. Do do that we'll need to create a vPoint2 variable to store the point location.


Next we need to prompt the user the elevation difference the user wants to use. The code below prompts the user for that information.


There is some error catching to use a default value. If the user hits enter or spacebar the default value of -0.5 is used. The On Error Resume Next has the code go to the next line of code instead of sending an error message to the user. So now we have all of the information we need to create the point. The lines of code below creates the point.


To save you some time the completed code may be found on this page.

Distances Between Two Points

In Civil 3D there is an inquiry toolbar that contains the CGSLIST command. The command provides the slope information for an object or distance between points.


Selecting an object provides the slope information for the segment selected and not the entire length of the object. The Points option let you select two points and it will return the inquiry between those two points.

The program works as intended, but could use some improvements especially if you want to use points most of the time instead of an object. The code below does the same thing as the CGSLIST command except for the object portion and pulling the number precision from the drawing.


The Call CGSLST at the end makes it loop through the command again. The program will stop once a point is not selected. You can add the vba through the cui. The completed code may be found here.

Wednesday, January 14, 2009

I Scream for Ice Cream

I had big plans to do a Civil 3D related post tonight, unfortunately imageI got sidetracked on the way and ended up catching a show and some ice scream at Doc Burnstein's Ice Cream Lab. The show was great, got to learn about the irreverent history of ice cream from Bert and Ernie. They must only hire people named Bert or Ernie because every show I've been to has Bert and Ernie doing it, even the girls. Heard some great bad jokes and evidently most world conflicts have been a result of the secret of making ice cream, not quite sure if Gaza or Israel need the secret of making ice cream but here it is.

"Add salt to the ice to drop the temperature of the ice surrounding the container"

A quick search of the Internet should result in a suitable recipe, if required I'll send my ice cream machine over.

During the ice cream lab show the audience gets to make and name a new ice cream flavor. The ice cream flavor for this show ended up being Poison Apple Pie which has apple ice cream as a base and marshmallows, walnuts and pie crust. If that sounds good to you the flavor goes on sale from Friday until it runs out.

Monday, January 12, 2009

VBA - Add Pipes to a Profile View

The API for Civil 3D, as far as I know, doesn't have way to add pipes or structures to a profile view. There is a possible workaround using AutoCAD's SendCommand. The code would look something like this:

ThisDrawing.SendCommand ("AddNetworkPartsToProf " & "3741.54989837,3396.84999773 " & " " & _
"4077.571130249153,3497.898627605000 ")

The first ZoomExtents is to refresh model space because if the graphics aren't current AutoCAD won't recognize the newly created pipe/structure or profile view. The next part sends the commands to the command line. The AddNetworkPartsToProf is the command to in Civil 3D to add pipe/structures to a profile view. The next part is the coordinate location of where a pipe/structure is located in the drawing and the last part is the point in the drawing where a profile view may be selected. The last ZoomExtents is just for show. The & symbol joins text strings together.

Sunday, January 11, 2009

Wish Post - This Subassembly Requires Superelevation

I was reading Jason Hickey's post on the new Being Civil blog and it got me thinking about where exactly does that default 5% slope come from. My first thought was that it came from the Alignment's Edit Feature Settings. I changed the value from 5% to 3%, at the location shown below, and noticed it didn't change.


Finding that the subassembly doesn't look at that value, I looked at the code that is supplied with the program and saw it was the default value. Since I don't regularly use the subassembly, it isn't that big of an issue for me, but if I do have to use it in the future my wish would be for the subassembly to use the default values specified in the Edit Feature Settings for an Alignment.

If you want a different default value you can open the code that comes with the program (File Location: C:\Program Files (x86)\AutoCAD Civil 3D 2009\Sample\Civil 3D API\C3DStockSubAssemblies) in Microsoft Visual Studio and change the numbers indicated by the arrows below, compile the code and replace the C:\ProgramData\Autodesk\C3D 2009\enu\C3DStockSubassemblies.dll file with it.


Thursday, January 08, 2009

Pipe Slope Along a Run

Civil 3D provides several ways to change the slope of pipes. You can use Prospector, right clicking and viewing the pipe's properties, grip editing the pipe or using pipe rules. Apart from the rules there is a limited number of ways to adjust the slope of a pipe run. The pipe rules, Cover and Slope, may be problematic for a run of pipes since the cover makes it difficult to get a slope at a constant grade. I did post about the availability of a Slope Only rule that I came up with for a coworker in Colorado, but nobody seemed interested in it. I'm just glad no one has asked for it recently because I think I misplaced the rule. For this post I'm going to be working outside of the rules and going with VBA.

I've covered on how to set up the VBA in pasts posts, so I'll skip it here. Once you have the VBA project set up we can go ahead and start programming. The first thing we need to do is get some information from the user.


So now that we have the pipes or structures and required slope we can modify the pipe slopes. The first thing we need to do is get the pipe application which is the AutoCAD object that contains all of the pipe information, which is borrowed from the sample file that comes with Civil 3D.


Now we need to get the pipe networks of the pipe parts selected to make sure the pipes/structures are in the same pipe network. Since we need to find it for each structure we'll use a separate Function to find the pipe network names. When using the Functions you can pass objects from the Sub to the Function and then return the value. The arrows are trying to illustrate what is being passed and where they are placed.


The code goes through all of the pipe networks in the drawing and then checks to see if the pipe or structure is included in the pipe network. So now that the pipe networks are known we can see if they are in the same network, if not the program will end using the Exit Sub.


So now we need to get all of the pipes and structures from the first pipe/structure selected and the second pipe/structure selected. To do that use the FindShortestNetworkPath method of the pipe network of the selected pipes/structures. The code below sets the pipe network and then creates an array based on what type of objects where selected (hopefully I covered all of the scenarios).


So now that we have the pipes/structures in an array the code will go through and change the slopes and elevations of the pipes. The code uses the first pipe's start elevation for the beginning elevation and then apply the elevations and slopes to the pipes. The structure's won't be changed, although they probably should be updated after adjusting the slopes and elevations. The last object selected, if it is a pipe, needs to be calculated separately since it is not included in the array for some reason.


So that's the code to do it. It could use some more code, maybe for recognizing that the pipes are going the opposite direction, but hey you don't pay for this. Here's a page that has the code as it is now:

Wednesday, January 07, 2009

Goals for this Year

Well traffic for the blog was up 290% from last year and it appears to be due to the number of posts and the frequency of the posts (September saw quite an increase in traffic when I did a post a day). I've learned over the past year that search engines, mainly Google, send roughly half of this site's traffic. To try and continue the growth in traffic I'm going to plan on doing 150 posts this year (compared to 127 last year), that's an average of 12.5 posts per month or 2.9 posts per week. I usually cruise the Discussion Group looking for topics, but with a goal of 150 posts this year I might need some help coming up with ideas for posts, so if you have a topic you want covered post a comment or send me an email (Christopher at

Tuesday, January 06, 2009

Resetting Subassembly Properties

If you have a subassembly that you've changed the values of and you want the default values back you can right click the subassembly in the Tool Palettes and choose Apply Tool Properties to Subassembly and then select the subassemblies you want to change back to the default values. The pictures below show the steps from left to right and from top to bottom.


Monday, January 05, 2009

*Warning* Multiply owned object, handle "17B7"

Sometimes an error message pops up in Civil 3D that gives you a warning that multiply owned objects are in the drawing. There is a nifty Lisp routine that has been going around that lets you delete the object. The object in question may be created when a child label is dragged to another drawing that already has the parent style in it. The Lisp does delete the object in question, but what if you want to know what type of object it is before deleting it? Well this post will show a way to figure out what the object is and then let you decide if you want to delete it.

We'll do this in VBA, though I'm sure you could do this in Lisp. First type VBAMAN at the command line and then choose the New button on the right side of the dialog box and then do a SaveAs to save it in a location you can remember.


Next type you can choose to type Option Explicit at the top of the blank page or you can skip it. Then Type Sub and what you want to call the routine, in this case I choose what my daughter's say cow's say. Then add "On Error Resume Next", this line will have the program continue if an error message is occurs in VBA. It is usually better to use better error catching, but it should OK for this program.

Next declare the variables that are going to be used. In this case sHandle as a string for the object's handle, oTempObject to convert the handle to an AutoCAD object and Response as a generic variable to catch the value the user selects in the MsgBox that will be created later on.

So now we have the base done we can get the handle from the user using the GetString method.

sHandle = ThisDrawing.Utility.GetString(0, "Enter String: ")

The user can copy and paste the handles from the command line to the command line. Now we need to make sure the user typed something so we need to check. If the user hasn't typed anything in we'll just assume they don't want to run it and exit the sub.

If sHandle = "" Then

Exit Sub

End If

Next we'll need to convert the handle into an AutoCAD object using the HandleToObject method.

Set oTempObject = ThisDrawing.HandleToObject(sHandle)

So hopefully the user entered a valid handle, if not it just asks them for a new handle because of a line at the end of the code and the On error Resume Next line of code. So then we may send a message box up and tell the user what type of object it is and ask if they want to delete it.

Response = MsgBox("The object is a " & oTempObject.ObjectName & " Do you want to delete the object?", vbYesNo)

If the user selects Yes, the object will be deleted, if not nothing will happen to the object.

If Response = vbYes Then
End If

There are usually more than one MOO, so we'll call the Moo Sub again to loop around until the user doesn't enter a value for the handle.

Call Moo

In my test drawing the object type was AeccDbLabelStyleText object it could be something different for you, but now you'll know what type of object it is before deleting it. The completed dvb file may be found on this page.

Saturday, January 03, 2009


I've gone through and added tags to the previous posts to make it easier to find posts on certain subjects. The drop down list may be found near the top of the page to the right under the label heading.


Blog Widget by LinkWithin