Search formula for cell references in VBA












1














Within VBA, I want to search an excel formula (String) to find cell references.



Specifically I want to find the position(s) in the string where there is either a relative cell reference (ANY relative cell reference, not a specific one), or a mixed cell reference.




  • I don't need to find absolute cell references, though I can just check and ignore those.

  • I don't mind if the reference is on a different sheet, I'm happy to find the bit after the ! symbol.

  • I will need to make sure that it doesn't find things that look like cell references in strings or sheet names or data names.


How can I do this? (This is the main question)



My thoughts:



I can see how I would find mixed cell references - I'm pretty sure the $ symbol can only ever come up in either mixed cell references, absolute references, inside sheet names, or inside strings (can anyone confirm that?), so with the right regular expression or algorithm you could find all those cases and then just check if it is an absolute cell reference and ignore that.



But how to find any and all relative cell references? The only idea I have is similar to the above. Beyond cell references, are there ever any times in Excel Formulas (outside of sheet names or inside strings) where there is a number following a letter? Any formula names or anything? The only other one I can think of is in a defined data name, but I'm not sure if you can use those in a formula, especially a Conditional Formatting formula). Can anyone think of any other times?



Anyone have any ideas?










share|improve this question




















  • 4




    Look into Range.Precedents.
    – Mathieu Guindon
    Nov 12 '18 at 15:22






  • 2




    Would you be interested in regex?
    – Kubie
    Nov 12 '18 at 15:33










  • Thanks Mathieu. I mentioned I have a formula string, that's because it's from a Conditional Format. Still, I might be able to place the formula in an empty cell, trace the precedents, get a list of cells that are in the formula, and then search specifically for those. It's an interesting idea, though a pretty complicated one. Thanks
    – James Carlyle-Clarke
    Nov 12 '18 at 15:56










  • Hi Kubie, yes, I would very much be interested in RegEx, though I think the points about how to search for any and all relative cell references is an important one, and I don't know whether my suggestion would work.
    – James Carlyle-Clarke
    Nov 12 '18 at 15:57






  • 1




    One comment about your comments. instead of writing "Hi #Name", consider using @Name at the beginning of your comment. In your case it might be that Kubie and Mathieu never read your comment
    – Pierre44
    Nov 12 '18 at 16:19
















1














Within VBA, I want to search an excel formula (String) to find cell references.



Specifically I want to find the position(s) in the string where there is either a relative cell reference (ANY relative cell reference, not a specific one), or a mixed cell reference.




  • I don't need to find absolute cell references, though I can just check and ignore those.

  • I don't mind if the reference is on a different sheet, I'm happy to find the bit after the ! symbol.

  • I will need to make sure that it doesn't find things that look like cell references in strings or sheet names or data names.


How can I do this? (This is the main question)



My thoughts:



I can see how I would find mixed cell references - I'm pretty sure the $ symbol can only ever come up in either mixed cell references, absolute references, inside sheet names, or inside strings (can anyone confirm that?), so with the right regular expression or algorithm you could find all those cases and then just check if it is an absolute cell reference and ignore that.



But how to find any and all relative cell references? The only idea I have is similar to the above. Beyond cell references, are there ever any times in Excel Formulas (outside of sheet names or inside strings) where there is a number following a letter? Any formula names or anything? The only other one I can think of is in a defined data name, but I'm not sure if you can use those in a formula, especially a Conditional Formatting formula). Can anyone think of any other times?



Anyone have any ideas?










