Archive for September 2004

International Relations

It’s a shame that English doesn’t have any fun characters like ö or n. I always thought that Dick would be more interesting.

If you need to include some of these characters into your spreadsheet, you can accomplish it with the Alt key and the numeric keypad. First, you have to know it’s ASCII value. Here’s what I do when I need a character that’s not on my keyboard:

Char

Then I fill that formula down to row 255 and look for the character I need. The row number will give you the ASCII value. Sometimes I need to do that in a couple of different columns with different fonts to find what I need. Once I have the ASCII value, I can type

J Alt+0246 rg to get Jörg. The 0246 must be on the numeric keypad, not the numbers along the top of the keyboard.

You’re probably thinking that an ASCII table would be handy to have around instead of creating it every time you needed it. Well Jon Peltier thought so too, so he made one.

FUNCRES.XLA

Someone sent me an email asking what this add-in was, but my reply bounced, so I’m posting it here. This file is from the Analysis Toolpack (I mean Toolpak). It holds all the code for the ATP functions like NETWORKDAYS. If you see it in your Project Explorer in the VBE, but don’t want it there, you can uninstall the add-in using Tools > Addins

Atp

More MINIF Examples

I’ve discussed MAXIF and MINIF previously, but using MIN in an array formula can be tricky. Mike provided another example that I thought was worth sharing.

Moreminif

To find the MAX value for Los Angeles is pretty straight forward.

=MAX((A2:A6=”Los Angeles”)*(B2:B6))

For any entry in A2:A6 that is not Los Angeles, the array will contain zero so the MAX function automatically takes care of it.

The next part was the tricky part, or so it seemed. Find the MIN value for Los Angeles but only for non-zero values. For that, you need to wrap the whole array in an IF statement and convert any zeros into strings so they are ignored by the MIN function. What makes this less tricky is the fact that non-Los Angeles entries will be zero (and we want to ignore those) and zero entries will be zero (and we want to ignore those). So all the rows that we want to ignore are zero. Here’s the formula

