Users
MicroStation V8i (SELECTseries 1)
Trademarks AccuDraw, Bentley, the “B” Bentley logo, MDL, MicroStation and SmartLine are registered trademarks; PopSet and Raster Manager are trademarks; Bentley SELECT is a service mark of Bentley Systems, Incorporated or Bentley Software, Inc. AutoCAD is a registered trademark of Autodesk, Inc. All ther brands and product names are the trademarks of their respective owners. Patents United States Patent Nos. 5,8.15,415 and 5,784,068 and 6,199,125. Copyrights ©2000‐2009 Bentley Systems, Incorporated. MicroStation ©1998 Bentley Systems, Incorporated. All rights reserved.
Course Overview ____________________________________ 1 Course Description ____________________________________ 1 Target Audience_______________________________________ 1 Prerequisites _________________________________________ 1 Course Objectives _____________________________________ 2 Modules Included _____________________________________ 2 Building Commands _________________________________ 3 Module Overview _____________________________________ 3 Module Prerequisites __________________________________ 3 Module Objectives_____________________________________ 4 Introductory Knowledge ________________________________ 4 Questions ________________________________________ 4 Answers__________________________________________ 4 Adding Elements – PrimitiveCommands ____________________ 4 Modifying Elements – LocateCommands ___________________ 7 Module Review _______________________________________ 9 Questions ________________________________________ 10 The User Interface ___________________________________ 11 Module Overview _____________________________________ 11 Module Prerequisites __________________________________ 11 Module Objectives_____________________________________ 11 Introductory Knowledge ________________________________ 11 Questions ________________________________________ 12 Answers__________________________________________ 12 Building a User Interface ________________________________ 12 Module Review _______________________________________ 15 Questions ________________________________________ 15 Working With Non‐Graphic Data _______________________ 17 Module Overview _____________________________________ 17 Module Prerequisites __________________________________ 17 Module Objectives_____________________________________ 17 Introductory Knowledge ________________________________ 17
Table of Contents Questions ________________________________________ 18 Answers__________________________________________ 18 Storing Non‐Graphic Information With Elements_____________ 18 Tags ________________________________________________ 19 Databases ___________________________________________ 21 Connecting _______________________________________ 21 Elements with database records ______________________ 24 XML ________________________________________________ 27 UserData ____________________________________________ 27 Xdata _______________________________________________ 28 Module Review _______________________________________ 32 Questions ________________________________________ 32 Extending Functionality ______________________________ 33 Module Overview _____________________________________ 33 Module Prerequisites __________________________________ 33 Module Objectives_____________________________________ 33 Introductory Knowledge ________________________________ 33 Questions ________________________________________ 33 Answers__________________________________________ 34 CExpression Processor__________________________________ 34 Calling C and MDL Functions _____________________________ 36 Using MDL functions in VBA classes ____________________ 38 Helpful notes______________________________________ 52 Module Review _______________________________________ 55 Questions ________________________________________ 55 Events ____________________________________________ 57 Module Overview _____________________________________ 57 Module Prerequisites __________________________________ 57 Module Objectives_____________________________________ 57 Introductory Knowledge ________________________________ 58 Questions ________________________________________ 58 Answers__________________________________________ 58 Types of Events _______________________________________ 58 File events ________________________________________ 59 Interfaces ________________________________________ 59 Module Review _______________________________________ 62 Questions ________________________________________ 62 Standards Checker Extensions _________________________ 63 Module Overview _____________________________________ 63 Module Prerequisites __________________________________ 63 Module Objectives_____________________________________ 63 Introductory Knowledge ________________________________ 63
Questions ________________________________________ 64 Answers__________________________________________ 64 Implementation _______________________________________ 64 Simple – use the basic framework _____________________ 65 Advanced – use the Fixes optional dialog________________ 66 Building Custom Standards Checker Applications ____________ 66 Questions ________________________________________ 76 Module Review Answers _____________________________ 77 Building Commands____________________________________ 77 Questions ________________________________________ 77 Answers__________________________________________ 77 User Interface ________________________________________ 78 Questions ________________________________________ 78 Answers__________________________________________ 78 Working With Non‐Graphic Data _________________________ 79 Questions ________________________________________ 79 Answers__________________________________________ 79 Extending Functionality _________________________________ 79 Questions ________________________________________ 79 Answers__________________________________________ 80 Events ______________________________________________ 80 Questions ________________________________________ 80 Answers__________________________________________ 80 Standards Checker Extensions____________________________ 81 Questions ________________________________________ 81 Answers__________________________________________ 81 Appendix __________________________________________ 83 New to MicroStation VBA? ______________________________ 83 The MicroStationDGN Object Model ___________________ 83 System Overview ______________________________________ 84 Configuration Variables for VBA _______________________ 84 Keyins for VBA_____________________________________ 85 COM Client Applications ________________________________ 86 ActiveX Controls and DLLs _______________________________ 87 Interface Programming _________________________________ 88 Sample Macros _______________________________________ 88 Scanning _________________________________________ 88 Geometry ________________________________________ 89 Working with other files _____________________________ 96 Dynamic user interface ______________________________ 97
Course Description
This course serves as an introduction to MicroStation VBA for application developers with working knowledge of Visual Basic/VBA and as a follow‐on to the MicroStation VBA Essentials course for those with prior experience with MicroStation VBA. Regardless of a student’s background, this course provides an essential foundation for the design, development, and deployment of MicroStation VBA macros automating fundamental operations in MicroStation.Target Audience
The primary audience for this course is Application Developers — analysts and programmers. This course may also be valuable for the following audience(s): • Administrators • Consultants • Managers • PlannersPrerequisites
• Have either a working knowledge of Visual Basic/VBA or successfully completed the MicroStation VBA Essentials course. If the former, you should review the section “New to MicroStation VBA?” in the Appendix to this course guide before proceeding with this course. • Familiarity with basic MicroStation concepts such as design files, models, references, and levels.Course Objectives • Familiarity with popular MicroStation tools and view controls. • Basic understanding of the MicroStation object model —in particular, the Application, Attachment, DesignFile, Element, and ModelReference objects.
Course Objectives
After completing this course, you will be able to: • Work with MicroStation's VBA objects to automate fundamental operations in the product. • Deploy VBA macros in MicroStation.Modules Included
The following modules are included in this course: • Building Commands • User Interface • Working With Non‐Graphic Data • Extending Functionality • Events • Standards Checker ExtensionsModule Overview
One of the basic building blocks of applications in MicroStation is the command structure. VBA opens this up to application developers through interfaces. The two interfaces used for commands are IPrimitiveCommandEvents and
ILocateCommandEvents. The command interfaces allow macros to follow a consistent structure. The structure of the command is designed to work with the state machine format that is built into MicroStation. By developing a collection of command classes, a set of tools can be integrated in the workspace. The basic structure for the macro is to define a subroutine in a module that will instantiate a class that implements one of the interfaces. The interface will provide the entry points for MicroStation to call, that the class will use to react to user actions. Interface programming is covered in depth in the module “Standards Checker Extensions”.
Module Prerequisites
• Familiarity with the concepts of placing, locating, manipulating and modifying elements in a model and the applicable tools. Refer to the Course Overview for additional pre‐requisites.Module Objectives
Module Objectives
After completing this module, you will be able to: • Implement commands that add elements to a model. • Implement commands that interactively find and query or modify elements in a model.Introductory Knowledge
Before you begin this module, let's define what you already know.Questions
1 What does a VBA project file contain? 2 In a model scan what kind of object will return only elements that match search criteria? 3 True or False: Hardly any MicroStation menu selections have a corresponding key‐in you can use to directly invoke it.Answers
1 Macros, including modules, classes, and forms which, in turn, contain subroutines and functions. 2 ElementScanCriteria 3 False. Most MicroStation menu selections and tools have a corresponding key‐in you can use to directly invoke it.Adding Elements – PrimitiveCommands
The IPrimitiveCommandEvents are typically used in commands that will be adding elements to a model. Primitive commands will use the data point and reset actions to interact with the user. The interface also defines entry points for the start of the command if key‐ins are to be picked up and used, along with command termination through the cleanup event. The following is the structure of a class that implements the
IPrimitiveCommandEvents interface.
Option Explicit
Implements IPrimitiveCommandEvents
Private Sub IPrimitiveCommandEvents_Cleanup() End Sub
Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d, _ ByVal View As View)
End Sub
Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, _ ByVal View As View, ByVal DrawMode As MsdDrawingMode)
End Sub
Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String) End Sub
Private Sub IPrimitiveCommandEvents_Reset() End Sub
Private Sub IPrimitiveCommandEvents_Start() End Sub
The IPrimitiveCommandEvents_Start method is called when this command class is invoked. Typically this method will initialize any settings that the command may need to set the initial prompts for the user.
The IPrimitiveCommandEvents_Keyin method is active if the usesKeyins option is True when the command class is instantiated. This will allow the user to type into MicroStation’s key‐in line while this command is active, for the class to use.
The IPrimitiveCommandEvents_Reset method is called when the user presses the Reset button. This is useful when a command wants to step backward. The IPrimitiveCommandEvents_Cleanup method is called when the command is terminated by another command being started.
The IPrimitiveCommandEvents_Dynamics method is active when the
CommandState.startDynamics is called. This method is used to let the command show reaction to mouse movements.
The IPrimitiveCommandEvents_DataPoint method is called when the user enters a data point.
Adding Elements – PrimitiveCommands These methods combine to produce the standard workflow used by a command that is adding an element to a model. In the next exercise a cell is to be built on the fly in the code. Exercise: Implement a command that will add a cell to a model 1 Launch MicroStation and open any design file. 2 Select Utilities > Macros > Project Manager. 3 Create and load the project Exercise_1. 4 Open the Visual Basic Editor. 5 Insert a class module and rename it Exercise1.
6 Type Implements IPrimitiveCommandEvents.
7 Type the function CreateSimpleGraphic that will be used to create a
simple graphic cell.
Function CreateSimpleGraphic(oPoint As Point3d) As CellElement
Dim oShape As ShapeElement Dim oElements(0) As Element
Dim oCell As CellElement Dim ptsCorners(3) As Point3d
ptsCorners(1).X = 10
ptsCorners(2).X = 10 ptsCorners(2).Y = 10
ptsCorners(3).Y = 10
Set oShape = CreateShapeElement1(Nothing, ptsCorners, msdFillModeFilled)
Set oElements(0) = oShape
Set oCell = CreateCellElement1("Simple", oElements, Point3dZero, False)
Set CreateSimpleGraphic = oCell
End Function
8 Add the methods, including the processing logic, for the
IPrimitiveCommandEvents interface.
9 Add logic to the DataPoint method that calls CreateSimpleGraphic and then displays and adds the cell to the model.
10 Switch to Module1, which is a normal module rather than a class module, and add a subroutine named PlaceCell that will serve as an entry point for the macro.
11 In PlaceCell, create a new instance of the class Exercise1, using the
line:
CommandState.startPrimitive new Exercise1
12 Run the macro. Press <F5> in the VBA Editor and return to MicroStation. Note: Often there is more than one way to create an element. Consider what information you will be gathering from users to create the element, then decide on the method.
Modifying Elements – LocateCommands
The ILocateCommandEvents are typically used to interactively find and query or
modify elements.
Locate commands will use the “locate accept and process” algorithm for finding elements. The interface defines entry points for validating the located element and cleaning up after the command. Following is the structure of a class that implements the ILocateCommandEvents interface.
Modifying Elements – LocateCommands
Option Explicit
Implements ILocateCommandEvents
Private Sub ILocateCommandEvents_Accept(ByVal Element As Element, _ Point As Point3d, _
ByVal View As View) End Sub
Private Sub ILocateCommandEvents_Cleanup() End Sub
Private Sub ILocateCommandEvents_Dynamics(Point As Point3d, _ ByVal View As View, _
ByVal DrawMode As MsdDrawingMode) End Sub
Private Sub ILocateCommandEvents_LocateFailed() End Sub
Private Sub ILocateCommandEvents_LocateFilter(ByVal Element _ As Element, _
Point As Point3d, _ Accepted As Boolean) End Sub
Private Sub ILocateCommandEvents_LocateReset() End Sub
Private Sub ILocateCommandEvents_Start() End Sub
The CommandState.createLocateCriteria method can be used to create the locate criteria object that will be used to filter, at a high level, the selectable elements. Once the LocateCriteria is created, use the include/exclude methods to set the features of the object. Then the
CommandState.setLocateCriteria is called to put the filter in place.
In the ILocateCommandEvents_LocateFilter method, the macro has the ability to preview the element. If it fails some test, then the element can be rejected. If the user identifies an element that does not meet the requirements of the locate criteria, the ILocateCommandEvents_LocateFailed method is called. In this method, the macro can notify the user of the error condition.
ILocateCommandEvents_LocateReset is used when an element has been selected, but the user has pressed the Reset button. In this case, many macros can release some of the resources that have accumulated during the locate process.
The Cleanup method is called when the command is terminated by starting
another command. This can be used to release resources that have been consumed by this command.
The ILocateCommandEvents_Dynamics method can be activated by calling the CommandState.startDynamics method. Dynamics can be used to show actions
like moving an element or other incremental changes that are a result of moving the mouse or pointer.
The ILocateCommandEvents_Accept method is called when the user enters a
data point confirming the acceptance of the element(s) that have been selected. In the next exercise you will implement a command that lets the user identify an element and then opens a dialog showing the type of element selected. Exercise: Implement a locate command 1 Continuing in the project Exercise_1, insert a new class module and rename it Exercise2.
2 Type Implements ILocateCommandEvents.
3 Add the methods, including the processing logic, for the
ILocateCommandEvents.
4 Add logic to the Accept method that will get the type and set a MsgBox to display this information.
5 Switch to Module1, and add a new subroutine named GetElementType that will serve as the entry point for the module.
6 In GetElementType, create a new instance of the class Exercise2, using the line:
commandState.startLocate new Exercise2
7 Run the macro.
Exercise: Implement a locate command with specified scan criteria
1 Add a LocateCriteria to the start method in Exercise2.
Module Review
Module Review
Questions
1 What are events? 2 What are the events that are available to the IPrimitiveCommandEvents interface? 3 What are the events that are available to the ILocateCommandEvents interface? 4 How does one make use of an interface?Module Overview
Building dialogs can begin as a simple task, but adding advanced features to enhance the user experience can take quite a bit of work. The UserForm set that is used in VBA is limited by design. To add features such as resizing and menus, macros have to make use of the Win32 API.Module Prerequisites
• Familiarity with the concept of locating elements in a model and the applicable tools. • Familiarity with the native VBA tools available for building a UserForms. Refer to the Course Overview for additional pre‐requisites.Module Objectives
After completing this module, you will be able to: • Build dialog boxes with functionality more advanced than that available through the native VBA UserForm controls.Introductory Knowledge
Before you begin this module, let's define what you already know.Building a User Interface
Questions
1 When creating a Message Box, how do specify its buttons be labeled “Yes” and “No”?
2 Which does the ShowModal property of a UserForm determine?
3 How do you initiate the creation of a UserForm in a VBA project. {First multiple choice/fill in the blank answer.}
{Second multiple choice/fill in the blank answer.} {Third multiple choice/fill in the blank answer.}
Answers
1 Specify vbYesNo as the second parameter of the call to the MsgBox function. 2 The ShowModal property determines whether the form is modal. 3 In the Visual Basic Editor, select Insert > UserForm.
Building a User Interface
When building a user interface, a developer must be mindful of how the user thinks. If the user is a visual person, the user interface needs to use graphics to convey a message. Some controls that may be useful are the SpinButton, ScrollBar, and Image Control. The SpinButton and ScrollBar can be used for manipulating the image that is displayed in the Image control. The Image Control can be used to preview design graphics. To do this when working with MicroStation elements, the dialog needs to use the GetPicture method from the element class. Dynamic contents allow the user interface to reflect the current set of information. Building a macro that has a picture of each cell in an attached cell library is an example of a macro that must create components on the fly. To do this, the macro creates a collection of buttons to add to the dialog, and the dialog must resize so they fit. TabPages are a method to make sense of large sets of related information. To start with, TabPages are defined in a set of either TabStrip or MultiPage items. The TabStrip displays the same set of controls on multiple pages, or tabs. TheMultiPage item displays a different set of controls on multiple pages. Tab pages can be added to the UserForm at runtime. The information may also be generated while the macro is running. To make pages of the tab set visible, macros need to work with the tabpage.visible property. To make a form resizable the macro needs to add the following declarations.
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, _
ByVal lpWindowName As Any) As Long
Private Declare Function GetWindowLong Lib "user32" Alias _ "GetWindowLongA" _
(ByVal HWND As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" _
(ByVal HWND As Long, _ ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Const WS_THICKFRAME = &H40000
Private Const GWL_STYLE = (-16)
Then when the form is activated the active method will need to call these functions to change the style of the dialog that is used:
Dim lngFrmHWND As Long
Dim lngStyle As Long Dim lngRetVal As Long
lngFrmHWND = FindWindow("ThunderDFrame", Me.Caption)
lngStyle = GetWindowLong(lngFrmHWND, GWL_STYLE) lngRetVal = SetWindowLong(lngFrmHWND, GWL_STYLE, _ lngStyle Or WS_THICKFRAME)
Finally, when the resize event occurs, the macro will need to take care of adjusting the contents of the dialog to the new area. An example follows.
Private Sub UserForm_Resize()
ListBox2.Left = 1
ListBox2.Width = Me.Width - 9
Building a User Interface
Label1.Top = ListBox2.Height + 2
Label1.Height = 5
Label1.Width = ListBox2.Width
ListBox1.Top = ListBox2.Height + Label1.Height + 5
ListBox1.Height = Me.Height / 2 - 10 ListBox1.Left = ListBox2.Left
ListBox1.Width = ListBox2.Width
Debug.Print "Height: " & Me.Height & " Width:" & Me.Width
Debug.Print "the upper list box is "; ListBox2.Height; " tall starts _ at "; ListBox2.Top
Debug.Print "the lower list box is "; ListBox1.Height; " tall starts _ at "; ListBox1.Top End Sub In the following exercise you will build a dialog which can be used by a locate macro to display the identified element. Exercise: Build the dialog 1 Continuing with the project Exercise_1 from “Building Commands”, insert a userform and make it non‐modal. 2 Add an Image to the form.
3 Add a this method to the UserForm:
Sub DisplayElement(oElement As Element) Dim stdPic As StdPicture
With PreviewImageArea
Set stdPic = oElement.GetPicture(PointsToPixelsX(.Width), _ PointsToPixelsY(.Height), True)
.Picture = stdPic End With
4 In the ILocateCommandEvents_Accept method, call the UserForm1.DisplayElement method.
5 Integrate the Image Area into the locate macro by calling the
Userform1.show method.
6 In the ILocateCommandEvents_Reset method, hide the form.
7 In the ILocateCommandEvents_Cleanup method, unload the form.
Module Review
Now that you have completed this module, let’s measure what you have learned.
Questions
1 Name at least five standard user interface controls available to VBA developers?
2 How can an Image Control be used in a dialog?
Data
Module Overview
Many applications require that a graphic element be supported by non‐graphic information. MicroStation supports many options to accomplish this and there are pros and cons for each solution. A developer must take these into account when deciding how to store information.Module Prerequisites
• Understanding of the concept of associating non‐graphic information with graphic elements and the applicable tools. Refer to the Course Overview for additional pre‐requisites.Module Objectives
After completing this module, you will be able to: • Create VBA code to attach and extract tag data. • Create VBA code to create and maintain database linkages. • Create VBA code to set and get Xdata.Introductory Knowledge
Before you begin this module, let's define what you already know.Storing Non-Graphic Information With Elements
Questions
1 What types of non‐graphic information can be associated with a graphic element? 2 What is ODBC? 3 True or False: MicroStation provides a utility to convert data records from an external database, which is linked to the active design file, into tag data.Answers
1 Tags Database linkages UserData Xdata XML 2 ODBC is a standard generic interface that allows applications to access SQL compliant databases. MicroStation supports ODBC database linkages among others. 3 True. The utility is the Database to Tag Convertor (DBTOTAG).Storing Non‐Graphic Information With Elements
Adding non‐graphic information allows for “smart” elements. And since graphics do not always tell the whole story, you can store extra, non‐graphic, information with elements. There are a number of methods for doing this, so the application developer will have to choose the method that works best for their needs. • If pre‐defined tools will be used or the information is relatively simple, tags are a likely choice. • If the information needs to be shared outside of MicroStation, then a database is the obvious choice. • If the information needs to be protected from editing, user data should be used. • If the information needs to be shared with an AutoCAD application, Xdata is the best choice.Another option is XML, an emerging standard for information interchange that will see more tools and development in MicroStation.
Tags
Tags provide a method to link some fixed structure, non‐graphic, data to an element. The tag process adds an element, which can be optionally displayed, to a model. The information contained in a tag element can be edited with standard MicroStation tools. Elements must be added to a file before a tag can be added to an element. Tags do not directly modify the element in the model. They keep a reference to the base element so it can be found. The tag itself is defined by a TagSet. Exercise: Scanning a model for elements with tags. 1 In MicroStation, open the file Database.dgn in the folder ...\WorkSpace\Projects\Examples\General\dgn. The model Tags contains tagged elements. 2 In the VBA Project Manager dialog, create and load the project Tags. 3 Switch to the Visual Basic Editor, insert a module, and create the following macro: Sub TagReport()Dim oScP As ElementScanCriteria Dim oEnum As ElementEnumerator
Dim oTagDefs As TagDefinitions Dim oTagSet As TagDefinition
Dim oTag As TagElement Dim strFileName As String
Dim tmpString As String Dim outString As String
Dim oModel As ModelReference
strFileName = ActiveDesignFile.FullName
tmpString = Replace(strFileName, ".dgn", ".txt") Open tmpString For Output As 1
Set oScP = New ElementScanCriteria oScP.ExcludeNonGraphical
Tags
For Each oModel In ActiveDesignFile.Models
outString = "*** Scanning model " & oModel.Name & " ***"
Print #1, outString
Set oEnum = oModel.Scan(oScP)
Do While oEnum.MoveNext Dim oEl As Element
If oEnum.Current.HasAnyTags Then Dim oTagsArray() As TagElement
Dim i As Long
Set oEl = oEnum.Current
oTagsArray = oEl.GetTags
For i = LBound(oTagsArray) To UBound(oTagsArray)
If (i >= 1) Then
If (oTagsArray(i - 1).TagSetName <> _ oTagsArray(i).TagSetName) Then
outString = _
"Found Tag Set = " & _ oTagsArray(i).TagSetName Debug.Print outString
Print #1, outString End If
Else
outString = "Found Tag Set = " & _ oTagsArray(i).TagSetName Print #1, outString End If outString = "--- " & _ oTagsArray(i).TagDefinitionName & _ " = " & oTagsArray(i).Value Print #1, outString Next Print #1, End If Loop Print #1, "---" Next Close 1
End Sub
4 Run the macro TagReport.
The macro creates the text file Database.txt in the same folder as the design file and writes to the text file the TagSetName and the tag data for each element. 5 Open Database.txt in a text editor such as Notepad to review the output. Exercise: Tag an element 1 Add a tag to a selected element. There are good examples in the MicroStation VBA help document, Objects, Tag Objects.
Databases
Databases offer a flexible storage system for non‐graphic information. The structure of the information must be determined by the database or application designer. Applications need to maintain the validity of information, since the database may not always be connected. To work with database information, MicroStation has to connect to the data source first, then work with the information that is stored on an element. The information is kept external to MicroStation so it is available to other non‐ MicroStation users through other applications.Connecting
One of the connection types available to VBA developers is the ADO data connection. The macro needs to create an ADOConnection, then set theconnection string. The connection string is the service provider type, the DSN name, and, for some types of service providers — for example, Oracle — the user name or id and the password. Note: The provider type is the software provider for the database driver, such as Oracle, OLEDB, or MSDASQL. To complete the next exercise, first make the GIS ODBC data source provided with MicroStation available on the system you are using, as follows:
Databases 1 In the Windows Control Panel, select Administrative Tools > Data Sources (ODBC). 2 In the ODBC Data Source Administrator dialog, select the User DSN tab (or, if you have administrative rights you can use the System DSN tab) and click Add. 3 In the Create New Data Source dialog, select the Microsoft Access Driver (*.mdb) and click Finish. 4 In the ODBC Microsoft Access Setup dialog, type GIS as the data source Name and, optionally, add a description of your choice. 5 Click Select. 6 Navigate to the ...\WorkSpace\System\macros directory and select gis.mdb. You may need to copy and paste the full path to gis.mdb in the Database File field. 7 Click OK. 8 In the ODBC Microsoft Access Setup dialog, click OK. 9 In the ODBC Data Source Administrator dialog, click OK. Exercise: Connect to the GIS ODBC data source 1 In the VBA Project Manager dialog, create and load the project ODBC_Datasource. 2 Switch to the Visual Basic Editor and insert a module that contains declarations of variables needed to connect to the data source:
'Global variables for connecting to the database Public DNSname As String
Public UIDPWD As String
Public ADOconn As ADODB.Connection
3 Insert a UserForm, frmDBConnect, and add to it the following text field and command button objects: txtDNSName — DSN Name cmdDBConnect — Connect cmdCancel — Cancel 4 Double‐click the Connect button object, and type the following code to handle a click of the button:
Private Sub cmdDBConnect_Click()
'accept values from the user DNSname = txtDNSName.Value
If DNSname <> "" Then
UIDPWD = "Provider=MSDASQL;"
UIDPWD = UIDPWD & "DSN=" UIDPWD = UIDPWD & DNSname
Set ADOconn = New Connection ADOconn.ConnectionString = UIDPWD
ADOconn.Open
MsgBox ("Opened connection.")
End If Unload Me
Exit Sub
RDOCC_EH:
MsgBox ("ERROR " & Err.Number & " " & Err.Description)
End Sub
5 Type the following code to handle a click of the Cancel button:
Private Sub cmdCancel_Click()
End End Sub 6 Select Tools > References. 7 In the References dialog, select Microsoft ActiveX Data Objects 2.5 Library and Microsoft ADO Ext. 2.8 for DDL and Security in addition to the libraries already selected, then click OK. 8 Run the form. 9 In the DSN Name field, type GIS. 10 Click Connect. Note: In the ...\WorkSpace\System\vba\examples folder, the VBA project files DataBaseExamples.mvba and dbcheck.mvba are for use with an Oracle database. The userform for connecting to the data source is therefore augmented to require a username and password.
Databases
Elements with database records
When working with graphic elements that are connected to database records, the process to extract the non‐graphic information is more complex. The element only stores a pair of numeric ids. • The Entity Number, which is related to a database table by looking in the MSCATALOG table. • The MSLink which is the unique value stored in a column of the table. The macro must first query the MSCATALOG table to get the tablename from the Entity Number. Once the table name is known, the macro can then query that table based on the MSLink number to get the information from the table. To work with the data, the macro will build a RecordSet that will be used to hold theresults of the queries. Some of the queries that you need will appear as follows.
'Get the Table name for a given entity.
Public Function GetTableName(MSCATstr As String, EntNum As Integer) _ As String
On Error Resume Next
Dim RecordCount As Integer Dim RecSet1 As adodb.Recordset
RecordCount = 1
'take this out for access since the USER_TABLES table does not exist!
If dbtype = "Oracle" Then
' Set RecSet1 = GetRecordSet(ADOconn, "SELECT TABLE_NAME FROM
‘ USER_TABLES WHERE TABLE_NAME = '" + MSCATstr + "'") ' RecordCount = RecSet1.RecordCount
End If
If RecordCount < 1 Then
'no entry found for given tablename MsgBox "MSCATALOG Not Found!"
RecSet1.Close
Set RecSet1 = Nothing
GetTableName = "" ElseIf RecordCount = 1 Then
RecordCount = 0
Set RecSet2 = GetRecordSet(ADOconn, "SELECT TABLENAME FROM " + _ MSCATstr + " WHERE ENTITYNUM = " & CStr(EntNum))
RecordCount = RecSet2.RecordCount
If RecordCount = 0 Then
MsgBox "No Table for Entity: " & CStr(EntNum), vbOKOnly
RecSet2.Close
Set RecSet2 = Nothing
GetTableName = "" ElseIf RecordCount = 1 Then
GetTableName = RecSet2!TableName RecSet2.Close
Set RecSet2 = Nothing Else
MsgBox "Multiple Tables for Entity: " _ & CStr(EntNum), vbOKOnly
RecSet2.Close
Set RecSet2 = Nothing GetTableName = ""
End If Else
MsgBox "MSCATALOG is not Unique!" RecSet1.Close
Set RecSet1 = Nothing GetTableName = ""
End If End Function
Public Sub PrintLink(LinkIndex As Integer) 'prints database info for a given dblink
Dim mslink As Integer Dim MSCATstr As String
Dim EntNum As Integer Dim TableName As String
Dim RS1 As adodb.Recordset Dim i As Integer
Databases
'check to see if element has database link mslink = dbLinks(LinkIndex).mslink
EntNum = dbLinks(LinkIndex).EntityNumber MSCATstr = GetMSCATALOG
TableName = GetTableName(MSCATstr, EntNum) If TableName <> "" Then
Set RS1 = GetRecordSet(ADOconn, _
"SELECT * FROM " + TableName + " _ WHERE MSLINK = " & CStr(mslink)) Dim RecordCount As Integer
RecordCount = RS1.RecordCount If RecordCount = 0 Then
' no records found with matching mslink number Debug.Print "No Records Found!!"
ElseIf RecordCount = 1 Then
' one entry found for given mslink number
For i = 0 To RS1.Fields.count - 1
Debug.Print RS1.Fields.Item(i).Name
frmDBLinkInfo.ListBox1.List(i, 1) = "NULL" Next
Else
' multiple entries found for mslink number
Debug.Print "MSLINK is not Unique!!" End If
RS1.Close
Set RS1 = Nothing
End If Else
' element does not have any database links Debug.Print "Element has no DB Links"
End If End Sub
Exercise: Obtain database information
1 Create a macro to query an element and get the database information that is related to the element.
XML
XML is a technology for creating self‐documented structured storage of information. XML can be used to create text files that can be interpreted by any macro that is capable of parsing XML data. Note: As of this writing, the XML API in VBA is limited to using the Microsoft MSXML6 libraries. In the future, methods will be provided to add XML as additional element information.UserData
UserData is extra information that is added to an element by a macro. The structure of the information is determined by the macro. The macro is assigned an ID number by Bentley. The ID number is used to prevent macro conflict. To work with user data, the macro will need to first get the user data as a block of information. Then it will need to process the block of data using the CopyXXX method. The Copy methods use the copyToDataBlock parameter to determine if the data is being copied to or from the datablock.' Do not use 22352 as your attribute ID. You must obtain a
' unique attribute ID from Bentley Systems.
Private Const attrId As Long = 22352
' AddLinkage and GetLinkage both transfer the data using TransferBlock. ' That way, it is easy to be certain that the transfer always occur in the
' same order.
Private Sub TransferBlock(dblk As DataBlock, _ name As String, _
value As Long, _
copyToDataBlock As Boolean)
dblk.CopyString name, copyToDataBlock
dblk.CopyLong value, copyToDataBlock End Sub
Sub AddLinkage()
Xdata
Dim id As DLong
Dim dblk As New DataBlock
id = DLongFromLong(50296)
Set ele = ActiveModelReference.GetElementByID(id)
TransferBlock dblk, "Added by User Attributes Example", 50296, True ele.AddUserAttributeData attrId, dblk
ele.Rewrite End Sub
Sub GetLinkage()
Dim ele As Element Dim id As DLong
Dim dblk() As DataBlock
Dim value As Long, name As String
id = DLongFromLong(50296)
Set ele = ActiveModelReference.GetElementByID(id)
dblk = ele.GetUserAttributeData(attrId) TransferBlock dblk(0), name, value, False
MsgBox "NAME: " & name & ", VALUE: " & value End Sub
Note: When macros use the CopyString method, VBA will copy a Unicode String to the element. If the macro needs to be compatible with MDL the macro needs to convert the String to an Array of bytes, then use the CopyByteArray method.
Xdata
Another method that applications can use to store information is Xdata. Xdata is a format that AutoCAD uses to store extra information on elements. This has the advantage of making the information compatible with the DWG format.Sub InterpretXData(Xdata() As XDatum) Dim I As Long
Dim J As Long Dim D As DLong
Dim vt As Variant
' Using Debug.Print, display all of the XData to the Immediate Window of
' the Visual Basic Editor.
For I = LBound(Xdata) To UBound(Xdata)
With Xdata(I)
Debug.Print GetXDatumName(.Type) & " --- ";
If VarType(.Value) = vbEmpty Then Debug.Print "the value is empty"
Else
Select Case .Type
Case msdXDatumTypePoint, _ msdXDatumTypeWorldDirection, _
msdXDatumTypeWorldSpaceDisplacement, _ msdXDatumTypeWorldSpacePosition
' Value is of the type Point3d.
Debug.Print .Value.X; .Value.Y; .Value.Z Case msdXDatumTypeDatabaseHandle
' Value is a hex string. Get the element ' ID by calling DLongFromHexString
Debug.Print "&H" & .Value Dim eleID As DLong
eleID = DLongFromHexString(.Value) Case msdXDatumTypeBinaryData, _
msdXDatumTypeUnsupported
' Value is of the type Byte().
For J = LBound(.Value) To UBound(.Value)
Debug.Print Hex(.Value(J)); " "; Next J
Case Else
' Value is of a type that can be printed directly.
Debug.Print .Value End Select
End If
End With ' Xdata(I)
Next I End Sub
Xdata
Sub ShowEleXData()
' Find all of the XData in any element
Dim ee As ElementEnumerator
Set ee = ActiveModelReference.GraphicalElementCache.Scan Do While ee.MoveNext
If ee.Current.HasAnyXData Then Dim appNames() As String
Dim index As Long
appNames = ee.Current.GetXDataApplicationNames
For index = LBound(appNames) To UBound(appNames) Dim aXdata() As XDatum
aXdata = ee.Current.GetXData(appNames(index)) InterpretXData aXdata Next End If Loop End Sub Sub ShowAllModelXData()
' Find all XData contained on any model in the active design file
Dim theModel As ModelReference Dim appNames() As String
Dim index As Long
For Each theModel In ActiveDesignFile.Models
If theModel.HasAnyXData Then
Debug.Print "---Reporting XData for model " & _ theModel.Name & " ---"
appNames = theModel.GetXDataApplicationNames For index = LBound(appNames) To UBound(appNames)
Dim aXdata() As XDatum
Debug.Print "--- Application " & _ appNames(index) & "---"
InterpretXData aXdata Next
End If Next
End Sub
Function GetXDatumName(xdType As MsdXDatumType) As String ' Translates an XData type into a String
Select Case xdType
Case msdXDatumTypeBinaryData
GetXDatumName = "Binary Data"
Case msdXDatumTypeControlString
GetXDatumName = "Control String"
Case msdXDatumTypeDatabaseHandle
GetXDatumName = "Database Handle"
Case msdXDatumTypeDistance GetXDatumName = "Distance" Case msdXDatumTypeInt16 GetXDatumName = "Int16" Case msdXDatumTypeInt32 GetXDatumName = "Int32" Case msdXDatumTypeLevel GetXDatumName = "Level" Case msdXDatumTypePoint GetXDatumName = "Point" Case msdXDatumTypeReal GetXDatumName = "Real"
Module Review
Case msdXDatumTypeScaleFactor
GetXDatumName = "Scale Factor"
Case msdXDatumTypeString
GetXDatumName = "String"
Case msdXDatumTypeUnsupported
GetXDatumName = "Unsupported"
Case msdXDatumTypeWorldDirection
GetXDatumName = "World Direction"
Case msdXDatumTypeWorldSpaceDisplacement
GetXDatumName = "World Space Displacement"
Case msdXDatumTypeWorldSpacePosition
GetXDatumName = "World Space Position"
End Select
GetXDatumName = GetXDatumName & "(" & xdType & ")"
End Function
Module Review
Now that you have completed this module, let’s measure what you have learned.Questions
1 What is the preferred method to work with an external database? 2 What is required to work with User Data? 3 What tools are used to work with XML data?Module Overview
The “C” programming environment is available to applications in order to work with the data structures used in MicroStation. Applications work through the Get/
SetCExpressionValue method of the Application Object to access the “C” expression evaluator that is in MicroStation’s runtime environment.
Module Prerequisites
• Familiarity with MDL as a platform for developing programmed customizations for MicroStation. Refer to the Course Overview for additional pre‐requisites.Module Objectives
After completing this module, you will be able to: • Create VBA code utilizing MDL functions.Introductory Knowledge
Before you begin this module, let's define what you already know.Questions
CExpression Processor 2 True or False: There are no practical limitations placed on the number of MDL applications that can be simultaneously loaded. 3 What is the MDL dialog in MicroStation used for and how do you open it?
Answers
1 Service provider type, DSN name, user name or id, password 2 True 3 The MDL dialog is used to load and unload MDL applications and to view technical details and key‐ins for MDL applications. To open it, select Utilities > MDL.CExpression Processor
An expression is a valid programming statement as it would be put into a “C” program. The GetCExpressionValue method takes in the “C” expression and, optionally, the MDL application that is required. The SetCExpressionValue method takes in the expression used to set some value in an MDL application. When an MDL function is not exposed to VBA, the Cexpression evaluator can often be used to call the function. The Cexpression processor can be used to call MDL functions from external Visual Basic programs.retValue GetCexpressionValue(“mdlPolygon_pointInsideXY (“ & _ VarPtr(pCentroid) & “,” & _
VarPtr(boundryPoints(0)) & “,” & _ numboundryPoints & “,” _
tol & ")") Option Explicit
Implements IPrimitiveCommandEvents
Private Sub IPrimitiveCommandEvents_Cleanup()
End Sub
Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d, _ ByVal View As View)
Dim areaP As Double Dim closureP As Double
Dim iXYP As Double Dim iXZP As Double
Dim iYZP As Double Dim tol As Double
Dim pCentroid As Point3d Dim pMoment As Point3d
Dim pPrincipalMoments As Point3d Dim pPrincipalDirections As Point3d
Dim retValue As Long
Dim oElement As Element tol = 1#
Set oElement = CommandState.LocateElement(Point, View, False)
retValue = 0
If Not oElement Is Nothing Then
If oElement.IsPlanarElement Or oElement.Type = _ msdElementTypeBsplineSurface Then
retValue = _
GetCExpressionValue("mdlMeasure_surfaceProperties (" & _ VarPtr(areaP) & "," & _
VarPtr(pCentroid) & "," & _ VarPtr(pMoment) & "," & _ VarPtr(iXYP) & "," & _ VarPtr(iXZP) & "," & _ VarPtr(iYZP) & "," & _
VarPtr(pPrincipalMoments) & "," & _ VarPtr(pPrincipalDirections) & "," & _ oElement.MdlElementDescrP & "," & _ tol & "," & " 0)")
Else
retValue =
GetCExpressionValue("mdlMeasure_volumeProperties (" & _ VarPtr(volumeP) & "," & _
VarPtr(areaP) & "," & _ VarPtr(closureP) & "," & _ VarPtr(pCentroid) & "," & _ VarPtr(pMoment) & "," & _ VarPtr(iXYP) & "," & _ VarPtr(iXZP) & "," & _
Calling C and MDL Functions
VarPtr(iYZP) & "," & _
VarPtr(pPrincipalMoments) & "," & _ VarPtr(pPrincipalDirections) & "," & _ oElement.MdlElementDescrP & "," & _ tol & "," & " 0)")
End If
If retValue = 0 Then
Debug.Print "the centroid is _
"; pCentroid.X; pCentroid.Y; pCentroid.Z
Else
Debug.Print "returned a "; retValue
End If End If
End Sub
Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, _ ByVal View As View, ByVal DrawMode As MsdDrawingMode)
End Sub
Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String) End Sub
Private Sub Class_Initialize()
End Sub
Private Sub IPrimitiveCommandEvents_Reset() End Sub
Private Sub IPrimitiveCommandEvents_Start()
CommandState.SetLocateCursor End Sub
Calling C and MDL Functions
One of the many features available to programmers in Visual Basic is the ability to import functions from other libraries. This can be done using the Declare
statement and providing the prototype for the function call in a Visual Basic module.
The syntax is as follows:
[Public | Private] Declare Sub subName Lib "libName.dll" [Alias "AliasName"] [ ( [ argumentList] ) ]
[Public | Private] Declare Function FuncName Lib "libName.dll" [Alias "AliasName"] [ ( [ argumentList] ) ] As Type
Public|Private defines the scope of the procedure. All declarations in a class module must be private. If neither Public or Private keyword is used, the declaration is implicitly Public.
The subName or FuncName must start with a letter, be unique within the scope, have less than 255 characters, and cannot be a VBA keyword, The library must be the complete name including the .dll extension unless it is one of the standard Windows libraries. If the path is not specified then the search is executed using the following logic: • The directory that the application was loaded • The current working directory • The Windows\System32 directory • The Windows\System directory • The PATH environment variable Optionally, the “Alias” can be used to define the name as written in the original source code. That is the “subName” local to the VBA module, only the Alias is the name in the DLL. The Argument list is the variable name and the type of information that the library needs. Some common conversions are as follows.
C DataType VBA DataType
BOOL ByVal fValue as Integer BYTE ByVal bytValue as Byte DWORD ByVal ingValue as Long int ByVal intValue as Long LPSTR ByVal strValue as String
Calling C and MDL Functions
Example declarations
Public Declare Function WinHelp Lib "user32" Alias "WinHelpA" _ (ByVal hwnd As Long, _
ByVal lpHelpFile As String, _ ByVal lngCommand As Long, _ dwData As Any) As Long
Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex _ As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, _
ByVal lpWindowName As Any) As Long
Private Declare Function GetWindowLong Lib "user32" Alias _ "GetWindowLongA" (ByVal HWND As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" (ByVal HWND As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Const WS_THICKFRAME = &H40000
Private Const GWL_STYLE = (–16) Private Sub UserForm_Activate()
Dim lngFrmHWND As Long Dim lngStyle As Long
Dim lngRetVal As Long
lngFrmHWND = FindWindow("ThunderDFrame", Me.Caption) lngStyle = GetWindowLong(lngFrmHWND, GWL_STYLE)
lngRetVal = SetWindowLong(lngFrmHWND, GWL_STYLE, _ lngStyle Or WS_THICKFRAME)
End Sub
Using MDL functions in VBA classes
You can use MDL functions in VBA classes by importing libraries delivered with the MicroStation SDK.
• The stdmdlbltin.dll library provides access to the core mdl functions in MicroStation. • The stdmdlaccessor.dll library provides some useful Element/Element descriptor functions. The MicroStation SDK is available for download at http://www.bentley.com/en‐US/Corporate/Bentley+Partner+Program/ Technology+Partners/MicroStation+SDK.htm. Some common MDL data types are:
In Visual Basic, an Integer is 16 bits and a Long is 32 bits. Passing an argument by reference generates a pointer to the variable.
Some examples of using these are as follows.
Levels
Option Explicit
Private Declare Function mdlLevel_setActiveByName Lib "stdmdlbltin.dll" _ (ByVal parentLevelIdIn As Long, _
ByVal pLevelNameIn As Long) As Long
Sub SetActiveLevelFromLibraryTest() Dim ParentID As Long
Dim oLevelName As String Dim status As Long
Dim oPtr As Integer
' this needs to end up as 0xffffffff
ParentID = &HFFFFFFFF oLevelName = "G-CODE"
status = mdlLevel_setActiveByName(ParentID, StrPtr(oLevelName)) Debug.Print status
End Sub
C DataType VBA DataType
Dpoint3d ByRef pt As Point3d
Transform ByRef transP As Transform3d DgnModelRefP ByVal modelRef As Long MSElementDescr ByRef edPP As Long
Calling C and MDL Functions
Multi‐line placement
Const NULLPtr As Long = 0
Declare Function mdlMline_create Lib "stdmdlbltin.dll" _ (ByVal mline As Long, _
ByVal seed As Long, _ ByRef normal As Point3d, _ ByRef points As Point3d, _ ByVal nPoints As Long) As Long
Declare Function mdlElmdscr_new Lib "stdmdlbltin.dll" _ (ByRef elDescrPP As Long, _
ByVal elemHeader As Long, _ ByVal element As Long) As Long
Function CreateMultiLine() As element
Dim bytes(0 To 2000) As Byte Dim vertices(0 To 4) As Point3d
Dim elmDescrP As Long
vertices(0) = Point3dFromXY(0,0) vertices(1) = Point3dFromXY(1,1)
vertices(2) = Point3dFromXY(2,0) vertices(3) = Point3dFromXY(3,1)
vertices(4) = Point3dFromXY(4,0)
mdlMline_create VarPtr(bytes(0)), NULLPtr, Point3dFromXYZ(0,0,1), _ vertices(0), 5
mdlElmdscr_new elmDescrP, NULLPtr, bytes(0)
Set CreateMultiLine = MdlCreateElementFromElementDescrP(elmDescrP)
End Function
Multi‐line information
Declare Sub mdlMline_getInfo Lib "stdmdlbltin.dll" _ (ByRef nPoints As Long, _
ByRef nLines As Long, _ ByRef dist1 As Double, _ ByRef dist2 As Double, _
ByRef zVector As Point3d, _ ByVal mline As Long)
Declare Function ElmdscrAccessor_getMSElement Lib "stdmdlaccessor.dll" _ (ByVal ElementDescr As Long) As Long
Sub DumpMLineInfo()
Dim ele As element Dim pElement As Long
Dim elmDescr As Long Dim nPoints As Long
Dim nLines As Long Dim dDist1 As Double
Dim dDist2 As Double Dim zVector As Point3d
Dim oScanCriteria As New ElementScanCriteria Dim ElementEnum As ElementEnumerator
oScanCriteria.ExcludeAllTypes
oScanCriteria.IncludeType msdElementTypeMultiLine
Set ElementEnum = ActiveModelReference.Scan(oScanCriteria)
Do While ElementEnum.MoveNext
With ElementEnum.Current
elmDescr = .MdlElementDescrP
pElement = ElmdscrAccessor_getMSElement(elmDescr) mdlMline_getInfo nPoints, nLines, dDist1, dDist2, _
zVector, pElement
Debug.Print "nPoints = " & nPoints; Debug.Print ", nLines = " & nLines;
Debug.Print ", dDist1 = " & dDist1; Debug.Print ", dDist2 = " & dDist2
End With Loop
End Sub
Note: In MicroStation V8 XM Edition and later, there exists a PropertyHandler object in the VBA object model that provides read‐write access to the property system used by the Element Information tool. Using PropertyHandler is
Calling C and MDL Functions
therefore a viable alternative not only for getting and setting element properties but also design file, model, and attachment properties. Because
PropertyHandler works on a file's copy of an object, if a macro uses the object to change element properties, those changes are not automatically reflected in the Element object. The macro has to load the object again —
perhaps by using the GetElementByID method — to get the changes. There
are numerous examples of using PropertyHandler in the MicroStation VBA
help document, Objects, PropertyHandler Object.
References
' Reference File Parameters Const REFERENCE_DISPLAY = 1 Const REFERENCE_SNAP = 2 Const REFERENCE_LOCATE = 3 Const REFERENCE_SLOTACTIVE = 4 Const REFERENCE_SCALELINESTYLES = 5 Const REFERENCE_FILENOTFOUND = 6 Const REFERENCE_FILENAME = 7 Const REFERENCE_DESCRIPTION = 8 Const REFERENCE_LOGICAL = 9 Const REFERENCE_SCALE = 10 Const REFERENCE_ROTATION = 11 Const REFERENCE_ATTACHNAME = 13 Const REFERENCE_SCALE_MASTERUNITS = 15 Const REFERENCE_RESERVEDA = 16 Const REFERENCE_HIDDEN_LINE = 18 Const REFERENCE_DISPLAY_HIDDEN = 19 Const REFERENCE_CLIP_ROTATE = 20 Const REFERENCE_WCHAR_DESCRIPTION = 21 Const REFERENCE_WCHAR_LOGICAL = 22 Const REFERENCE_SCALE_STORED = 23 Const REFERENCE_SCALE_BY_UNITS = 24 Const REFERENCE_ANONYMOUS = 25 Const REFERENCE_OWNINGMODELREF = 26 Const REFERENCE_SOURCEMODELID = 27 Const REFERENCE_REFNUM = 28 Const REFERENCE_ELEMENTID = 29
Const REFERENCE_DISPLAYRASTERREFS = 30 Const REFERENCE_WCHAR_MODELNAME = 31 Const REFERENCE_USE_LIGHTS = 32 Const REFERENCE_DONOTNEST = 33 Const REFERENCE_CLIPBACK = 34 Const REFERENCE_CLIPFRONT = 35 Const REFERENCE_NESTDEPTH = 36 Const REFERENCE_RENDERMODE = 37 Const REFERENCE_REDUNDANT = 38 Const REFERENCE_LEVEL_OVERRIDES = 39 Const REFERENCE_DISPLAYFILENAME = 40 Const REFERENCE_DISPLAYATTACHNAME = 41 Const REFERENCE_DISPLAYMODELNAME = 42 Const REFERENCE_DWGBLOCKNAME = 43 Const REFERENCE_DONTDETACHONALL = 44 Const REFERENCE_DISPLAYFLAG = 45 Const REFERENCE_MODELNOTFOUND = 46 Const REFERENCE_CLIP_ROTMATRIX = 47 Const REFERENCE_LEVEL = 48 Const REFERENCE_DWGUNITMODE = 49 Const REFERENCE_HSVVALUEADJUST = 50 Const REFERENCE_HSVSATURATIONADJUST = 51 Const REFERENCE_BASENESTDEPTH = 52 Const REFERENCE_RIGHTNOTGRANTED = 53 Const REFERENCE_PRINTCOLORADJUST = 54 Const REFERENCE_METADATAONLY = 55 Const REFERENCE_EXTENDED = 56 Const REFERENCE_HSVHUESETTING = 57 Const REFERENCE_HSVADJUSTMENTFLAGS = 58 Const REFERENCE_DISPLAYPRIORITY = 59 Const REFERENCE_NAMEDGROUP = 60 Const REFERENCE_REVISION = 61 Const REFERENCE_TRANSPARENCY = 62 Const REFERENCE_PLOT_3D = 63 Const REFERENCE_NESTOVERRIDES = 64 Const REFERENCE_NEWLEVELDISPLAY = 65
Calling C and MDL Functions Const REFERENCE_GLOBALLINESTYLESCALES = 66 Const REFERENCE_TREAT_AS_ELEMENT = 67 Const REFERENCE_PROVIDERID = 68 Const REFERENCE_RAWREVISION = 69 Const REFERENCE_REVISIONNOTFOUND = 70 Const REFERENCE_USEANNOTATIONSCALE = 71 Const REFERENCE_ATTACHMETHOD = 73 Const REFERENCE_ACTIVATESTATUS = 74 Const REFERENCE_SYNCHWITHSAVEDVIEW = 75 Const REFERENCE_USEVIEWFLAGS = 76 Const REFERENCE_SAVEDVIEWNAME = 77 Const REFERENCE_SAVEDVIEWELEMENTID = 78 Const REFERENCE_LEVELCONTROLSDISPLAY = 79 Const REFATTACH_NEST_NONE = 0 Const REFATTACH_NEST_COPY = 1 Const REFATTACH_NEST_DISPLAY = 2 Const REFCOLORTABLE_USEPREF = 0 Const REFCOLORTABLE_ALWAYS = 1 Const REFCOLORTABLE_NEVER = 2 Const REFERENCE_LOCATEON = 0 Const REFERENCE_LOCATEOFF = 1 Const REFERENCE_PARENTLOCATEOFF = 2 Const REFERENCE_NOLOCATERIGHTS = 3 Const REFERENCE_PARENTNOLOCATERIGHTS = 4
' Reference File mdl Functions
Declare Function mdlRefFile_attach Lib "stdmdlbltin.dll" _ (ByRef outModelRefP As Long, _
ByVal fileName As String, _ ByVal logical As Long, _ ByVal description As Long, _ ByRef masterOrigin As Point3d, _ ByRef referenceOrigin As Point3d, _ ByVal scale As Double, _
ByRef rotMatrix As Matrix3d, _ ByVal nClipPoints As Long, _ ByRef clipPoints As Point2d, _ ByVal levelDisplayFlag As Long, _ ByVal snapLock As Long, _
Declare Function mdlRefFile_attachByView Lib "stdmdlbltin.dll" _ (ByRef outModelRefP As Long, _
ByVal fileName As String, _ ByVal logical As Long, _ ByVal description As Long, _ ByRef viewName As Long, _ ByVal scale As Double, _
ByRef centerPoint As Point3d, _ ByVal levelDisplayFlag As Long, _ ByVal snapLock As Long, _
ByVal locateLock As Long) As Long
Declare Function mdlRefFile_attachCoincident Lib "stdmdlbltin.dll" _ (ByRef outModelRefP As Long, _
ByVal fileName As String, _ ByVal logical As Long, _ ByVal description As Long, _ ByVal levelDisplayFlag As Long, _ ByVal snapLock As Long, _
ByVal locateLock As Long) As Long
Declare Function mdlRefFile_attachCoincidentExtended Lib _ "stdmdlbltin.dll" _
(ByRef outModelRefP As Long, _ ByVal fileName As String, _ ByVal logical As Long, _ ByVal description As Long, _ ByVal levelDisplayFlag As Long, _ ByVal snapLock As Long, _
ByVal locateLock As Long, _
ByVal callAsynchs As Long) As Long
Declare Function mdlRefFile_attachmentIdFromModelRef Lib _ "stdmdlbltin.dll" _
(ByVal modelRef As Long) As DLong
Declare Function mdlRefFile_beginAttachment Lib "stdmdlbltin.dll" _ (ByRef outModelRefP As Long, _
ByVal fileName As Long, _ ByVal modelName As Long, _ ByVal logical As Long, _
ByVal description As Long) As Long
Declare Function mdlRefFile_completeAttachment Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long, _
Calling C and MDL Functions
ByVal nestDepth As Long, _
ByVal initialDisplay As Long) As Long
Declare Function mdlRefFile_detach Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long) As Long
Declare Function mdlRefFile_getFromAttachmentID Lib "stdmdlbltin.dll" _ (ByRef refFilePP As Long, _
ByRef modelRefP As Long, _ ByVal srcModelRef As Long, _
ByVal attachmentID As DLong) As Long
Declare Function mdlRefFile_getInfo Lib "stdmdlbltin.dll" _
(ByVal modelRef As Long) As Long ' Returns a pointer to a structure
Declare Function mdlRefFile_getLocateLock Lib "stdmdlbltin.dll" _ (ByVal refP As Long) As Long
Declare Function mdlRefFile_getParameters Lib "stdmdlbltin.dll" _ (ByVal param As Long, _
ByVal paramName As Long, _ ByVal modelRef As Long) As Long
Declare Function mdlRefFile_getParent Lib "stdmdlbltin.dll" _
(ByVal refP As Long) As Long ' Returns a pointer to a structure
Declare Function mdlRefFile_getRefCount Lib "stdmdlbltin.dll" () As Long
Declare Function mdlRefFile_getSnapLock Lib "stdmdlbltin.dll" (ByVal refP As Long) As Long
Declare Function mdlRefFile_is3d Lib "stdmdlbltin.dll" (ByVal refP As Long) As Long
Declare Function mdlRefFile_isPrimary Lib "stdmdlbltin.dll" (ByVal refP As Long) As Long
Declare Function mdlRefFile_reattach Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long, _
ByVal outName As String, _ ByVal fileName As String, _
Declare Function mdlRefFile_reload Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long, _
ByVal updateDisplay As Long, _ ByVal forceReload As Long) As Long
Declare Function mdlRefFile_rotate Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long, _
ByRef pivotP As Point3d, _ ByVal xrotation As Double, _ ByVal yrotation As Double, _ ByVal zrotation As Double, _ ByVal view As Long) As Long
Declare Function mdlRefFile_setClip Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long, _
ByRef pts As Point2d, _ ByVal nverts As Long) As Long
Declare Function mdlRefFile_setParameters Lib "stdmdlbltin.dll" _ (ByVal param As Long, _
ByVal paramName As Long, _ ByVal modelRef As Long) As Long
Declare Function mdlRefFile_updateReference Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long, _
ByVal displayMode As Long) As Long
Declare Function mdlRefFile_writeAttachment Lib "stdmdlbltin.dll" _ (ByVal modelRef As Long) As Long
Declare Function mdlRefFile_writeAttachmentConditionally Lib _ "stdmdlbltin.dll" _
(ByVal modelRef As Long) As Long
Declare Function mdlMline_create Lib "stdmdlbltin.dll" _ (ByVal mline As Long, _
ByVal seed As Long, _ ByRef normal As Point3d, _ ByRef points As Point3d, _ ByVal nPoints As Long) As Long
Calling C and MDL Functions
Declare Function mdlElmdscr_new Lib "stdmdlbltin.dll" _ (ByRef elDescrPP As Long, ByVal elemHeader As Long, _ ByVal element As Long) As Long
Const NULLPtr As Long = 0
Sub DumpRefData()
Dim activeModel As ModelReference
Dim refModel As ModelReference Dim refModel2 As ModelReference
Dim refModels As ModelReferences Dim attach As Attachment
Dim attchmnts As Attachments Dim status As Long
Dim refP As Long Dim modrefP As Long
Dim pts(0 To 4) As Point2d Dim nverts As Long
Dim refDesc As String Dim buffer(255) As Byte
Dim dgnfile As DesignFile Dim param As Variant
Dim scalefactor As Double
scalefactor = ActiveModelReference.UORsPerMasterUnit nverts = 5 pts(0).X = 0 pts(0).Y = 0 pts(1).X = 5 * scalefactor pts(1).Y = 0 pts(2).X = 5 * scalefactor pts(2).Y = 2 * scalefactor pts(3).X = 0 pts(3).Y = 2 * scalefactor pts(4).X = 0 pts(4).Y = 0
Dim ModelName As String Dim LogicalName As String
Dim Description As String
ModelName = "Default" LogicalName = "testing"
Description = "test file"
status = mdlRefFile_beginAttachment(modrefP, ActiveDesignFile.Name, _ 0, StrPtr(LogicalName), StrPtr(Description))
If status = 0 Then
status = mdlRefFile_setClip(modrefP, pts(0), nverts)
Debug.Print "Reference Clip Status = " & status
status = mdlRefFile_completeAttachment(modrefP, 2, -1, 0)
End If End Sub
Declare Sub mdlElmdscr_setVisible Lib "stdmdlbltin.dll" _ (ByVal edP As Long, _
ByVal visible As Long)
Sub SetVisible()
Dim ele As element Dim eleDescr As Long
Dim oScanCriteria As New ElementScanCriteria Dim ElementEnum As ElementEnumerator
Set ElementEnum = ActiveModelReference.Scan(oScanCriteria)
Do While ElementEnum.MoveNext
Set ele = ElementEnum.Current
eleDescr = ele.MdlElementDescrP
mdlElmdscr_setVisible eleDescr, 0 If ele.FilePosition <> 0 Then
ele.Rewrite End If