share|improve this question




















  • 4




    Look into Range.Precedents.
    – Mathieu Guindon
    Nov 12 '18 at 15:22






  • 2




    Would you be interested in regex?
    – Kubie
    Nov 12 '18 at 15:33










  • Thanks Mathieu. I mentioned I have a formula string, that's because it's from a Conditional Format. Still, I might be able to place the formula in an empty cell, trace the precedents, get a list of cells that are in the formula, and then search specifically for those. It's an interesting idea, though a pretty complicated one. Thanks
    – James Carlyle-Clarke
    Nov 12 '18 at 15:56










  • Hi Kubie, yes, I would very much be interested in RegEx, though I think the points about how to search for any and all relative cell references is an important one, and I don't know whether my suggestion would work.
    – James Carlyle-Clarke
    Nov 12 '18 at 15:57






  • 1




    One comment about your comments. instead of writing "Hi #Name", consider using @Name at the beginning of your comment. In your case it might be that Kubie and Mathieu never read your comment
    – Pierre44
    Nov 12 '18 at 16:19














1












1








1







Within VBA, I want to search an excel formula (String) to find cell references.



Specifically I want to find the position(s) in the string where there is either a relative cell reference (ANY relative cell reference, not a specific one), or a mixed cell reference.




  • I don't need to find absolute cell references, though I can just check and ignore those.

  • I don't mind if the reference is on a different sheet, I'm happy to find the bit after the ! symbol.

  • I will need to make sure that it doesn't find things that look like cell references in strings or sheet names or data names.


How can I do this? (This is the main question)



My thoughts:



I can see how I would find mixed cell references - I'm pretty sure the $ symbol can only ever come up in either mixed cell references, absolute references, inside sheet names, or inside strings (can anyone confirm that?), so with the right regular expression or algorithm you could find all those cases and then just check if it is an absolute cell reference and ignore that.



But how to find any and all relative cell references? The only idea I have is similar to the above. Beyond cell references, are there ever any times in Excel Formulas (outside of sheet names or inside strings) where there is a number following a letter? Any formula names or anything? The only other one I can think of is in a defined data name, but I'm not sure if you can use those in a formula, especially a Conditional Formatting formula). Can anyone think of any other times?



Anyone have any ideas?










share|improve this question















Within VBA, I want to search an excel formula (String) to find cell references.



Specifically I want to find the position(s) in the string where there is either a relative cell reference (ANY relative cell reference, not a specific one), or a mixed cell reference.




  • I don't need to find absolute cell references, though I can just check and ignore those.

  • I don't mind if the reference is on a different sheet, I'm happy to find the bit after the ! symbol.

  • I will need to make sure that it doesn't find things that look like cell references in strings or sheet names or data names.


How can I do this? (This is the main question)



My thoughts:



I can see how I would find mixed cell references - I'm pretty sure the $ symbol can only ever come up in either mixed cell references, absolute references, inside sheet names, or inside strings (can anyone confirm that?), so with the right regular expression or algorithm you could find all those cases and then just check if it is an absolute cell reference and ignore that.



But how to find any and all relative cell references? The only idea I have is similar to the above. Beyond cell references, are there ever any times in Excel Formulas (outside of sheet names or inside strings) where there is a number following a letter? Any formula names or anything? The only other one I can think of is in a defined data name, but I'm not sure if you can use those in a formula, especially a Conditional Formatting formula). Can anyone think of any other times?



Anyone have any ideas?







excel vba string formula






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 16:15

























asked Nov 12 '18 at 15:12









James Carlyle-Clarke

441415




