How in to parse constants in formula to cells

E

EagleOne

2003

If I have a "formulas" like:
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(A1*3) 'Need all constants
including the "3" in (A1*3) parsed to cells Z1 thru Z10

-or-

=Round(A1*0.035) ' Need the.35 parsed to Z11

-or-

=P39/$C40*12-P39 'Need the "12" parsed to Z13

-or-

=1000/2 Need 1000 parsed to Z14 and 2 parsed to Z15

I have thought of Cells.Find; Mid(), but what is the smartest lines of VBA code to evaluate formulas
for constants whether + - * / and then parse those constants to cells elsewhere on the w/s?

TIA EagleOne
 
G

Guest

This is just an idea.

1. using SUBSTITUTE() replace + - / * ^ with a common symbol.
2. using SPLIT() separate the equation into pieces
3. using IsNumber() or IsNumeric() find the pieces that are numbers
 
E

EagleOne

Interesting idea.

My idea was to LEN( Formula).
For/next loop the Formula string from Left to Right while incrementing the start point in Mid() till
Len(Formula).

That said, there are best ideas out there.

Thanks for your time/effort

EagleOne
 
R

Ron Rosenfeld

2003

If I have a "formulas" like:
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(A1*3) 'Need all constants
including the "3" in (A1*3) parsed to cells Z1 thru Z10

-or-

=Round(A1*0.035) ' Need the.35 parsed to Z11

-or-

=P39/$C40*12-P39 'Need the "12" parsed to Z13

-or-

=1000/2 Need 1000 parsed to Z14 and 2 parsed to Z15

I have thought of Cells.Find; Mid(), but what is the smartest lines of VBA code to evaluate formulas
for constants whether + - * / and then parse those constants to cells elsewhere on the w/s?

TIA EagleOne


Is your ROUND function supposed to be an actual Excel function? If so, the
syntax is wrong as you've left out the number of digits:

=ROUND(A1*0.035,num_digits).

Since num_digits will also be a constant, would you want that extracted also?
--ron
 
E

EagleOne

An excellent question. The answer is No to formula arguments. I need just the constants used by or
in the formula.
 
R

Ron Rosenfeld

An excellent question. The answer is No to formula arguments. I need just the constants used by or
in the formula.

That makes it very difficult.

Without that requirement, you could easily strip out the operators and cell
references by using Regular Expressions, and then return everything else that
is numeric.

With the requirement that numeric arguments to functions not be returned, such
as the type I mentioned, you would have to have some kind of table to analyze
each function. I can't think of any other way to, for example, given:

=ROUND(.035,1)

to extract the ".035" but not extract the "1"


--ron
 
R

Ron Rosenfeld

Appreciate your time & knowledge. I agree, the challenge is awesome.

EagleOne

If I were going to do that, I think I would first replace every character that
is a function parameter with a nonsense string, perhaps a tilde ~.

Then replace all the cell references and operators with tilde's.

Then extract the numbers that remain.

I would use regular expressions to do all that.
--ron
 
E

EagleOne

Ron,

Here is what I came up with. Any thoughts for improvement appreciated.

For testing, the "formula" I used in "A1":
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(C1*3)

My results are:
687319~523187~7344000~758450~2232642~1995819~2721538~1491693~723564~3

Because I changed the operational signs to "~" I have lost positive vs negative numbers.

Can you think of a way to preserve the positive vs negative numbers?

EagleOne
 
E

EagleOne

Forgot the code:


Ron,

