Solved

Need help with a RegEx function in Excel 2003

Posted on 2010-09-15
5
365 Views
Last Modified: 2012-05-10
Please take a look at the attached workbook. I need to replace the word "ActiveCell" in the RegEx function "GetSeats" so that it will calculate and re-calculate correctly for all cells containing the function. I tried using "InputCell," but that didn't work. I don't know enough about Regular Expressions to know what in the function code refers to the cell.

Also, when you have two row groupings in the cell being referenced by the function (such as ROWS 9-11, ROWS 35-36), there should be a comma between the resulting strings, but there isn't.

Thanks,
John
Function GetSeats(InputCell As Range) As String

    Dim RegEx, RegM, RegMC

    Dim MyDic

    Dim tmpStr As String

    Dim i As Long

 

    Set MyDic = CreateObject("scripting.dictionary")

    Set RegEx = CreateObject("vbscript.regexp")

    With RegEx

        .Pattern = "ROW(S)? (\d+)-(\d+)"

        .Global = True

        .IgnoreCase = True

        If .test(InputCell.Value) Then

            Set RegMC = .Execute(InputCell)

            For Each RegM In RegMC

                If MyDic.exists(LCase$(RegM)) = False Then

                    For i = RegM.submatches(1) To RegM.submatches(2)

                        Select Case i

                        Case Is <= ActiveCell.Offset(0, 96)

                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 111) & ", "

                        Case Is <= ActiveCell.Offset(0, 98)

                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 112) & ", "

                        Case Is <= ActiveCell.Offset(0, 100)

                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 113) & ", "

                        Case Else

                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 114) & ", "

                        End Select

                    Next

                    tmpStr = Left$(tmpStr, Len(tmpStr) - 2)

                    MyDic.Add LCase$(RegM), 1

                End If

            Next

        End If

        .Pattern = "\d+[A-M]+"

        If .test(InputCell.Value) Then

            Set RegMC = .Execute(InputCell)

            For Each RegM In RegMC

                If tmpStr = vbNullString Then

                    tmpStr = RegM

                Else

                    tmpStr = tmpStr & ", " & RegM

                End If

            Next

        End If

        GetSeats = tmpStr

    End With

End Function

Open in new window

RegEx3.xls
0
Comment
Question by:gabrielPennyback
  • 2
  • 2
5 Comments
 
LVL 50

Expert Comment

by:Dave Brett
ID: 33687572
John,

You can add a second cell ref to replace activecell. Plus then update the OFFSET logic, see below

So AD11 then becomes
=IF(T11=0,MID(AV11,BG11,4),IF(T11=T9,"",GetSeats(T11,T1)))

to anchor T1 as the OFFSET reference

I didn't understand your "," point. Can you psl expand

Cheers

Dave

Function GetSeats(InputCell As Range) As String   ' 'brettdj
    Dim RegEx, RegM, RegMC
    Dim MyDic
    Dim tmpStr As String
    Dim i As Long
 
    Set MyDic = CreateObject("scripting.dictionary")
    Set RegEx = CreateObject("vbscript.regexp")
    With RegEx
        .Pattern = "ROW(S)? (\d+)-(\d+)"
        .Global = True
        .IgnoreCase = True
        If .test(InputCell.Value) Then
            Set RegMC = .Execute(InputCell)
            For Each RegM In RegMC
                If MyDic.exists(LCase$(RegM)) = False Then
                    For i = RegM.submatches(1) To RegM.submatches(2)
                        Select Case i
                        Case Is <= ActiveCell.Offset(0, 96)
                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 111) & ", "
                        Case Is <= ActiveCell.Offset(0, 98)
                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 112) & ", "
                        Case Is <= ActiveCell.Offset(0, 100)
                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 113) & ", "
                        Case Else
                            tmpStr = tmpStr & i & ActiveCell.Offset(0, 114) & ", "
                        End Select
                    Next
                    tmpStr = Left$(tmpStr, Len(tmpStr) - 2)
                    MyDic.Add LCase$(RegM), 1
                End If
            Next
        End If
        .Pattern = "\d+[A-M]+"
        If .test(InputCell.Value) Then
            Set RegMC = .Execute(InputCell)
            For Each RegM In RegMC
                If tmpStr = vbNullString Then
                    tmpStr = RegM
                Else
                    tmpStr = tmpStr & ", " & RegM
                End If
            Next
        End If
        GetSeats = tmpStr
    End With