441415








  • 4




    Look into Range.Precedents.
    – Mathieu Guindon
    Nov 12 '18 at 15:22






  • 2




    Would you be interested in regex?
    – Kubie
    Nov 12 '18 at 15:33










  • Thanks Mathieu. I mentioned I have a formula string, that's because it's from a Conditional Format. Still, I might be able to place the formula in an empty cell, trace the precedents, get a list of cells that are in the formula, and then search specifically for those. It's an interesting idea, though a pretty complicated one. Thanks
    – James Carlyle-Clarke
    Nov 12 '18 at 15:56










  • Hi Kubie, yes, I would very much be interested in RegEx, though I think the points about how to search for any and all relative cell references is an important one, and I don't know whether my suggestion would work.
    – James Carlyle-Clarke
    Nov 12 '18 at 15:57






  • 1




    One comment about your comments. instead of writing "Hi #Name", consider using @Name at the beginning of your comment. In your case it might be that Kubie and Mathieu never read your comment
    – Pierre44
    Nov 12 '18 at 16:19














  • 4




    Look into Range.Precedents.
    – Mathieu Guindon
    Nov 12 '18 at 15:22






  • 2




    Would you be interested in regex?
    – Kubie
    Nov 12 '18 at 15:33










  • Thanks Mathieu. I mentioned I have a formula string, that's because it's from a Conditional Format. Still, I might be able to place the formula in an empty cell, trace the precedents, get a list of cells that are in the formula, and then search specifically for those. It's an interesting idea, though a pretty complicated one. Thanks
    – James Carlyle-Clarke
    Nov 12 '18 at 15:56










  • Hi Kubie, yes, I would very much be interested in RegEx, though I think the points about how to search for any and all relative cell references is an important one, and I don't know whether my suggestion would work.
    – James Carlyle-Clarke
    Nov 12 '18 at 15:57






  • 1




    One comment about your comments. instead of writing "Hi #Name", consider using @Name at the beginning of your comment. In your case it might be that Kubie and Mathieu never read your comment
    – Pierre44
    Nov 12 '18 at 16:19








4




4




Look into Range.Precedents.
– Mathieu Guindon
Nov 12 '18 at 15:22




Look into Range.Precedents.
– Mathieu Guindon
Nov 12 '18 at 15:22




2




2




Would you be interested in regex?
– Kubie
Nov 12 '18 at 15:33




Would you be interested in regex?
– Kubie
Nov 12 '18 at 15:33












Thanks Mathieu. I mentioned I have a formula string, that's because it's from a Conditional Format. Still, I might be able to place the formula in an empty cell, trace the precedents, get a list of cells that are in the formula, and then search specifically for those. It's an interesting idea, though a pretty complicated one. Thanks
– James Carlyle-Clarke
Nov 12 '18 at 15:56




Thanks Mathieu. I mentioned I have a formula string, that's because it's from a Conditional Format. Still, I might be able to place the formula in an empty cell, trace the precedents, get a list of cells that are in the formula, and then search specifically for those. It's an interesting idea, though a pretty complicated one. Thanks
– James Carlyle-Clarke
Nov 12 '18 at 15:56












Hi Kubie, yes, I would very much be interested in RegEx, though I think the points about how to search for any and all relative cell references is an important one, and I don't know whether my suggestion would work.
– James Carlyle-Clarke
Nov 12 '18 at 15:57




Hi Kubie, yes, I would very much be interested in RegEx, though I think the points about how to search for any and all relative cell references is an important one, and I don't know whether my suggestion would work.
– James Carlyle-Clarke
Nov 12 '18 at 15:57




1




1




One comment about your comments. instead of writing "Hi #Name", consider using @Name at the beginning of your comment. In your case it might be that Kubie and Mathieu never read your comment
– Pierre44
Nov 12 '18 at 16:19




One comment about your comments. instead of writing "Hi #Name", consider using @Name at the beginning of your comment. In your case it might be that Kubie and Mathieu never read your comment
– Pierre44
Nov 12 '18 at 16:19












1 Answer
1






active

oldest

votes


















1














I wasn't sure what your use case is, but you could try something along the lines in this function:




This project uses Early Binding - you must set a reference to:



Microsoft VBScript Regular Expressions 5.5



Function findCellReferences(vTestVal As Variant) As Variant

'Check if vTestVal is a range, if so, convert to string
If TypeName(vTestVal) = "Range" Then
vTestVal = vTestVal.Formula
ElseIf TypeName(vTestVal) <> "String" Then
findCellReferences = "Type-Err!"
Exit Function
End If

Dim oMatches As MatchCollection

