Thursday, July 24, 2008

Array Formulas

Arrays formulas constitute a powerful tool that can simplify calculations in an elegant manner. It may require some effort to get used to them but the payoff is immediate.

So, what is an array formula? Well, an formula is a formula that operates on an array of values. For the purpose of this discussion, an array is nothing but a list or collection of values. In this sense, a range, such as A1:A12, is an array.

Another critical point to note is that unlike 'normal' formulas, array formulas are entered by pressing Ctr, Shift and Enter keys simultaneously. Hence the popular appelation of array formulas as 'CSE' formulas. Otherwise, array formulas also begin with '=' and adhere to other normal rules.

An illustration will help shed more light on this topic.

Excel table

To find out the total number of salespersons who sold more than 5 but less than 40 items, an array formula can be used. Salespersons are in the range A2:A7 and the sold items in the range B2:B7. Select an empty cell, type =SUM((B2:B8>5)*(B2:B5<40)) into it and press Ctrl, Shift and Enter keys simultaneously. The Excel automatically places the formula within braces to signify it as an array formula. The cell where the formula was entered displays the total number of salespersons who sold more than 5 but less than 40 items, which is 4.

This is what happens. The formula compares values contained in B1 against 5. If the value is greater than 5, TRUE is returned. Else the returned value is FALSE. Similarly, the value contained in B2 is compared against 40. If it is less than 40, then TRUE is returned. Else, FALSE is returned. Now, the two returned values are multiplied. As Excel treats TRUE as 1 and FALSE as 0, the multiplication results in either 1 or 0. This procedure is repeated for all the cells, producing a series of 1's and 0's, which are totaled by the function SUM, giving the total number of salespersons who sold more than 5 but less than 40 items.

Saturday, July 19, 2008

Rushdie Enchants Readers



That poet of the British Raj, Rudyard Kipling, famously wrote that the East and West shall never meet. Having lived as a journalist, poet and writer of well-loved fiction amidst the grandeur and squalor of the Sub-continent, Kipling had seen enough to reach this pessimistic conclusion.

In the latest addition to his literary oeuvre, Salman Rushdie sets out to bring about in The Enchantress of Florence what Kipling thought was impossible: the meeting of East and West. He tries to show that the East and West may be geographically apart, but the everyday concerns, obsessions, vanities, aspirations, cogitations, follies and foibles of the people of high and low station in both parts of the globe may not be as different as they appear at the superficial level.

In the story, the great Mughal emperor Akbar sits on the peacock throne of Fatehpur Sikri in India. In Florence, the Medicis rule the roost, helped by the elevation of a Medici scion to the papal seat in Rome. Threading the two glorious cities is the outrageous tale of a roguish, yellow-haired Florentine, a self-proclaimed Mughal of love, who may be the progeny of a lost Mughal princess, or a fraud and trickster.

Chess Problem No# 1

The following chess problem by L I Loshinsky won the first prize, Abastumansky Shakhmaty Bureau, in 1933. White moves and mates in two.

An Excel & Outlook Hack

Last week, one of my workmates asked me if I could construct an Excel solution to automate a particularly tedious task he had to perform on a daily basis. The task involved opening emails, copying the senders, editing them, and searching for them in Workbooks. If the searches failed, the emails would be flagged as unread and the procedure repeated, ad nauseum. The idea was to ensure that all the senders were found in the Workbooks.

As an Excel VBA hacker, the only part that was not immediately apparent to me was the method to access the non-default Outlook mailbox in which my workmate was receiving the emails, which totaled around 2/3 hundreds a day. After a few google searches, I found the workaround and managed to construct an Excel add-in that now helps my workmate perform the task with a few clicks.

The first step was to add the Outlook object code library from the Excel VBA IDE by clicking Tools > References, and then ticking Microsoft Outlook 11.0 Object Library and clicking Ok on the dialogue box. Next, the following procedure was created.


Option Explicit

Sub mainProc()

Application.ScreenUpdating = False

'//////////////////////////////////////////////
' declare the vars
'//////////////////////////////////////////////

Dim Sh As Worksheet
Dim Olapp As Object
Dim Olns As Namespace
Dim Fldr As MAPIFolder
Dim OlMail As Variant
Dim intFinalRow As Integer
Dim i, j, k As Integer
Dim intProgCent As Integer
Dim intTotMails As Integer
Dim strFolderId As String

On Error GoTo Err_Rtn:

strFolderId = "xxx"

Set Sh = ActiveSheet
Set Olapp = New Outlook.Application
Set Olns = Olapp.GetNamespace("MAPI")
Set Fldr = Olns.GetFolderFromID(strFolderId)
intTotMails = Fldr.Items.Count
j = 0
k = 0
frmProgressBar.Show

intFinalRow = Sh.Range("F65536").End(xlUp).Row

For Each OlMail In Fldr.Items
j = j + 1
intProgCent = (j / intTotMails) * 100
With frmProgressBar
.ProgressBar1.Value = intProgCent
.lblPercent = Str(intProgCent) & "%"
End With

If OlMail.UnRead = True Then
For i = 1 To intFinalRow
With Sh
If Trim(.Range("F" & i).Value) = _
Right(Trim(OlMail.SenderName), 9) Then
.Range("A" & i & ":K" & i).Interior.ColorIndex = 17
OlMail.UnRead = False
k = k + 1
Exit For
End If
End With
Next i
End If
DoEvents
Next OlMail
Unload frmProgressBar
MsgBox "Total found " & k
Set Fldr = Nothing
Set Olns = Nothing
Set Olapp = Nothing
Set Sh = Nothing
Application.ScreenUpdating = True
Exit Sub
Err_Rtn:
Unload frmProgressBar
Application.ScreenUpdating = True
MsgBox Err.Description
End Sub

The code is self-explanatory. It loops through all the emails in the folder with id equal to the value of strFolderId. If an email is not already read, the nine rightmost characters of the sender name are extracted with the inbuilt VBA function Right() and compared with the values in the 'F' column of the active worksheet. If a match is found, the color of the row of the matched value is changed and the email flagged as read. If no match is found, the code interrogates the next email.

There is also a progress bar and a pop-up dialogue box that displays the total number of matches found at the end of the program execution.

Only one thing needs a bit more explanation. The variable strFolderId is set to "xxx" in line 24. In fact, the value is a long string that is found by running the following macro in Outlook.

Option Explicit

Sub findFolderId()
Dim Ons As Outlook.NameSpace
Dim Fldr As Outlook.MAPIFolder
On Error Resume Next

Set Ons = Application.GetNamespace("MAPI")
Set Fldr = Ons.PickFolder
Debug.Print Fldr.StoreID
Set Ons = Nothing
Fldr = Nothing
On Error GoTo 0
End Sub

The folder id will be displayed in the Immediate window.

One final note. Since this code implements 'early binding' after manually adding the reference to the Outlook object code library, the application will fail to work if/when the object library is upgraded, as might happen when a newer version of MS Office suite is installed. To preempt this issue, the code should be changed to use 'late binding'. In some future post, that is what I might do.