This is the last of my seven-piece tribute to Bill Ernest and no tribute to him would be complete without some serious @Formula jockeying.

I learned about @Formulas at the feet of the Master. By slogging my way through the unbelievably complex @Formula code underlying Bill's Quality at Work masterpiece I eventually learned an amazing amount about how to use this strange and interesting language (and wore out a Lotus Notes Reference Manual in the process).

But, no matter how good I got, he was better. We used to joke that Bill's Indian name was He Who Walks On Water With LotusScript, but it was really with @Formulas that he was the most unbelievable.

Therefore, it's fitting to end this series with a quick lesson in the power of the formula language.

Back to the basics

To do anything useful with @Formulas, you need to really, truly, understand several basic functions:

This was one of the last just-plain-cool ideas Bill cooked up for us. Here's the situation: You have a form which lists out responsibilities for any number of different people. A Training Plan, for instance, where you have the names of all the people who need to be trained and, along with them, the names of the individuals assigned to train each one:

Employee

Trainer

Sam Johnson

Nita Smeans

Alice Wan

George Wilson

Dave Smith

Doug Adams

Jack Jacobson

Nita Smeans

Wally Wilson

Roger Winters

Something like that. As each person's training is completed, the trainer should be able to open this document and indicate completion. As a part of that, the form should be updated with the current date and time so everyone can know exactly who was trained and when.

The problem is you have many different trainers who may be trying to update the Training Plan at the same time. If you open it and I open it and we both make changes and save the document, guess what? We'll get replication conflicts.

If you've ever tried to use Action Buttons from the web you know how ugly they are. Butt ugly. I'm not sure why they have to be that way but, well, they are. It's bad enough that for years now I've simply avoided using them. When I needed functionality like I'd normally have used Action Buttons for, I'd build it myself some other way.

I like the way they look in the Notes client and want them to look more or less like that from the web. In ProcessIt! Bill and I went so far as to build a frameset so the Action Buttons could be at the top of the window (and not scroll) and the form at the bottom of the window (and scrollable), just like in the Notes client. We used graphics made from screen shots of actual Action Buttons from the Notes client so things would look right, too.

As a solution, that approach works really well and looks great but there's a price to pay: It's a pain in the butt to get working effectively. Because they're in separate frames every click has to send an instruction to the other frame and then you have to get whatever it was you were trying to do to work. It's a lot of messing around just to get a button to work nicely, and not for the timid.

Do your applications collect credit card information? If so, you eventually have to do something with it. How do you know if the number the user has typed in is a valid number? One way, of course is to submit it for payment, but not everywhere you put a credit card number are you intending to pay something right at that moment.

It turns out that the digits on credit card numbers, while they look random, are not. The numbers are built so you can do some simple math on them and verify that you have a correctly-input number. Or, at least a valid one...there's no way to know if it's the right one without submitting it.

The math is actually quite simple. Here's how it works:

To verify a credit card number, start with the rightmost digit and multiply it by 1. Take the next digit and multiply it by 2. Take the third digit and multiply it by 1 again. Repeat the process all the way along the number from right to left multiplying them alternatively by 1 and 2.

So, let's say you've entered the number 1234-5678-9012-3456 on my web site. I multiply 6 x 1, 5 x 2, 4 x 1, and so on, ending up with this list of numbers:

6
10
4
6
2
2
0
18
8
14
6
10
4
6
2
2

Now, take all the digits of all these products and add them up. In other words, if you have a two-digit number like 12, add the digits: 1 + 2. For my example here, the math would be:

If the sum of all the digits of all the products is a number that ends in zero (10, 20, 30, 40, etc.), then that's a valid number. Since mine ends in 3, it's invalid.

]]>Sat, 7 May 2005 09:34:31 -04001http://www.scottgood.com/jsg/blog.nsf/CommentsRSS?Open&id=2D45A1EFC39C3B3D85256FF900719717http://www.scottgood.com/jsg/blog.nsf/PostComment?RunAgent&id=2D45A1EFC39C3B3D85256FF900719717http://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C4SXQBigBill's Big 7Scott Goodhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C4SXQhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C4SXQParsing out names, once and for all

You know the problem: You've got a list of names you want to sort alphabetically by last name but the first and last names aren't in separate fields, it's all just one big string. No big deal, right? You just look for the space:

LastName := @Right(ContactName; " ");

Piece of cake. Oh, wait. What about double last names? You know, like St. John or Van Dyke? Just taking things right of the space isn't going to cut it there. You might take everything right of the first space, but what if there's a middle name?

While your head is spinning about that, consider that some of these people have titles they like to see in their names as suffixes. Or, prefixes, even. Some have more than one. So, you've got this name you want to arrange in a last-name-first format:

Dr. Horace Allen van der Wald, Esq., MD, PhD

Something like that.

And, just to make it interesting, let's say that intermixed in your list of contact names are Contact documents you used for related but different purposes, like keeping track of numbers for the Help Desk or Technical Support or the Marketing Department. Those names, of course you wouldn't want rearranged. You don't want it to say "Desk, Help" you want it to still say "Help Desk." Right next to "van der Wald, Dr. Horace Allen, Esq., MD, PhD."

That's what you want. So, the question is, how on earth can you possibly write a view column formula to do it?

Doing what?, you may already be asking. That's "permutated" as in "permutation." This is one of those things most people don't know is possible in the formula language. Most of the others who do know about it still don't have any clue why they'd use it.

