Archive for December 2007

Terminating Dependent Classes

disco chick
I have four objects that are all dependent on each other. They are CInvoice has many CInvoiceLines, CInvoiceLine has many CRoyaltyLines, CRoyaltyLine has many CRoyaltyAdjustments. In order to properly terminate all of these class modules, I need to remove any and all dependencies. If I don't, the classes will stay alive and consume memory. With four levels like this eating memory, I will eventually have to answer the question: Do I want to send an error report?

I think I have my termination sequences right, but I'll let you be the judge in the comments. I start in the CInvoice class, which I'll call a Parent class. It has many children, including the CInvoiceLines class (a child collection) and each individual CInvoiceLine class (a child class). The CInvoiceLine class then becomes a parent class for my next round of terminations. His children are the CRoyaltyLines class and each instance of the CRoyaltyLine class.

All of my Terminate events are structured like

Public Sub Terminate()
 
End Sub

I don't use the built-in class terminate event because it doesn't fire at the right time. When I'm in a parent class, I do these three things:

  1. Call the Terminate method of the Child Collection Class
  2. Set the local Child Collection Class variable to Nothing
  3. Set the local Parent variable to Nothing

Items 1 and 2 are done in a parent class that is not also a child class. Item 3 is done in a child class that is not also a parent class. All three items are done in a class that is both a parent and a child. For instance, CInoviceLine is a parent with respect to CRoyaltyLines, but a child with respect to CInvoice, so all three steps must occur.

When I'm in a Child Collection Class (ex: CInvoiceLines), I do these three things:

  1. Call the Terminate method for each member of the collection
  2. Set the local Parent variable to Nothing
  3. Set the local Collection variable to Nothing

When item 1 is executed, it may be terminating a class that's a parent class and the whole things starts over again. Here's an example: In the CInvoice class

Public Sub Terminate()
   
    mobjLines.Terminate  'Term the child collection class
    Set mobjLines = Nothing 'term the local ccc variable
 
End Sub

Since mobjLines is a CInvoiceLines object, that Terminate method gets called first. In the CInvoiceLines class

Public Sub Terminate()
   
    Dim i As Long
   
    'Terminate each member
    For i = 1 To mcolLines.Count
        mcolLines.Item(i).Terminate
    Next i
       
    Set mobjParent = Nothing 'kill the parent variable
    Set mcolLines = Nothing 'kill the collection variable
   
End Sub

When mcolLines.Item(i).Terminate is called, it's calling the Terminate method of a class that's both a child and a parent. In CInvoiceLine

Public Sub Terminate()
   
    mobjRoyaltyLines.Terminate 'Term the child collection class
    Set mobjParent = Nothing    'kill the parent variable
    Set mobjRoyaltyLines = Nothing   'kill the ccc variable
   
End Sub

The only difference between this and CInvoice is that I killed the parent variable because it's also a child class. I won't go through the rest, except to show you the last class, CRoyaltyAdjustment

Public Sub Terminate()
   
    Set mobjParent = Nothing
   
End Sub

Since this is a child class, but not a parent class, only killing the local parent variable is necessary.

Boy, there's nothing more thrilling than terminating classes, is there? That's why I added the image - to spice it up a little. For a little background, I'm abstracting my relational database into objects in VBA. That way I can reference clsInvoice.Lines(1).RoyaltyLines(2).Adjustments(3).Amount, which I contend is easier to code and read. But the setup is a real pain.

Page update: Copy a range from closed workbooks (ADO)

Hi all

I update my ADO page today.
http://www.rondebruin.nl/ado.htm

The code is also working in Excel 2007 now (Excel 2000-2007).
I use Late binding now to avoid private mails like "It is not working"
When you use the Subfolder option in Example 7 it will loop through all files in all levels below the rootfolder.

If you have problems or suggestions let me know.

I wish all readers of this blog a Merry Christmas and a Super 2008.

Ron de Bruin
http://www.rondebruin.nl/tips.htm

Fixing Help

It seems to be universally understood that Help in Office products gets worse with every release. I'm still using 2003 almost exclusively, but I haven't heard anyone shouting from the roof tops about the improvements in 2007's Help. I've been thinking about help in general and what makes a good help system.

Leaders in the Field

Who has good help? I'm struggling to name an application that has truly useful help. I use the suite of Office apps, Quickbooks, Agent, Foxit, ACT!, AssetKeeper, irfanView, jetAudio, Firefox, PDFCreator, SnagIt, and others. I can't hold any of them up as a shining example of how to do it. Maybe the program that is the most intuitive wins because you aren't forced to look at help. Maybe help doesn't really matter because I obviously use a lot of apps with crappy help systems.

One of the things I look for in a new program is community. I want to know who is posting questions in the wild and how frequently. If you want to evaluate a new product, don't read the testimonials on the company's website, see if they have an active community. In most cases, you don't even need to care what people are saying. If there's an active community, it's generally a positive. At best it means that a lot of people have chosen the software. At worst, it means that the software was thrust unwanted on a lot of people, but those people are still using it and creating workarounds and such.

Does that mean that I shouldn't complain about help? Should I just accept that help will always be crappy? Should I accept that the only real help I'll ever get is in user-to-user situations?

