28
About the Speaker: Robert is the Design Technology Manager for Sparling, the largest specialty electrical engineering and technology consulting firm in the United States, located in Seattle Washington. He provides strategic direction, technical oversight, and high-level support for Sparling’s enterprise design and production technology systems. He is instrumental in positioning Sparling as an industry and client leader in leveraging technology in virtual building and design. Robert has been writing AutoLISP ® code since the release of AutoCAD v2.5, and VBA since introduced in R14. He has customized applications for the electrical/lighting, plumbing/piping, and HVAC disciplines. Robert has also developed applications for ® Filling the Gaps in the Sheet Set Manager R. Robert Bell – Sparling CP215-2 The Sheet Set Manager (SSM) offers many advantages for producing your construction documents, but do you wish it could do just a bit more? For instance, would you like to export the data stored in SSM directly to Excel? Does your title block include a total count of the Sheets? Are you trying to find a way to automatically index each Sheet? This class will answer these three questions. AutoCAD as a consultant. A former member of the Board of Directors for AUGI , he is active on AUGI forums and Autodesk discussion groups. [email protected]

Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

  • Upload
    lyduong

  • View
    235

  • Download
    6

Embed Size (px)

Citation preview

Page 1: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

About the Speaker: Robert is the Design Technology Manager for Sparling, the largest specialty electrical engineering and technology consulting firm in the United States, located in Seattle Washington. He provides strategic direction, technical oversight, and high-level support for Sparling’s enterprise design and production technology systems. He is instrumental in positioning Sparling as an industry and client leader in leveraging technology in virtual building and design. Robert has been writing AutoLISP® code since the release of AutoCAD v2.5, and VBA since introduced in R14. He has customized applications for the electrical/lighting, plumbing/piping, and HVAC disciplines. Robert has also developed applications for

®

Filling the Gaps in the Sheet Set Manager R. Robert Bell – Sparling

CP215-2 The Sheet Set Manager (SSM) offers many advantages for producing your construction documents, but do you wish it could do just a bit more? For instance, would you like to export the data stored in SSM directly to Excel? Does your title block include a total count of the Sheets? Are you trying to find a way to automatically index each Sheet? This class will answer these three questions.

AutoCAD as a consultant. A former member of the Board of Directors for AUGI , he is active on AUGI forums and Autodesk discussion groups. [email protected]

Page 2: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking
Page 3: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

3 | P a g e

Introduction The Sheet Set Manager (SSM) can be a boon for organizing your drawings for a project. The palette interface is easy to understand. However, the ease of use is at the sacrifice of a command-line interface. Without a command-line interface automating the Sheet Set Manager seems impossible. That is not the case. However, there is a larger issue.

The average office will find the tools for automating the Sheet Set Manager to be inscrutable. The help file for the Sheet Set Manager is sparse at best. Also, there is no way to automate the SSM using Visual LISP as your language. An interface is available in VBA, but understanding the interface requires some instruction.

Understanding all the options in the Sheet Set Manager is a topic for another course. Heidi Hewlett has written white papers for Autodesk and has offered courses at Autodesk University and AUGI CAD Camps for several years. This course is not intended to teach you how to use the SSM via the normal user interface.

There is sample code installed with AutoCAD demonstrating automating the Sheet Set Manager using VBA. The sample can e found at C:\Program Files\<AutoCAD Version>\Sample\ActiveX\SheetSetVBA. There were also some pioneering samples executed by Lee Ambrosius and taught as a course at Autodesk University 2005. That course is available at www.AUGI.com. The title is “Taking a Look at the Sheet Set Object” and its course number is CP151. This course builds upon the concepts introduced by both sources and directly addresses a few of the common gaps in the Sheet Set Manager.

Exposing the Gaps The first gap is exporting information about the sheets to an external program such as Microsoft® Office Excel®. VBA is a natural approach to interfacing between the SSM and Excel.

The second gap is automatically indexing the sheets in your sheet set. Some title blocks include a “# of #” item, where each sheet is individually numbered (indexed) and the second number is the total for the entire set. Often, the second number includes sheets not produced by your office. So it is not as simple as counting all the sheets and placing that value in a custom property. Obviously each sheet is going to need a custom property for the index number and the sheet set will need at least one custom property to store the total number of sheets.

Overview of the Object Model Sheet objects are stored in a sheet set object, a sheet set is

Page 4: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

4 | P a g e

stored in a database object, and databases are loaded in the SSM object. The database object is needed in order to regulate adding data to the sheet set. A sheet set may be accessed by more than one person at the same time, but edits can only be made by one person at a time. Adding the database layer to the Sheet Set Manager permits locking of the file while edits are made or rolling back the changes instead of committing them.

There are other objects available in the object model. This course will not address all the objects of the SSM. The focus of this course is to work with the objects needed to fill the gaps previously mentioned.

Working with the SSM Database Dealing with a database adds another complexity. You should not cache objects directly, rather, store the object ID instead. This technique will be used for the code that is part of this course. The database can be stored directly. All objects below the database will be destroyed and recreated during a reload operation. Reloads do not cause the database to be destroyed. A database will be automatically reloaded from time to time as other users edit the sheet set.

The required procedure is to store the IAcSmObjectId for each object you need to cache which can be done using the GetObjectID method of the object with which you are working. This ID object has a method called GetPersistObject that returns the “real” object. This object is a generic interface component named IAcSmPersist. This component should be cast into the appropriate object.

It is important to lock and unlock the database as few times as possible. This will improve performance. For this reason, it is better to makes changes in batches, rather than immediately.

Page 5: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager Where are the Collections? One thing in the API that immediately jumps out to the VBA programmer is that there are no collections where you would expect them. For example, there is no collection of sheets in a sheet set object. So you cannot use the Item property to get a particular sheet. Rather, the object model provides a mechanism to iterate thru an object.

Iterating thru objects in the Sheet Set Manager is accomplished using objects called enumerators. It is not as simple as getting a collection and iterating thru it. Rather, you create an enumerator object and use its methods to work your way thru that particular part of the SSM. Each type of object in the SSM that can have multiple instances will have its own type of

enumerator. For example, the IAcSmEnumDatabase object is used to get each loaded database.

Create an enumerator object. Each enumerator has two methods, Next and Reset. The methods are obvious. The following table lists the enumerators used in the sample code and the objects with which they work. Note that these are not all the enumerators available in the SSM object model.

Enumerator Object

IAcSmEnumProperty Properties

IAcSmEnumComponent Sheets and Subsets

IAcSmEnumPersist Sheet Sets

IAcSmEnumDatabase Databases

The VBA Project References The code will require three references. The first reference is to the AcSmComponents17 1.0 Type Library (for AutoCAD 2007/2008).