End Function

Open in new window

RegEx3a.xls
0
 
LVL 1

Author Comment

by:gabrielPennyback
ID: 33688271
Hi Dave, I'll check this out when I get back to work tomorrow. I just opened the workbook that I attached and it's not working the way it was on my computer., so here's a revised version. It explains the caomma thing.
Thanks,
John

RegEx4.xls
0
 
LVL 50

Accepted Solution

by:
Dave Brett earned 500 total points
ID: 33688334
John,

Thats useful

Now sorted.

The reason you had to D2 for each formula is that the old code used the formula cell as a reference point - so if that cell was not active then the UDF dies

The new version can be used like
=GetSeats(T11,DV11)
which sayes look at T11 for the row string, then compare the sub rows versus the J-Y2 Class info in DU to EV, to assign the sets in EK to EN

Cheers

Dave

Sub CalcAffectedSeats()
'Application.Calculation = xlCalculationManual
'On Error GoTo alert
[G4].Calculate
If [G4] > 0 Then
[AllSerNos].AutoFilter Field:=1, Criteria1:="#N/A"
'Call Alert1
Exit Sub
Else
End If
[AllSeats].ClearContents
[AllSeatsAffected].Calculate
Application.Calculation = xlCalculationManual
    Call GetAffectedSeats(Range("AD6:AD" & Range("AD" & Rows.Count).End(xlUp).Row), 200)
    [SumSeats].Calculate
    [G1].Calculate
'alert:
'MsgBox "Most likely there's an incident here involving a tail that's not in the Flight Hours table. Check for errors in AllConfigs.xls", vbOKOnly
End Sub
Sub GetAffectedSeats(rng As Range, Optional cutoffRow As Long) 'WarCrimes
    Dim seatArray As Variant, seat As Variant
    Dim cel As Range
    Dim k As Long, i As Long, seatNum As Variant, numSeats As Long
    Application.ScreenUpdating = False
    'Late binding
    Dim RegEx As Object, RegMatchCollection As Object   'Dimension the RegExp objects
    Set RegEx = CreateObject("vbscript.regexp") 'create the RegExp Object with late binding
   
    With RegEx  'set the RegExp parameters
        .Global = False  'look for first match only
        .Pattern = "\d+" 'look for numeric strings of any length (only returns first match because Global = FALSE)
    End With

    For Each cel In rng
        seatArray = Split(cel, ",")
                
        Range("AE" & cel.Row & ":AI" & cel.Row) = 0  'Reset the affected seat counts
        'OPTIONAL:   'If IsMissing(cutoffRow) Or (Not IsMissing(cutoffRow) And cel.Row <= cutoffRow) _
        'OPTIONAL:   '  Or (Not IsMissing(cutoffRow) And cel.Row > cutoffRow And Range("T" & cel.Row) <> Range("T" & cel.Row - 1)) Then
            For Each seat In seatArray
                Set RegMatchCollection = RegEx.Execute(seat)
                seatNum = RegMatchCollection.Item(0)
                numSeats = Len(Trim(seat)) - Len(seatNum)
        
                Select Case CLng(seatNum)
                    Case ActiveSheet.Cells(cel.Row, [J_Lo].Column) To ActiveSheet.Cells(cel.Row, [J_Hi].Column)     'J-Class
                        Range("AF" & cel.Row) = Range("AF" & cel.Row) + numSeats
                    Case ActiveSheet.Cells(cel.Row, [B_Lo].Column) To ActiveSheet.Cells(cel.Row, [B_Hi].Column)     'B-Class
                        Range("AG" & cel.Row) = Range("AG" & cel.Row) + numSeats
                    Case ActiveSheet.Cells(cel.Row, [Y_Lo].Column) To ActiveSheet.Cells(cel.Row, [Y_Hi].Column)     'Y-Class
                        Range("AH" & cel.Row) = Range("AH" & cel.Row) + numSeats
                    Case ActiveSheet.Cells(cel.Row, [Y2_Lo].Column) To ActiveSheet.Cells(cel.Row, [Y2_Hi].Column)   'Y2-Class
                        Range("Ai" & cel.Row) = Range("Ai" & cel.Row) + numSeats
                End Select
            Next seat
            Range("AE" & cel.Row) = Evaluate("=SUM(AF" & cel.Row & ":AI" & cel.Row & ")")
        'OPTIONAL:   ' End If
    Next cel
    Application.ScreenUpdating = True
