I have an application that displays a list of “documents” for a particular product. Most of the documents are pdfs, but some are iso images for burning a CD. The display sheet shows each CD associated with the product, and for each CD the iso, the label that’s stuck to the CD, and the pdfs that should accompany it. The user selects the product, operating system, and version from comboboxes to display the appropriate documents.
Normally, the code for a combobox lives in the containing sheet’s class module (like Sheet1). However, good coding practice dictates that all of the VBA be in the add-in and not in the template. To accomplish this, I made a custom class module to house the three comboboxes and respond to their events. The class is named CSheetEvents and contains these variable declarations:
1 2 3 |
Private WithEvents mobjProductCombo As ComboBox Private WithEvents mobjSystemCombo As ComboBox Private WithEvents mobjVersionCombo As ComboBox |
The variables are private to the class module and I use Property Get and Property Set procedures to assign them. An example is:
1 2 3 4 5 6 7 8 9 10 11 |
Public Property Get ProductCombo() As ComboBox Set ProductCombo = mobjProductCombo End Property Public Property Set ProductCombo(objProductCombo As ComboBox) Set mobjProductCombo = objProductCombo End Property |
When the user selects the appropriate menu item, the code opens the template and assigns the three comboboxes. The relevant portion of that code is:
1 2 3 4 5 |
With Wb.Sheets(1).OLEObjects Set gclsSheet.ProductCombo = .Item(“cbxProduct”).Object Set gclsSheet.SystemCombo = .Item(“cbxSystem”).Object Set gclsSheet.VersionCombo = .Item(“cbxVersion”).Object End With |
The variable gclsSheet
is a global variable that holds an instance of the CSheetEvents so that it doesn’t go out of scope. With the comboboxes properly assigned inside the class, they will now respond to events. The change event of cbxProduct fills cbxSystem. The change event of cbxSystem fills cbxVersion. And the change event of cbxVersion lists the CDs and hyperlinks to all of the documents.
When the user has printed the documents, he closes the sheet. Since I’ve used a template, there is an unsaved document named AllCDConfigurations1 – a workbook created from the template AllCDConfiguration.xlt. I don’t want the user to be faced with a message to save this document, so I also included a workbook object in my class module. By defining a workbook variable with the WithEvents
keyword, I can capture the Before_Close
event and eliminate that save message.
1 2 3 4 5 6 7 8 9 10 11 12 |
Private Sub mobjWb_BeforeClose(Cancel As Boolean) On Error Resume Next Cancel = True Application.EnableEvents = False If Not EnableMenu(False) Then Err.Raise glHANDLED_ERROR mobjWb.Close False Application.EnableEvents = True Me.Terminate End Sub |
The Cancel = True
part stops the normal close operation and the mobjWb.Close False
part closes the workbook without saving changes.