Curso Básico de Programación
en Visual Basic
Entrega
Diecisiete: 16/Abr/98
por Guillermo "guille" Som
Si quieres linkar con otras entregas, desde el índice lo puedes hacer
![]()
A estas alturas ya estarás
acostumbrado a mis "desvarios", eso demuestra que soy
de lo menos ordenado de lo que se pueda ser, pero... ese es un
problemilla que llevo conmigo desde chiquitillo, así que...
La cuestión es que parece ser que no voy a terminar con esto del
acceso a los ficheros... y eso que tengo ganas de terminar con
ello para poder pasar a otra cosa, pero... se me resiste el
tema...
Realmente no es que se me resista, es que por el camino van
surgiendo nuevas cosillas que es bueno que sepas y como este
curso no está enfocado para que lo aprueben en ningún plan
nacional de estudios... pues eso...
Lo que si que me interesa saber es que no te pierdes con tantos
desvarios... es decir, que sigues la línea... aunque eres libre
de poder desviarte y salirte por la tangente para mirar los
manuales y la ayuda del Visual Basic, que aunque no te lo creas,
también sirve para aprender... ahora, lo que pasa es que hay que
saber comprenderla... y de eso creo que es de lo que de una forma
u otra me estoy encargando yo... si no lo consigo, malo y si lo
consigo... mejor para todos.
Siguiendo con esos desvarios, vamos a empezar esta entrega con el manejo de las cadenas, que, aunque ya vimos un poco de ella en la entrega anterior, no estará de más saber algo más. Ten en cuenta que la mayoría de las veces vamos a manipular cadenas... y no es plan de que nos pillen "atados" sin saber que hacer... (chiste malo, lo reconozco...)
Seguramente no me voy a enrollar demasiado en este tema, digo "seguramente" porque no sé en que acabará esta entrega... así que paciencia y disfruta y aprende con lo que se diga en ella.
Ahora vamos al tema.
Ya hemos visto, cómo tomar caracteres de una cadena desde el principio (LEFT), desde el final (RIGHT) y desde cualquier punto (MID); también podemos saber cuantos caracteres tiene una cadena (LEN) e incluso convertir un número en cadena (CSTR) o una cadena en número (VAL).
Tienes que recordar que el VB tiene como tipo de variable por defecto el Variant, por tanto estas funciones realmente devuelven un tipo Variant, dentro de este tipo hay una serie de subtipos, que realmente son los tipos que vimos al principio de este curso, es decir Integer, Long, String, etc. ¿A que viene este nuevo lio Guille? A que es conveniente que lo sepas, nada más, pero, al menos por ahora no te preocupes por ello, el VB se encarga de hacer sus conversiones, aunque nosotros podemos obligarle a que lo haga, para ello debermos usar esas dunciones añadiéndole al final el signo dólar ($), ya sabes que ese signo es el que se emplea para indicar que una variable es de cadena. Por tanto LEFT$, MID$ y RIGHT$ devolverán siempre una cadena, mientras que LEFT, MID y RIGHT lo que devuelven es un Variant de subtipo String... un lio... pero ya te digo que no debes preocuparte.
Hay un montón de funciones para esto del manejo y conversión de las cadenas, en esta entrega veremos algunas de ellas, las que usaremos más a menudo. Si eres de espíritu inquieto, (por decir algo), puedes echar mano de la ayuda del Visual Basic y buscar las distintas funciones e instrucciones que manejan o manipulan las cadenas... la verdad que te puedes entretener bastante con ellas... aunque no te fies de todo lo que veas y te diga la ayuda si no lo compruebas por ti mismo... que al menos uno de los ejemplos está equivocado, pero me imagino que se deberá a la traducción... en fin... por no fiarte, no te fies ni de lo que yo te diga, siempre comprueba las cosas, así saldrás de dudas... y si no sales de dudas, pues... peor "pa tí"
Creo que voy a complicarte un poco más la vida, pero no te espantes, no va a ser en vano.
Además de los tipos de datos que
hemos vistos hasta ahora, hay otro que sirve para esto de las
cadenas, o casi, ya que se podría usar para manejar cada uno de
los bytes de una cadena, fijate que he dicho "bytes" y
no caracteres, ya que si trabajas en un entorno de 32 bits, cada
caracter de una cadena se compone de dos bytes, si estás usando
el VB de 16 bits sólo hay un byte por cada uno de los
caracteres. El tipo en cuestión es BYTE y en
ese tipo sólo se puede almacenar un valor que va desde 0 a 255,
es decir un byte, la lógica algunas veces es aplastante...
Así que, si le echas un vistazo a la ayuda, te encontrarás con
algunas funciones que tienen al final una letra B, eso significa
que devuelve valores tipo Byte, así por ejemplo LENB, devolverá
el número de bytes que tiene una cadena.
Prueba esto, verás que si lo usas con el VB de 16 bits te devuelve una cosa distinta a lo que haría en 32 bits:
Print Len("Hola Mundo")
Print LenB("Hola Mundo")
Lo que se mostrará, (recuerda de ponerle un show, si escribes este código en el evento Show del form), será 10 y 20 si usas el VB de 32 bits, (recuerda que el VB5 sólo es de 32 bits), pero en 16 bits (VB3 ó VB4-16), mostrará en ambos casos 10.
Vamos a practicar algunas cosillas con esto de los Bytes (o con datos de tipo Byte).
Ya sabes que puedes crear una
array de cualquier tipo de datos, incluso de tipos definidos,
así que también podemos crear arrays del tipo Byte, pero este
tipo de arrays tienen una particularidad.
Una cadena (variable de tipo string), realmente es un array del
tipo Byte, esto nos permite manejar las cadenas de caracteres
como si fuesen arrays de bytes o mejor aún usar los arrays del
tipo byte, como si fuesen cadenas.
Vamos a comprobarlo, pon estas líneas de código en el evento
Load de un form:
Show 'para que se muestre Dim aByte() As Byte aByte = "Hola Mundo" Print aByte
Como comprobarás se muestra Hola
Mundo... igual que si lo hubieses asignado a una cadena de
caracteres.
En el VB4-16 te habrá dado un error, para evitar ese error y que
se muestre el contenido, puedes asignarlo a una cadena e imprimir
esa cadena, también puedes asignarlo a un Label y se mostrará
el contenido de ese array como si fuese una cadena.
Esto mismo, por supuesto también es aplicable al Visual Basic de
32 bits.
| Aclaración
para los que trabajeis con 16 bits: Para no complicar mucho las cosas, si estás usando 16 bits, comprueba lo que aquí se diga y saca tus propias conclusiones. A pesar de que aún hay sistemas funcionando de 16 bits y gente que por tanto programa para esos sistemas, creo que el enfoque adecuado de este curso debería concentrarse en los sistemas de 32 bits, de todas formas, la mayoría de las cosas "realmente" válidas servirán tanto para 16 como para 32 bits. Pero voy aún más lejos, dentro de poco, no sé realmente en cuantas entregas, pero el enfoque se irá concentrando en el Visual Basic 5 y posteriores, (cuando los haya), ya que en el VB5 se han introducido cosas realmente interesantes para la programación enfocada a objetos, (que pronto empezaremos a tocar), que aunque la mayoría de esas cosas sean válidas para el VB4, en algún momento dejará de serlo y sólo serán aplicables al VB5 y posteriores... Quiero dejar esto claro, para que después no haya sorpresas... de todas formas, recalco que esto es un curso básico y como tal, servirá para prácticamente cualquier versión de VB, aunque mi "despiste" seguramente me llevará a tocar cosas sólo aplicables en el VB5... aunque eso será seguramente en la segunda parte de este curso... que la habrá, de eso puedes tener casi un 100% de certeza. |
Pero si pruebas esto:
Print Len(aByte)
El Visual Basic te dirá que
"nanai de la china", osease que no puedes saber cuantos
caracteres tiene un array de bytes...
Al menos usando Len... ni aún usando LenB, así que si quieres
lo compruebas, pero te dará el mismo error.
Ahora bien, para saber los elementos que contiene un array, vimos
que existen dos funciones: LBOUND y UBOUND, la primera para saber
el valor del primer elemento y la última para saber el último
elemento del array. Por tanto podemos usar estas dos funciones
para averiguar la longitud de esa cadena:
Print UBound(aByte)
Esto nos dará el número máximo de bytes de este array... sí, muestra 19 (en 32 bits), en el entorno de 16 bits nos informará de que el elemento mayor de esta matriz es de 9; ya sabes que para 32 bits cada caracter son dos bytes, por tanto 10 carecteres son 20 bytes. El porqué de que muestre uno menos es porque empieza a contar por CERO, es decir que el elemento inferior de este array será cero, lo podemos comprobar con esto otro:
Print LBound(aByte)
Tanto en VB de 16 cómo de 32 bits mostrará cero.
Si te preguntas que pasaría si se
añadiera a las declaraciones generales del Form la instrucción:
Option Base 1, puedes comprobarlo, pero no
cambiará los resultados mostrados, los arrays de Byte siempre
empiezan por cero, independiente del valor que indiquemos en el
Option Base.
Esto es una afrimación a medias, me explico, si a un array de
bytes le asignas el contenido de una cadena, el elemento inferior
siempre será CERO, pero puedes dimensionar una matriz de este
tipo de la misma forma que lo harías con cualquier otra de
cualquier otro tipo de datos. Lo que ocurre es que deberías
tener la precaución de que el número de elementos fuese par si
lo que pretendes es que contenga "algo parecido" a una
cadena.
Vamos a seguir probando un poco más, escribe este código:
Dim aByte() As Byte
aByte = "Hola"
Dim i&
Print aByte
For i = LBound(aByte) To UBound(aByte)
Print aByte(i);
Next
Print
En el VB de 16 bits, te mostrará
esto: 72 111 108 97, sin embargo en 32 bits el resultado sería
este otro:
72 0 111 0 108 0 97 0 (si, ya se que he dicho que no iba a decir nada de
los 16 bits, pero...)
Con esto, se demuestra, más o menos, eso de que cada caracter de
32 bits ocupa dos bytes, el primero es el normal y el segundo es
el extendido...
Para "rematar" esto de los arrays de bytes, una última
prueba, si usas el VB4-16 deberás modificarlo un poco, ya que
sólo tienes un byte por cada caracter y realmente es menos
"instructivo" que si estás usando 32 bits.
'Se supone que tienes estas declaraciones de las variables i y a:
'Dim a$, i&
'Los valores deben ser pares
ReDim aByte(-10 To 19)
Dim j%
j = 65
For i = LBound(aByte) To UBound(aByte) Step 2
aByte(i) = j
aByte(i + 1) = 0
j = j + 1
Next
Print aByte
Print LBound(aByte), UBound(aByte)
a = aByte
Print a
Aquí hemos usado un array de bytes con índices que van de -10 a 19, recuerda que de -10 a -1 van 10 y de 0 a 19 van 20, por tanto serán 30 los bytes que tiene este array, es decir 15 caracteres, que van desde A (65) hasta O (letra o mayúscula, 79), por eso se imprimen estos quince caracteres: ABCDEFGHIJKLMNO.
Para terminar con estas pruebas, escribe esto a continuación de lo anterior:
Print LeftB(a, 6)
Print RightB(a, 6)
Print MidB(a, 5, 6)
Esto será lo que habrá mostrado
(en 32 bits): ABC, MNO y CDE
Fijate que el MidB empieza por un número impar, si lo hicieras
por uno par, el VB te mostraría una serie de interrogaciones...
porque no sabe que es lo que quieres hacer con eso... más o
menos...
Si te preguntas que es lo que ocurriría si en lugar de MidB(a,
5, 6) escribieras esto otro: MidB(a, 0, 6), te encontrarías con
un error del Visual Basic, ya que el argumento desde,
debe ser un valor 1 hasta la longitud de la cadena.
Bien, ya sabes algo más, el resto que veamos tratará de las funciones de cadenas normales y corrientes, cualquier otra prueba con bytes la haces "por libre", cosa que te recomiendo para que te vayas acostumbrando a ellas, pero no te compliques demasiado, ya que no son tan frecuentes como debieran y siempre tendrás a mano la ayuda para poder "recordar" que están ahí.
Más funciones de manejo de cadenas, por favor.
Convertir números a
cadenas:
Cuando quieras convertir un número en una cadena, además de
usar la "conversión automática" que hace el propio
VB, puedes usar cualquiera de estas dos funciones: CStr
y Str$
La diferencia "visible" entre estas dos funciones es,
que la primera te devuelve sólo el número, sin espacios,
mientras que la segunda, en caso de que sea un número positivo,
devolverá el número pero con un espacio delante:
Dim a$, i%
i = 10
a = CStr(i)
Print "i=" & a
a = Str$(i)
Print "i=" & a
Como verás, en el primer caso se mostrará: i= 10, en el segundo: i=10, es decir que Str$ le añade el espacio que tiene los números positivos. Si el valor de i fuese -10 mostraría lo mismo en ambos casos.
Cambiar a mayúsculas /
minúsculas:
Para hacer esto, usaremos las funciones: LCase y
UCase, la primera convierte la cadena a
minúsculas y la segunda a mayúsculas:
a = "Un niñito cálido"
Print LCase(a)
Print UCase(a)
Aunque sea una chorradilla de
frase, es para que compruebes que los caracteres acentuados y la
eñe también se convierten.
Como en los números no tiene sentido esto de la conversión,
permanecen iguales.
Quitar los espacios del
principio y del final:
Las funciones usadas para hacer esto, son tres: LTrim$,
RTrim$ y Trim$
La primera quita los espacios del principio, la segunda los
espacios en blanco del final y la tercera los quita tanto del
principio como del final.
Esta última función es lo mismo que si hicieramos esto:
Ltrim$(RTrim$(unaCadena)), que es lo que hacía yo antes de que
el Visual Basic incluyese esta función...
Vamos a ver un ejemplo:
a = " Un ejemplo "
Print "<" & LTrim$(a) & ">"
Print "<" & RTrim$(a) & ">"
Print "<" & Trim$(a) & ">"
El resultado será el siguiente: <Un
ejemplo >, < Un ejemplo>, <Un
ejemplo>
Es decir: se comprueba que actúan como se esperaba...
Averiguar el código de
los caracteres:
Ya sabes que cada "letra" que puede tener una cadena de
caracteres está representada por un código, así la A es el
código 65, la Z es el 90, la a es el 92 y la z es el 132. El
código del espacio es 32.
Para averiguar los códigos de los caracteres y para asignar a
una cadena cualquier código, convertido en el correspondiente
caracter, se usan las funciones Chr$ y Asc.
La primera devuelve el caracter correspondiente al número que se
le pasa como parámetro.
La segunda hace la operación inversa, nos dice cual es el
código del caracter que se le ha indicado.
Veamos un ejemplo:
Print Asc("Z")
Print Chr$(90)
El primero nos dirá que 90 es el código de la Z mayúsculas y en el segundo caso, nos confirma que el caracter representado por 90 será la Z.
Si en ASC se le pasa una cadena con más de una caracter, sólo nos devuelve el valor del primero:
Print Asc("Hola")
Imprimirá 72, es decir el valor de la H mayúscula.
Llenar una cadena con una
cantidad de caracteres:
Para esto, podemos usar un bucle y en cada iteración del mismo
incrementar el contenido de una cadena o bien podemos usar dos de
las funciones que el Visual Basic pone a nuestra disposición: Space$
y String$
La primera devuelve la cantidad de espacios que se le indique, si
queremos 10 espacios haremos esto: a = Space$(10)
A la segunda se le pasan dos parámetros, el primero indicando la
cantidad de caracteres que queremos y el segundo el código de
ese caracter: a = String$(10, 65) nos dará diez
letras A mayúsculas.
También podemos pasarle en el segundo parámetro una cadena, por
tanto el ejemplo anterior se podría escribir así:
a = String$(10, "A")
Si la cadena que le pasamos tiene más de un caracter, nos
devuelve sólo el primer caracter de esa cadena:
a = String$(10, "Pepe")
Es decir sólo 10 letras P.
Comparar el contenido de
dos cadenas:
Ya sabes que las cadenas se pueden comparar igual que se hacen
con los números: usando el signo igual.
If "Hola" = "hola" Then
Es un ejemplo "chorra", pero se puede hacer.
Esta comparación debería devolver FALSE, ya que la H inicial en
una de las cadenas está en mayúsculas y en la otra en
minúscula. Si no le hemos indicado nada al VB, nos dirá que son
diferentes, pero podemos indicarle al Visual que al comparar las
cadenas, ignore las diferencias entre las mayúsculas y
minúsculas. Para ello tendremos que agregar en la parte general
del módulo, donde está el Option Explicit, la siguiente
instrucción:
Option Compare Text
De esta forma, las comparaciones realizadas siempre serán
independiente de que sean mayúsculas o minúsculas, incluso si
están mezcladas las mayúsculas con las minúsculas.
Por defecto el Visual Basic hace lo que se llama una comparación
binaria, es decir que comprueba el código de cada uno de los
caracteres que componen las cadenas; también se le puede indicar
esto para que todas la comparaciones realizadas sean siempre en
modo "binario", aunque no hace falta indicarlo, ya que
es el valor por defecto, pero si quieres hacerlo, para saber que
estás haciendo las comparaciones de esa forma, añade esta
línea:
Option Compare Binary
Las comparaciones también se pueden efectuar para saber cual es mayor o menor, el VB se guiará por el código de cada caracter comparado, deberás tener en cuenta que los números están antes que las letras, por tanto "1234" sería menor que "ABCD" y "VWXYZ" será mayor que "DEFGH"
Pero además de efectuar las
comparaciones de esta forma, existe una función que sirve
precisamente para eso: StrComp
Esta función permite que las comparaciones se hagan de distinta
forma:
Usando el valor por defecto, es decir el indicado en Option
Compare,
usando siempre comparación binaria, (distingue entre mayúsculas
y minúsculas)
y usando siempre comparación "textual", (no hace
distinción entre mayúsculas y minúsculas)
Los parámetros que usa esta
función son los siguientes: cadena1, cadena2 y opcionalmente el
tipo de comparación a realizar.
Si este último parámetro no se especifica, se efectuará la
comparación según se indique en Option Compare.
En otro caso, los valores pueden ser: 0 (comparación binaria) ó
1 (comparación textual).
Existe otro valor que es usado para las bases de datos de Access,
pero que nunca lo he llegado a probar... sólo lo he visto cuando
he leido la ayuda.
Los valores que devolverá esta
función serán:
0 si las dos cadenas son iguales,
-1 si la primera cadena es menor que la segunda
1 si la primera cadena es mayor que la segunda.
Debes tener en cuenta que "HOLA" es menor que "hola", si la comparación es binaria, lo mismo con "Hola", ya que la H mayúscula tiene un código menor que la h minúscula.
Veamos un ejemplo:
Dim b$
a = "Hola"
b = "hola"
Print "Usando el Option Compare: "; StrComp(a, b)
Print "Usando comparación textual: "; StrComp(a, b, vbTextCompare)
Print "Usando comparación binaria: "; StrComp(a, b, vbBinaryCompare)
Los valores de las constantes vbTextCompare y vbBinaryCompare ya están definidos por el VB y son 1 y 0 respectivamente.
Asignar valores e
incrementar el contenido de una cadena:
Muchas de las cosillas que estamos viendo en esta entrega, ya se
han usado en otras entregas, pero así tendrás una referencia
más a mano... además de servirte de recordatorio, por si lo has
olvidado.
La concatenación consiste en añadir a una cadena el contenido
de otras cadenas o caracteres.
Como sabrás si quieres
incrementar el valor de una variable numérica, haces esto: Num =
Num + 1
El basic interpretará primero la expresión, o lo que haya
después del signo igual y el resultado lo asignará a la
variable que está a la izquierda del signo igual.
Lo mismo hace con las cadenas de caracteres, lo que ocurre es que
sólo permite la suma. Aunque desde hace tiempo que Microsoft no
recomienda esta forma de concatenar las cadenas, ya que el Visual
Basic puede "malintepretarlo" y recomienda que se use
el signo & (ampersando, creo que se llama). Usando ese signo,
el VB sabe exactamente lo que debe hacer.
Por tanto si haces esto:
a = "Hola"
b = "mundo"
a = a & " " & b
Print a
Te mostrará Hola mundo, es decir ha guardado en "a" lo que ya había además de un espacio y el contenido de "b"
Este tipo de concatenación
también pudes hacerlo en los controles Label y Text o en
cualquiera que disponga de alguna propiedad en la que puedas
guardar una cadena.
Por ejemplo el Caption de un label (que es la propiedad por
defecto y por tanto se puede omitir).
Si tienes un Label2 en el form, podrías hacer esto:
Label2 = "Hola"
Label2 = Label2 & " " & b
Y se mostrará en ese label lo mismo que antes se imprimió. Esto mismo se puede hacer indicando que se asigna a la propiedad Caption de esa etiqueta:
Label2.Caption = "Hola"
Label2.Caption = Label2.Caption & " " & b
El resultado sería el mismo.
Averiguar la posición de
una cadena dentro de otra:
Para esto usaremos la función Instr, esta función espera dos
parámetros como mínimo, aunque permite cuatro:
Instr( [posInicio,] Cadena1, Cadena2[,
tipo_comparación])
Las dos cadenas, son las que usará para devolver la posición de
la segunda cadena dentro de la primera.
Si hacemos esto: Print Instr("Hola mundo",
"mundo") nos mostrará un SEIS, ya que
"mundo" está en la posición sexta, al menos ahí es
dónde empieza.
Si se especifica posInicio, empezará a comprobar a partir de esa
posición inclusive, por tanto:
Print Instr("Hola mundo", "o")
imprimirá 2
Print Instr( 6, "Hola mundo", "o")
imprimirá 10, ya que busca una letra "o" a partir de
la posición 6.
El último parámetro:
tipo_comparación es para realizar comparaciones binarias o de
texto, como ya hemos visto anteriormente, si este parámetro
tiene la misma función que en StrComp. Es decir si no se
especifica, la comparación se hace según el Option Compare y si
se indica, se hace según lo indicado.
Si especificas este parámetro, deberás indicar también la
posición de inicio, sino el VB te dirá que los tipos de datos
no coinciden.
Un ejemplo:
Print InStr("Hola mundo", "o")
Print InStr(6, "Hola mundo", "o")
Print InStr("Hola mundo", "O")
Print InStr(1, "Hola mundo", "O", vbBinaryCompare)
Print InStr(1, "Hola mundo", "O", vbTextCompare)
Dependiendo de que tengamos Option
Compare Text el tercer caso imprimirá un cero (si no tenemos la
comparación textual) o un 2 si tenemos esa opción de
comparación
En los demás casos, siempre devolverá el mismo resultado.
Pero no te confundas, devuelven lo mismo, porque sabemos que debe
devolverlo, ya que se especifica como segunda cadena una
constante que representa a una "o" minúscula y en la
primera cadena tenemos dos de esa letra, otro gallo cantaría si
tanto la primera como la segunda cadena fuesen variables y no
sabemos lo que va a contener.
Cuando sea imprescindible saber la
posición de una cadena dentro de otra, teniendo en cuenta el que
haya que distinguir o no entre las mayúsculas y minúsculas, es
recomendable que uses el tipo de comparación que quieres
realizar.
Si no lo haces, al menos recuerda o comprueba que tipo de
comparación se realizarán por defecto en ese módulo.
Bien, creo que ya tienes a tu
disposición casi todas las funciones de manejo de cadenas que
puedas necesitar.
Ahora toca que practiques un poco con ellas para que le vayas
cogiendo el "tranquillo" y te las aprendas.
Una cosa que quiero aclarar es que no pretendo hacer con este curso un "sustituto" de la ayuda o los manuales del Visual Basic, por eso te recomiendo siempre que las instrucciones con las que te encuentres en algunos de los ejemplos, las busques en la ayuda o los manuales, lo mismo que para saber "manejarte" en el entorno de Visual Basic. Sé que esto ya lo he dicho antes, o al menos debería haberlo dicho, pero lo hago de nuevo para que no esperes un "diccionario" de todas las instrucciones que tiene el Visual Basic. Lo que pretendo siempre es que te enteres de cómo se usan esas instrucciones e incluso cuando usar una en lugar de otra... en fin... si ves que alguna que otra vez se me va la "olla", me lo dices e intentaré solucionar ese despiste.
¿Ejercicios?
Te podría poner muchos... pero sólo voy a ponerte uno y con ese
tendrás "pa rato"
Escribe una función que devuelva la posición de una cadena
dentro de otra, pero comprobando esa posición por el final.
Es decir que Instr("Hola Mundo","o")
devolvería 2, pero con nuestra función devolvería 10.
Podríamos llamarla RInstr y se usaría así: RInstr("Hola
mundo","o")
Haz una segunda versión en la cual se le pase como primer
parámetro la posición por la que se empezará a comprobar, de
esta forma: RInstr2(6,"Hola
mundo","o") nos dará un valor 2
En las soluciones veremos cómo podemos indicar parámetros
opcionales en nuestros procedimientos y crearemos una única
función que se use igual que Instr, es decir pasándo como
primer parámetro opcional la posición de inicio de la
búsqueda.
Y siguiendo la "sana" costumbre, te pido tu opinión sobre esta entrega.
Nos vemos.
Guillermo
P.S.
Aquí tienes las soluciones a esta entrega
![]()