=MIN(IF((A2:A6=”Los Angeles”)*(B2:B6)=0,”",B2:B6))

I really got twisted around on that one, but I suppose even the failures are useful. To use my failing effort, suppose that you want to find the MIN for Los Angeles but only for values that are greater than 5. Now it’s not true that all of the rows I want to ignore will be zero, so there’s one extra step involved.

=MIN(IF((A2:A6=”Los Angeles”)*(B2:B6>5)*(B2:B6)=0,”",B2:B6))

You can probably guess how I over-complicated the first MIN. Oh well, live and learn.

Classes: Creating Custom Objects

Classes are objects and objects are classes. Have you ever seen an error message like this:

“Cannot get the WorksheetFunction property of the Range class”

We call it the Range Object, but we could just as accurately call it the Range Class. Objects are nothing more than the properties, methods, and events they contain. A Range object is what it is because of its unique combination of properties, methods, and events (and because the name of the class is “Range”).

You may have seen how to use classes for Application Level Events, CommandbarButton events, or QueryTable events. You can also use classes to create your own custom objects. Some of the benefits of using class modules are

  • Encapsulation – a programming best practice, encapsulation allows you to keep related code in one place making debugging easier and leading to…
  • Portability – with an encapsulated class, you can move that class to another VBA project and use it there.
  • Ease of Programming – while coding the “business” end of an application, it’s easier to use a classes properties and methods than to code all that information yourself. Of course, setting up the class takes some time and resources too.
  • Self-Documentation – Properly named classes and their respective properties and methods aid in creating self documenting code.

Assume you want to create a card game in Excel. You can create a Card class which has certain properties and methods which you can then use to program your game. If later you want to create a different card game, you copy that class to another project and save yourself some setup time. Here’s a simple example of Card class:

Private mValue As String

Property Get Value() As String

    Value = mValue
   
End Property

Property Let Value(aValue As String)

    If aValue Like “1#[C,D,H,S]“ Then
        mValue = aValue
    ElseIf aValue Like “#[C,D,H,S]“ Then
        mValue = aValue
    Else
        Err.Raise Number:=vbObjectError + 513, _
            Source:=“MyCardGame.Card”, _
            Description:=“Value must in the form 1D, 2H, 10S, 13C”
    End If
   
End Property

Property Get Suit() As String

    Suit = Right(mValue, 1)
   
End Property

Property Get Number() As Long

    Number = Val(mValue)
   
End Property

The name of the class is Card and it has three properties, Value, Suit, and Number. Value is a read/write property and Suit and Number are both read-only. I start by defining a private variable called mValue. This will hold the Value property for this instance of the class. Then I define a series of Property Let/Get statements that allow the programmer access to that variable.

The Value property has both a Property Get and a Property Let procedure which is what makes it read/write. The Get procedure merely returns the mValue variable. The Let procedure assigns a value to the mValue variable, but also includes some error checking. If the programmer tries to assign a value to the Value property that is not in the proper format, and error is raised. The property format being a number 1-13 followed by a one-letter suit (Clubs, Diamonds, Hearts, Spades).

The Suit and Number properties only have Get procedures. The programmer cannot assign values to these properties, only read them. Both Get procedures use the mValue variable to retrieve the portion of the Value that the property calls for. For the Suit property, it returns the right most character – the one-letter alpha that is the suit. For the Number property, the Val() function is used to strip off the suit and only return the number.

You don’t need to provide the programmer with a Suit and Number property, but since the programmer will likely be you, you want to make life as easy as possible. If you create a poker game and want to determine if a poker hand is a flush, you can just use the Suit property.

Here’s some code that uses the new Card object.

Sub TestCard()

    Dim Crd As Card
   
    Set Crd = New Card
   
    ‘Nothing assigned to value
   Debug.Print Crd.Value, Crd.Suit, Crd.Number
   
    Crd.Value = “9S”
   
    Debug.Print Crd.Value, Crd.Suit, Crd.Number
   
    Crd.Value = “10D”
   
    Debug.Print Crd.Value, Crd.Suit, Crd.Number
   
End Sub

And the results:

Cardclass1

OfficeUpdate Gripe

Last week I had to apply SR-1a to my Excel installation. I’m sure I should have applied that release long ago, but I’m a procrastinator. If it doesn’t fix a problem that I currently have, I’m not too quick to get it.

The first gripe I had about updating office is that I had to find my CDs. Why do they make me do that? They can’t be verifying that I’m a paying customer, because if I stole the CDs, I would just use the stolen ones. Unless there’s something I don’t know about the process, I assume stolen CDs would work as well as legitimate ones.

And it’s not just one CD. My FrontPage installation is on separate CD than the rest of Office. So more CDs that I have to find. What a pain.

I updated, restarted, and it fixed the problem that I was having. Then I go into the VBE to test something. I wanted to see if using SendKeys with the escape key would solve this little ActiveX control problem. I don’t use SendKeys very often so I couldn’t remember if it was {ESC} or {ESCAPE} (it turns out it’s both). To find out, I put my cursor on SendKeys at hit F1. Would you like to guess what happened then? An installation dialog that eventually asked me to insert my FrontPage disk. Oh, you mean the disk that I just put away 1/2 hour ago, that disk? It took me 15 minutes to learn that both ways were syntactically correct.

I have two gripes with this: Why does Excel VBA help require anything that has to do with FrontPage? You might say it’s because Help is an office wide component, but it didn’t ask for my office disk, just the FrontPage disk. And why the hell didn’t it just install this part when I was installing the service release? I always do custom installs that include the VBA help, so it should have already been setup.

The result of this is that I will not be installing any more service releases unless I really need them. I’m probably throwing the baby out with bath water, but I don’t care. End of gripe.

Ask to Refresh

When you have external data in a workbook that is set to refresh when the file opens, you get a dialog warning you that queries can be harmful. In Excel 2000 in looks like this

Askrefresh1

If you check the box so that it doesn’t ask you again, getting that dialog box is a bit of a chore. Thankfully, Bill Manville told me the registry key that controls this behavior. I don’t really want to see this dialog, but I’ve seen a number of people ask about it over the last few years and it always bugged me that I didn’t know the answer. Thanks to Bill, I can sleep easy.

Askrefresh2

Change the QuerySecurity key to zero to get Excel to show that dialog again. The first time I tried this, it didn’t work for me using Excel 2000 SR-1. I applied SR-1a and it worked flawlessly after that. I’m really bad about using officeupdate. I did have a little problem after applying the update, but I’ll save that gripe for another post.

Splash Screen

A splash screen is that thing that appears when you start a program. It’s designed to distract you from how long it takes to load the program. It’s also used for a little advertising or to nag you to register the software.

Here’s a simple way to create a splash screen for your program (written in Excel 2000 or higher). First create a userform

Splash2

Then set the ShowModal property to False to show the form modelessly. When you show a form modeless, the code that shows it continues to execute while the form is showing.

Splash1

Finally, code your program’s initialization procedure. There’s code in this example that shows the form for at least five seconds in case the initialization procedure runs to quick. If you go through the trouble of showing a splash screen, you’ll want to make sure that it’s visible long enough for the user to see it. If you have a lot of initialization stuff, you may be able to ignore that part altogether.

Sub StartProgram()

    Dim dtDelay As Date
    
    dtDelay = Now
    
    ufSplash.Show
    
    ‘Do initialization stuff
    
    If Now < (dtDelay + TimeSerial(0, 0, 5)) Then
        Application.Wait dtDelay + TimeSerial(0, 0, 5)
    End If
    
    Unload ufSplash
    
End Sub

Weekend Picks

Last Week: 4 for 5
YTD: 8 for 15

Purdue -20 1/2 Illinois
Louisville -7 1/2 N. Carolina
Maryland -17 1/2 Duke
TCU +9 1/2 S. Florida
Minnesota -14 1/2 Northwestern

Okay, I don’t want anymore comments about my abilities being worse than chance – at least until after this week.

Devil Cat

Supidcat2_1

I am an animal lover. I love animals in the zoo, in other people’s houses, and in the wild. I don’t love animals in my house. Pets are like children that never grow up. They never learn to talk, use the bathroom, or balance a checkbook. Many people like pets – more power to them. I like other people’s pets, I just don’t want to be a servant to a pet like those other people seem to be.

So I laid down the law in my house – no pets unless they have gills. My wife heard this proclamation and decided she would never get a cat going through legal channels. In an act of civil disobedience, she brought home a cat. Now what am I supposed to do? I can’t end my marriage over a cat and if I make her get rid of it, she will just resent me for it. I fear I’m stuck with it.

I’ll admit that it’s a pretty cute cat. Of course, I was cute when I was 6 weeks old too. Now look at me. I’m fatter, uglier and I cost a lot more to maintain. As am I, so shall be this cat. Forty bucks for declawing, $60 for spaying (or the other one, I’m not sure), food, litter, toys, vet bills, etc.

Those of you who share my sentiments are pitying me right now. Thank you, I feel the love. The other 95% of you are probably pet owners and think I’m a jerk. It’s okay, I am. Maybe there’s some good that will come out of it. Maybe, over time, I will learn to like pets (e.g. having my house smell like a barn and flushing money down the toilet). I have learned one lesson, however: I should have been more like Dale Carnegie. I shouldn’t have laid down the law, but rather persuaded my wife that she didn’t want a cat. I don’t know if I would have been successful, but I do know that I couldn’t have failed any worse than this.

You know what I hate about blogs? It’s a bunch of people talking about their pets. Now I’ve gone and ruined a perfectly good blog by doing the same thing. Next I’ll be telling you what color my socks are. Thanks for indulging me and I promise not to mention this cat again unless it learns how to use Excel.

Daily Dose Programming Notes

According to TypePad, I will be exceeding my bandwidth limit this month. This is the first time I’ve ever checked this stat, so I don’t know if it’s a big deal or not. It will be a big deal if I get shut down.

Typepad

I suppose it’s good news that I’m over the limit. That must mean that people are reading this site – and that ain’t not bad. Nevertheless, I’ll probably have to find a new home for it soon. I’ll be pinging both Longhead and msmvps.com in the next couple of days to see about moving it there. Longhead hosts my other site, and they are an absolutely terrific host. They were going to install blogging software just for me when I started this, but I called them off to go with TypePad. I’m sure they would still do it (maybe they’ve done it already), but if msmvps.com works out, it won’t make much difference to me.

Irrespective of any moves I make, I’m thinking of recajiggering my categories. I didn’t put a whole lot of thought into them when I set this up, but I think it may be easier to find information if I had more categories. Question for you: Should I have more, less, or the same number of categories that I have now? If you said more, would you care to suggest some? I’m thinking VBA Basics and VBA Advanced should go away and all those posts should be split up into categories like Userforms, Userform Controls, Looping, etc.. I haven’t quite worked out what those would be, so any suggestions you have would be peachy.

Atomz, the fine folks who provide the search at the bottom of the left-hand sidebar sent me a message that they will now be including advertising in the search results. I don’t blame them. I think they offer a nice service and they deserve to make a buck. That doesn’t mean I will still be using them, but I think I’ll see what it looks like before I do anything hasty.

Finally, I’m on the road to recovery from my summer cold. I was hoping it was a cat alergy in disguise (more on that later), but alas, I seem to be getting better.