Archive for the ‘Formulas’ Category.

Steady vs. Volatile

I read my retirement account statement today. It wasn’t pretty. A lot of low, single digit returns lately. I know people who complain when the market tanks, but I’m not one of them. When it comes to my retirement, I want the market to keep going down until I’m 59 1/2, then shoot up ten-fold in one day. That would suit me just fine. As long as the market goes down, it means I get to buy stock cheaper tomorrow than I did today. Assuming there are no underlying problems with that stock - and there won’t be if I’m properly diversified - then I am likely buying something for less than its true worth.

Is that flawed? It could be that the lost compounding negates the cheaper price. In other words, if my small initial investment quadrupled the first day, I wouldn’t even need average returns to do well because my base was established so early. Those are the extremes, I guess.

Here’s how I set about testing my hypothesis: In my example, I invest $200 per month in a $1 stock. In a steady market the stock price increases .8% every month like clockwork. In a volatile market, the stock price swings wildly, but the final stock price is the same as the steady market.

In the volatile market, I have about $700 more in my account than if the market was steady. Either way the stock is $1.24, I was just able to buy more of it in the volatile market. It’s the underlying fundamentals of a company that determine its stock price over time, but the utter wackiness of investors that determine it in the short term.

I believe investment folk call it dollar-cost averaging when you invest the same amount of money periodically. What do you think? Should I rejoice at each downturn?

PS To get the volatile market returns, I used this formula: =RAND()/10*IF(RAND()>.5,-1,1). Then I hit F9 until I got close to the correct final stock price. Finally I fiddled with some percentages haphazardly to make the two final stock prices match.

PPS Yes, that’s Excel 2007 you see there. More on that later.

ExcelRefTool; A New Formula Auditing Tool

Hi,

A while ago I requested beta testers for a new utility, now called “ExcelRefTool”.

Thanks to my beta testers, the tool is now mature enough to be exposed to the general public.

Have a look here, download the demo if you like and give it a spin.

And thanks again, to everyone who took the trouble of beta testing this tool for me!

Regards,

Jan Karel Pieterse
www.jkp-ads.com

Formula Challenge

I wrote a VBA user-defined function for this task, but I can’t help but think there’s a worksheet formula that can do the job. In case you were looking for something to do this weekend, here’s something to occupy your time.

You get a two column range, the starting group, the ending group, the number of days, and the threshold. The formula should return the number of groups between 2 (E2) and 4 (E3) inclusive that have at least 2 (E4) consecutive amounts greater than or equal to 400 (E5).

The answer is 2. Groups 1 and 5 are outside the range, so they don’t count. Group 2 only has 1 consecutive amount over the threshold. Groups 3 and 4 both have 2 consecutive amounts over the threshold. I should be able to change the inputs in column E to change the answer.

Have fun.

Unique Fruit

I need help. I have this:

I can tell my how many unique fruits are in column A with this array formula

E4: =SUM(1/COUNTIF(A2:A13,A2:A13))

And I can tell how many rows have both Apple in column A and 1 in column B with this array formula

E5: =SUM((A2:A13=”Apple”)*(B2:B13=1))

But I can’t seem to figure out the formula to tell me the count of unique fruits that have a 1 in column B. The answer is two, apple and peach. What’s the formula that gets me there?

Having a number and a formula “co-exist” in a cell

On an ongoing project, the client uses the TM1 OLAP system. One of the interesting things I noticed was this:

A user can "slice" data from the database into Excel. The result is a new worksheet where the appropriate cell contains a formula such as =DBRW(...), which essentially looks up the TM1 database for the current value that corresponds to the specified parameters.

So far so good. But, here's the twist. One can enter a new value into the cell containing the formula. TM1 will update the OLAP database with this new value and restore the formula.

As soon as I saw what was happening I guessed how it was done. Here's the implementation of a proof-of-concept. Of course, as a proof-of-concept there are a lot of safeties, performance issues, and other niceties that are missing.

An obvious requirement is that that one must have a secondary data storage since it is impossible for a value and a formula to actually co-exist in a cell. So, that requires a backend database to store the actual value and I decided to use MS Access to create one.

The database had a single table with 3 columns: Col1, Col2, DataVal. For those who want to know how this maps to an OLAP system, think of Col1 and Col2 as dimensions in a TM1 OLAP system and DataVal as the value at the intersection of specific elements in those dimensions.

That led to the infrastructure to access data in the database. In a standard module:

