How do display a formula

  • Thread starter Thread starter Jonathan
  • Start date Start date
J

Jonathan

Hi,
Is it possible to show the actual numbers that were used for a computation?
i.e:

In cell A1 I have '2'
In cell A2 I have '3'

In cell A3 I have '=A1*A2' Therefore, Excel displays 6.

Is it possible to see '2*3' somehow??

Thanks,
Jonathan
 
the only way i know of is tools/formula auditing/evaluate formula
 
Hi Jonathan,

One way is to go into Tools|Options|View & check the 'Formulas' option. Note that this causes Excel to display the formulae instead
of their results and, if your formulae are referencing other cells, its the references that display, not the contents of those other
cells.

An alternative is to use a macro that adds the formulae to the cell comments, then display the comments. Here's a macro to do just
that:
Sub AddFormulasToComments()
Application.ScreenUpdating = False
Dim CommentRange As Range, TargetCell As Range
'skip over errors caused by trying to delete comments in cells with no comments
On Error Resume Next
'If the whole worksheet is selected, limit action to the used range.
If Selection.Address = Cells.Address Then
Set CommentRange = Range(ActiveSheet.UsedRange.Address)
Else
Set CommentRange = Range(Selection.Address)
End If
'If the cell contains a formula, turn it into a comment.
For Each TargetCell In CommentRange
With TargetCell
'check whether the cell has a formula
If Left(.Formula, 1) = "=" Then
'delete any existing comment
.Comment.Delete
'add a new comment
.AddComment
'copy the formula into the comment box
.Comment.Text Text:=.Formula
'display the comment
.Comment.Visible = True
End If
End With
Next
MsgBox " To print the comments, choose" & vbCrLf & " File|Page Setup|Sheet|Comments," & vbCrLf & "then choose the required print
option.", vbOKOnly
Application.ScreenUpdating = True
End Sub

By default, worksheet comments don’t print. To print the comments, choose File|Page Setup|Sheet|Comments, then choose the required
print option. The code provides a message to that effect.
 
OP wanted the actual numbers to show, not the formula.
In cell A1 I have '2'
In cell A2 I have '3'

In cell A3 I have '=A1*A2' Therefore, Excel displays 6.

Is it possible to see '2*3' somehow??


Gord Dibben MS Excel MVP
 
Here is the problem with what you are asking for as I see it... you are
thinking too small. For the formula you showed, fine, no problem, but what
about something like this?

=SUMPRODUCT((A1:A1000=B1:B1000)*C1:C1000)

There are 1000 values times three involved in those ranges... what, and how,
would you display all that? Just showing the content of the end of range
cells would convey absolutely nothing about the actual numbers involved in
calculating this formula. And trust me when I say this... that is a
relatively tame example... I could conceive of much, much more complex
examples.

Rick
 
One way to do this is to use the UDF SubVal.

Put this in a normal module
Code:
Option Explicit

Public CollectionHoldsValues As Boolean
Public subValCollection As New Collection

Function SubVal(inputRange As Range) As String
    Application.Volatile
    On Error GoTo OutOfFtn
  
    If CollectionHoldsValues Then
        On Error Resume Next
        SubVal = subValCollection(inputRange.Range("A1").Address(, , , True))
        On Error GoTo 0
    Else
        On Error Resume Next
            subValCollection.Add Item:=inputRange.Range("a1"), key:=inputRange.Range("a1").Address(, , , True)
        On Error GoTo 0
        SubVal = "null"
    End If
Exit Function
OutOfFtn:
    SubVal = vbNullString
    On Error GoTo 0
End Function

Function ValuesInsteadOfPrecedents(ByVal inRange As Range) As String
    Rem returns the formula of inRange With value replacing references
    Dim PrecedentsRRay As Variant
    Dim onePrecedent As Variant
    Dim formulaString As String
    If inRange.Cells.Count = 1 Then
        ValuesInsteadOfPrecedents = inRange.Formula
        PrecedentsRRay = ArrayOfPrecedents(inRange)
        If UBound(PrecedentsRRay) = 0 Then Exit Function
        If PrecedentsRRay(1) Is Nothing Then Exit Function
        For Each onePrecedent In PrecedentsRRay
            ValuesInsteadOfPrecedents = SwapValueForRange(ValuesInsteadOfPrecedents, onePrecedent)
        Next onePrecedent
    End If
End Function
 
Function SwapValueForRange(formulaStr As String, replaceRange As Variant) As String
    Rem replace one precedent With its value In the formula String
    Const Indicator As String = "\"
    Dim testStr As String
    Dim replacementString As String
     
    If replaceRange.Cells.Count = 1 Then
        replacementString = Indicator & CStr(replaceRange.Text)
    Else
        replacementString = Indicator & CStr(replaceRange.Range("A1").Text) & ":" & Indicator
        With replaceRange
            replacementString = replacementString & CStr(.Cells(.Rows.Count, .Columns.Count).Text)
        End With
    End If
     
    formulaStr = Application.Substitute(formulaStr, "$", vbNullString)
    SwapValueForRange = formulaStr
     
    SwapValueForRange = Application.Substitute(SwapValueForRange, replaceRange.Address(False, False, xlA1, True), replacementString)
    If SwapValueForRange = formulaStr Then
        testStr = replaceRange.Address(False, False, xlA1, True)
        testStr = Left(testStr, InStr(testStr, "[") - 1) & Mid(testStr, InStr(testStr, "]") + 1)
        SwapValueForRange = Application.Substitute(SwapValueForRange, testStr, replacementString)
        If SwapValueForRange = formulaStr Then
            SwapValueForRange = Application.Substitute(SwapValueForRange, replaceRange.Address(False, False), replacementString)
        End If
    End If
