The question:"There are values (numbers) in the input range. I would like to find the formula of how the calculation of these values is done to get the asked result."
In response I created the user defined function:
FIND_FORMULA
returns the formula of how the calculation of values can be done.Syntax
FIND_FORMULA(rValues, iResult, [sOperators], [rNames], [bHidePlus], [bFindForZero], [bShowBrackets])
Arguments:
rValues - required - the range of cells which FIND_FORMULA will try combine to find the result.
iResult - required - the value which should be the result of the found formula.
sOperators - optional - text string of the operators which FIND_FORMULA will try to use for finding the formula (e.g. "+-*/"). The default value is "+-".
rNames - optional - the range of cells which FIND_FORMULA will use as variable names. If this argument is omitted the addresses of the cells (rValues) will be used.
bFindForZero - optional - determines what FIND_FORMULA does if the result is equal to 0. If bHidePlus is true the function will try to find the formula. In opposite case the function will return zero-length string. The default value is false.
bShowBrackets - optional - if bShowBrackets is true FIND_FORMULA will add the round brackets at the start and at the end of the returned formula. The default value is true.
bHidePlus - optional - if bHidePlus is false and the result is positive number FIND_FORMULA will add "+" at the start of the returned formula. The default value is true.
Remarks:
- rValues must be a single-row and single-area range which must have two cells at least.
- iResult must be a whole number.
- rNames must be a single-row and single-area range which must have the same number of cells as rValues.
Examples:
| A | B | C | D | E | F | G | H | I | J | |
| 1 | a | b | c | d | e | f | g | h | ? | output |
| 2 | formula | |||||||||
| 3 | 5 | 12 | 9 | 6 | 5 | 11 | 15 | 20 | #VALUE! | |
| 4 | =FIND_FORMULA(A3:H3,0,,A1:D1) | |||||||||
| 5 | 2 | 11 | 7 | 9 | 8 | 15 | 8 | 19 | a:h=25 (+-) | (A5+E5+F5) |
| 6 | =FIND_FORMULA(A5:H5,25) | |||||||||
| 7 | 14 | 15 | 7 | 15 | 11 | 16 | 16 | 8 | a:h=-13 (+-) | -(a+b-f) |
| 8 | =FIND_FORMULA(A7:H7,-13,,A1:H1) | |||||||||
| 9 | 18 | 14 | 19 | 16 | 9 | 6 | 12 | 19 | a:h=25 (+-) | (c+f) |
| 10 | =FIND_FORMULA(A9:H9,25,"",A1:H1) | |||||||||
| 11 | 11 | 6 | 15 | 11 | 18 | 17 | 14 | 6 | a:h=66 (*/) | (A11*B11) |
| 12 | =FIND_FORMULA(A11:H11,66,"*/") | |||||||||
| 13 | 16 | 3 | 13 | 20 | 20 | 10 | 6 | 7 | a:h=520 (*/) | +(C13*D13*E13/F13) |
| 14 | =FIND_FORMULA(A13:H13,520,"*/",,,,FALSE) | |||||||||
| 15 | 11 | 13 | 6 | 7 | 11 | 5 | 1 | 16 | a:h=520 (*/) | #N/A |
| 16 | =FIND_FORMULA(A15:H15,520,"*/") | |||||||||
| 17 | 19 | 6 | 1 | 12 | 3 | 5 | 3 | 18 | h+a:g=40 (+-) | h+(a+e) |
| 18 | =H1&FIND_FORMULA(A17:G17,40-H17,,A1:G1,,,FALSE) | |||||||||
| 19 | 20 | 8 | 4 | 19 | 20 | 6 | 2 | 18 | a:f=12 (+-) | (a-b) |
| 20 | =FIND_FORMULA(A19:H19,12,,A1:H1) | |||||||||
| 21 | 20 | 8 | 4 | 19 | 20 | 6 | 2 | 18 | a:f=12 (+) | (b+c) |
| 22 | =FIND_FORMULA(A21:H21,12,"+",A1:H1) | |||||||||
| 23 | 1 | 9 | 3 | 10 | 18 | 17 | 5 | 16 | a:g=h (+-) | h=-(a-f) |
| 24 | =H1&"="&FIND_FORMULA(A23:G23,H23,,A1:G1,,FALSE,TRUE) | |||||||||
| 25 | 16 | 6 | 15 | 11 | 8 | 14 | 15 | 15 | g-a:f=h (+-) | h=g |
| 26 | =H1&"="&G1&FIND_FORMULA(A25:F25,H25-G25,,A1:F1,,,FALSE) | |||||||||
| 27 | 16 | 6 | 15 | 11 | 8 | 14 | 15 | 15 | g-a:f=h (+-) | h=g+(b+e-f) |
| 28 | =H1&"="&G1&FIND_FORMULA(A27:F27,H27-G27,,A1:F1,TRUE,,FALSE) | |||||||||
| 29 | 14 | 1 | 8 | 13 | 20 | 2 | 19 | 9 | a:h=200 (+-*/) | (a*d+e-f) |
| 30 | =FIND_FORMULA(A29:H29,200,"+-*/",A1:H1) | |||||||||
| 31 | 9 | 7 | 1 | 9 | 3 | 12 | 18 | 1 | a:h=-90 (+-*/) | -(a*f-g) |
| 32 | =FIND_FORMULA(A31:H31,-90,"+-*/",A1:H1,,FALSE) | |||||||||
| 33 | 6 | 20 | 7 | 13 | 3 | 5 | 9 | 6 | a:h=-54 (+-*/) | -(a*g) |
| 34 | =FIND_FORMULA(A33:H33,-54,"+-*/",A1:H1) | |||||||||
| 35 | 12 | 17 | 13 | 20 | 16 | 10 | 3 | 1 | a:h=-92 (+) | -(a+b+c+d+e+f+g+h) |
| 36 | =FIND_FORMULA(A35:H35,-92,"+",A1:H1,,FALSE) | |||||||||
| 37 | -2 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | a:h=-37 (+-) | a-b-c-d-e-f-g-h |
| 38 | =FIND_FORMULA(A37:H37,-37,,A1:H1,,FALSE) | |||||||||
Download:
You can download the workbook with code and examples here
The code:
Select all
Function FIND_FORMULA(rValues As Range, iResult As Long, Optional sOperators As String = "+-", Optional rNames As Range = Nothing, Optional bFindForZero As Boolean = False, Optional bShowBrackets As Boolean = True, Optional bHidePlus As Boolean = True) As Variant
Dim vRetValue As Variant
If Not rValues.Rows.Count = 1 Or rValues.Columns.Count = 1 Then
vRetValue = xlErrValue
End If
If Not TypeName(vRetValue) = "Long" Then
If Len(sOperators) = 0 Then
sOperators = "+-"
End If
End If
If Not TypeName(vRetValue) = "Long" Then
If Not rNames Is Nothing Then
If Not rNames.Rows.Count = 1 Or rNames.Columns.Count = 1 Or Not rNames.Columns.Count = rValues.Columns.Count Then
vRetValue = xlErrValue
End If
End If
End If
If Not TypeName(vRetValue) = "Long" Then
Dim iRemainder As Integer
iRemainder = iResult
If iRemainder = 0 And Not bFindForZero Then
vRetValue = vbNullString
Else
If Application.WorksheetFunction.CountIf(rValues, iRemainder) = 0 Then
Dim iNumbers() As Integer
ReDim iNumbers(1 To rValues.Columns.Count)
Dim sStrings() As String
ReDim sStrings(1 To rValues.Columns.Count)
Dim i As Integer
For i = 1 To UBound(iNumbers)
iNumbers(i) = rValues.Cells(1, i).Value
If rNames Is Nothing Then
sStrings(i) = rValues.Cells(i).Address(RowAbsolute:=False, ColumnAbsolute:=False)
Else
sStrings(i) = rNames.Cells(i).Value
End If
Next i
Dim vNumberCombinations() As Variant
Dim sStringCombinations() As String
ReDim vNumberCombinations(0)
ReDim sStringCombinations(0)
Dim vNumberComb() As Variant
Dim sStringComb() As String
For i = 2 To UBound(iNumbers)
ReDim vNumberComb(1 To i)
ReDim sStringComb(1 To i)
Call subNumberCombinations(vNumberCombinations, sStringCombinations, vNumberComb, sStringComb, iNumbers, sStrings, i, 1, 1)
Next i
Dim bExists As Boolean
Dim sNumberFormula As String, sStringFormula As String
Dim sOperComp As String
Dim iOperComp As Integer, iEle As Integer
For i = 0 To UBound(vNumberCombinations)
For iOperComp = 0 To Application.WorksheetFunction.Power(Len(sOperators), UBound(Split(vNumberCombinations(i), ","))) - 1
sOperComp = fncGetOperators(sOperators, iOperComp, UBound(Split(vNumberCombinations(i), ",")))
sNumberFormula = Split(vNumberCombinations(i), ",")(0)
sStringFormula = Split(sStringCombinations(i), ",")(0)
For iEle = 1 To UBound(Split(vNumberCombinations(i), ","))
sNumberFormula = sNumberFormula & Mid(sOperComp, iEle, 1) & Split(vNumberCombinations(i), ",")(iEle)
sStringFormula = sStringFormula & Mid(sOperComp, iEle, 1) & Split(sStringCombinations(i), ",")(iEle)
Next iEle
If Evaluate(sNumberFormula) = iRemainder Then
vRetValue = vRetValue & IIf(bHidePlus, vbNullString, "+") & IIf(bShowBrackets, "(", vbNullString) & sStringFormula & IIf(bShowBrackets, ")", vbNullString)
bExists = True
Exit For
ElseIf Evaluate(sNumberFormula) = -iRemainder Then
bShowBrackets = True
vRetValue = vRetValue & "-" & IIf(bShowBrackets, "(", vbNullString) & sStringFormula & IIf(bShowBrackets, ")", vbNullString)
bExists = True
Exit For
End If
Next iOperComp
If bExists Then
Exit For
End If
Next i
If Not bExists Then
vRetValue = xlErrNA
End If
Else
With Application.WorksheetFunction
If rNames Is Nothing Then
vRetValue = vRetValue & rValues.Cells(.Match(iRemainder, rValues, 0)).Address(RowAbsolute:=False, ColumnAbsolute:=False)
Else
vRetValue = vRetValue & .Index(rNames, .Match(iRemainder, rValues, 0))
End If
End With 'Application.WorksheetFunction
End If
End If
End If
If TypeName(vRetValue) = "Long" Then
FIND_FORMULA = CVErr(vRetValue)
Else
FIND_FORMULA = vRetValue
End If
End Function
Private Sub subNumberCombinations(vNumberCombinations() As Variant, sStringCombinations() As String, vNumberComb() As Variant, sStringComb() As String, iNumbers() As Integer, sStrings() As String, iCount As Integer, iElement As Integer, iIndex As Integer)
Dim i As Long
For i = iElement To UBound(iNumbers)
vNumberComb(iIndex) = iNumbers(i)
sStringComb(iIndex) = sStrings(i)
If iIndex = iCount Then
If Not vNumberCombinations(0) = vbNullString Then
ReDim Preserve vNumberCombinations(UBound(vNumberCombinations) + 1)
ReDim Preserve sStringCombinations(UBound(sStringCombinations) + 1)
End If
vNumberCombinations(UBound(vNumberCombinations)) = Join(vNumberComb, ",")
sStringCombinations(UBound(sStringCombinations)) = Join(sStringComb, ",")
Else
Call subNumberCombinations(vNumberCombinations, sStringCombinations, vNumberComb, sStringComb, iNumbers, sStrings, iCount, i + 1, iIndex + 1)
End If
Next i
End Sub
Private Function fncGetOperators(sOperators As String, iNumber As Integer, iLength As Byte) As String
Dim sRetValue As String
If Len(sOperators) > 1 Then
Dim iRemainder As Integer
iRemainder = iNumber
sRetValue = vbNullString
While Not iRemainder = 0
sRetValue = Mid$(sOperators, iRemainder Mod Len(sOperators) + 1, 1) & sRetValue
iRemainder = iRemainder \ Len(sOperators)
Wend
End If
sRetValue = Replace(Space(iLength - Len(sRetValue)) & sRetValue, " ", Left$(sOperators, 1))
fncGetOperators = sRetValue
End Function
|
|
Tweet |
Working with two monitors is realy great. There are keyboard shortcuts in Windows 7 that make the work with them much easier and faster ...
No comments:
Post a Comment