With New RegExp
.Pattern = "(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|" & _
"$?[a-z]{1,3}:$?[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])"
.IgnoreCase = True
.Global = True
If .test(vTestVal) Then
Dim i As Long, retArr()
Set oMatches = .Execute(vTestVal)
With oMatches
ReDim retArr(.Count - 1)
For i = 0 To .Count - 1
retArr(i) = .Item(i).SubMatches(0)
Next
End With
findCellReferences = Join(retArr, ",")
Else
findCellReferences = False
End If
End With

End Function


This function can accept two different data-types:




  1. Range

  2. String


This allows you to use this as a worksheet function to test the textual value of a formula, or you can use this to test an input string directly.



Here's the return checking a cell:



enter image description here



And here's what the formulas look like for the above:



enter image description here



This can also be used within VBA:



Sub Test()

Rem: Passing a string argument
Debug.Print findCellReferences("A1:B1, $C1")
' Prints: A1:B1,$C1

End Sub




Breaking down the Regular Expression: Regex101



(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|$?[a-z]{1,3}:$?
[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])




  • (?:^|[,(=s]) Requires one of the following to occur before your match



    • ^ Start of string; or

    • A single character which is either



      • , a comma (useful in formulas)


      • ! an exclamation (for Sheet! references)


      • ( opening parenthesis (useful in formulas)


      • = literal equal sign (useful in formulas)


      • s a whitespace character






  • (...) capturing group that will return your value (one of three options)



    • $?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)? not entire row / column



      • $ for an absolute reference (column), followed by ? making it optional


      • [A-Z] character class for any letter, + one or more times


      • $ for an absolute reference (row), followed by ? making it optional


      • d any digit, + one or more times


      • (?:...) non capturing group to match a range of ranges (such as A1:B1)


        • This uses the same methods as above

        • Followed by ?, making the entire non-capturing group optional






    • $?[a-z]{1,3}:$?[a-z]{1,3} Entire Columns, such as A:C


    • $?d+:$?d+ Entire Rows, such as 1:3




  • (?:$|[s,)]) Requires one of the following to occur after your match



    • $ end of string; or

    • A single character which is one of



      • s a whitespace character


      • , a comma


      • ) closing parenthesis








Credits:


Suggestions by tripleee:

- Use Character class [xyz] instead of OR statements (?:x|y|z)

- Better indention of breakdown

- Grammar usage


Suggestions by Makyen:

- Support for entire rows 1:4 and columns A:C

- Limit FPs by checking Excel's max column limitation [a-z]{1,3} (instead of [a-z]+)








share|improve this answer























  • Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
    – James Carlyle-Clarke
    Nov 13 '18 at 6:13










  • I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
    – K.Dᴀᴠɪs
    Nov 13 '18 at 6:14












  • Will this exclude bits of literal strings that happen to look like cell references?
    – chris neilsen
    Nov 13 '18 at 7:51






  • 1




    That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
    – K.Dᴀᴠɪs
    Nov 13 '18 at 8:05












  • Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
    – James Carlyle-Clarke
    Nov 19 '18 at 2:33











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53265024%2fsearch-formula-for-cell-references-in-vba%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














I wasn't sure what your use case is, but you could try something along the lines in this function:




This project uses Early Binding - you must set a reference to:



Microsoft VBScript Regular Expressions 5.5



Function findCellReferences(vTestVal As Variant) As Variant

'Check if vTestVal is a range, if so, convert to string
If TypeName(vTestVal) = "Range" Then
vTestVal = vTestVal.Formula
ElseIf TypeName(vTestVal) <> "String" Then
findCellReferences = "Type-Err!"
Exit Function
End If

Dim oMatches As MatchCollection

With New RegExp
.Pattern = "(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|" & _
"$?[a-z]{1,3}:$?[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])"
.IgnoreCase = True
.Global = True
If .test(vTestVal) Then
Dim i As Long, retArr()
Set oMatches = .Execute(vTestVal)
With oMatches
ReDim retArr(.Count - 1)
For i = 0 To .Count - 1
retArr(i) = .Item(i).SubMatches(0)
Next
End With
findCellReferences = Join(retArr, ",")
Else
findCellReferences = False
End If
End With