Option Explicit
Dim Cn As ADODB.Connection
    Dim aRSTable1 As ADODB.Recordset
Function initializeADO(DataSrcName As String) As ADODB.Connection
        Dim Cn As ADODB.Connection
        Set Cn = New ADODB.Connection
        With Cn
            .Provider = "Microsoft.Jet.OLEDB.4.0"
            .ConnectionString = DataSrcName
            .Open
            End With
        Set initializeADO = Cn
    End Function
Sub openADO()
    Set Cn = initializeADO("C:\Documents and Settings\Owner\My Documents\testADO\db1.mdb")
    End Sub
Public Function DBVal(Table, Col1, Col2)
    If aRSTable1 Is Nothing Then Set aRSTable1 = New ADODB.Recordset
    If Cn Is Nothing Then openADO
    On Error Resume Next: aRSTable1.Close: On Error GoTo 0
    aRSTable1.Open "SELECT DataVal FROM " & Table _
        & " WHERE Col1='" & Col1 & "' AND Col2='" & Col2 & "'", Cn
    DBVal = aRSTable1.Fields("DataVal").Value
    End Function

OK, nothing unusual about the above. It's standard stuff to write a User Defined Function that retrieves data from an external database. Again, remember this is proof-of-concept code and leaves out a lot of safeties and performance effectiveness issues.

This is used in a worksheet cell as =DBVal(A3,B3,C3) where A3 contains the Access table being queried, and B3 and C3 the values for the 2 columns Col1 and Col2 respectively. In TM1 parlance, this would correspond to the cube name, and the two elements of the 2 dimensions in the cube.

Next, the infrastructure to allow a new value to update the database.

First, a worksheet event procedure that keeps track of the existing formula. Note that I would never deploy an event procedure in a worksheet code module, but it works well to test concepts.

Option Explicit
Dim CellFormula As String

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells.Count <> 1 Then Exit Sub
    If Not Target.HasFormula Then CellFormula = "": Exit Sub
    CellFormula = Target.Formula
    End Sub

Next, an event procedure that responds to a new value entered by the user.

Private Sub Worksheet_Change(ByVal Target As Range)

    If Target.Cells.Count <> 1 Then Exit Sub
    If Target.HasFormula Then Exit Sub
    If CellFormula = "" Then Exit Sub
   
   
    Dim NewVal
    NewVal = Target.Value
    updateDB CellFormula, NewVal
   
    On Error Resume Next
    Application.EnableEvents = False
    Target.Formula = CellFormula
    Application.EnableEvents = True
    On Error GoTo 0
   
    End Sub

The SelectionChange event procedure above saves the cell formula, if it has one, at the time the user selects the cell. Then, if the user enter a value, the Change event procedure uses the new value to update the database through UpdateDB and then restores the formula saved by the SelectionChange procedure.

The corresponding code for the updateDB subroutine in the standard code module:

Sub updateDB(CellFormula As String, NewVal)
    If Cn Is Nothing Then openADO
    Dim Params
    Params = Split(CellFormula, "(")
    Params = Split(Left(Params(1), Len(Params(1)) - 1), ",")
    Cn.Execute "UPDATE " & Range(Params(0)).Value & " SET DataVal=" & NewVal _
        & " WHERE Col1='" & Range(Params(1)).Value & "' AND Col2='" & Range(Params(2)).Value & "'"
    End Sub

And, for completeness, code, in the standard module, to close the database connection:

Sub closeADO()
    On Error Resume Next
    aRSTable1.Close
    Set aRSTable1 = Nothing
    Cn.Close
    Set Cn = Nothing
    End Sub

To use the above, in the Access database, a table named Table1. I had 4 records in it corresponding to values of "a" and "b" for Col1 and Col2. The associated DataVal values were 1, 2, 3, and 4, respectively.

In the Excel worksheet, Cell A3 had the value "Table1" and in B3 and C3 one could enter the values corresponding to Col1 and Col2 (i.e., either "a" or "b"). The =DBVal() formula then retrieved the corresponding value from the database.

Now, enter a new value in the cell that contains the =DBVal() formula. The code will update the database with the new value and restore the =DBVal() formula. This will show the new value in the cell.

Reverse compatibility problem of the old ATP functions

Hi all

For the users of a non English version of Excel 2007 maybe this information is useful.
http://www.rondebruin.nl/atp.htm

Have a nice day

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