Delivery

There are two main aspects to help; delivery and content. Back in the old days, I would press F1 and a new window would appears. It would have a table of contents, and index, and a window with some content in it. I would read the content, and switch back to Excel to implement my new found knowledge. At some point in the last 10 years, a user told Microsoft that they didn't like switching back and forth between help and the app. They couldn't see the example in help while they were typing in Excel. So MS made the help window float on top of the app. Eventually it ended up in the Task Pane. Boy do I miss the table of contents. Now it seems that you have to know at least part of the answer so you can search for the right thing.

The modal help window has its merits. And the made up story about its genesis is logical. As for help that phones home, I have no logical story. What user said "I don't like when my help is out of date."? I'm sure people complained of errors in the help file and MS decided to move the content to the web so they could fix errors quickly. But how big of a problem was that really? I was perfectly happy with offline help and I wouldn't mind seeing it come back.

Then there's the unwanted help situation. Have you ever entered a circular reference in Excel? If you haven't, you get an error message which you are required to clear. Once cleared, you get a help window, which you are required to close. Oh, you may read that help window the first time you do it, but you certainly aren't reading it more than once. This has to be the worst help delivery system in human history. Unless the idea is to train me not to enter circular references because the consequences are so painful. If that's the case, then its the best system.

Here's what I want in a help system. I want to press F1 and get a small form.

If I'm in a cell editing, put the worksheet function name I'm working on in the text box. Allow me to browse the contents and index. Show me decent search results when I search, and always allow me to go to the contents or index pages. I don't need to see articles from MSDN. If I have an internet connection, I'll use it with my browser. I want fast, fast, fast. I don't want it to take the same amount of time to open help as it did Excel - especially if I hit F1 on accident and I'm going to cancel.

Content

I've probably ranted enough for one day, but there's this other side of help called content. There is no excuse for a poor delivery system, but can the same be said about content? In some cases, yes. We've all seen those help systems that list the menu choices. Those are horrible. I was reading the instructions for my new remote (I got a new LCD TV for Christmas). It had entries like: To adjust the Brightness, select Brightness from the menu and use the Channel Up and Channel Down keys. Oh really? That's how you adjust the brightness? What it doesn't tell me is what to set the brightness to, what the heck brightness is, and why I would want to be adjusting it in the first place.

That's an example of how bad it can be, and Excel help is a step up. Excel help gives you the syntax (that's important) and sometimes a nice explanation of the arguments, and usually the worst example possible. Outside of reminding myself what the syntax is, I'm usually better off searching the internet for real life examples that reading the help. I find it kind of difficult to bash the help writers too much, because I don't think I'd do a better job. Writing help has to be really difficult. The best advice I can give help writers is to ask "why" after you ask "how". Understand why the user is looking at this help page.

What are the characteristics of a good help system? Do you have examples of apps that have great help? Leave a comment.

Google Toolbar Slows Excel

This report comes from Charles Williams of DecisionModels.com fame. Charles knows a thing or two about performance in Excel.

For the last few weeks I have been trying to find out why clearing a large range of cells caused Excel to hang on some PCs but not on others. This does not happen with Excel 97, but does with Excel 2000, 2002, 2003 and 2007.

It turns out that its not just Clear, but also Delete or transferring data from a variant to a range, or even just selecting a large range of cells. The further down the sheet and to the right the slower it gets. And the more recent the Excel version the slower it gets.

Someone on the newsgroups discovered that, when using VBA, you could bypass this problem by switching off EnableEvents, and then someone else discovered that the culprit was Google Desktop Search.

The problem actually turns out to be the Google Desktop Office Com Addin. When you deactivate this you get a miraculous speedup.

With Excel 2007 it is fairly easy to deactivate:
Office Button-->Excel Options-->Addins-->Com Addins and deselect Google Desktop Office Addin

With earlier versions of Excel you have to customise a toolbar and add the Com Addins dialog to it.
View-->Toolbars-->Customise-->Commands tab-->Tools then about halfway down you will find Com Addins, select and drag to the toolbar of your choice.
Then you can uncheck Google Desktop Office addin.

If you have multiple versions of Excel installed you only have to do this once.

Presumably this COM addin sets up one or more application-level events to monitor things like Selection Change and Worksheet change and then tries to trap the change in order to index it.

If you want to measure this effect you can download a Variant Benchmark Timer from my website that allows you to run a read and write benchmark with and without EnableEvents.

DecisionModels.com/Downloads

This represents an interesting new twist in the Google-Microsoft wars!

Thanks Charles.

Catching Paste Operations

You know the situation: You have carefully setup a workbook with intricate Validation schemes. But then along comes your user and he copies and pastes at will. Result: Validation zapped, workbook structure violated.

What to do? The only way I find to be reliable is to catch all possible paste operations. But this isn't very easy, since there are a zilion ways to paste.

I have put together a sample workbook and an explanatory article on how one could go about protecting a workbook by intercepting paste operations.

Let me know what you think!!

Regards,

Jan Karel Pieterse
www.jkp-ads.com

Donut Selection

This one really hits home:

Click image for larger view.