End Function


This function can accept two different data-types:




  1. Range

  2. String


This allows you to use this as a worksheet function to test the textual value of a formula, or you can use this to test an input string directly.



Here's the return checking a cell:



enter image description here



And here's what the formulas look like for the above:



enter image description here



This can also be used within VBA:



Sub Test()

Rem: Passing a string argument
Debug.Print findCellReferences("A1:B1, $C1")
' Prints: A1:B1,$C1

End Sub




Breaking down the Regular Expression: Regex101



(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|$?[a-z]{1,3}:$?
[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])




  • (?:^|[,(=s]) Requires one of the following to occur before your match



    • ^ Start of string; or

    • A single character which is either



      • , a comma (useful in formulas)


      • ! an exclamation (for Sheet! references)


      • ( opening parenthesis (useful in formulas)


      • = literal equal sign (useful in formulas)


      • s a whitespace character






  • (...) capturing group that will return your value (one of three options)



    • $?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)? not entire row / column



      • $ for an absolute reference (column), followed by ? making it optional


      • [A-Z] character class for any letter, + one or more times


      • $ for an absolute reference (row), followed by ? making it optional


      • d any digit, + one or more times


      • (?:...) non capturing group to match a range of ranges (such as A1:B1)


        • This uses the same methods as above

        • Followed by ?, making the entire non-capturing group optional






    • $?[a-z]{1,3}:$?[a-z]{1,3} Entire Columns, such as A:C


    • $?d+:$?d+ Entire Rows, such as 1:3




  • (?:$|[s,)]) Requires one of the following to occur after your match



    • $ end of string; or

    • A single character which is one of



      • s a whitespace character


      • , a comma


      • ) closing parenthesis








Credits:


Suggestions by tripleee:

- Use Character class [xyz] instead of OR statements (?:x|y|z)

- Better indention of breakdown

- Grammar usage


Suggestions by Makyen:

- Support for entire rows 1:4 and columns A:C

- Limit FPs by checking Excel's max column limitation [a-z]{1,3} (instead of [a-z]+)








share|improve this answer























  • Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
    – James Carlyle-Clarke
    Nov 13 '18 at 6:13










  • I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
    – K.Dᴀᴠɪs
    Nov 13 '18 at 6:14












  • Will this exclude bits of literal strings that happen to look like cell references?
    – chris neilsen
    Nov 13 '18 at 7:51






  • 1




    That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
    – K.Dᴀᴠɪs
    Nov 13 '18 at 8:05












  • Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
    – James Carlyle-Clarke
    Nov 19 '18 at 2:33
















1














I wasn't sure what your use case is, but you could try something along the lines in this function:




This project uses Early Binding - you must set a reference to:



Microsoft VBScript Regular Expressions 5.5



Function findCellReferences(vTestVal As Variant) As Variant

'Check if vTestVal is a range, if so, convert to string
If TypeName(vTestVal) = "Range" Then
vTestVal = vTestVal.Formula
ElseIf TypeName(vTestVal) <> "String" Then
findCellReferences = "Type-Err!"
Exit Function
End If

Dim oMatches As MatchCollection

With New RegExp
.Pattern = "(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|" & _
"$?[a-z]{1,3}:$?[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])"
.IgnoreCase = True
.Global = True
If .test(vTestVal) Then
Dim i As Long, retArr()
Set oMatches = .Execute(vTestVal)
With oMatches
ReDim retArr(.Count - 1)
For i = 0 To .Count - 1
retArr(i) = .Item(i).SubMatches(0)
Next
End With
findCellReferences = Join(retArr, ",")
Else
findCellReferences = False
End If
End With

End Function


This function can accept two different data-types:




  1. Range

  2. String


This allows you to use this as a worksheet function to test the textual value of a formula, or you can use this to test an input string directly.



Here's the return checking a cell:



enter image description here



And here's what the formulas look like for the above:



enter image description here



This can also be used within VBA:



Sub Test()

Rem: Passing a string argument
Debug.Print findCellReferences("A1:B1, $C1")
' Prints: A1:B1,$C1

End Sub




Breaking down the Regular Expression: Regex101



(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|$?[a-z]{1,3}:$?
[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])




  • (?:^|[,(=s]) Requires one of the following to occur before your match



    • ^ Start of string; or

    • A single character which is either



      • , a comma (useful in formulas)


      • ! an exclamation (for Sheet! references)


      • ( opening parenthesis (useful in formulas)


      • = literal equal sign (useful in formulas)


      • s a whitespace character






  • (...) capturing group that will return your value (one of three options)



    • $?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)? not entire row / column



      • $ for an absolute reference (column), followed by ? making it optional


      • [A-Z] character class for any letter, + one or more times


      • $ for an absolute reference (row), followed by ? making it optional


      • d any digit, + one or more times


      • (?:...) non capturing group to match a range of ranges (such as A1:B1)


        • This uses the same methods as above

        • Followed by ?, making the entire non-capturing group optional






    • $?[a-z]{1,3}:$?[a-z]{1,3} Entire Columns, such as A:C


    • $?d+:$?d+ Entire Rows, such as 1:3




  • (?:$|[s,)]) Requires one of the following to occur after your match



    • $ end of string; or

    • A single character which is one of



      • s a whitespace character


      • , a comma


      • ) closing parenthesis








Credits:


Suggestions by tripleee:

- Use Character class [xyz] instead of OR statements (?:x|y|z)

- Better indention of breakdown

- Grammar usage


Suggestions by Makyen:

- Support for entire rows 1:4 and columns A:C

- Limit FPs by checking Excel's max column limitation [a-z]{1,3} (instead of [a-z]+)








share|improve this answer























  • Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
    – James Carlyle-Clarke
    Nov 13 '18 at 6:13










  • I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
    – K.Dᴀᴠɪs
    Nov 13 '18 at 6:14












  • Will this exclude bits of literal strings that happen to look like cell references?
    – chris neilsen
    Nov 13 '18 at 7:51






  • 1




    That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
    – K.Dᴀᴠɪs
    Nov 13 '18 at 8:05












  • Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
    – James Carlyle-Clarke
    Nov 19 '18 at 2:33














1












1








1






I wasn't sure what your use case is, but you could try something along the lines in this function:




This project uses Early Binding - you must set a reference to:



Microsoft VBScript Regular Expressions 5.5



Function findCellReferences(vTestVal As Variant) As Variant

'Check if vTestVal is a range, if so, convert to string
If TypeName(vTestVal) = "Range" Then
vTestVal = vTestVal.Formula
ElseIf TypeName(vTestVal) <> "String" Then
findCellReferences = "Type-Err!"
Exit Function
End If

Dim oMatches As MatchCollection

With New RegExp
.Pattern = "(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|" & _
"$?[a-z]{1,3}:$?[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])"
.IgnoreCase = True
.Global = True
If .test(vTestVal) Then
Dim i As Long, retArr()
Set oMatches = .Execute(vTestVal)
With oMatches
ReDim retArr(.Count - 1)
For i = 0 To .Count - 1
retArr(i) = .Item(i).SubMatches(0)
Next
End With
findCellReferences = Join(retArr, ",")
Else
findCellReferences = False
End If
End With

End Function


This function can accept two different data-types:




  1. Range

  2. String


This allows you to use this as a worksheet function to test the textual value of a formula, or you can use this to test an input string directly.



Here's the return checking a cell:



enter image description here



And here's what the formulas look like for the above:



enter image description here



This can also be used within VBA:



Sub Test()

Rem: Passing a string argument
Debug.Print findCellReferences("A1:B1, $C1")
' Prints: A1:B1,$C1

End Sub




Breaking down the Regular Expression: Regex101



