Curso Básico de Programación
en Visual Basic

Soluciones de la entrega Diecisiete.
Fecha: 16/Abr/98

 

Empezaremos viendo la parte fácil del ejercicio, es decir la que nos muestra la posición cuando la función espera sólo dos parámetros, el primero será la cadena en la que hay que encontrar lo que haya en la segunda cadena.

Private Function RInstr1(ByVal s1 As String, ByVal s2 As String) As Long
    Dim i As Long
    Dim sTmp As String

    RInstr1 = 0
    For i = Len(s1) To 1 Step -1
        sTmp = Mid$(s1, i, Len(s2))
        If sTmp = s2 Then
            RInstr1 = i
            Exit For
        End If
    Next
End Function

Este tiene poco que explicar.
Se hace un bucle desde la última posición de la primera cadena Len(s1) hasta el principio, ya que lo que necesitamos es encontrar la posición de s2 empezando a "mirar" desde el final.
A continuación guardamos en sTmp un trozo de cadena que va desde la posición actual y que contiene tantos caracteres como tenga la segunda cadena, si te fijas, el bucle se podría hacer también de esta forma:
For i = Len(s1) - Len(s2) + 1 To 1 Step -1
Ya que no nos sirve comparar el último caracter con la cadena s2 cuando esta última tiene más de un caracter, por ejemplo.
Esto es inapreciable en cadenas cortas, pero en otras más largas, acortará el tiempo del bucle.

Para el segundo caso, hay que saber que los procedimientos (sub y function) permiten parámetros opcionales, estos se indican con la palabra Optional delante de los parámetros que vayan a ser opcionales.
La única pega es que cuando un parámetro es opcional los que le siguen también tienen que ser opcionales.
Entonces ¿cómo indicar que el parámetro opcional sea el primero?
Pues... más o menos fácil... aunque con truco.
Cuando un parámetro es opcional, se puede usar la función IsMissing para comprobar si se ha especificado o no ese parámetro.
Esto es cierto siempre que el parámetro opcional sea de tipo Variant sin un valor por defecto. En el VB4 todos los parámetros opcinales deben ser Variant y sin valores por defecto, pero en VB5 (y posteriores) los parámetros opcionales pueden ser del tipo que queramos, además de poder tener un valor por defecto, es decir, si no se especifica, se le da un valor "predeterminado".
Ahora vamos a usar sólo los parámetros sin valores predeterminados, pero más adelante seguramente lo usaremos.

Sabiendo que con IsMissing podemos averiguar si se ha especificado o no el parámetro en opcional, haremos lo siguiente:
Si se especifican los tres parámetros, el primero será la posición por la que se empezará a comprobar.
Si no se especifica el último parámetro, engañaremos al Visual Basic, diciéndole que los dos parámetros introducidos son la primera y la segunda cadena...
Ya ves que sólo es echarle un poco de "cabeza" al asunto...

Vamos a ver la declaración de esta función:

Private Function RInstr(ByVal v1 As Variant, ByVal v2 As Variant, Optional ByVal v3 As Variant) As Long
    Dim i As Long
    Dim sTmp As String
    Dim s1 As String
    Dim s2 As String
    Dim posIni As Long

    If IsMissing(v3) Then
        'Si no se especifican los tres parámetros
        s1 = CStr(v1)       'La primera cadena
        s2 = CStr(v2)       'la segunda cadena
        posIni = Len(s1)    'el último caracter de la cadena
    Else
        posIni = CLng(v1)   'la posición por la que empezar
        s1 = CStr(v2)       'la primera cadena (segundo parámetro)
        s2 = CStr(v3)       'la segunda cadena (tercer parámetro)
    End If

    'Valor inicial de la búsqueda, si no se encuentra, es cero
    RInstr = 0
    'Siempre se empieza a buscar por el final
    For i = posIni - Len(s2) + 1 To 1 Step -1
        'Tomar el número de caracteres que tenga la segunda cadena
        sTmp = Mid$(s1, i, Len(s2))
        'Si son iguales...
        If sTmp = s2 Then
            'esa es la posición
            RInstr = i
            Exit For
        End If
    Next
End Function

Ahora quedaría hacer una función que comtemple las mismas opciones que tiene el InStr normal, es decir que se pueda especificar un cuarto parámetro que nos indique si la comparación se hace de una forma u otra.

¿Que te parece esto como un ejercicio nuevo?
Sabía que contestaría de forma afirmativa... je, je...

Pues inténtalo... y si quieres ver la solución, selecciona el contenido de la caja negra esa que hay al final y verás...

 

A ver si ya terminamos en la próxima entrega el acceso aleatorio a los ficheros.

Nos vemos.
Guillermo

 


Ir al índice principal del Guille


Para ver la solución, selecciona todo el contenido del siguiente cuadro y verás...

Nota:
He quitado lo de la selección porque no siempre funciona... al menos ahora no se ve el texto al seleccionarlo...

 

'
Private Function RInstr(ByVal v1 As Variant, ByVal v2 As Variant, _
                        Optional ByVal v3 As Variant, _
                        Optional ByVal v4 As Variant) As Long
    Dim i As Long
    Dim sTmp As String
    Dim s1 As String
    Dim s2 As String
    Dim posIni As Long

    If IsMissing(v3) Then
        'Si no se especifican los tres parámetros
        s1 = CStr(v1)       'La primera cadena
        s2 = CStr(v2)       'la segunda cadena
        posIni = Len(s1)    'el último caracter de la cadena
    Else
        posIni = CLng(v1)   'la posición por la que empezar
        s1 = CStr(v2)       'la primera cadena (segundo parámetro)
        s2 = CStr(v3)       'la segunda cadena (tercer parámetro)
    End If

    'Valor inicial de la búsqueda, si no se encuentra, es cero
    RInstr = 0
    'Siempre se empieza a buscar por el final
    For i = posIni - Len(s2) + 1 To 1 Step -1
        'Tomar el número de caracteres que tenga la segunda cadena
        sTmp = Mid$(s1, i, Len(s2))
        'Si se especifica el tipo de comparación
        If Not IsMissing(v4) Then
            'Se usa StrComp con ese parámetro
            If StrComp(sTmp, s2, v4) = 0 Then
                'esa es la posición
                RInstr = i
                Exit For
            End If
        Else
            'Aquí también se podría usar
            'If StrComp(sTmp, s2) = 0 Then
            'Si son iguales...
            If sTmp = s2 Then
                'esa es la posición
                RInstr = i
                Exit For
            End If
        End If
    Next
End Function

A diferencia del Visual Basic, no dará error si se especifica el cuarto parámetro y no se especifican los demás, por la sencilla razón de que si sólo se especifican 3, el cuarto nunca llega a tener un valor... (elemental mi querido Guille).
De lo que tendrás que tener "precaución", al menos si quieres que funcione todo bien, es de indicar los valores que se esperan... ya que sino es así, no conseguirás tu propósito... o al menos no el deseado.

 


 

Ir al índice principal del Guille