Home All Groups Group Topic Archive Search About

Excaping recursive functions

Author
8 Apr 2005 7:09 PM
Michael
Hi Everyone,
I got the following code from Deborah Kurata's book. I need to return the
control that matches the name that I pass into the function. It does iterate
through the form but it will not return a control reference. Following the
code, it does actually get a reference, but when it returns from one of the
recursize calls, the code keeps going. For examle:
First call to FinControl
  Has child so call FindControl again
  Finds control, returns the reference
  'Comment I need a garnteed way of exiting now
  Keeps looping, and if a control has child again, call FindControl again

Private Function FindControl( ByVal ControlName As String, ByVal CurrentForm
As control) As Control
    Dim rtn As Control
        For Each ctrl As Control In CurrentForm.Controls
            If ctrl.Name = Controlname then
                rtn = ctrl
                exit For
            End If           
            If ctrl.HasChildren then
                FindControl(ControlName, ctrl)
            End If           
        Next ctrl
        return rtn
    End Function

What is the best way to handle this one. Thanks for any info.
Michael

Author
8 Apr 2005 7:50 PM
Jay B. Harlow [MVP - Outlook]
Michael,
I would expect:

|            If ctrl.HasChildren then
                rtn = FindControl(ControlName, ctrl)
                Exit For
|            End If

However I would not define the rtn variable, I would simply use the Return
statement when I found an item. Something like:

| Private Function FindControl( ByVal ControlName As String, ByVal
CurrentForm
| As control) As Control
|        For Each ctrl As Control In CurrentForm.Controls
|            If ctrl.Name = Controlname then
               Return ctrl
|            End If
|            If ctrl.HasChildren then
                Return FindControl(ControlName, ctrl)
|            End If
|        Next ctrl
        Return Nothing
|    End Function

However some developer's prefer not to use the above, as they consider it
"multiple return points"...

Hope this helps
Jay

Show quoteHide quote
"Michael" <Mich***@discussions.microsoft.com> wrote in message
news:7E54AF9E-B968-4DAA-9C8E-364E14827ED9@microsoft.com...
| Hi Everyone,
| I got the following code from Deborah Kurata's book. I need to return the
| control that matches the name that I pass into the function. It does
iterate
| through the form but it will not return a control reference. Following the
| code, it does actually get a reference, but when it returns from one of
the
| recursize calls, the code keeps going. For examle:
| First call to FinControl
|  Has child so call FindControl again
|  Finds control, returns the reference
|  'Comment I need a garnteed way of exiting now
|  Keeps looping, and if a control has child again, call FindControl again
|
| Private Function FindControl( ByVal ControlName As String, ByVal
CurrentForm
| As control) As Control
|    Dim rtn As Control
|        For Each ctrl As Control In CurrentForm.Controls
|            If ctrl.Name = Controlname then
|                rtn = ctrl
|                exit For
|            End If
|            If ctrl.HasChildren then
|                FindControl(ControlName, ctrl)
|            End If
|        Next ctrl
|        return rtn
|    End Function
|
| What is the best way to handle this one. Thanks for any info.
| Michael
|
Author
8 Apr 2005 10:37 PM
Stephany Young
I think that Jay might have got it slightly wrong.

In the original procedure, if the target control was 'top level' then I
would expect the procedure to find it and return a reference to it:

  For Each ctrl As Control In CurrentForm.Controls
    If ctrl.Name = Controlname Then
      rtn = ctrl
      Exit For
    End If
    ...
  Next ctrl
  Return rtn

However, once a recursive call is made, the result is being 'thrown away',
the loop will continue and the symptoms as described will be exhibited:

  ...
  If ctrl.HasChildren Then
    FindControl(ControlName, ctrl)  <--- The result from this call is not
assigned to anything
  End If

My take on it is:

  Private Function FindControl( ByVal ControlName As String, ByVal
CurrentForm As control) As Control

    Dim rtn As Control

    For Each ctrl As Control In CurrentForm.Controls
      If ctrl.Name = Controlname Then
        rtn = ctrl
        Exit For
      End If
      If ctrl.HasChildren Then
        rtn = FindControl(ControlName, ctrl)
        If Not (rtn Is Nothing) then Exit For
      End If
    Next ctrl

    Return rtn

  End Function

