Introduction
Sure, I have heard macros are great and save you a lot of time in development, but to be honest I never had the time to develop any because I was too busy developing. Well today I was met with a rare development lull and decided to invest in learning how to create macros in Visual Studio .NET and save some time in the future.
The macro that we are going to create is one that will automatically create our member variables as well as their corresponding public properties. To demonstrate how a macro can do different things dependant upon user input, we will include a message box asking whether or not the members should be sorted alphabetically.
Using the code
Macro Requirements:
The macro needs to turn this
CustomerName String
AccountBalance Double
CustomerPhone String
CustomerAddress String
CustomerID Integer
into this:
Private mAccountBalance as Double
Private mCustomerAddress as String
Private mCustomerID as Integer
Private mCustomerName as String
Private mCustomerPhone As String
Public Property AccountBalance As Double
Get
Return mAccountBalance
End Get
Set(ByVal Value As Double)
mAccountBalance = Value
End Set
End Property
Public Property CustomerAddress As String
Get
Return mCustomerAddress
End Get
Set(ByVal Value As String)
mCustomerAddress = Value
End Set
End Property
Public Property CustomerID As Integer
Get
Return mCustomerID
End Get
Set(ByVal Value As Integer)
mCustomerID = Value
End Set
End Property
Public Property CustomerName As String
Get
Return mCustomerName
End Get
Set(ByVal Value As String)
mCustomerName = Value
End Set
End Property
Public Property CustomerPhone As String
Get
Return mCustomerPhone
End Get
Set(ByVal Value As String)
mCustomerPhone = Value
End Set
End Property
Getting Started:
To create our macro we will need to enter the Macro IDE (Tools -> Macros -> Macro IDE
or Alt+F11
). From within the Macro IDE right click an existing macro project or create a new one and add a macro module. You can have a number of methods within each macro but for now we only need one called ConvertProperties()
. This method will take the text that is currently selected, process it and replace it with member and property declarations.
Accessing the Selected Text:
The EnvDTE name space allows us to get access to what text the user has selected.
Dim txt As TextSelection
txt = DTE.ActiveDocument.Selection
Using RegEx
:
Regular Expressions will come in handy to identify the text that is selected and allow us to step through the property names and data types successfully. The first word it comes across will be the varname and the second will be the typename.
Dim r As Regex
r = New Regex( _
"\s*(?<varname>\S*)\s*(?<typename>\S*)", _
RegexOptions.IgnoreCase Or RegexOptions.ExplicitCapture)
Line by Line Processing:
By doing a split on the selected text via a line feed we end up with an array of lines that we can walk through. We see if the line matches our regular expression, and if it does, we build the member syntax as well as the property syntax using the varname and typename as parameters. After the syntax is dynamically generated we can insert it into the document. Note that the code below is stripped down for simplicity
.
Dim line, originalCode As String
Dim lines() As String = Split(txt.Text, vbLf)
For Each line In lines
line = line.Trim
If Not line = "" Then
Dim mtch As Match
mtch = r.Match(line)
If mtch.Success Then
publicName = mtch.Groups("varname").Value.Trim
dataType = mtch.Groups("typename").Value.Trim
memberName = String.Concat("m", publicName)
propertyProcedure = _
String.Format("Public Property {1} As {2}{0}" _
& " Get{0}" _
& " Return {3}{0}" _
& " End Get{0}" _
& " Set(ByVal Value As {2}){0}" _
& " {3} = Value{0}" _
& " End Set{0}" _
& "End Property", vbCrLf, publicName, _
dataType, memberName)
txt.Insert(vbCrLf & propertyProcedure)
End If
End If
Next
User Input:
You may have a need to allow for the user to dictate how the macro behaves. To demonstrate this in our macro, we will cause the macro to throw up a dialog box that asks the user if the members should be sorted alphabetically.
Dim sortAZ As MsgBoxResult
sortAZ = MsgBox("Sort Alphabetically", MsgBoxStyle.YesNo, "Sort Order")
If sortAZ = MsgBoxResult.Yes Then
System.Array.Sort(lines)
End If
Using Our Macro:
Now that we have created our macro, we now need a way of using it. This can be done by selecting our text that has a property name and data type on each line and then double clicking our macro method name in the macro explorer. We can also assign a short cut key such as Alt-M by going into Tools -> Options -> Environment -> Keyboard
and assigning the Macros.MerlinMacros.Merlin.ConvertProperties
to the Alt-M key.
Points of Interest
There is a product called QuickCode .NET (http://www.dvxp.com/en/QuickCode.aspx ) which has some cool features for basic macro type functionality. I quickly met the limitations of the product when trying to process more than 1 line at a time, but it is this reason I looked into creating my first macro in the first place.
History
- 2/25/2004 - article submitted