End Sub
Function GetSeats(InputCell As Range, RefCell As Range) As String   ' 'brettdj
    Dim RegEx, RegM, RegMC
    Dim MyDic
    Dim tmpStr As String
    Dim i As Long
 
    Set MyDic = CreateObject("scripting.dictionary")
    Set RegEx = CreateObject("vbscript.regexp")
    With RegEx
        .Pattern = "ROW(S)? (\d+)-(\d+)"
        .Global = True
        .IgnoreCase = True
        If .test(InputCell.Value) Then
            Set RegMC = .Execute(InputCell)
            For Each RegM In RegMC
                If MyDic.exists(LCase$(RegM)) = False Then
                    For i = RegM.submatches(1) To RegM.submatches(2)
                   ' If Len(tmpStr) > 0 Then tmpStr = tmpStr & ", "
                        Select Case i
                        Case Is <= RefCell
                            tmpStr = tmpStr & i & RefCell.Offset(0, 15) & ", "
                        Case Is <= ActiveCell.Offset(0, 98)
                            tmpStr = tmpStr & i & RefCell.Offset(0, 16) & ", "
                        Case Is <= ActiveCell.Offset(0, 100)
                            tmpStr = tmpStr & i & RefCell.Offset(0, 17) & ", "
                        Case Else
                            tmpStr = tmpStr & i & RefCell.Offset(0, 18) & ", "
                        End Select
                    Next
                   
                    MyDic.Add LCase$(RegM), 1
                End If
            Next
             tmpStr = Left$(tmpStr, Len(tmpStr) - 2)
        End If
        .Pattern = "\d+[A-M]+"
        If .test(InputCell.Value) Then
            Set RegMC = .Execute(InputCell)
            For Each RegM In RegMC
                If tmpStr = vbNullString Then
                    tmpStr = RegM
                Else
                    tmpStr = tmpStr & ", " & RegM
                End If
            Next
        End If
        GetSeats = tmpStr
    End With
End Function

Open in new window

RegEx4.xls
0
 
LVL 1

Author Comment

by:gabrielPennyback
ID: 33697829
Great, Dave, thanks. I understand this well enough that I modified the cases so that they are all based on the RefCell.
I would like to understand it better of course. Can you point out some specific values in my actual workbook that will help me understand what's going on in this line?
For i = RegM.submatches(1) To RegM.submatches(2)  
What part of T6 is captured in RegM.submatches(1)?
What part of T6 is captured in RegM.submatches(2)?
Same for T8.
What exactly is the function doing with cells T6 and T8 to produce the results it produces?
Thanks,
John

For i = RegM.submatches(1) To RegM.submatches(2)

                        Select Case i

                        Case Is <= RefCell

                            tmpStr = tmpStr & i & RefCell.Offset(0, 15) & ", "

                        Case Is <= RefCell.Offset(0, 2)

                            tmpStr = tmpStr & i & RefCell.Offset(0, 16) & ", "

                        Case Is <= RefCell.Offset(0, 4)

                            tmpStr = tmpStr & i & RefCell.Offset(0, 17) & ", "

                        Case Else

                            tmpStr = tmpStr & i & RefCell.Offset(0, 18) & ", "

                        End Select

                    Next

Open in new window

0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Workbook link problems after copying tabs to a new workbook? David Miller (dlmille) Intro Have you either copied sheets to a new workbook, and after having saved and opened that workbook, you find that there are links back to the original sou…
Recently Microsoft released a brand new function called CONCAT. It's supposed to replace its predecessor CONCATENATE. But how does it work? And what's new? In this article, we take a closer look at all of this - we even included an exercise file for…
This Micro Tutorial demonstrate the bugs in Microsoft Excel for Mac with Pivot Charts.
This Micro Tutorial will demonstrate on a Mac how to change the sort order for chart legend values and decrpyt the intimidating chart menu.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now