(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|$?[a-z]{1,3}:$?
[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])




  • (?:^|[,(=s]) Requires one of the following to occur before your match



    • ^ Start of string; or

    • A single character which is either



      • , a comma (useful in formulas)


      • ! an exclamation (for Sheet! references)


      • ( opening parenthesis (useful in formulas)


      • = literal equal sign (useful in formulas)


      • s a whitespace character






  • (...) capturing group that will return your value (one of three options)



    • $?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)? not entire row / column



      • $ for an absolute reference (column), followed by ? making it optional


      • [A-Z] character class for any letter, + one or more times


      • $ for an absolute reference (row), followed by ? making it optional


      • d any digit, + one or more times


      • (?:...) non capturing group to match a range of ranges (such as A1:B1)


        • This uses the same methods as above

        • Followed by ?, making the entire non-capturing group optional






    • $?[a-z]{1,3}:$?[a-z]{1,3} Entire Columns, such as A:C


    • $?d+:$?d+ Entire Rows, such as 1:3




  • (?:$|[s,)]) Requires one of the following to occur after your match



    • $ end of string; or

    • A single character which is one of



      • s a whitespace character


      • , a comma


      • ) closing parenthesis








Credits:


Suggestions by tripleee:

- Use Character class [xyz] instead of OR statements (?:x|y|z)

- Better indention of breakdown

- Grammar usage


Suggestions by Makyen:

- Support for entire rows 1:4 and columns A:C

- Limit FPs by checking Excel's max column limitation [a-z]{1,3} (instead of [a-z]+)








share|improve this answer














I wasn't sure what your use case is, but you could try something along the lines in this function:




This project uses Early Binding - you must set a reference to:



Microsoft VBScript Regular Expressions 5.5



Function findCellReferences(vTestVal As Variant) As Variant

'Check if vTestVal is a range, if so, convert to string
If TypeName(vTestVal) = "Range" Then
vTestVal = vTestVal.Formula
ElseIf TypeName(vTestVal) <> "String" Then
findCellReferences = "Type-Err!"
Exit Function
End If

Dim oMatches As MatchCollection

With New RegExp
.Pattern = "(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|" & _
"$?[a-z]{1,3}:$?[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])"
.IgnoreCase = True
.Global = True
If .test(vTestVal) Then
Dim i As Long, retArr()
Set oMatches = .Execute(vTestVal)
With oMatches
ReDim retArr(.Count - 1)
For i = 0 To .Count - 1
retArr(i) = .Item(i).SubMatches(0)
Next
End With
findCellReferences = Join(retArr, ",")
Else
findCellReferences = False
End If
End With

End Function


This function can accept two different data-types:




  1. Range

  2. String


This allows you to use this as a worksheet function to test the textual value of a formula, or you can use this to test an input string directly.



Here's the return checking a cell:



enter image description here



And here's what the formulas look like for the above:



enter image description here



This can also be used within VBA:



Sub Test()

Rem: Passing a string argument
Debug.Print findCellReferences("A1:B1, $C1")
' Prints: A1:B1,$C1

End Sub




Breaking down the Regular Expression: Regex101



(?:^|[,!(=s])((?:$?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)?|$?[a-z]{1,3}:$?
[a-z]{1,3}|$?d+:$?d+))(?:$|[s,)])




  • (?:^|[,(=s]) Requires one of the following to occur before your match



    • ^ Start of string; or

    • A single character which is either



      • , a comma (useful in formulas)


      • ! an exclamation (for Sheet! references)


      • ( opening parenthesis (useful in formulas)


      • = literal equal sign (useful in formulas)


      • s a whitespace character






  • (...) capturing group that will return your value (one of three options)



    • $?[A-Z]{1,3}$?d+(?::$?[A-Z]{1,3}$?d+)? not entire row / column



      • $ for an absolute reference (column), followed by ? making it optional


      • [A-Z] character class for any letter, + one or more times


      • $ for an absolute reference (row), followed by ? making it optional


      • d any digit, + one or more times


      • (?:...) non capturing group to match a range of ranges (such as A1:B1)


        • This uses the same methods as above

        • Followed by ?, making the entire non-capturing group optional






    • $?[a-z]{1,3}:$?[a-z]{1,3} Entire Columns, such as A:C


    • $?d+:$?d+ Entire Rows, such as 1:3




  • (?:$|[s,)]) Requires one of the following to occur after your match



    • $ end of string; or

    • A single character which is one of



      • s a whitespace character


      • , a comma


      • ) closing parenthesis