The next reference is to the Microsoft Scripting Runtime, which will provide the Dictionary object for data storage.

The final reference is to Excel. Adding a reference to Ehas the advantage of early binding, which makes writingthe code easier. It has the disadvantage of tying the codeto a specific version of Microsoft Office.

xcel

The ssmUtils Module There are three procedures used to support the class modules.

Alert, is used to warn the user about issues. However, instead of simply presenting a MsgBox, the procedure examines AutoCAD’s current state and presents the message at the command prompt when a script is running or CmdDia is set to zero.

LockDb, attempts to lock the database and returns the lock status.

UnlockDb, unlocks the database if it was locked by the current user and returns the lock status.

The rrbiSheet Class The rrbiSheet class is used to store the data for each sheet in the sheet set and provide access back to the actual sheet object. There are only properties associated with this object.

5 | P a g e

Page 6: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

DoNotPlot: True only when the sheet is marked in the SSM to not “Include for publish”. This property is also used to control if a sheet should be included in the total sheet count. This property is read-only for the purpose of this course.

Filename: exposes the base filename of drawing that holds the sheet layout. This filename is included in the data provided to the Excel worksheet. This property is read-only.

SheetID: this is the IAcSmObjectId for the sheet. It is used to convert the cached item to a real AcSmSheet object via.

SheetIndex: used to store the index number of the sheet. The index number is determined by the sheet’s order in the SSM, the starting number for the sheet set, and the sheet’s DoNotPlot property. The sheet custom property is modified only when the given number does not match the stored number.

SheetName: returns a combined name of the sheet. The subset name, sheet number, and sheet title are concatenated. This should result in a unique identifier for each sheet in the sheet set. This property is read-only.

SheetNumber: returns the number of the sheet as assigned in the SSM. If there are duplicate sheet numbers in the same sheet set, the first case of the duplicate is flagged in the Excel worksheet. This property is read-only for the purpose of this course.

SheetTitle: returns the title of the sheet as assigned in the SSM. This property is read-only for the purpose of this course.

Subset: stores the name of the subset. This property is populated by the calling code as it iterates thru the sheet set’s objects.

Support procedures for this object include:

GetSheetIndex: returns the value stored in the sheet’s custom property.

SetCustomProperty: sets the value of the sheet custom property, Sheet Index Number. This procedure modifies the database, so it locks the database while modifying it. The database is immediately unlocked and the change is committed.

GetSheet: returns the AcSmSheet object for the cached object ID. Note that the object created inside the procedure is immediately destroyed. The calling procedure is responsible for destroying the object returned by this procedure.

The rrbiSheetSet Class The rrbiSheetSet class is used to store the sheet objects and sheet set-specific data. It provides access back to the database and access to the actual sheet set object.

6 | P a g e

Page 7: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

7 | P a g e

Db: this property holds the AcSmDatabase. This property must be populated by the calling procedure before the other properties and methods are used.

Description: returns the description of the sheet set as specified in the SSM. This property is read-only for the purpose of this course.

Filename: returns the full filename of the sheet set. This property is read-only.

Name: returns the name of the sheet set as specified in the SSM. This property is read-only for the purpose of this course.

SheetCount: this is a read-only property that provides the number of sheets set to plot in the sheet set.

SheetStartNumber: this property is used to work with the sheet set custom property, “Sheet Index Start Number”. Setting this property causes a check of the existing data. If the count of the plotting sheets the given number is greater than the total sheet count, the total sheet count is adjusted upwards to accommodate the new start number. If the number is less than 1 it is changed to 1. The custom properties in the sheet set are changed to reflect thadjustments.

plus

e

TotalSheetCount: this property is used to work with the sheet set custom property, “Set Total Number”. Setting this property causes a check of the existing data. If the number is smaller than the starting number plus the count of the plotting sheets, the total sheet count is adjusted upwards to accommodate the calculated size of the set. If the number is less than 1 it is changed to 1 when the set has not been populated with plotting sheets.

GetCustomProperties: returns all the custom properties for the sheet set.

GetSheets: returns all the sheets in the sheet set.

Support procedures for this object include:

GetSheetCount: returns the count of all plotting sheets.

GellAllSheets: this procedure recursively iterates thru the sheet set, storing all the sheets found, even in subsets. This procedure is also setting the index number for each sheet as the sheet’s object is created.

GetSheetSetCustomProperties: this procedure is used to populate the module-level variable that holds all the sheet set’s custom properties. It will also create the two required custom sheet set properties needed to support sheet set indexing.

Reindex: iterates thru all the sheets, changing their index number as needed when the sheet set’s starting number has been changed.

Page 8: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

8 | P a g e

SetCustomProperty: this procedure sets the given custom property to the given value. This procedure modifies the database, so it locks the database while modifying it. The database is immediately unlocked and the change is committed.

The rrbiSheetSetDatabase Class The rrbiSheetSetDatabase class stores the database. It serves mostly as a data verification mechanism and to provide access to the rrbiSheetSet object.

Db: this property ho ing lds the AcSmDatabase. This property must be populated by the callprocedure before the other properties are used. Setting the database also creates the rrbiSheetSet object and sets its database.

Filename: returns the full filename of the sheet set. This property is read-only for the purpose of this course.

Name: returns the name of the sheet set. Used to index the open databases. This property is read-only.

ReadOnly: returns True when the database is read-only. This property is read-only.

GetSheetSet: this method returns the rrbiSheetSet object for the current database.

The rrbiSheetSetDatabases Class The rrbiSheetSetDatabases class simply stores a collection of all the loaded

databases. Therefore, there are only two properties to support iterating thru the collection, Count and Item. However, the Initialize procedure is another example of iterating in the SSM object model. In this case, the objects are cached because they are AcSmDatabase objects.

The rrbiLayout Class The rrbiLayout class stores each layout found in the open drawing, yet does more than just that. It is important to see if each layout is part of a sheet set, and if the sheet set is the one in which we are interested.

Filename: stores the filename of the sheet set attached to the current drawing if there is any. If there is none an empty string is returned. This property is read-only.

Layout: stores the AcadLayout object for our rrbiLayout object. Setting this property also sets the variables that store the data for the rest of the properties. Sadly, the sheet information for a layout cannot reliably be found in the named dictionary, AcSheetSetData. The layout name store there can get out of sync rather easily. Also, if there happens to be more than one layout in the same drawing that are sheets in the sheet set, the multiple layouts are not located in the dictionary. Therefore, fields are temporarily placed on each layout and its data is read.

LayoutName: returns the name of the layout. This property is read-only for the purpose of this course.

