|
[ABC home] [ABC Archives by Issue] [ABC Archives by Author] [Search] [Privacy]
|
Now, we can put our final version in A5 as follows:
This will return in our example: Smith, John. Our work is done.
One word of caution here. If the person entering the data has put extra spaces in at the start or end of the name string, your functions will have a hard time. If you suspect this may be the case, you can replace every reference to A1 with: TRIM(A1). This will have the effect of removing all leading and trailing spaces from the string. Back to our function. Type into cell A1 the name John James Smith and see what happens.
Things start going wrong in A3, where only the first forename appears, and we end up with ‘James Smith, John’. Oops. As it stands, our formula will not cope properly with more than one space in the string. Here are some more entries which would cause issues:
Remember the SEARCH function in A2? That looks for the first space character in the string. We can get it to look not for the first instance of a space, but for the second, by simply adding a third argument to a new formula in A6, thus:
The effect of this third argument is to search again for a space, but starting to search one character to the right of the first space we found. If there isn’t a second space, the formula will return an error, but we can allow for that like this:
This looks for the second space. If this would cause an error, then it just returns the position of the first, as found by the formula in A2, but if looking for the second doesn’t generate an error, then that’s what the formula does. This approach won’t always work, though, because there may be more even than two spaces, as in the last example above. Ideally, we could get the SEARCH command to start at the end of the string and work backwards, but it doesn’t work that way and there is no worksheet formula which does. Instead, we have to find an approach which will find out how many spaces there are in the string and then give the position of the last one. Actually, we can achieve this quite easily using just the formulas we’ve already met here, plus one other. In cell C1, enter:
In C2 enter the new formula:
The first set of quotes in this formula contains a space, the second nothing. The effect of this formula is to return a version of the string without any spaces, thus:
In C3, you can enter this formula:
This tells you the difference between the number of characters in John James William Smith and the number of characters in JohnJamesWilliamSmith. The result is 3, which is, of course, the number of spaces in the original string. But the SUBSTITUTE has an optional fourth argument as well, and it is this one which we will now put into use. In C4, enter:
That fourth argument is the instance number you want to substitute. If you omit it, this formula will replace every space with a caret (^). But by giving the instance number as the number of spaces we calculated in C3, it will only change the last space to a caret, returning this string:
Now, unless your data has a lot of caret characters in it (and if it does, use a different symbol) you can be pretty sure that there will only be one in the string, so it is this character which now becomes the object of your new SEARCH command in cell C5, thus:
In this case, the formula produces 19, because the caret is the 19th character in the string. From there, it is an easy job to play with the string using the LEFT and RIGHT formulae as we did before. Below is a summary of the full process thus generated:
Now, this is a lengthy process, but once you’ve been through it, you can turn this chain of formulae into one big, Swiss Army Knife of a formula which looks like this:
If you’ve been using the TRIM function as suggested above, you have an even longer formula:
Scary, huh? Not really. I didn’t type that all in by hand, I simply cut and pasted it together. For instance, C8 started off saying:
What I did was copy the formula in C7 and replace the reference to C7 with the actual C7 formula (discarding the superfluous extra = sign) to get this:
Then I replaced the C6 reference with the formula in C6 and the C4 reference with the formula in C4, and so on until the only cell referenced was cell C1. It’s simple, but the resulting formula never fails to impress those not party to this technique! Still, be that as it may, the formula is still big and unwieldy. If we want to use it again later on another sheet, we’d better pray we have a copy of the formula somewhere to paste in, because it will take a while if we have to start again from scratch. Also, it’s a lovely piece of technical writing, but visible to all users of our spreadsheet and thus copiable by others. This may not be a problem if you don’t rely on this sort of work for your living, but that’s precisely what some of us do! And so it makes sense to overcome these disadvantages by creating a custom worksheet formula. If you haven’t used one of these before, don’t worry. It’s quite straightforward, requiring only a little knowledge of VBA to convert the enormous worksheet formula above to the far more manageable:
This formula behaves just like a regular, built-in Excel worksheet function. If you package your code as an add-in (beyond the scope of this article), you can keep the underlying VBA which makes it work firmly under the bonnet. With the power of Excel’s built in functions, you might imagine that the worksheet version might be far simpler than the VBA routine needed to do the same thing, but you’d be wrong. Remember how we mourned the lack early on in this article of a worksheet formula which would search for a character within a string, working backwards from the end of that string? Well, guess what? VBA has such a method. The VBA method InStr does much the same as Excel’s SEARCH function, but there is a companion method in VBA called InStrRev, which starts from the other end. As a result, our VBA code looks like this: Function NAMEREVERSE(strValue As String) strLen = Len(strValue) strNumSpace = InStrRev(strValue, " ") strSurname = Right(strValue, strLen - strNumSpace) strRest = Left(strValue, strNumSpace - 1) NAMEREVERSE = strSurname & ", " & strRest End Function Notice how we have used a very similar approach as in our first attempt at a worksheet formula. Instead of SEARCH, we use IsStrRev, allowing us, of course, to start at the end and work backwards. The worksheet formulas LEN, RIGHT and LEFT have direct equivalents in VBA, which are used here to achieve the same effects. If placed in any module, this will enable NAMEREVERSE to be used in the workbook containing the code just like any regular worksheet function. If you want this new command to be available in all workbooks, you have two choices. You can either package the workbook with the code module as an add-in, or you can paste the code into the PERSONAL.XLS workbook. So there we have it, a common, real-world problem solved first on a worksheet, then extended to deal with awkward cases. We saw how it easily became a big and frightening single formula, and then saw how to make it more portable and less accessible to the curious by coding a custom function in VBA. Paradoxically, in this case it also became a lot simpler in the transition. Ray Blake lives in England and spent 15 years training people in the financial services industry there. He had always used PCs in his work, and gradually realized he might make a career out of them. He and his business partner set up GR Business Process Solutions (www.grbps.com) which specializes in innovative IT to support knowledge testing and skills assessment. Although he spends a lot of time these days developing in VB and Access, Excel remains his favorite development tool, because, as he says, 'It can do everything; there's no computer application you can think of that you couldn't develop in Excel.' |
|
Privacy Policy, Disclaimer, and Legal Stuff This page was last updated on Monday, December 31, 2007 . copyright © 2000 - 2008, Linda F. Johnson, Linda's Computer Stop, ABC ~ All 'Bout Computers. All rights reserved. |