The check for Not Nothing is important otherwise the loop will continue to
the end of the 'children', control will drop through the end of the loop and
Nothing will be returned regardless of whether we found it or not. The early
exit when we find it in a recursive call corrects this oversight.


Show quoteHide quote
"Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@msn.com> wrote in message
news:etuZZRHPFHA.1396@TK2MSFTNGP10.phx.gbl...
> Michael,
> I would expect:
>
> |            If ctrl.HasChildren then
>                rtn = FindControl(ControlName, ctrl)
>                Exit For
> |            End If
>
> However I would not define the rtn variable, I would simply use the Return
> statement when I found an item. Something like:
>
> | Private Function FindControl( ByVal ControlName As String, ByVal
> CurrentForm
> | As control) As Control
> |        For Each ctrl As Control In CurrentForm.Controls
> |            If ctrl.Name = Controlname then
>               Return ctrl
> |            End If
> |            If ctrl.HasChildren then
>                Return FindControl(ControlName, ctrl)
> |            End If
> |        Next ctrl
>        Return Nothing
> |    End Function
>
> However some developer's prefer not to use the above, as they consider it
> "multiple return points"...
>
> Hope this helps
> Jay
>
> "Michael" <Mich***@discussions.microsoft.com> wrote in message
> news:7E54AF9E-B968-4DAA-9C8E-364E14827ED9@microsoft.com...
> | Hi Everyone,
> | I got the following code from Deborah Kurata's book. I need to return
> the
> | control that matches the name that I pass into the function. It does
> iterate
> | through the form but it will not return a control reference. Following
> the
> | code, it does actually get a reference, but when it returns from one of
> the
> | recursize calls, the code keeps going. For examle:
> | First call to FinControl
> |  Has child so call FindControl again
> |  Finds control, returns the reference
> |  'Comment I need a garnteed way of exiting now
> |  Keeps looping, and if a control has child again, call FindControl again
> |
> | Private Function FindControl( ByVal ControlName As String, ByVal
> CurrentForm
> | As control) As Control
> |    Dim rtn As Control
> |        For Each ctrl As Control In CurrentForm.Controls
> |            If ctrl.Name = Controlname then
> |                rtn = ctrl
> |                exit For
> |            End If
> |            If ctrl.HasChildren then
> |                FindControl(ControlName, ctrl)
> |            End If
> |        Next ctrl
> |        return rtn
> |    End Function
> |
> | What is the best way to handle this one. Thanks for any info.
> | Michael
> |
>
>
Author
10 Apr 2005 8:34 PM
Jay B. Harlow [MVP - Outlook]
Stephany,
|        rtn = FindControl(ControlName, ctrl)
|        If Not (rtn Is Nothing) then Exit For

That makes more sense... It was one of those answers I didn't verify first
;-)

Thanks
Jay