SheetName: returns a combined name of the sheet. The subset name, sheet number, and sheet title are concatenated. This should result in a unique identifier for each sheet in the sheet set. This property is read-only. It is used to compare the layout against the sheet data.

Page 9: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

9 | P a g e

SheetNumber: returns the sheet number associated with the layout. This property is read-only for the purpose of this course.

SheetTitle: returns the sheet title associated with the layout. This property is read-only for the purpose of this course.

Subset: returns the subset to which the sheet belongs, if any. This property is read-only for the purpose of this course.

Support procedures for this object include:

GetFilename: searches for the named dictionary and its XRecord that holds the data of the filename of the associated sheet set. If there is no sheet set tied to the current drawing, an empty string is returned.

The rrbiSetLayer0 Class The rrbiSetLayer0 class is simply used to change the current layer to 0, avoiding any bugs with the layer being locked or frozen (why would we do this with layer 0?!). When the class terminates, the original layer is restored.

The ProjectIndex Class The ProjectIndex class is the true workhorse of the system. It creates the connection to Excel. It also gathers the data and determines what needs to

be placed in the worksheet. It will modify the layout tab names if the need is determined. It has only one property and two methods. There are a large number of support procedures.

Filename: returns the full filename of the Excel file. This property is read-only for the purpose of this course.

VerifySheets: verifies the data in the Excel file against the data found in the sheet set. If the Excel file is not created, it creates it. Each entry in the Excel file is marked with an icon to indicate if it part of the sheet set, if it is non-plotting, if there is a duplicated sheet number, or the drawing file is missing.

WriteTabs: gathers the data from each tab in the current drawing and places the data into the Excel file for only those tabs that are part of the sheet set.

Support procedures for this object include:

FitColumns: auto-fits each used column in the worksheet for its data rows.

GetExcel: returns a running instance of Microsoft Office Excel.

GetExcelSheet: returns a worksheet named “Current Submittal”.

GetLayouts: returns a collection of rrbiLayout objects, which are the layouts that belong to a sheet set.

GetSheetMark: returns a string that is used to indicate the status of each sheet in the sheet set. If a sheet number recorded in the worksheet has a mismatched filename, it is marked as a duplicate. If a sheet has been set to not publish, it is marked as such. When neither of the preceding conditions is met, the sheet is assumed to be ok and marked as such.

GetWorkbook: returns the workbook for the filename stored in the module-level variable. If the workbook is not loaded, it is opened.

Page 10: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

10 | P a g e

InitProjIndex: formats a new workbook with header row data. Fonts and font sizes are assigned to the worksheet and then to specific cells. All worksheets except the first one will be deleted.

IsExcelRunning: returns True when Excel is found to be running.

MarkExcelSheet: is used by the VerifySheets method to iterate thru the sheets in the sheet set and compare them to the entries in the worksheet. Entries in the worksheet that have no matching sheet are marked as missing. Other entries are marked as determined by the GetSheetMark procedure.

RecordTabs: is used by the WriteTabs method to add or modify the data in the worksheet. Entries are marked as determined by the GetSheetMark procedure, or marked as ok if the entry did not previously exist.

RenameTab: is used by the WriteTabs method to rename a layout to match the sheet number of the sheet, and to modify the actual SSM data to match the new tab name.

Sample Execution Code The following three procedures are used during the course to demonstrate the features of the code presented in this course.

• The first sample is only used to examine the properties and methods of the objects created by the classes.

• The second sample creates the project index and modifies a drawing’s layout which, in turn, modifies the sheet in the SSM.

• The third sample modifies the indexing properties of the sheet set and re-indexes the sheets.

Page 11: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

11 | P a g e

Option Explicit Sub Test() If ThisDrawing.Name <> "E0.1 Symbols.dwg" Then ssmUtils.Alert "Load the drawing for the demo." End If Dim mySSM As rrbiSheetSetDatabases Set mySSM = New rrbiSheetSetDatabases Dim mySSetDb As rrbiSheetSetDatabase Set mySSetDb = mySSM.Item("C:\Users\rbell\Documents\AutoCAD Sheet Sets\Test.dst") If Not (mySSetDb Is Nothing) Then Dim mySSet As rrbiSheetSet Set mySSet = mySSetDb.GetSheetSet Dim mySheets As Scripting.Dictionary Set mySheets = mySSet.GetSheets Dim mySheet As rrbiSheet Set mySheet = mySheets.Items(0) Dim myLayout As rrbiLayout Set myLayout = New rrbiLayout Set myLayout.Layout = ThisDrawing.Layouts.Item("E0.1") Set myLayout = Nothing Set mySheet = Nothing Set mySSet = Nothing Set mySSetDb = Nothing Else ssmUtils.Alert "Demo sheet set is not loaded." End If Set mySSM = Nothing End Sub

Sub Test2() Dim mySSM As rrbiSheetSetDatabases Set mySSM = New rrbiSheetSetDatabases Dim mySSetDb As rrbiSheetSetDatabase Set mySSetDb = mySSM.Item("C:\Users\rbell\Documents\AutoCAD Sheet Sets\Test.dst") If Not (mySSetDb Is Nothing) Then Dim myProjIndex As ProjectIndex Set myProjIndex = New ProjectIndex myProjIndex.WriteTabs myProjIndex.VerifySheets Set myProjIndex = Nothing Set mySSetDb = Nothing Else ssmUtils.Alert "Demo sheet set is not loaded." End If Set mySSM = Nothing End Sub

Page 12: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

12 | P a g e

Sub Test3() Dim mySSM As rrbiSheetSetDatabases Set mySSM = New rrbiSheetSetDatabases Dim mySSetDb As rrbiSheetSetDatabase Set mySSetDb = mySSM.Item("C:\Users\rbell\Documents\AutoCAD Sheet Sets\Test.dst") If Not (mySSetDb Is Nothing) Then Dim mySSet As rrbiSheetSet Set mySSet = mySSetDb.GetSheetSet mySSet.SheetStartNumber = 1 mySSet.TotalSheetCount = 3 Set mySSet = Nothing Set mySSetDb = Nothing Else ssmUtils.Alert "Demo sheet set is not loaded." End If Set mySSM = Nothing End Sub

Conclusion The addition of a verifiable, printable list of sheets in an Excel file is well worth the effort to use the SSM API. Since you now have an Excel file with the sheet set information you may use it to replace the built-in Sheet Set Index with its limitations. Also, the built-in ability to index the plotting sheets of a sheet set covers a large gap in the SSM.

The sample code presented in this course is a subset of working code in a production environment. This code has proved to be invaluable in covering some of the gaps in the SSM. Hopefully you will also find this to be true.

The following pages replicate the code used during the course.

Page 13: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