Credits:


Suggestions by tripleee:

- Use Character class [xyz] instead of OR statements (?:x|y|z)

- Better indention of breakdown

- Grammar usage


Suggestions by Makyen:

- Support for entire rows 1:4 and columns A:C

- Limit FPs by checking Excel's max column limitation [a-z]{1,3} (instead of [a-z]+)









share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 13 '18 at 8:23

























answered Nov 13 '18 at 5:22









K.Dᴀᴠɪs

6,956112239




6,956112239












  • Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
    – James Carlyle-Clarke
    Nov 13 '18 at 6:13










  • I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
    – K.Dᴀᴠɪs
    Nov 13 '18 at 6:14












  • Will this exclude bits of literal strings that happen to look like cell references?
    – chris neilsen
    Nov 13 '18 at 7:51






  • 1




    That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
    – K.Dᴀᴠɪs
    Nov 13 '18 at 8:05












  • Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
    – James Carlyle-Clarke
    Nov 19 '18 at 2:33


















  • Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
    – James Carlyle-Clarke
    Nov 13 '18 at 6:13










  • I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
    – K.Dᴀᴠɪs
    Nov 13 '18 at 6:14












  • Will this exclude bits of literal strings that happen to look like cell references?
    – chris neilsen
    Nov 13 '18 at 7:51






  • 1




    That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
    – K.Dᴀᴠɪs
    Nov 13 '18 at 8:05












  • Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
    – James Carlyle-Clarke
    Nov 19 '18 at 2:33
















Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
– James Carlyle-Clarke
Nov 13 '18 at 6:13




Hi K. Davis, you've certainly given me a lot to look through and experiment with. Before that process I can only thank you deeply for taking the time and expending the effort. I don't know what the effect of changes @tripleee's changes to the code are, if any, but I'll look at those too.
– James Carlyle-Clarke
Nov 13 '18 at 6:13












I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
– K.Dᴀᴠɪs
Nov 13 '18 at 6:14






I consulted him after I made this post - his edits are certainly welcome @JamesCarlyle-Clarke
– K.Dᴀᴠɪs
Nov 13 '18 at 6:14














Will this exclude bits of literal strings that happen to look like cell references?
– chris neilsen
Nov 13 '18 at 7:51




Will this exclude bits of literal strings that happen to look like cell references?
– chris neilsen
Nov 13 '18 at 7:51




1




1




That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
– K.Dᴀᴠɪs
Nov 13 '18 at 8:05






That could be negated by removing the s from the equation. OP will just have to prevent spaces around legitimate ranges @chrisneilsen - The issue is that VBScript RegEx doesn't support lookarounds.
– K.Dᴀᴠɪs
Nov 13 '18 at 8:05














Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
– James Carlyle-Clarke
Nov 19 '18 at 2:33




Hi K. Davis, that's quite a thing of beauty and it seems to find any references passed to functions eg SUM(H7:M7). I haven't tested all of the edge cases (eg custom function names with letter followed by a number, named ranges with similar). The problem is it doesn't seem to find either cell reference in 'A3+B4' (with or without the equals sign). Regular expressions is not my area of expertise so I can't immediately see how I would improve on that. I also don't really get the last comment you made above, but it sounds like you are saying I should remove any spaces other than in strings?
– James Carlyle-Clarke
Nov 19 '18 at 2:33


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53265024%2fsearch-formula-for-cell-references-in-vba%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Hercules Kyvelos

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud