This tutorial assumes that you have read all previous tutorials, but have no other VBA knowledge for AutoCAD® or otherwise.
In this tutorial, I will explain the basics of subroutines.
In the last tutorial, I explained some basic code. The observant of you will have noticed that there were a few parts of the code that I left unexplained:
Sub QuickExample() End Sub
This is a subroutine. The first line defines the beginning, and the second line defines the end. Similarly to variables (remember those from the last tutorial?), the name can be changed to whatever we like (certain rules apply). However, the subroutine name must end with a pair of parantheses. If they are omitted, they will be added automatically. You may notice after typing a line such as Sub QuickExample and pressing enter, that the End Sub statement is automatically inserted. If any subroutine has no corresponding End Sub, it will not run, and an error will occur.
A subroutine is a container for our code. If we had a subroutine that contains code that converts TEXT to MTEXT, it would be logical to call it something like ConvertText2MText. When we use the command VBARUN from AutoCAD®, we are presented with a dialog box that gives us the option to execute whatever subroutine we like. So in this example, we would pick the option that refers to the ConvertText2MText subroutine.
The above method using VBARUN is how to execute a subroutine directly from AutoCAD®. We can also run the subroutine from within VBA – perhaps from another subroutine. The way to do that, is to write the subroutine name in our code. So to run the subroutine in the example above, we would simply write:
When VB reaches this line of code, it will jump to the line of code that says
Sub ConvertText2Mtext(). Then, it will run the content, and when it reaches the End Sub statement, VB will return to where it was originally, and continue to process code as normal. This can be a useful way of splitting up our VBA applications into logical and understandable chunks that can be called upon whenever necessary.
So lets expand on our example. Lets say that we have 4 subroutines. I’ll put 3 of them below:
Sub ConvertText2MText() MsgBox "Convert Text to MText" End Sub Sub ConvertLines2Polylines() MsgBox "Convert lines to polylines" End Sub Sub SetupSystemVariables() MsgBox "Do setting up of system variables" End Sub
I’ve omitted the actual code for these subroutines as it isn’t what I’m focusing on. Each of the above could be called directly from AutoCAD® by entering VBARUN into the command line, and then selecting the desired subroutine to run. But if we actually want to run all of them however, it might be useful to set up another subroutine to call them all:
Sub ReformatDrawing() MsgBox "Beginning running all subroutines..." ConvertText2MText ConvertLines2Polylines SetupSystemVariables MsgBox "Completed!" End Sub
When you execute the ReformatDrawing subroutine, it will run the other 3 subroutines in the order that they appear. Some of you might say “You could just put all of the code into one subroutine – why not just do that?”. Well yes you could, but when you start making complicated code its not advisable because it makes it hard to follow. Also, programming in this way makes your code nicely reusable because it easy to transfer whole subroutines from one project to another.
More on Subroutines
We’ve covered the purpose, and basic usage of subroutines. Now I will show you what else subroutines can be useful for.
It is sometimes useful for the subroutine to do certain things based on given input. Say for example we wanted a subroutine that inserts some text into the drawing at a changable position. We can make it so that we can give the subroutine some parameters, and make it do things based on the information we provide. In this example, we could make it so that the subroutine will put text into our drawing based on coordinates that we supply. So I will explain how to pass parameters to a subroutine. Here we have a subroutine that inserts text into our drawing (it’s the same as the one in Tutoral 1):
Sub InsertText() Dim MyString As String 'Create string variable MyString = "Hello! This is the contents of the string variable called MyString" 'set it to something MsgBox MyString 'show it in a messagebox Dim Point(2) As Double 'This is how to create an array Point(0) = 10 'This is x Point(1) = 20 'This is y Point(2) = 0 'This is z Dim TextHeight as double 'Create double precision floating point number variable TextHeight = 10 'set textheight to 10 ThisDrawing.ModelSpace.AddText MyString, Point, TextHeight 'Add text to drawing in modelspace End Sub
This subroutine is fine, but it’s not very useful because it does the same thing every time! However, if we alter the code slightly, we can make it a bit more intuative. We can alter the subroutine so that it is anticipating additional information. If we do this, we will have to provide the additional information when we call it. To make the subroutine expect additional information, we add contents to the parantheses as follows:
Sub InsertText(MyString as String) MsgBox MyString 'show whatever was passed to the subroutine in a messagebox Dim Point(2) As Double 'This is how to create an array Point(0) = 10 'This is x Point(1) = 20 'This is y Point(2) = 0 'This is z Dim TextHeight as double 'Create double precision floating point number variable TextHeight = 10 'set textheight to 10 ThisDrawing.ModelSpace.AddText MyString, Point, TextHeight 'Add text to drawing in modelspace End Sub
Now, to call this subroutine we would use something like:
InsertText “Hello! This is some text that I am passing to the subroutine”
This would need to be contained in another subroutine. I’ll rewrite it all so that it makes some sense:
Sub MainSubroutine InsertText "Hello! This is some text that I am passing to the subroutine" End Sub Sub InsertText(MyString as String) MsgBox MyString 'show whatever was passed to the subroutine in a messagebox Dim Point(2) As Double 'This is how to create an array Point(0) = 10 'This is x Point(1) = 20 'This is y Point(2) = 0 'This is z Dim TextHeight as double 'Create double precision floating point number variable TextHeight = 10 'set textheight to 10 ThisDrawing.ModelSpace.AddText MyString, Point, TextHeight 'Add text to drawing in modelspace End Sub
If we input VBARUN into the command line, and select MainSubroutine, we should get exactly the same scenario as we did to begin with. However, it happens differently. This time, we are running the subroutine called MainSubroutine, this is in turn calling the subroutine InsertText, and is providing that subroutine with some text. When VB jumps to the InsertText subroutine, it creates a variable called MyString, and automatically stores the text in here. Notice that I have removed some of the code inside the new sub – it no longer needs to create the MyString variable (with the Dim statement), or set the text in that variable, because it now happens automatically as part of the call to the subroutine.
This is a simple example using one parameter. At the moment this doesn’t really add any more functionality, but we can add more parameters as follows:
Sub MainSubroutine InsertText "This is the first call to the InsertText Sub", 10, 20, 0, 10 InsertText "This is call number 2!", 10, 40, 0, 10 InsertText "This is the third and final call", 10, 60, 0, 10 End Sub Sub InsertText(MyString as String, XCoordinate as Double, YCoordinate as Double, ZCoordinate as Double, TextHeight as Double) Dim Point(2) As Double 'This is how to create an array Point(0) = XCoordinate 'Set the contents of Point(0) to whatever is stored in the variable XCoordinate Point(1) = YCoordinate 'Set the contents of Point(1) to whatever is stored in the variable YCoordinate Point(2) = ZCoordinate 'Set the contents of Point(2) to whatever is stored in the variable ZCoordinate ThisDrawing.ModelSpace.AddText MyString, Point, TextHeight 'Add text to drawing in modelspace End Sub
Now we’ve set up the InsertText subroutine so that it accepts parameters for the contents of the text, the location, and height. This is more useful from a programming point of view because we can now insert some text into the drawing at any position, any height, and containing whatever contents we like; all only using one line of code as shown in the MainSubroutine.
If you found this useful, please do subscribe to my blog – I’ll always be adding something useful!