13 | P a g e

ssmUtils Option Explicit Public Sub Alert(Prompt As String, _ Optional Buttons As VbMsgBoxStyle = vbExclamation, _ Optional Title As String = "Sheet Set Gaps") Const acCmdActiveScript = 4 If (ThisDrawing.GetVariable("CmdActive") And acCmdActiveScript) <> acCmdActiveScript And _ ThisDrawing.GetVariable("CmdDia") = 1 Then MsgBox Prompt, Buttons, Title Else ThisDrawing.Utility.Prompt vbCrLf & Prompt End If End Sub

Public Function LockDb(pDb As AcSmDatabase) As AcSmLockStatus With pDb If .GetLockStatus = AcSmLockStatus_UnLocked Then .LockDb pDb LockDb = .GetLockStatus End With End Function

Public Function UnlockDb(pDb As AcSmDatabase, Optional Commit As Boolean) As AcSmLockStatus With pDb If .GetLockStatus = AcSmLockStatus_Locked_Local Then .UnlockDb pDb, Commit UnlockDb = .GetLockStatus End With End Function

rrbiSheet Option Explicit Private mSubset As String Private mSheetID As IAcSmObjectId Private mSheetIndex As Long Private Const ssmSheetIndex = "Sheet Index Number"

Property Get DoNotPlot() As Boolean Dim mySheet As AcSmSheet Set mySheet = GetSheet DoNotPlot = mySheet.GetDoNotPlot Set mySheet = Nothing End Property