Here is what I came up with. Any thoughts for improvement appreciated.
****************************
Sub ExtractFormulaConstants()
Dim X As String, Z As String
Dim Y As Variant, Signs As Variant
Dim Ndx As Long
Signs = Array("=", "(", ")", "+", "-", "*", "/")
X = Range("A1").Formula
Z = ""
For Ndx = LBound(Signs) To UBound(Signs) Step 1
X = Replace(X, Signs(Ndx), "~")
Next
Y = Split(X, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
If IsNumeric(Y(Ndx)) Then
Z = Z & Y(Ndx) & "~"
End If
Next
If Right(Z, 1) = "~" Then
Z = Left(Z, Len(Z) - 1)
End If
Y = Split(Z, "~")
ActiveSheet.Range("G1:G" & UBound(Y) + 1).Resize(UBound(Y) + 1) = Split(Z, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
Range("G" & Ndx + 1).Value = Y(Ndx)
Next

MsgBox "Process Completed! Press OK to Continue"

End Sub




****************************
For testing, the "formula" I used in "A1":
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(C1*3)

My results are:
687319~523187~7344000~758450~2232642~1995819~2721538~1491693~723564~3

Because I changed the operational signs to "~" I have lost positive vs negative numbers.

Can you think of a way to preserve the positive vs negative numbers?

EagleOne
 
R

Ron Rosenfeld

Forgot the code:


Ron,

Here is what I came up with. Any thoughts for improvement appreciated.
****************************
Sub ExtractFormulaConstants()
Dim X As String, Z As String
Dim Y As Variant, Signs As Variant
Dim Ndx As Long
Signs = Array("=", "(", ")", "+", "-", "*", "/")
X = Range("A1").Formula
Z = ""
For Ndx = LBound(Signs) To UBound(Signs) Step 1
X = Replace(X, Signs(Ndx), "~")
Next
Y = Split(X, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
If IsNumeric(Y(Ndx)) Then
Z = Z & Y(Ndx) & "~"
End If
Next
If Right(Z, 1) = "~" Then
Z = Left(Z, Len(Z) - 1)
End If
Y = Split(Z, "~")
ActiveSheet.Range("G1:G" & UBound(Y) + 1).Resize(UBound(Y) + 1) = Split(Z, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
Range("G" & Ndx + 1).Value = Y(Ndx)
Next

MsgBox "Process Completed! Press OK to Continue"

End Sub




****************************
For testing, the "formula" I used in "A1":
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(C1*3)

My results are:
687319~523187~7344000~758450~2232642~1995819~2721538~1491693~723564~3

Because I changed the operational signs to "~" I have lost positive vs negative numbers.

Can you think of a way to preserve the positive vs negative numbers?

EagleOne

If you want to treat the "-" as part of the number when it precedes a number,
as opposed to treating it as an operator, then

Using your approach, you could first
Replace all the "-" with "+-"

and then remove "-" from your list of signs.

Here's a routine that uses regular expressions to do the same thing. It will
work on your sample data. However, it would need to be extended to take care
of the worksheet function issue I raised earlier.

In order for this to run, from the VBA Editor top menu, select
Tools/References
Select: Microsoft VBScript Regular Expressions 5.5


=========================================
Option Explicit
Sub ParseFormula()
Dim FormConstants()
Dim FormulaText As String
Dim Pattern As String
Dim CellRef As String
Dim Operator As String
Dim Ignore As String
Dim NumConstant As String
Dim i As Long

Operator = "[/*^&()=<>,]"
CellRef = "\$?[A-Z]{1,2}\$?\d{1,5}"
Ignore = "(" & Operator & "|" & CellRef & ")"
NumConstant = "-?(\d*\.)?\d+"

FormulaText = Selection.Formula

FormulaText = RESub(FormulaText, Ignore, "~")
ReDim FormConstants(1 To RECount(FormulaText, NumConstant))

For i = 1 To UBound(FormConstants)
FormConstants(i) = REMid(FormulaText, NumConstant, i)
Next i

For i = 1 To UBound(FormConstants)
Selection.Offset(0, i) = FormConstants(i)
Next i

End Sub
'------------------------------
Function REMid(str As String, Pattern As String, _
Optional Index As Variant = 1, _
Optional CaseSensitive As Boolean = True) _
As Variant 'Variant as value may be string or array

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

Dim i As Long 'counter
Dim t() As String 'container for array results

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

'Test whether the String can be compared.
If (objRegExp.Test(str) = True) Then

'Get the matches.
Set colMatches = objRegExp.Execute(str) ' Execute search.

On Error Resume Next 'return null string if a colmatch index is non-existent
If IsArray(Index) Then
ReDim t(1 To UBound(Index))
For i = 1 To UBound(Index)
t(i) = colMatches(Index(i) - 1)
Next i
REMid = t()
Else
REMid = CStr(colMatches(Index - 1))
If IsEmpty(REMid) Then REMid = ""
End If
On Error GoTo 0 'reset error handler
Else
REMid = ""
End If
End Function
'-------------------------------
Function RECount(str As String, Pattern As String, _
Optional CaseSensitive As Boolean = True) As Long

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

'Test whether the String can be compared.
If (objRegExp.Test(str) = True) Then

'Get the matches.
Set colMatches = objRegExp.Execute(str) ' Execute search.
RECount = colMatches.Count
Else
RECount = 0
End If
End Function
'--------------------------
Function RESub(str As String, Pattern As String, _
Optional NewText As String = "", _
Optional Index As Variant = 1, _
Optional CaseSensitive As Boolean = True) _
As Variant 'Variant as value may be string or array

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

Dim i As Long 'counter
Dim t() As String 'container for array results

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

RESub = objRegExp.Replace(str, NewText)

End Function
'=========================================
--ron
 
E

EagleOne

Ron,

I'll work on this tomorrow morning. Thank you so much for your time and knowledge.

If possible, check back tomorrow.

EagleOne


Ron Rosenfeld said:
Forgot the code:


Ron,

Here is what I came up with. Any thoughts for improvement appreciated.
****************************
Sub ExtractFormulaConstants()
Dim X As String, Z As String
Dim Y As Variant, Signs As Variant
Dim Ndx As Long
Signs = Array("=", "(", ")", "+", "-", "*", "/")
X = Range("A1").Formula
Z = ""
For Ndx = LBound(Signs) To UBound(Signs) Step 1
X = Replace(X, Signs(Ndx), "~")
Next
Y = Split(X, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
If IsNumeric(Y(Ndx)) Then
Z = Z & Y(Ndx) & "~"
End If
Next
If Right(Z, 1) = "~" Then
Z = Left(Z, Len(Z) - 1)
End If
Y = Split(Z, "~")
ActiveSheet.Range("G1:G" & UBound(Y) + 1).Resize(UBound(Y) + 1) = Split(Z, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
Range("G" & Ndx + 1).Value = Y(Ndx)
Next

MsgBox "Process Completed! Press OK to Continue"

End Sub




****************************
For testing, the "formula" I used in "A1":
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(C1*3)

My results are:
687319~523187~7344000~758450~2232642~1995819~2721538~1491693~723564~3

Because I changed the operational signs to "~" I have lost positive vs negative numbers.

Can you think of a way to preserve the positive vs negative numbers?

EagleOne

If you want to treat the "-" as part of the number when it precedes a number,
as opposed to treating it as an operator, then

Using your approach, you could first
Replace all the "-" with "+-"

and then remove "-" from your list of signs.

Here's a routine that uses regular expressions to do the same thing. It will
work on your sample data. However, it would need to be extended to take care
of the worksheet function issue I raised earlier.

In order for this to run, from the VBA Editor top menu, select
Tools/References
Select: Microsoft VBScript Regular Expressions 5.5


=========================================
Option Explicit
Sub ParseFormula()
Dim FormConstants()
Dim FormulaText As String
Dim Pattern As String
Dim CellRef As String
Dim Operator As String
Dim Ignore As String
Dim NumConstant As String
Dim i As Long

Operator = "[/*^&()=<>,]"
CellRef = "\$?[A-Z]{1,2}\$?\d{1,5}"
Ignore = "(" & Operator & "|" & CellRef & ")"
NumConstant = "-?(\d*\.)?\d+"

FormulaText = Selection.Formula

FormulaText = RESub(FormulaText, Ignore, "~")
ReDim FormConstants(1 To RECount(FormulaText, NumConstant))

For i = 1 To UBound(FormConstants)
FormConstants(i) = REMid(FormulaText, NumConstant, i)
Next i

For i = 1 To UBound(FormConstants)
Selection.Offset(0, i) = FormConstants(i)
Next i

End Sub
'------------------------------
Function REMid(str As String, Pattern As String, _
Optional Index As Variant = 1, _
Optional CaseSensitive As Boolean = True) _
As Variant 'Variant as value may be string or array

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

Dim i As Long 'counter
Dim t() As String 'container for array results

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

'Test whether the String can be compared.
If (objRegExp.Test(str) = True) Then

'Get the matches.
Set colMatches = objRegExp.Execute(str) ' Execute search.

On Error Resume Next 'return null string if a colmatch index is non-existent
If IsArray(Index) Then
ReDim t(1 To UBound(Index))
For i = 1 To UBound(Index)
t(i) = colMatches(Index(i) - 1)
Next i
REMid = t()
Else
REMid = CStr(colMatches(Index - 1))
If IsEmpty(REMid) Then REMid = ""
End If
On Error GoTo 0 'reset error handler
Else
REMid = ""
End If
End Function
'-------------------------------
Function RECount(str As String, Pattern As String, _
Optional CaseSensitive As Boolean = True) As Long

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

'Test whether the String can be compared.
If (objRegExp.Test(str) = True) Then

'Get the matches.
Set colMatches = objRegExp.Execute(str) ' Execute search.
RECount = colMatches.Count
Else
RECount = 0
End If
End Function
'--------------------------
Function RESub(str As String, Pattern As String, _
Optional NewText As String = "", _
Optional Index As Variant = 1, _
Optional CaseSensitive As Boolean = True) _
As Variant 'Variant as value may be string or array

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

Dim i As Long 'counter
Dim t() As String 'container for array results

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

RESub = objRegExp.Replace(str, NewText)

End Function
'=========================================
--ron
 
E

EagleOne

Ron,

Could you be more specific with your comment:

"However, it would need to be extended to take care
of the worksheet function issue I raised earlier."

Other than my error with the Round worksheet function argument,
I am not sure what you mean.

Thanks, EagleOne


Ron Rosenfeld said:
Forgot the code:


Ron,

Here is what I came up with. Any thoughts for improvement appreciated.
****************************
Sub ExtractFormulaConstants()
Dim X As String, Z As String
Dim Y As Variant, Signs As Variant
Dim Ndx As Long
Signs = Array("=", "(", ")", "+", "-", "*", "/")
X = Range("A1").Formula
Z = ""
For Ndx = LBound(Signs) To UBound(Signs) Step 1
X = Replace(X, Signs(Ndx), "~")
Next
Y = Split(X, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
If IsNumeric(Y(Ndx)) Then
Z = Z & Y(Ndx) & "~"
End If
Next
If Right(Z, 1) = "~" Then
Z = Left(Z, Len(Z) - 1)
End If
Y = Split(Z, "~")
ActiveSheet.Range("G1:G" & UBound(Y) + 1).Resize(UBound(Y) + 1) = Split(Z, "~")
For Ndx = LBound(Y) To UBound(Y) Step 1
Range("G" & Ndx + 1).Value = Y(Ndx)
Next

MsgBox "Process Completed! Press OK to Continue"

End Sub




****************************
For testing, the "formula" I used in "A1":
=687319+523187-7344000+758450+2232642+1995819-2721538+1491693+723564+(C1*3)

My results are:
687319~523187~7344000~758450~2232642~1995819~2721538~1491693~723564~3

Because I changed the operational signs to "~" I have lost positive vs negative numbers.

Can you think of a way to preserve the positive vs negative numbers?

EagleOne

If you want to treat the "-" as part of the number when it precedes a number,
as opposed to treating it as an operator, then

Using your approach, you could first
Replace all the "-" with "+-"

and then remove "-" from your list of signs.

Here's a routine that uses regular expressions to do the same thing. It will
work on your sample data. However, it would need to be extended to take care
of the worksheet function issue I raised earlier.

In order for this to run, from the VBA Editor top menu, select
Tools/References
Select: Microsoft VBScript Regular Expressions 5.5


=========================================
Option Explicit
Sub ParseFormula()
Dim FormConstants()
Dim FormulaText As String
Dim Pattern As String
Dim CellRef As String
Dim Operator As String
Dim Ignore As String
Dim NumConstant As String
Dim i As Long

Operator = "[/*^&()=<>,]"
CellRef = "\$?[A-Z]{1,2}\$?\d{1,5}"
Ignore = "(" & Operator & "|" & CellRef & ")"
NumConstant = "-?(\d*\.)?\d+"

FormulaText = Selection.Formula

FormulaText = RESub(FormulaText, Ignore, "~")
ReDim FormConstants(1 To RECount(FormulaText, NumConstant))

For i = 1 To UBound(FormConstants)
FormConstants(i) = REMid(FormulaText, NumConstant, i)
Next i

For i = 1 To UBound(FormConstants)
Selection.Offset(0, i) = FormConstants(i)
Next i

End Sub
'------------------------------
Function REMid(str As String, Pattern As String, _
Optional Index As Variant = 1, _
Optional CaseSensitive As Boolean = True) _
As Variant 'Variant as value may be string or array

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

Dim i As Long 'counter
Dim t() As String 'container for array results

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

'Test whether the String can be compared.
If (objRegExp.Test(str) = True) Then

'Get the matches.
Set colMatches = objRegExp.Execute(str) ' Execute search.

On Error Resume Next 'return null string if a colmatch index is non-existent
If IsArray(Index) Then
ReDim t(1 To UBound(Index))
For i = 1 To UBound(Index)
t(i) = colMatches(Index(i) - 1)
Next i
REMid = t()
Else
REMid = CStr(colMatches(Index - 1))
If IsEmpty(REMid) Then REMid = ""
End If
On Error GoTo 0 'reset error handler
Else
REMid = ""
End If
End Function
'-------------------------------
Function RECount(str As String, Pattern As String, _
Optional CaseSensitive As Boolean = True) As Long

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

'Test whether the String can be compared.
If (objRegExp.Test(str) = True) Then

'Get the matches.
Set colMatches = objRegExp.Execute(str) ' Execute search.
RECount = colMatches.Count
Else
RECount = 0
End If
End Function
'--------------------------
Function RESub(str As String, Pattern As String, _
Optional NewText As String = "", _
Optional Index As Variant = 1, _
Optional CaseSensitive As Boolean = True) _
As Variant 'Variant as value may be string or array

Dim objRegExp As RegExp
Dim objMatch As Match
Dim colMatches As MatchCollection

Dim i As Long 'counter
Dim t() As String 'container for array results

' Create a regular expression object.
Set objRegExp = New RegExp

'Set the pattern by using the Pattern property.
objRegExp.Pattern = Pattern

' Set Case Insensitivity.
objRegExp.IgnoreCase = Not CaseSensitive

'Set global applicability.
objRegExp.Global = True

RESub = objRegExp.Replace(str, NewText)

End Function
'=========================================
--ron
 
R

Ron Rosenfeld

Ron,

Could you be more specific with your comment:

"However, it would need to be extended to take care
of the worksheet function issue I raised earlier."

Other than my error with the Round worksheet function argument,
I am not sure what you mean.

Thanks, EagleOne

You mentioned in an earlier post that did NOT want to return the values that
were used as function criteria, such as num_digits in the ROUND function.

There are a number of functions with similar criteria.

For example, range_lookup in the various LOOKUP functions (which can be
expressed as 0, 1, TRUE or FALSE)

match_type in the MATCH function

decimals & no_commas in the FIXED function

etc.

There's no general rule of which I am aware that can differentiate a number
that is a function argument versus a number that the function is operating on.
So unless someone comes up with something, you'd have to look at every
function, and only return the value that is in the appropriate location.


--ron
 
G

Guest

Something like this ?

Sub extractConstants()
Dim range_to_check As Range
Dim re As New RegExp
Dim matches, match, i, c

Set range_to_check = [A1:A4] ' SET AS NEEDED

re.Global = True
re.Pattern = "[=(^*/+\-](-*\d*\.?\d+)"
For Each c In range_to_check
Set matches = re.Execute(c.Formula)
For Each match In matches
i = i + 1
Debug.Print i, match, match.SubMatches(0)
Next
Next
End Sub
 
R

Ron Rosenfeld

Something like this ?

Sub extractConstants()
Dim range_to_check As Range
Dim re As New RegExp
Dim matches, match, i, c

Set range_to_check = [A1:A4] ' SET AS NEEDED

re.Global = True
re.Pattern = "[=(^*/+\-](-*\d*\.?\d+)"
For Each c In range_to_check
Set matches = re.Execute(c.Formula)
For Each match In matches
i = i + 1
Debug.Print i, match, match.SubMatches(0)
Next
Next
End Sub

Nice regex. I was trying to think of something like that but could not.

But it fails on formulas such as:

=AVERAGE(1,2,3)

It also fails to return the negative values, as the OP mentioned in a
subsequent post.


--ron
 
E

EagleOne

PapaDos,

Code works great. I have not used VbScript 5.5 before.

Was this task just easier done in VbScript? If you have time could you share in 25 words or less
(To keep your time to a minimum) why VbScript? I realize I am exposing my ignorance.

Ron Rosenfeld also suggested VbScript 5.5

Thanks EagleOne
 
E

EagleOne

Ron,
I was able to use PapaDos code as to negatives via:

Range("G" & i).Value = IIf(Left(match, 1) = "-", match, match.SubMatches(0))

That said, I am also interested re: =AVERAGE(1,2,3)

Both you and PapaDos spent a great deal of time for which I am very appreciative.

EagleOne


Ron Rosenfeld said:
Something like this ?

Sub extractConstants()
Dim range_to_check As Range
Dim re As New RegExp
Dim matches, match, i, c

Set range_to_check = [A1:A4] ' SET AS NEEDED

re.Global = True
re.Pattern = "[=(^*/+\-](-*\d*\.?\d+)"
For Each c In range_to_check
Set matches = re.Execute(c.Formula)
For Each match In matches
i = i + 1
Debug.Print i, match, match.SubMatches(0)
Next
Next
End Sub

Nice regex. I was trying to think of something like that but could not.

But it fails on formulas such as:

=AVERAGE(1,2,3)

It also fails to return the negative values, as the OP mentioned in a
subsequent post.


--ron
 
R

Ron Rosenfeld

PapaDos,

Code works great. I have not used VbScript 5.5 before.

Was this task just easier done in VbScript? If you have time could you share in 25 words or less
(To keep your time to a minimum) why VbScript? I realize I am exposing my ignorance.

Ron Rosenfeld also suggested VbScript 5.5

Thanks EagleOne

VbScript Regular Expressions is used in both our routines so we can use Regular
Expressions, which are a much more efficient method of handling this sort of
text manipulation.


--ron
 

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

Top