Customize AutoCAD through Programming28 Mar, 2013 By: Andrew G. Roe
Learn how to search for text and modify layers with Visual Studio.NET.
Consider the following scenario: In an AutoCAD drawing with a large amount of text, you want to find all the text containing a certain word or phrase, then move that text to a specific layer. Perhaps the drawing has some notes containing the word “valve,” for example, and you want to consolidate all this text in a layer called Valves.
AutoCAD provides a nice search-and-replace feature — the Find command — and with a few extra clicks we could move the identified text to another layer. But for a more automated approach to modifying text properties, you will need to put on your customization hat.
In my previous articles about AutoCAD programming, we learned how to use the .NET programming environment to extract drawing information, create AutoCAD entities, and modify them programmatically. In this article, we will combine some of these tools and explore more deeply how we can use .NET programming tools to accomplish the task at hand.
As before, this example uses the Visual Basic.NET programming environment, although you can use Visual C#.NET instead. To complete this exercise, you'll need either Visual Studio.NET or the free Visual Studio Express. (If you're using AutoCAD 2013, you should also download the ObjectARX software development kit [SDK] to run this example. Even though it's not an ObjectARX example, the necessary references are located in the SDK for 2013.)
Create a Text Search Program
1. Start Visual Studio and create a new VB.NET project called TextSeeker. (If you need a refresher on creating a new project, see "The World of AutoCAD Programming Platforms, Part 3.")
2. Double-click on My Project in the Solution Explorer; the Project Properties screen will appear.
3. Click the References tab on the left.
4. Click the Add button to display the Add Reference dialog box.
5. In the Add Reference dialog box, click the Browse tab, and navigate to the folder containing AutoCAD’s DLL files. Typically this is the ObjectARX 2013\inc-win32 or ObjectARX 2013\inc-win64 folder, depending on which version of AutoCAD you are using. Select the Autodesk.AutoCAD.Interop.Common.dll and Autodesk.AutoCAD.Interop.dll files by clicking on one and Ctrl+clicking on the other.
(Note: This example is for AutoCAD 2013. If you are using AutoCAD 2012 or older versions, you can click the COM tab and select the appropriate type library and ObjectDBX common type library: axdb18enu.tlb and acax18enu.tlb for AutoCAD 2012. Alternatively, you can download the ObjectARX SDK for older versions and reference the two DLL files listed above.)
6. Click OK to close the Add Reference dialog box.
7. Double-click on the Form1.vb[Design] tab to display the form. From the Toolbox, click and drag a text box, a list box, a button, and two labels onto the form, arranging them as shown below.
8. Click View > Properties Window. In the Properties window, change the Text property for the button to Search and Modify.
9. Change the Text property for the form to Text Seeker.
10. Change the Text property for the two labels to Search String and Target Layer, respectively. The form should now look like the image below.
11. Double-click the button to display the Code window. A subroutine is already set up for the button you just double-clicked.
12. Modify the code to read as shown below, inserting the first two lines at the top of the code window and the others to fit within the preset code. (Hint: You can copy and paste the code instead of retyping it!)
Imports Autodesk.AutoCAD.Interop Imports Autodesk.AutoCAD.Interop.Common Public Class Form1 ' AutoCAD must be open before running this example. Dim AcadApp As AcadApplication Dim acadDoc As AcadDocument Dim objEntity As AcadEntity Dim objLayer As AcadLayer Dim objText As AcadText Dim objNewLayer As Object Dim txtSearch As String Dim intTextEntities As Integer Dim intMatch As Integer Dim blnFound As Boolean Public Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click If txtSearch = Nothing Or objNewLayer = Nothing Then MsgBox("You must enter a search string and a layer.") Exit Sub End If intTextEntities = 0 For Each objEntity In acadDoc.ModelSpace Select Case objEntity.ObjectName Case "AcDbText", "AcDbMText" intTextEntities = intTextEntities + 1 blnFound = objEntity.textstring.ToString.Contains(txtSearch) ' Find string in text. If blnFound = True Then intMatch = intMatch + 1 Dim UserResult As DialogResult = MessageBox.Show("Found match. Do you want to change layers?", "Change Layer", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) Select Case UserResult Case DialogResult.Yes objEntity.Layer = objNewLayer Case DialogResult.No ' Do nothing Case DialogResult.Cancel Exit Sub End Select End If End Select Next MessageBox.Show("Found " & intTextEntities & " text entity(ies) and " & _ intMatch & " match(es) to the search string: " & txtSearch) Close() End Sub End Class
Let’s examine what we have so far, as this might look confusing if you’re a novice programmer. With references properly set, the Imports statements are used to specify which libraries, or namespaces, will be accessed by the application. Dim statements declare variables for the AutoCAD Application and Document objects, as well as for the various AutoCAD objects we’ll be accessing. A String variable is declared to store the value for a search string, and Integer variables are declared to store values for the number of entities found and the number of matches found.
The code following the Dim statements might be even more confusing, so let’s look at the highlights to remove some of the mystery. The Public Sub Button1… line identifies the beginning of a subroutine that defines what happens when the user clicks Button 1. An If…Then block ensures that the user enters a search string and selects a layer. A For Each…Next loop searches through all entities in the drawing, and a Select Case structure finds only the text and multi-line text entities (AcDbText and AcDbMText, respectively). Another Select Case structure determines what happens when the user clicks a button in a dialog box. A message box displays the results at the end of the search.
We still have some more code to add before we’re ready to run this program.
13. In the Code window, just above the End Class statement, add the following:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load txtSearch = Nothing intMatch = 0 intTextEntities = 0 AcadApp = GetObject(, "AutoCAD.Application") acadDoc = AcadApp.ActiveDocument For Each objLayer In acadDoc.Layers ListBox1.Items.Add(objLayer.Name) Next End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged txtSearch = TextBox1.Text End Sub Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e _ As System.EventArgs) Handles ListBox1.SelectedIndexChanged objNewLayer = ListBox1.SelectedItem End Sub End Class
The first piece of code contains a subroutine that defines what happens when the form loads. It assigns initial values for the text and integer variables, then gets the AutoCAD application object and document objects, respectively. A For Each…Next loop populates the list box with a list of active layers in the drawing.
The next code snippet contains a subroutine that defines what happens when the user types something in the text box and assigns this to the txtSearch variable. The final segment identifies which layer the user selects and assigns it to the objNewLayer variable. Let’s test the program.
1. With AutoCAD running and a drawing with some text entities open, click the Play button (or press F5) to build and run the application.
2. Type some text that matches existing text somewhere in the drawing.
3. Select a layer from the list box, as shown in the figure below.
4. Click the button to search for the text and ask the user whether to move it to the selected layer.
5. Click the X in the upper-right corner of the form to stop execution of the program and close the form.
You can click File > Save All to save the code, the form, and the other elements of your .NET application. Visual Studio creates an EXE file that can be run as a standalone application outside the .NET environment.
You can also create a plugin — a module that can be run from within the AutoCAD environment. Autodesk describes this process in an online training document, "My First Plug-in Training."
This example illustrates some key concepts of accessing the AutoCAD object model and modifying entities programmatically. It requires AutoCAD to be running and contains no error handling.
In a real application, you'd want to check to see if AutoCAD is running, and if not, start it. You’d also want to provide error handling for those inevitable situations where users try to make the program do something unintended. And you can probably think of various ways to further customize this example, but this shows you how to get started.
In future installments of this series, we'll continue to explore additional facets of AutoCAD programming, such as building plugins and working with Autodesk’s vertical products. If you would like to suggest a topic, feel free to send me an e-mail.
About the Author: Andrew G. Roe
Autodesk Technical Evangelist Lynn Allen guides you through a different AutoCAD feature in every edition of her popular "Circles and Lines" tutorial series. For even more AutoCAD how-to, check out Lynn's quick tips in the Cadalyst Video Gallery. Subscribe to Cadalyst's free Tips & Tools Weekly e-newsletter and we'll notify you every time a new video tip is published. All exclusively from Cadalyst!