Show quoteHide quote
"Stephany Young" <noone@localhost> wrote in message
news:uCiLRuIPFHA.4088@TK2MSFTNGP10.phx.gbl...
|I think that Jay might have got it slightly wrong.
|
| In the original procedure, if the target control was 'top level' then I
| would expect the procedure to find it and return a reference to it:
|
|  For Each ctrl As Control In CurrentForm.Controls
|    If ctrl.Name = Controlname Then
|      rtn = ctrl
|      Exit For
|    End If
|    ...
|  Next ctrl
|  Return rtn
|
| However, once a recursive call is made, the result is being 'thrown away',
| the loop will continue and the symptoms as described will be exhibited:
|
|  ...
|  If ctrl.HasChildren Then
|    FindControl(ControlName, ctrl)  <--- The result from this call is not
| assigned to anything
|  End If
|
| My take on it is:
|
|  Private Function FindControl( ByVal ControlName As String, ByVal
| CurrentForm As control) As Control
|
|    Dim rtn As Control
|
|    For Each ctrl As Control In CurrentForm.Controls
|      If ctrl.Name = Controlname Then
|        rtn = ctrl
|        Exit For
|      End If
|      If ctrl.HasChildren Then
|        rtn = FindControl(ControlName, ctrl)
|        If Not (rtn Is Nothing) then Exit For
|      End If
|    Next ctrl
|
|    Return rtn
|
|  End Function
|
| The check for Not Nothing is important otherwise the loop will continue to
| the end of the 'children', control will drop through the end of the loop
and
| Nothing will be returned regardless of whether we found it or not. The
early
| exit when we find it in a recursive call corrects this oversight.
|
|
| "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@msn.com> wrote in message
| news:etuZZRHPFHA.1396@TK2MSFTNGP10.phx.gbl...
| > Michael,
| > I would expect:
| >
| > |            If ctrl.HasChildren then
| >                rtn = FindControl(ControlName, ctrl)
| >                Exit For
| > |            End If
| >
| > However I would not define the rtn variable, I would simply use the
Return
| > statement when I found an item. Something like:
| >
| > | Private Function FindControl( ByVal ControlName As String, ByVal
| > CurrentForm
| > | As control) As Control
| > |        For Each ctrl As Control In CurrentForm.Controls
| > |            If ctrl.Name = Controlname then
| >               Return ctrl
| > |            End If
| > |            If ctrl.HasChildren then
| >                Return FindControl(ControlName, ctrl)
| > |            End If
| > |        Next ctrl
| >        Return Nothing
| > |    End Function
| >
| > However some developer's prefer not to use the above, as they consider
it
| > "multiple return points"...
| >
| > Hope this helps
| > Jay
| >
| > "Michael" <Mich***@discussions.microsoft.com> wrote in message
| > news:7E54AF9E-B968-4DAA-9C8E-364E14827ED9@microsoft.com...
| > | Hi Everyone,
| > | I got the following code from Deborah Kurata's book. I need to return
| > the
| > | control that matches the name that I pass into the function. It does
| > iterate
| > | through the form but it will not return a control reference. Following
| > the
| > | code, it does actually get a reference, but when it returns from one
of
| > the
| > | recursize calls, the code keeps going. For examle:
| > | First call to FinControl
| > |  Has child so call FindControl again
| > |  Finds control, returns the reference
| > |  'Comment I need a garnteed way of exiting now
| > |  Keeps looping, and if a control has child again, call FindControl
again
| > |
| > | Private Function FindControl( ByVal ControlName As String, ByVal
| > CurrentForm
| > | As control) As Control
| > |    Dim rtn As Control
| > |        For Each ctrl As Control In CurrentForm.Controls
| > |            If ctrl.Name = Controlname then
| > |                rtn = ctrl
| > |                exit For
| > |            End If
| > |            If ctrl.HasChildren then
| > |                FindControl(ControlName, ctrl)
| > |            End If
| > |        Next ctrl
| > |        return rtn
| > |    End Function
| > |
| > | What is the best way to handle this one. Thanks for any info.
| > | Michael
| > |
| >
| >
|
|
Author
9 Apr 2005 9:15 AM
Cor Ligthert
Michael,

I am fond of those recursive ones. An alternative

\\\\
Private Function ControlName(ByVal parentCtr As Control, _
    ByVal NameString As String) As Control
        If ControlName Is Nothing Then
            Dim ctr As Control
            For Each ctr In parentCtr.Controls
                If ctr.Name = NameString Then
                    Return ctr
                Else
                    Dim getControl As Control = ControlName(ctr, NameString)
                    If Not getControl Is Nothing Then Return getControl
                End If
            Next
        Else
            Return ControlName
        End If
    End Function
///

I don't say this one is better.

Cor
Author
9 Apr 2005 11:46 AM
Herfried K. Wagner [MVP]
"Michael" <Mich***@discussions.microsoft.com> schrieb:
> I got the following code from Deborah Kurata's book. I need to return the
> control that matches the name that I pass into the function. It does
> iterate
> through the form but it will not return a control reference. Following the
> code, it does actually get a reference, but when it returns from one of
> the
> recursize calls, the code keeps going.

Accessing controls by their names or indices
<URL:http://dotnet.mvps.org/dotnet/faqs/?id=controlbynameindex&lang=en>

--
M S   Herfried K. Wagner
M V P  <URL:http://dotnet.mvps.org/>
V B   <URL:http://classicvb.org/petition/>
Author
9 Apr 2005 12:18 PM
Cor Ligthert
Herfried,

The chalenge is here the escape when found.

:-)

Cor
Author
9 Apr 2005 1:24 PM
Herfried K. Wagner [MVP]
"Cor Ligthert" <notmyfirstn***@planet.nl> schrieb:
> The chalenge is here the escape when found.

ACK.

--
M S   Herfried K. Wagner
M V P  <URL:http://dotnet.mvps.org/>
V B   <URL:http://classicvb.org/petition/>