Property Get Filename() As String Dim mySheet As AcSmSheet Set mySheet = GetSheet Dim res As Variant res = Split(mySheet.GetLayout.GetFilename, "\", , vbTextCompare) Filename = Replace(Expression:=res(UBound(res)), _ Find:=".dwg", _ Replace:="", _ Compare:=vbTextCompare) Set mySheet = Nothing End Property

Property Set SheetID(ByVal pSheetID As IAcSmObjectId) Set mSheetID = pSheetID mSheetIndex = GetSheetIndex End Property

Page 14: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

14 | P a g e

Property Get SheetID() As IAcSmObjectId If Not (mSheetID Is Nothing) Then Set SheetID = mSheetID Else ReportError End If End Property

Property Get SheetIndex() As Long SheetIndex = mSheetIndex End Property

Property Let SheetIndex(Number As Long) If Number <> mSheetIndex Then mSheetIndex = Number SetCustomProperty ssmSheetIndex, CStr(mSheetIndex) End If End Property

Property Get SheetName() As String Dim mySheet As AcSmSheet Set mySheet = GetSheet SheetName = mSubset & IIf(mSubset = "", "", "-> ") & _ mySheet.GetNumber & " - " & mySheet.GetTitle Set mySheet = Nothing End Property

Property Get SheetNumber() As String Dim mySheet As AcSmSheet Set mySheet = GetSheet SheetNumber = mySheet.GetNumber Set mySheet = Nothing End Property

Property Get SheetTitle() As String Dim mySheet As AcSmSheet Set mySheet = GetSheet SheetTitle = mySheet.GetTitle Set mySheet = Nothing End Property

Property Let Subset(Name As String) mSubset = Name End Property

Property Get Subset() As String Subset = mSubset End Property

Private Function GetSheet() As AcSmSheet If Not (mSheetID Is Nothing) Then Dim mySheet As AcSmSheet Set mySheet = mSheetID.GetPersistObject Set GetSheet = mySheet Set mySheet = Nothing Else ReportError End If End Function

Page 15: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

15 | P a g e

Private Function GetSheetIndex() As Long Dim mySheet As AcSmSheet Set mySheet = GetSheet Dim myProps As AcSmCustomPropertyBag Set myProps = mySheet.GetCustomPropertyBag On Error Resume Next Dim myProp As IAcSmCustomPropertyValue Set myProp = myProps.GetProperty(ssmSheetIndex) GetSheetIndex = CLng(myProp.GetValue) Set myProp = Nothing Set myProps = Nothing Set mySheet = Nothing End Function

Private Function SetCustomProperty(Name As String, Value As String) As AcSmCustomPropertyValue Dim mySheet As AcSmSheet Set mySheet = GetSheet Dim myProp As AcSmCustomPropertyValue Set myProp = New AcSmCustomPropertyValue myProp.InitNew mySheet Dim myDb As AcSmDatabase Set myDb = mySheet.GetDatabase If ssmUtils.LockDb(myDb) = AcSmLockStatus_Locked_Local Then myProp.SetFlags CUSTOM_SHEET_PROP myProp.SetValue Value mySheet.GetCustomPropertyBag.SetProperty Name, myProp ssmUtils.UnlockDb myDb, True Set SetCustomProperty = myProp Set myProp = Nothing Else ssmUtils.Alert "Unable to obtain permission to write to the sheet set.", , "Alert" End If Set mySheet = Nothing Set myDb = Nothing End Function

Private Sub ReportError() Err.Raise vbObjectError + 401, "rrbiSheet Class", "Sheet object not set." End Sub

Private Sub Class_Terminate() Set mSheetID = Nothing End Sub

rrbiSheetSet Option Explicit Private mDb As AcSmDatabase Private mSSetID As IAcSmObjectId Private mProps As Scripting.Dictionary Private mSheets As Scripting.Dictionary Private mSheetCount As Long Private mStartNum As Long Private mTotalCount As Long Private Const ssmStartNum = "Sheet Index Start Number" Private Const ssmTotalCount = "Set Total Number"

Property Get Db() As AcSmDatabase Set Db = mDb End Property

Page 16: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

16 | P a g e

Property Set Db(ByVal pObject As AcSmDatabase) Set mDb = pObject Dim mySSet As AcSmSheetSet Set mySSet = mDb.GetSheetSet Set mSSetID = mySSet.GetObjectId GetSheetSetCustomProperties Call GetAllSheets(mSheets, mySSet.GetSheetEnumerator, "") mSheetCount = GetSheetCount(mSheets) Set mySSet = Nothing End Property

Property Get Description() As String Dim mySSet As IAcSmComponent Set mySSet = mSSetID.GetPersistObject Description = mySSet.GetDesc Set mySSet = Nothing End Property

Property Get Filename() As String Filename = mDb.GetFilename End Property

Property Get Name() As String Dim mySSet As IAcSmComponent Set mySSet = mSSetID.GetPersistObject Name = mySSet.GetName Set mySSet = Nothing End Property

Property Get SheetCount() As Long SheetCount = mSheetCount End Property

Property Get SheetStartNumber() As Long SheetStartNumber = mStartNum End Property

Property Let SheetStartNumber(Number As Long) If Number + mSheetCount - 1 > mTotalCount Then mStartNum = Number mTotalCount = mStartNum + mSheetCount - 1 ssmUtils.Alert "The starting number and your sheet count is greater than" & vbCrLf & _ "the assigned total sheet count." & vbCrLf & _ "The total sheet count has been adjusted to " & _ CStr(mTotalCount) & ".", vbInformation, "Invalid Total Sheet Count" SetCustomProperty ssmTotalCount, CStr(mTotalCount) ElseIf Number > 0 Then mStartNum = Number Else mStartNum = 1 ssmUtils.Alert "The starting number for your sheets must be greater than 0." & vbCrLf & _ "The number has been set to 1.", vbInformation, "Invalid Start Number" End If SetCustomProperty ssmStartNum, CStr(mStartNum) Reindex mSheets End Property

Property Get TotalSheetCount() As Long TotalSheetCount = mTotalCount End Property

Page 17: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

17 | P a g e

Property Let TotalSheetCount(Number As Long) If mSheetCount + mStartNum - 1 > Number Then mTotalCount = mSheetCount + mStartNum - 1 ssmUtils.Alert "The starting number and your sheet count is greater than" & vbCrLf & _ "the assigned total sheet count." & vbCrLf & _ "The total sheet count has been adjusted to " & _ CStr(mTotalCount) & ".", vbInformation, "Invalid Total Sheet Count" SetCustomProperty ssmTotalCount, CStr(mTotalCount) ElseIf Number > 0 Then mTotalCount = Number Else mTotalCount = 1 ssmUtils.Alert "The total number of sheets for the entire project must be" & _ " greater than 0." & vbCrLf & _ "The number has been set to 1.", vbInformation, "Invalid Total Number" End If SetCustomProperty ssmTotalCount, CStr(mTotalCount) End Property

Public Function GetCustomProperties() As Scripting.Dictionary Set GetCustomProperties = mProps End Function

Public Function GetSheets() As Scripting.Dictionary Set GetSheets = mSheets End Function

Private Function GetSheetCount(ByVal pSheets As Scripting.Dictionary) As Long With pSheets Dim i As Long For i = 0 To UBound(.Keys) Dim mySheet As rrbiSheet Set mySheet = .Item(.Keys(i)) Dim res As Long If Not (mySheet.DoNotPlot) Then res = res + 1 Next i End With GetSheetCount = res End Function

Private Sub GetAllSheets(ByRef pSheets As Scripting.Dictionary, _ ByVal pGetNext As IAcSmEnumComponent, _ Name As String, Optional Index As Long) Dim myItem As IAcSmComponent Set myItem = pGetNext.Next Do Until myItem Is Nothing If myItem.GetTypeName = "AcSmSubset" Then Dim aSubset As AcSmSubset Set aSubset = myItem Call GetAllSheets(pSheets, aSubset.GetSheetEnumerator, aSubset.GetName, Index) Set aSubset = Nothing ElseIf myItem.GetTypeName = "AcSmSheet" Then Dim aSheet As rrbiSheet Set aSheet = New rrbiSheet Set aSheet.SheetID = myItem.GetObjectId aSheet.Subset = Name If Not (aSheet.DoNotPlot) Then Index = Index + 1 aSheet.SheetIndex = Index + mStartNum Else aSheet.SheetIndex = 0 End If pSheets.Add aSheet.SheetName, aSheet End If Set myItem = Nothing Set myItem = pGetNext.Next Loop Set myItem = Nothing End Sub

Page 18: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

18 | P a g e

Private Sub GetSheetSetCustomProperties() Dim mySSet As IAcSmComponent Set mySSet = mSSetID.GetPersistObject Dim allProps As AcSmCustomPropertyBag Set allProps = mySSet.GetCustomPropertyBag Dim getNext As IAcSmEnumProperty Set getNext = allProps.GetPropertyEnumerator Dim aName As String Dim aVal As AcSmCustomPropertyValue getNext.Next aName, aVal Set mProps = New Scripting.Dictionary Do Until aName = "" mProps.Add aName, aVal.GetValue getNext.Next aName, aVal Loop Dim myProp As AcSmCustomPropertyValue If Not (mProps.Exists(ssmStartNum)) Then Set myProp = SetCustomProperty(ssmStartNum, "0") If Not (myProp Is Nothing) Then mProps.Add ssmStartNum, myProp.GetValue Set myProp = Nothing Else mStartNum = CLng(mProps.Item(ssmStartNum)) End If If Not (mProps.Exists(ssmTotalCount)) Then Set myProp = SetCustomProperty(ssmTotalCount, "0") If Not (myProp Is Nothing) Then mProps.Add ssmTotalCount, myProp.GetValue Set myProp = Nothing Else mTotalCount = CLng(mProps.Item(ssmTotalCount)) End If Set getNext = Nothing Set allProps = Nothing Set mySSet = Nothing End Sub

Private Sub Reindex(pSheets As Scripting.Dictionary) Dim myKeys As Variant myKeys = pSheets.Keys Dim myItems As Variant myItems = pSheets.Items Dim i As Long For i = 0 To pSheets.Count - 1 Dim aSheet As rrbiSheet Set aSheet = myItems(i) If Not (aSheet.DoNotPlot) Then Dim myIndex As Long myIndex = myIndex + 1 aSheet.SheetIndex = myIndex + mStartNum - 1 Else aSheet.SheetIndex = 0 End If Set aSheet = Nothing Next i End Sub

Page 19: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

19 | P a g e

Private Function SetCustomProperty(Name As String, Value As String) As AcSmCustomPropertyValue Dim myProp As AcSmCustomPropertyValue Set myProp = New AcSmCustomPropertyValue Dim mySSet As AcSmSheetSet Set mySSet = mSSetID.GetPersistObject myProp.InitNew mySSet If ssmUtils.LockDb(mDb) = AcSmLockStatus_Locked_Local Then myProp.SetFlags CUSTOM_SHEETSET_PROP myProp.SetValue Value mySSet.GetCustomPropertyBag.SetProperty Name, myProp ssmUtils.UnlockDb mDb, True Set SetCustomProperty = myProp Set myProp = Nothing Set mySSet = Nothing Else ssmUtils.Alert "Unable to obtain permission to write to the sheet set.", , "Alert" End If End Function

Private Sub Class_Initialize() Set mSheets = New Scripting.Dictionary End Sub

Private Sub Class_Terminate() Set mSheets = Nothing Set mProps = Nothing Set mSSetID = Nothing Set mDb = Nothing End Sub

rrbiSheetSetDatabase Option Explicit Private mDb As AcSmDatabase Private mSSet As rrbiSheetSet

Property Get Db() As AcSmDatabase If Not (mDb Is Nothing) Then Set Db = mDb Else Err.Raise vbObjectError + 201, _ "rrbiSheetSetDatabase Class", _ "Sheet Set database is not loaded." End If End Property

Property Set Db(ByVal pObject As AcSmDatabase) Set mDb = pObject Set mSSet = New rrbiSheetSet Set mSSet.Db = mDb End Property

Property Get Filename() As String Filename = mDb.GetFilename End Property

Property Get Name() As String Name = mSSet.Name End Property

Property Get ReadOnly() As Boolean ReadOnly = (mDb.GetLockStatus = AcSmLockStatus_Locked_ReadOnly) End Property

Public Function GetSheetSet() As rrbiSheetSet Set GetSheetSet = mSSet End Function

Page 20: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

20 | P a g e

Private Sub Class_Terminate() ssmUtils.UnlockDb mDb Set mDb = Nothing End Sub

rrbiSheetSetDatabases Option Explicit Private mSSM As AcSmSheetSetMgr Private mDbs As Collection

Property Get Count() As Long Count = mDbs.Count End Property

Property Get Item(Filename As String) As rrbiSheetSetDatabase On Error Resume Next Set Item = mDbs.Item(Filename) If Err.Number <> 0 Then Err.Raise vbObjectError + 101, _ "rrbiSheetSetDatabases Class", _ "Item not found." End If End Property

Private Sub Class_Initialize() Set mSSM = New AcSmSheetSetMgr Dim getNext As IAcSmEnumDatabase Set getNext = mSSM.GetDatabaseEnumerator Dim aItem As AcSmDatabase Set aItem = getNext.Next Set mDbs = New Collection Do Until aItem Is Nothing Dim myDb As rrbiSheetSetDatabase Set myDb = New rrbiSheetSetDatabase Set myDb.Db = aItem mDbs.Add myDb, myDb.Filename Set aItem = Nothing Set aItem = getNext.Next Loop Set getNext = Nothing End Sub

Private Sub Class_Terminate() Set mDbs = Nothing Set mSSM = Nothing End Sub

rrbiLayout Option Explicit Private mLayout As AcadLayout Private mSubset As String Private mSheetNumber As String Private mSheetTitle As String Private mFilename As String

Property Get Filename() As String Filename = mFilename End Property

Page 21: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

21 | P a g e

Property Set Layout(pLayout As AcadLayout) Set mLayout = pLayout mFilename = GetFilename If mFilename <> "" Then Dim setLayer As rrbiSetLayer0 Set setLayer = New rrbiSetLayer0 Dim pt0(0 To 2) As Double Dim myField As AcadMText Set myField = mLayout.Block.AddMText(pt0, 0#, "%<\AcSm Subset.Name>%") mSubset = myField.TextString myField.Delete If mSubset = "####" Then mSubset = "" Set myField = mLayout.Block.AddMText(pt0, 0#, "%<\AcSm Sheet.Number>%") mSheetNumber = myField.TextString myField.Delete If mSheetNumber = "####" Or mSheetNumber = "----" Then mSheetNumber = "" Set myField = mLayout.Block.AddMText(pt0, 0#, "%<\AcSm Sheet.Title>%") mSheetTitle = myField.TextString myField.Delete If mSheetTitle = "####" Or mSheetTitle = "----" Then mSheetTitle = "" End If End Property

Property Get Layout() As AcadLayout Set Layout = mLayout End Property

Property Get LayoutName() As String LayoutName = mLayout.Name End Property

Property Get SheetName() As String SheetName = mSubset & IIf(mSubset = "", "", "-> ") & _ mSheetNumber & " - " & mSheetTitle End Property

Property Get SheetNumber() As String SheetNumber = mSheetNumber End Property

Property Get SheetTitle() As String SheetTitle = mSheetTitle End Property

Property Get Subset() As String Subset = mSubset End Property

Private Function GetFilename() As String On Error Resume Next Dim myDict As AcadDictionary Set myDict = ThisDrawing.Dictionaries.Item("AcSheetSetData") Dim myXRec As AcadXRecord Set myXRec = myDict.Item("ShSetFileName") Dim xrType, xrData myXRec.GetXRecordData xrType, xrData GetFilename = xrData(0) Set myXRec = Nothing Set myDict = Nothing End Function

Page 22: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

22 | P a g e

Private Sub Class_Terminate() Set mLayout = Nothing End Sub

rrbiSetLayer0 Option Explicit Private mLayer As AcadLayer

Private Sub Class_Initialize() With ThisDrawing Set mLayer = .ActiveLayer Dim nLayer As AcadLayer Set nLayer = .Layers.Item("0") nLayer.Lock = False On Error Resume Next nLayer.Freeze = False On Error GoTo 0 .ActiveLayer = nLayer End With End Sub

Private Sub Class_Terminate() ThisDrawing.ActiveLayer = mLayer Set mLayer = Nothing End Sub

ProjectIndex Option Explicit Private mSSM As rrbiSheetSetDatabases Private mSSetDb As rrbiSheetSetDatabase Private mSSet As rrbiSheetSet Private mExcel As Excel.Application Private mLayouts As Collection Private mFilename As String Private Const IndexTab As String = "Current Submittal" Private Const CheckCol As String = "A:A" Private Const chkCol = 1 Private Const SheetNumberCol As String = "B:B" Private Const shtNumCol = 2 Private Const shtNameCol = 3 Private Const fileCol = 4 Private Const verifyCol As Long = 5 Private Const CheckFont = "Wingdings 2" Private Const CheckSize = 10 Private Const CheckHdr = "A3" Private Const TitleCell As String = "B1" Private Const TitleFont = "Arial Black" Private Const TitleSize = 14 Private Const DescCell As String = "B2" Private Const DataFont = "Arial Narrow" Private Const DataSize = 10 Private Const HdrCells As String = "B3:D3" Private Const dataRowStart As Long = 4 Private Const markOK = "™" Private Const markNoPlot = "W" Private Const markDuplicate = "N" Private Const markNotFound = "Ò" Private Const markCheck = "P"

Property Get Filename() As String Filename = mFilename End Property

Page 23: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

23 | P a g e

Public Sub VerifySheets() If Not (mSSet Is Nothing) Then Dim myFSO As FileSystemObject Set myFSO = New FileSystemObject If Not (myFSO.FileExists(mFilename)) Then InitProjIndex If myFSO.FileExists(mFilename) Then MarkExcelSheet Set myFSO = Nothing Else ssmUtils.Alert "There is no sheet set associated with the current drawing.", , "Alert" End If End Sub

Public Sub WriteTabs() If Not (mSSet Is Nothing) And mLayouts.Count > 0 Then Dim aLayout As AcadLayout For Each aLayout In ThisDrawing.Layouts If Not (aLayout.ModelType) Then Dim myLayoutData As rrbiLayout Set myLayoutData = mLayouts.Item(aLayout.Name) Dim shtNum As String shtNum = myLayoutData.SheetNumber If aLayout.Name <> shtNum And shtNum <> "" Then RenameTab aLayout, myLayoutData End If Next aLayout Dim myFSO As FileSystemObject Set myFSO = New FileSystemObject If Not (myFSO.FileExists(mFilename)) Then InitProjIndex If myFSO.FileExists(mFilename) Then RecordTabs Set myFSO = Nothing ElseIf mLayouts.Count = 0 Then ssmUtils.Alert Prompt:="The sheet set associated with the current drawing is not " & _ mSSet.Filename & ", " & vbCrLf & "which is the requested sheet set.", _ Title:="Alert" Else ssmUtils.Alert "There is no sheet set associated with the current drawing.", , "Alert" End If End Sub

Private Sub FitColumns(ByVal thisSheet As Excel.Worksheet) Dim myRange As Excel.Range Set myRange = thisSheet.UsedRange Dim nRows As Long nRows = myRange.Rows.Count Set myRange = thisSheet.Range(CStr(dataRowStart - 1) & ":" & CStr(nRows)) myRange.Columns.AutoFit Set myRange = Nothing End Sub

Private Function GetExcel() As Excel.Application If IsExcelRunning Then Set GetExcel = GetObject(, "Excel.Application") Else Set GetExcel = CreateObject("Excel.Application") End If End Function

Page 24: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

24 | P a g e

Private Function GetExcelSheet(pSheets As Excel.Sheets, Name As String) As Excel.Worksheet On Error Resume Next Dim testSheet As Excel.Worksheet Set testSheet = pSheets.Item(Name) If Err.Number = 0 Then Set GetExcelSheet = testSheet Else ssmUtils.Alert "The required Excel worksheet """ & _ Name & _ """ cannot be found." & vbCrLf & _ "A blank sheet of that name has been created." & vbCrLf & _ "The formatting will need to be corrected.", _ vbInformation, _ "Excel" Set testSheet = pSheets.Add testSheet.Name = Name GetExcelSheet = testSheet Err.Clear End If End Function

Private Function GetLayouts() As Collection Dim myLayouts As Collection Set myLayouts = New Collection Dim aLayout As AcadLayout For Each aLayout In ThisDrawing.Layouts If Not (aLayout.ModelType) Then Dim myLayout As rrbiLayout Set myLayout = New rrbiLayout Set myLayout.Layout = aLayout If myLayout.Filename = mSSet.Filename Then myLayouts.Add myLayout, myLayout.LayoutName End If Next aLayout Set GetLayouts = myLayouts Set myLayouts = Nothing End Function

Private Function GetSheetMark(pRange As Excel.Range, _ Filename As String, _ DoNotPlot As Boolean) As String If pRange.Columns(fileCol).Value <> Filename Then GetSheetMark = markDuplicate ElseIf DoNotPlot Then GetSheetMark = markNoPlot Else GetSheetMark = markOK End If End Function

Private Function GetWorkbook() As Excel.Workbook Dim found As Boolean Dim i As Long For i = 1 To mExcel.Workbooks.Count Dim testWB As Excel.Workbook Set testWB = mExcel.Workbooks.Item(i) found = (testWB.FullName = mFilename) If found Then Exit For Next i If found Then Set GetWorkbook = testWB Else Set GetWorkbook = mExcel.Workbooks.Open(Filename:=mFilename, AddToMru:=True) End If End Function

Page 25: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

25 | P a g e

Private Sub InitProjIndex() mExcel.ScreenUpdating = False Dim myWB As Excel.Workbook Set myWB = mExcel.Workbooks.Add Dim myXLSheet As Excel.Worksheet Dim myRange As Excel.Range Set myXLSheet = myWB.Sheets.Item(1) myXLSheet.Name = IndexTab Set myRange = myXLSheet.Range("A:IV") myRange.Font.Name = DataFont myRange.Font.Size = DataSize Set myRange = myXLSheet.Range(TitleCell) myRange.Value = mSSet.Name myRange.Font.Name = TitleFont myRange.Font.Size = TitleSize Set myRange = myXLSheet.Range(DescCell) myRange.Value = mSSet.Description Set myRange = myXLSheet.Range(CheckCol) myRange.Font.Name = CheckFont myRange.Font.Size = CheckSize Set myRange = myXLSheet.Range(CheckHdr) myRange.Value = markCheck Set myRange = myXLSheet.Range(HdrCells) myRange.Borders(xlEdgeBottom).LineStyle = xlContinuous myRange.Range("A1").Value = "Sheet #" myRange.Range("B1").Value = "Sheet Title" myRange.Range("C1").Value = "Filename" Dim i As Long For i = myWB.Sheets.Count To 1 Step -1 If i > 1 Then myWB.Sheets(i).Delete Next i myWB.Close True, mFilename Set myRange = Nothing Set myXLSheet = Nothing Set myWB = Nothing End Sub

Private Function IsExcelRunning() As Boolean Dim myExcel As Excel.Application On Error Resume Next Set myExcel = GetObject(, "Excel.Application") IsExcelRunning = (Err.Number = 0) Set myExcel = Nothing Err.Clear End Function

Private Sub MarkExcelSheet() Dim mySheets As Scripting.Dictionary Set mySheets = mSSet.GetSheets mExcel.ScreenUpdating = False Dim myWB As Excel.Workbook Set myWB = GetWorkbook If Not myWB.ReadOnly Then ThisDrawing.Utility.Prompt vbCrLf & "Verifying current Project Index... " Dim myXLSheet As Excel.Worksheet Set myXLSheet = GetExcelSheet(myWB.Sheets, IndexTab)

Page 26: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

26 | P a g e

Dim iSSM As Long For iSSM = 0 To mySheets.Count - 1 Dim sNumber As String sNumber = mySheets.Items(iSSM).SheetNumber Dim myRange As Excel.Range Set myRange = myXLSheet.Range(SheetNumberCol) Set myRange = myRange.Find(What:=sNumber, _ SearchOrder:=xlByColumns, _ LookIn:=xlValues, _ LookAt:=xlWhole) If Not myRange Is Nothing Then Set myRange = myXLSheet.Range(myRange.Row & ":" & myRange.Row) With myRange .Columns(chkCol).Value = GetSheetMark(myRange, _ mySheets.Items(iSSM).Filename, _ mySheets.Items(iSSM).DoNotPlot) .Columns(verifyCol).Value = "checked" End With Else Set myRange = myXLSheet.Rows(iSSM + dataRowStart) If myRange.Columns(shtNumCol).Value <> "" Then myRange.Insert (xlShiftDown) Set myRange = myXLSheet.Rows(iSSM + dataRowStart) End If With myRange .Columns(shtNumCol).Value = sNumber .Columns(shtNameCol).Value = mySheets.Items(iSSM).SheetTitle .Columns(fileCol).Value = mySheets.Items(iSSM).Filename .Columns(chkCol).Value = GetSheetMark(myRange, _ mySheets.Items(iSSM).Filename, _ mySheets.Items(iSSM).DoNotPlot) .Columns(verifyCol).Value = "checked" End With End If Next iSSM Set myRange = myXLSheet.UsedRange Dim i As Long For i = dataRowStart To myRange.Rows.Count If myRange.Cells(i, verifyCol).Value = "checked" Then myRange.Cells(i, verifyCol).Value = "" Else myRange.Cells(i, chkCol).Value = markNotFound End If Next i With myWB FitColumns GetExcelSheet(.Sheets, IndexTab) .Close True End With ThisDrawing.Utility.Prompt "done." & vbCrLf Else ssmUtils.Alert "Unable to open the Project Index." myWB.Close False End If mExcel.ScreenUpdating = True Set myRange = Nothing Set myXLSheet = Nothing Set myWB = Nothing End Sub

Private Sub RecordTabs() Dim mySheets As Scripting.Dictionary Set mySheets = mSSet.GetSheets mExcel.ScreenUpdating = False Dim myWB As Excel.Workbook Set myWB = GetWorkbook

Page 27: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

27 | P a g e

If Not myWB.ReadOnly Then ThisDrawing.Utility.Prompt vbCrLf & "Processing current Project Index... " Dim myXLSheet As Excel.Worksheet Set myXLSheet = GetExcelSheet(myWB.Sheets, IndexTab) Dim i As Long For i = 1 To mLayouts.Count Dim aLayout As rrbiLayout Set aLayout = mLayouts.Item(i) Dim lNumber As String lNumber = aLayout.SheetNumber Dim iSSM As Long For iSSM = 0 To mySheets.Count - 1 Dim sNumber As String sNumber = mySheets.Items(iSSM).SheetNumber If UCase(sNumber) = UCase(lNumber) Then Dim myRange As Excel.Range Set myRange = myXLSheet.Range(SheetNumberCol).Find(What:=sNumber, _ SearchOrder:=xlByColumns, _ LookIn:=xlValues, _ LookAt:=xlWhole) If Not (myRange Is Nothing) Then Set myRange = myXLSheet.Range(myRange.Row & ":" & myRange.Row) With myRange .Columns(chkCol).Value = GetSheetMark(myRange, _ mySheets.Items(iSSM).Filename, _ mySheets.Items(iSSM).DoNotPlot) .Columns(shtNumCol).Value = lNumber .Columns(shtNameCol).Value = aLayout.SheetTitle .Columns(fileCol).Value = mySheets.Items(iSSM).Filename End With Else Set myRange = myXLSheet.Rows(iSSM + dataRowStart) If myRange.Columns(shtNumCol).Value <> "" Then myRange.Insert (xlShiftDown) Set myRange = myXLSheet.Rows(iSSM + dataRowStart) End If With myRange .Columns(chkCol).Value = markOK .Columns(shtNumCol).Value = lNumber .Columns(shtNameCol).Value = aLayout.SheetTitle .Columns(fileCol).Value = mySheets.Items(iSSM).Filename End With End If ThisDrawing.Utility.Prompt vbCrLf & "Recorded sheet " & lNumber & ", " Exit For End If Next iSSM Next i With myWB FitColumns GetExcelSheet(.Sheets, IndexTab) .Close True End With ThisDrawing.Utility.Prompt "done." & vbCrLf Else ssmUtils.Alert "Unable to open the Project Index." myWB.Close False End If mExcel.ScreenUpdating = True Set aLayout = Nothing Set mySheets = Nothing Set myRange = Nothing Set myXLSheet = Nothing Set myWB = Nothing End Sub

Page 28: Filling the Gaps in the Sheet Set Manager - Autodesk · PDF fileFilling the Gaps in the Sheet Set Manager ... Adding the database layer to the Sheet Set Manager permits locking

Filling the Gaps in the Sheet Set Manager

28 | P a g e

Private Sub RenameTab(pLayout As AcadLayout, pLayoutData As rrbiLayout) Dim newName As String newName = pLayoutData.SheetNumber On Error GoTo FailedRename pLayout.Name = newName On Error GoTo 0 Dim mySheets As Scripting.Dictionary Set mySheets = mSSet.GetSheets Dim mySheet As rrbiSheet Set mySheet = mySheets.Item(pLayoutData.SheetName) Dim ssmSheet As AcSmSheet Set ssmSheet = mySheet.SheetID.GetPersistObject Dim ssmLayout As IAcSmNamedAcDbObjectReference Set ssmLayout = ssmSheet.GetLayout If ssmLayout.GetFilename = ThisDrawing.FullName Then If ssmUtils.LockDb(mSSetDb.Db) = AcSmLockStatus_Locked_Local Then ssmLayout.InitNew ssmSheet ssmLayout.SetName newName ssmLayout.SetFileName ThisDrawing.FullName ssmUtils.UnlockDb mSSetDb.Db, True Else ssmUtils.Alert "Unable to obtain permission to write to the sheet set.", , "Alert" End If End If Exit Sub FailedRename: ssmUtils.Alert "Unable to rename layout " & pLayout.Name & " to " & newName & "." Resume Next End Sub

Dim cSSetName As String cSSetName = ThisDrawing.GetVariable("SSFound") If cSSetName <> "" Then Set mSSM = New rrbiSheetSetDatabases Set mSSetDb = mSSM.Item(cSSetName) Set mSSet = mSSetDb.GetSheetSet Set mLayouts = GetLayouts Set mExcel = GetExcel mFilename = Replace(Expression:=mSSet.Filename, _ Find:=".dst", _ Replace:=".xlsx", _ Compare:=vbTextCompare) If mExcel Is Nothing Then Err.Raise vbObjectError + 701, _ "ProjectIndex", _ "Microsoft Office Excel could not be loaded." End If End If End Sub

Private Sub Class_Terminate() If Not (mExcel Is Nothing) Then mExcel.ScreenUpdating = True If mExcel.Workbooks.Count = 0 Then mExcel.Quit Set mExcel = Nothing End If Set mLayouts = Nothing Set mSSet = Nothing Set mSSetDb = Nothing Set mSSM = Nothing End Sub