End Function
 
Function ArrayOfPrecedents(homeCell As Range) As Variant
    Rem returns an array of all of the homeCell 's precedent
    Dim startPlace As Range, startWindow As Window
    Dim outRRay() As Range
    Dim i As Long, pointer As Long
    Set startPlace = Selection
    Set startWindow = ActiveWindow
    If homeCell.HasFormula Then
        ReDim outRRay(1 To Len(homeCell.Formula))
        On Error Resume Next
        homeCell.Parent.ClearArrows
         
        Application.EnableSound = False
        homeCell.ShowPrecedents: Rem problem Line
        Application.EnableSound = True
        On Error GoTo 0
         
        On Error GoTo FoundAllExternalPrecedents
         
        For i = 1 To UBound(outRRay)
            homeCell.NavigateArrow True, 1, i
            If Selection.Address(, , , True) = homeCell.Address(, , , True) Then
                Rem closedRef
            Else
                pointer = pointer + 1
                Set outRRay(pointer) = Selection
            End If
        Next i
         
FoundAllExternalPrecedents:
        On Error GoTo 0
         
        For i = 2 To UBound(outRRay)
            homeCell.NavigateArrow True, i, 1
            If Selection.Address(, , , True) = homeCell.Address(, , , True) Then Exit For
            pointer = pointer + 1
            Set outRRay(pointer) = Selection
        Next i
         
        On Error Resume Next
        homeCell.Parent.ClearArrows
        On Error GoTo 0
         
        ReDim Preserve outRRay(1 To Application.Max(1, pointer))
        ArrayOfPrecedents = outRRay
    Else
        ReDim outRRay(0 To 0)
        ArrayOfPrecedents = outRRay
    End If
    startWindow.Activate
    Application.Goto reference:=startPlace, Scroll:=False
End Function
and this in the ThisWorkbook code module
Code:
Option Explicit

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Dim oneCell As Range, i As Long
Dim startPlace As Range, startWindow As Window
Dim newValue As String
If 0 < subValCollection.Count Then
    Set startPlace = Selection
    Set startWindow = ActiveWindow
    Application.EnableEvents = False

    For i = 1 To subValCollection.Count
        Set oneCell = subValCollection(i)
        newValue = ValuesInsteadOfPrecedents(oneCell)

        subValCollection.Remove oneCell.Address(, , , True)
        
        If subValCollection.Count = 0 Then
            subValCollection.Add Item:=newValue, key:=oneCell.Address(, , , True)
        Else
            subValCollection.Add Item:=newValue, key:=oneCell.Address(, , , True), before:=1
        End If
    Next i
    CollectionHoldsValues = True
    
    Calculate

    startWindow.Activate
    Application.Goto reference:=startPlace, Scroll:=False
    Application.EnableEvents = True
End If

Set subValCollection = Nothing
CollectionHoldsValues = False
End Sub

Then if A1 hold the formula =A2+A3 , A2 holds 2 , A3 holds 3,
a cell holding =SubVal(A1) will display the string "=\2+\3" (no quotes) and will update as the values of A2 and A3 change.
The back-slash indicates that the 2 comes from a cell reference rather than from a constant.
If the formula in A1 was = A2+3, =SubVal(A1) would return =\2+3.
(The indicator conststant can be changed in SwapValueForRange.)

Since it is partly driven by the Worksheet_Change event, the UDF must be called from a formula in a cell rather than from a VB routine.
This will work for all precedent cells, on the same or different sheets, same or different OPEN workbooks
It won't pull values from closed workbooks.

I hope this helps.

Edit: to answer Rick's question, if A1 = 1, A1000 = 1000, B1 = 2, B1000=2000, C1=3 and C1000=3000,
the formula =SUMPRODUCT((A1:A1000=B1:B1000)*C1:C1000)
processed by the UDF will return =SUMPRODUCT((\1:\1000=\2:\2000)*\3:\3000)
 
Last edited:
Hi Gordon,

I noted the limitation as to what can be displayed in my reply.
 
I saw that.

Just wondered why the elaborate macro to add all those Comments that don't
give OP what he asked for in the first place.

To achieve the same thing as your macro without the Comments just enter
=ShowFormula(cellref) in an adjacent cell..............

Function ShowFormula(Cell)
Application.Volatile
ShowFormula = "No Formula"
If Cell.HasFormula Then ShowFormula = Cell.Formula
End Function

But still does not do what OP wantes.


Gord
 
Hi Gord,

I din't want to add anything to another cell in case that cell was or could be used for something else.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top