Well, fear not; I'm here to tell you.

But before I tell you how to use it, let me spend a few paragraphs on what it is. You know what addition is. In Notes there are really two kinds of addition: addition with number (1 + 1 = 2), and addition with strings ("A" + "B" = "AB"). You already knew that.

There's also addition of sets of numbers or strings. List (or array) addition, in other words:

(1 : 2 : 3) + (1 : 2 : 3) = 2 : 4 : 6

("A" : "B" : "C") + ("A" : "B" : "C") = "AA" : "BB" : "CC"

You probably knew that. Permutated addition takes this to the next step by giving you all possible combinations of the numbers or strings being added together. Permutated addition uses the *+ sign instead of just the +. With permutation, you get all the combinations of answers:

(1 : 2 : 3) *+ (1 : 2 : 3) = 2 : 3 : 4 : 3 : 4 : 5 : 4 : 5 : 6

Start with the first number in the first list, 1, then add it to each of the second list's number (1, 2 and 3), then do the same with the 2 and the 3 from the first list. It's a little easier to see what comes from where if you do it with two different strings:

]]>Thu, 5 May 2005 06:37:10 -04001http://www.scottgood.com/jsg/blog.nsf/CommentsRSS?Open&id=04C20C74FCE5C44585256FF8003A0362http://www.scottgood.com/jsg/blog.nsf/PostComment?RunAgent&id=04C20C74FCE5C44585256FF8003A0362http://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C3F6UBigBill's Big 7Scott Goodhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C3F6Uhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C3F6UIn honor of Bill Ernest (see the post below), beginning today and for the next week I'm going to post each day one of the truly cool things you can do with Notes (and/or Domino) based on things Bill figured out. So, here goes:

#1: Building dynamic JavaScript in a WebQuerySave agent.

If you build web applications involving any sophistication, pretty soon you get to the point where simply submitting a document and diverting to a URL specified in the $$Return field is not enough. For instance, what you probably want to do is return to the view you came from when you first opened the document, just like you would if you were using the Notes client.

The problem is, how do you do that?

At first, it seems like an easy question. You know the name of the view, just put it in the $$Return and be done with it. But that doesn't really work, for a couple of reasons. First, $$Return can take you back to a view but it might not be the right view. If it is the right view (whether by application of your fine development skills or just plain old good luck), chances are it's not in the right part of the view.

]]>Wed, 4 May 2005 07:13:16 -040015http://www.scottgood.com/jsg/blog.nsf/CommentsRSS?Open&id=36FB4475503D5C0285256FF7003D5276http://www.scottgood.com/jsg/blog.nsf/PostComment?RunAgent&id=36FB4475503D5C0285256FF7003D5276The loss of a good friendhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C2G6HBigBill's Big 7Scott Goodhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C2G6Hhttp://www.scottgood.com/jsg/blog.nsf/d6plinks/SGOD-6C2G6HYesterday afternoon, following a great deal of concern over his whereabouts, we learned that Bill Ernest had died. If you've done business with us, or if you've spent any time in either the Partner Forum or the Penumbra Forum, you probably know Bill--or know of him.

Bill was one of the original Notes people. As an employee of Quality Decision Management, back in the late 1980s, Bill started building Notes applications with the Beta of Notes Release 1. He took to Notes as a duck takes to water and, following those early efforts, never again left the world of Notes and Domino. Along the way, he became truly one of the best in the world at what he did.

Starting with that early primitive edition, Bill single-handedly built THE first Notes-based workflow tool, a product called Quality at Work. It was QaW and the amazing things it could do, which first attracted my partner, Steve, and me, like moths to a light bulb, to Notes.

The first time I put my hands on Notes was in January 1993 at QDM's office in North Andover, Massachusetts, with Bill looking over my shoulder. It wasn't until about two years later Bill felt the need to leave QDM and decided to move to Columbus to become our first employee.

In addition to being quite possibly the greatest @Formula writer of all time, Bill was the most amazing coder I've ever had the pleasure to work with. He could "see" code, and understand it, without actually reading it, in the same way an artist sees color and light. I can't tell you how many times I've brought him a big block of code to ask a specific question about and watched as he scrolled the page, backed up, highlighted forty or fifty lines of my blood and sweat, then casually hit "Delete" and replaced it with half a dozen lines which did the same thing much more eloquently.

It was, really, quite amazing.

Bill's time at Teamwork Solutions was both long (10 years) and fruitful for us all. Thanks to him, we have some of the most sophisticated and easiest-to-use Notes application development tools anywhere on earth. But Bill wasn't just a code geek.

Outside of the office he was one of the most interesting people you've ever met. He knew a lot about everything and was The Man when it came to playing those electronic trivia games in bars. Playing with him on your team was simply a matter of pushing the buttons he said to push. He always knew the answer.

Surprising to many, Bill was also a connoisseur of fine foods and wines, and a great lover of limited-edition Bourbons. While his working hours were, um, shall we say, varied, and his ability to make it into the office before 11 AM questionable, Bill could always be counted on to make a 7 AM tee time.

Within the past year, after 10 years of living in an apartment, Bill decided he was actually going to stay here in Columbus. Accordingly, he joined a country club and bought himself a home. Last week he bought a lawn mower and cut his own grass for the first time.

Although his office was usually a mess, somehow I expect his home was probably immaculate. Such were the dichotomies of Bill.

Bill died peacefully in his sleep, probably last Wednesday night. He had been ill that day in the office. He was 47.