IntelliCAD Beta 2000 Visual Basic for Applications (VBA) 6
By: Frank Zander
This article takes a sneak peek at the new Visual Basic for Applications (VBA) 6 inside of the soon to be released IntelliCAD 2000. This article was written using an early beta version of IntelliCAD 2000. Therefore the displayed information may change slightly in the final release of IntelliCAD 2000. In this article, I will discuss several of the exciting new features of IntelliCAD 2000's implementation of VBA. I will then demonstrate how to create a VBA program to search for all of the blocks in a drawing and insert the list of blocks into the drawing.
What's new?
- Visual Basic for Applications (VBA) 6
All Microsoft Office 2000 applications use VBA 6. IntelliCAD 2000 implements VBA 6, the latest version of VBA. . Everything you learn to do in VBA 6 in IntelliCAD 2000 is portable to all Office 2000 programs (and vice versa). Figure 1 shows the IntelliCAD 2000Visual Basic for Applications integrated development environment (VBAIDE) that includes the same elements familiar to developers using Microsoft Visual Basic, including a Project Window, a Properties Window and debugging tools. Visual Basic for Applications also includes support for Microsoft Forms for creating custom dialog boxes and ActiveX® Controls for rapidly building user interfaces.
Figure1
- VBA 6.0 Macro Warning and Security
With the ability to embed VBA projects into drawings, malicious code and viruses have entered the CADD world. With the implementation of VBA 6, programmers can now digitally sign code. Digitally signed VBA code allows the end user to verify the author of the code, allowing the end user to verify the author of the code. Figure 2 shows the Digital Signature author dialog box for programmers.
Figure 2
IntelliCAD 2000 allows the end user to set the macro warning to High, Medium or Low. See Figure 3. Using the High setting, only signed code is allowed to run after after the user accepts the digital signature of the author. The user can also add the digital signature to the Trusted Sources tab in the Security dialog box (see Figure 3) then, all subsequent VBA code from the same author will run with out a security warning. By clicking the "Detail..." button (see Figure 2), users can inspect the certificate and verify its validity. See Figure 4 for an example of a digitally signed code certificate.
Figure 3
If the end user encounters an unsigned VBA macro, one of the following will occur:
- If the application's security settings are set on "High," the client application will not permit the unsigned code to run.
- If the application's security settings are set on "Medium," the client application will display a warning to ask the user if they want to enable or disable this unsigned code.
By contrast, if a user encounters signed VBA code in a file, the user is informed:
- Of the true identity of the publisher (in this case Frank Zander).
- That there is no problem with the certificate (no additional warnings)
- The Details button will show the digitally signed certificate (see Figure 4).
In addition, if the digitally signed code is changed, the user is notified of the modification.
Figure 4
- The IntelliCAD 2000 Object model
The IntelliCAD 2000 object model is complete! The Preview version of IntelliCAD98 VBA did not allow programmers to "get at" several of the drawing objects. For instance, I was never able to get the selectionset methods to work (or maybe it was just me not having help file instructions on how to use this method). Because the Preview VBA in IntelliCAD98 did not include any help for the object model, finding any clue as to the object properties and methods was an exercise in frustration. Now, with IntelliCAD 2000, the object model and programming methods so nicely parrot those found in AutoCAD 2000 and r14 that AutoCAD VBA programmers will find programming in IntelliCAD 2000 a breeze. Aha! This is what I was hoping for. Even without a help file (as of press time) I was able to figure out the object model and methods using my background in VBA programming in AutoCAD. Surely, a help file outlining the VBA object model and methods will be included with the shipping version of IntelliCAD 2000. As an example of how closely IntelliCAD 2000 mimics AutoCAD's VBA, below are two code snippets from each program to create a Mtext object and a selectionset..
IntelliCAD 2000 code for Mtext:
NewMText = ThisDocument.ModelSpace.AddMText(PT1, MtextWidth, strMTextOutPut)
AutoCAD 2000 code for Mtext:
NewMText = ThisDrawing.ModelSpace.AddMText(PT1, MtextWidth, strMTextOutPut)
IntelliCAD 2000 code for Selection set:
NewSS.Select vicSelectionSetAll, , , FilterType, FilterData
AutoCAD 2000 code for Selection set:
NewSS.Select acSelectionSetAll, , , FilterType, FilterData
Think of the advantages of writing code for one CADD program and re-useing (possibly with minor adjustments) in another. IntelliCAD98 did this with LISP and now IntelliCAD 2000 does it with VBA.
Creating the Block Report Program
- Forms, Controls and Modules
To create the Block Report program (see Figure 5) you will first need to create a form and a module. The form contains a listbox with the name lstResults and four buttons named cmdFindBlocks, cmdRemove, cmdMtextPlace, and cmdExit. The module contains one Public Sub program called LoadBlockReport. The code for the Form and the Module are located in the sections called The Form code:, and The Module code: A completed project including the form and module used in the Block Report program are availale for downloading from Contract CADD Group's website at: http://www.contractcaddgroup.com
Figure 5
Running an IntelliCAD2000 VBA macro.
- To run an IntelliCAD 2000 VBA macro from the command prompt with a dialog box (see Figure 6) type: VBARUN.
Then select the Start.LoadBlockReport macro from the dialog box.
Figure 6
- To run the Block Report program from the command prompt with out a dialog box type: -VBARUN
Then enter the macro: Start.LoadBlockReport
- To launch the Block Report program from a custom icon on a tool bar (see figure 7) use:
^C^C^C-vbarun;Start.LoadBlockReport;
Figure 7
In Conclusion
I look forward to using the shipping version of IntelliCAD 2000. Once the object model and properties are documented and example code is included in the help system, this will be a very attractive CADD VBA development platform. The ability to digitally sign code in VBA 6 will give programmers better control over their intellectual property. End users will be able to use digitally-signed VBA programs with confidence. The code for this project is available for downloading for both IntelliCAD98 and IntelliCAD 2000 at Contract CADD Group's website: http://www.contractcaddgroup.com
Frank Zander is a CADD consultant at Contract CADD Group in Surrey, British Columbia, Canada. He can be reached via e-mail at: frank.zander@contractcaddgroup.com or by phone at: (604) 591-1140. Visit Contract CADD Group's website at: http://www.contractcaddgroup.com
The Module code:
Option Explicit
Public Sub LoadBlockReport()
frmBlockReport.Show
End Sub
The Form Code:
Option Explicit
Private Sub cmdExit_Click()
Unload Me
End Sub
Private Sub cmdFindBlocks_Click()
' Find all blocks in a Drawing an display in the list box
Dim objDoc As Document
Dim objBlock As Object
Dim FoundBlockInList As Boolean
Dim strBlockName As String
Dim Counter As Integer
Dim I As Integer
Dim NewSS As SelectionSet
Dim FilterType(0) As Integer
Dim FilterData(0) As Variant
FilterType(0) = 0
FilterData(0) = "INSERT"
' Hide this form
Me.Hide
Set objDoc = Application.ActiveDocument
Set NewSS = objDoc.SelectionSets.Add("VBA")
' Create a selection set filtering for blocks
NewSS.Select vicSelectionSetAll, , , FilterType, FilterData
' If are in this drawing go the the graceful exit below
If Not NewSS.Count > 0 Then GoTo GracefullExit
' remove the ' below to make the list box invisible for faster processing
' lstResults.Visible = False
' Put a new header on the List Box
Call ListBoxHeader
Counter = NewSS.Count
txtStatus.Visible = True
cmdFindBlocks.Visible = False
cmdExit.Visible = False
cmdRemove.Visible = False
cmdMtextPlace.Visible = False
' Repaint the Form
frmBlockReport.Repaint
' Typically this is should read:
' For I = 0 to NewSS.Count -1
' IntelliCAD 2000 (at the time of this writing)
' was using 1 based rather than 0 base for the selection sets.
For I = 1 To NewSS.Count
Set objBlock = NewSS.Item(I)
FoundBlockInList = False
' Find the block name in the list
strBlockName = objBlock.Name
FoundBlockInList = BlockListLookUp(strBlockName)
If FoundBlockInList = False Then
lstResults.AddItem "", lstResults.ListCount
lstResults.List(lstResults.ListCount - 1, 0) = objBlock.Name
lstResults.List(lstResults.ListCount - 1, 1) = 1
End If
Next
' Free the selection set
Set NewSS = Nothing
' Make the List box Visible
lstResults.Visible = True
' Start the enable remove button program
Call EnableRemoveButton
If Not lstResults.ListCount >= 2 Then MsgBox "No blocks found in drawing", vbInformation
txtStatus.Visible = False
cmdFindBlocks.Visible = True
cmdExit.Visible = True
cmdRemove.Visible = True
cmdMtextPlace.Visible = True
GracefullExit:
' Display this form
Me.Show
End Sub
Function BlockListLookUp(strBlockName As String) As Boolean
' Check to see if a block is in the list box
Dim I As Integer
Dim FoundBlockInList As Boolean
For I = 0 To lstResults.ListCount - 1
If lstResults.List(I, 0) = strBlockName Then
lstResults.List(I, 1) = lstResults.List(I, 1) + 1
FoundBlockInList = True
End If
Next
If FoundBlockInList = True Then
BlockListLookUp = True
Else
BlockListLookUp = False
End If
End Function
Private Sub cmdMtextPlace_Click()
' Place an MText object in to the drawing containing the block names and the count
Dim objDoc As Document
Dim objUtil As Object
Dim strDrawingName As String
Dim intCounter As Integer
Dim strMTextOutPut As String
Dim MtextWidth As Double
Dim objNewMtextReport As Object
Dim strSetting As String
Dim strOUT1 As String
Dim strOUT2 As String
Dim Qt As String
Dim NewMText As Mtext
Dim PT1 As Point
' set Qt to equal chr(34)
' this is the ASCII character "
Qt = Chr(34)
Set objDoc = Application.ActiveDocument
' Width of the Mtext object
If objDoc.GetVariable("dimscale") <> 0 Then
MtextWidth = 525 * objDoc.GetVariable("dimscale")
Else
MtextWidth = 525
End If
' Header info for the block report
strMTextOutPut = " Block Report: \P Qty. Block "
' Process every row in the Block results list
For intCounter = 1 To lstResults.ListCount - 1
' set the length of the string to 10 characters
strOUT1 = "12345"
' Get the text from the listbox at this location
RSet strOUT1 = lstResults.List(intCounter, 1)
' add text to the mtext out string
strMTextOutPut = strMTextOutPut & "\P" & strOUT1
strOUT2 = lstResults.List(intCounter, 0)
' add text to the mtext out string
strMTextOutPut = strMTextOutPut & Space(5) & strOUT2
' Process the next intCounter
Next intCounter
'Hide the Block Report form
frmBlockReport.Hide ' or Me.Hide
' Get the insert point for the block report
Set PT1 = objDoc.Utility.GetPoint(, "Insert Block Report -- Upper Left corner:")
If objDoc.ActiveSpace = vicModelSpace Then
Set NewMText = objDoc.ModelSpace.AddMText(PT1, MtextWidth, strMTextOutPut)
Else
Set NewMText = objDoc.PaperSpace.AddMText(PT1, MtextWidth, strMTextOutPut)
End If
' Regenerate the mtext object
NewMText.Update
' Show the block report form
frmBlockReport.Show ' or me.show
End Sub
Private Sub cmdRemove_Click()
On Error GoTo ClearForm
lstResults.SetFocus
'Ensure ListBox contains list items
If lstResults.ListCount >= 1 Then
'If no selection, choose last list item.
If lstResults.ListIndex = -1 Then lstResults.ListIndex = lstResults.ListCount - 1
lstResults.RemoveItem (lstResults.ListIndex)
End If
' run the Enable Remove Button sub
Call EnableRemoveButton
' exit this sub
Exit Sub
ClearForm:
Call ListBoxHeader
End Sub
Sub EnableRemoveButton()
' make the Remove button and Place button enabled or disabled
' check for entries of blocks in the listbox
If lstResults.ListCount >= 2 Then
cmdRemove.Enabled = True
cmdMtextPlace.Enabled = True
Else
cmdRemove.Enabled = False
cmdMtextPlace.Enabled = False
End If
End Sub
Private Sub UserForm_Initialize()
Call ListBoxHeader
Call EnableRemoveButton
End Sub
Private Sub ListBoxHeader()
' Setup the list box header information
With lstResults
' Clear the list box
.Clear
' Set the number of columns
.ColumnCount = 2
' Set the column widths
.ColumnWidths = "80;20"
' Text Tip
.ControlTipText = "Blocks and Quantity"
' add an entry in the list box
.AddItem "", 0
' Set the values in the first row and column
.List(0, 0) = "Block Name:"
' Set the values in the first row and second column
.List(0, 1) = "Qty:"
End With
End Sub
|