Curso Básico de Programación
en Visual Basic
Entrega
Dieciséis: 6/Abr/98
por Guillermo "guille" Som
Si quieres linkar con otras entregas, desde el índice lo puedes hacer
![]()
Habrás notado que ya no aparecen
los links al principio de esta entrega, ello se debe a que he
añadido una nueva página, desde la cual puedes linkar con todas
las entregas, además de poder ver una lista de las
"palabras" tratadas en todas las entregas aparecidas,
así como en que entrega(s) apareció esa palabra, no es nada
"preciso", pero intentaré ir
"depurándolas".
La intención es que puedas saber de un vistazo en que entrega se
ha tratado y... espero hacerlo pronto, en cual de ellas es en la
que se ha explicado, porque una cosa es que se use la palabra y
otra diferente que se explique...
Como digo, es sólo un primer intento, que espero ir mejorando, para que te sea fácil encontrar la palabra o tema que te interesa.
Decirte que esa lista la he "sacado" con una utilidad, que seguramente pondré pronto en mis páginas y que trata de mostrar cada una de las "palabras" que aparecen en los ficheros que se procesen... además de esa utilidad, he tenido que ir leyéndome cada una de las palabras y tomándo nota, por lo tanto alguna se me ha podido escapar...
Bueno, ya vale... vamos al tema de la presente entrega: Los ficheros aleatorios (Random)
Pues eso, ahora le toca el turno a
los ficheros aleatorios. Ya te comenté que este tipo de fichero
se suele usar cuando todos los datos que incluye tienen la misma
longitud. Normalmente a cada uno de los datos guardados se les
llama registro. Todos los registros tienen la misma longitud, o
al menos deberían tenerla... no, no es una contradicción, pero
si quieres que funcione bien, deben ser iguales, porque el
sistema que usa el VB para acceder a cada uno de los registros es
una simple operación:
Posición_Actual = (Número_Registro -1) *
Tamaño_del_Registro + 1
Pero no te asustes... tú no tienes que hacer ningún cálculo...
de eso se encarga el Visual Basic.
Para acceder a los datos de los ficheros abiertos como Random, vienen como anillo al dedo, (si es que el anillo te encaja bien), los tipos definidos por el usuario, aunque cualquier cadena serviría para esta tarea.
Antes de empezar a manejar ficheros de acceso aleatorio, es importante planear lo que vamos a almacenar en ellos; siempre se debe planear, pero en esta ocasión es un poco más importante, más que nada porque, como ya he dicho, tenemos la obligación de saber la longitud de los datos, (al menos de cada uno de los registros), a almacenar. Ya que esa longitud, (la de cada registro), debemos especificarla a la hora de abrir el fichero.
Un pequeño detalle antes de continuar, cuando abrimos un fichero secuencial para lectura (Input), el Visual Basic o el sistema operativo, sólo nos permite leer datos de ese fichero, es decir: no podemos leer y escribir al mismo tiempo. Igualmente ocurre cuando lo abrimos para escritura (Output), sólo que en esta ocasión sólo podemos escribir y no leer. Sin embargo, con los ficheros abiertos como aleatorios (Random) o binarios (Binary), una vez que el fichero esté abierto, podemos leer o escribir indistintamente. Alguna ventaja teniamos que tener... no iban a ser todo "obligaciones".
Sigamos con lo nuestro...
Veamos cómo, por fin, usar estos
ficheros:
Para verlo... nada mejor que con un ejemplo:
Primero definimos un tipo de datos, en este caso vamos a guardar el nombre, edad y la cuenta de email de unos colegas, por tanto emplearemos un tipo definido con estos tres campos, veamos:
Private Type t_colegas
Nombre As String * 30
Edad As Integer
email As String * 50
End Type
Declaramos una variable de este "nuevo" tipo de datos, que será la que usaremos para acceder al fichero:
Dim unColega As t_colegas
Y abrimos el fichero:
Open "miscolegas.dat" For Random As nFic Len = Len(unColega)
El Len(unColega),
le está indicando al VB que la longitud de cada registro es la
que tenga ese tipo de datos.
No siempre hay que hacerlo así, podríamos asignar a una
variable esa longitud y usarla para abrir el fichero:
lenColega = Len(unColega) Open "miscolegas.dat" For Random As nFic Len = lenColega
Lo que quiero dejar claro es que
al Visual Basic no le importa con qué variable accedemos al
fichero, sino que longitud tendrá esa variable, o si lo
prefieres, cual será la longitud de cada registro.
Por tanto, si sabemos que nuestro tipo de datos, (o lo que es lo
mismo: cada registro), tiene 82 bytes de longitud, podríamos
usar un string con esa longitud para acceder al fichero en
cuentión y...
¡Toc,
toc! ¡¡¡Guille!!!
¿Sí?
¿No
crees que te estás precipitando?
¿Yo? ¿Por qué?
Porque
estás hablando de acceder así o asao a los datos y aún no has
explicado cómo leer o escribir esos datos...
Pues... sí... es cierto... je...
Si no fuera por el otro Guille... en fin...
Esto..., cuando quieras leer el
contenido de un registro en particular del fichero abierto, usa
esta instrucción:
Get #canal, num_registro, variable_de_datos
Para escribir usa esta otra:
Put #canal, num_registro, variable_de_datos
Es decir GET para
leer y PUT para escribir, en esto los ingleses
lo tienen más fácil, ya que al menos a ellos esas dos palabras
tienen algo de sentido...
Después de cualquiera de estas instrucciones se indica el
número de fichero (#canal), seguido por el
número de registro al que queremos acceder, (num_registro),
y por último la variable, (variable_de_datos),
que usamos para leer, (GET), los datos del disco
o almacenarlos en él (PUT)
Un detalle que tienes que tener
siempre presente al definir un tipo de datos para acceder a los
ficheros aleatorios: asegurate de que todas las cadenas
contenidas en ese tipo, sean de longitud fija; lo mismo si dentro
del tipo usas arrays, estos deben ser de índices constantes, es
decir que estén definidos al crear el tipo.
Todas estas "precauciones" se consiguen con datos
"estáticos", es decir que permanecen sin cambios, al
menos en lo que a tamaño se refiere. Los "dinámicos"
son los que pueden cambiar "dinámicamente" de tamaño.
Aclaremos estos puntos antes de continuar.
Una variable declarada de esta
forma:
Dim cadenaEstatica As String * 50
Siempre tendrá 50 caracteres, incluso si hacemos esta
asignación:
cadenaEstatica = ""
Con esto no eliminamos las 50 celdas de memoria, sino que la
rellenamos de espacios...
Prueba con este código:
Crea un nuevo proyecto y añade esto en el Form_Load:
Private Sub Form_Load()
Dim cadenaEstatica As String * 50
Show
cadenaEstatica = "Hola"
Print cadenaEstatica & "Pepe"
cadenaEstatica = ""
Print cadenaEstatica & "Pepe"
Print
Print "Longitud de la cadena:"; Len(cadenaEstatica)
Print "Asc(cadenaEstatica) ="; Asc(cadenaEstatica)
End Sub
El resultado sería este:

Es decir que una cadena estática
(o de longitud fija), siempre tendrá el número de caracteres
que le indicamos al declararla.
Sin embargo una cadena dinámica sólo tendrá los caracteres que
le asignemos.
Prueba este código:
Private Sub Form_Load()
Dim cadenaDinamica As String
Show
cadenaDinamica = "Hola"
Print cadenaDinamica & "Pepe"
cadenaDinamica = ""
Print cadenaDinamica & "Pepe"
Print
Print "Longitud de la cadena:"; Len(cadenaDinamica)
Print "Asc(cadenaDinamica) ="; Asc(cadenaDinamica)
End Sub
Habrás obtenido algo parecido a esto:

Osea "Illegal Function
Call", este error lo da al intentar conseguir el código
ASCII de la cadena... pero como la cadena está vacía... pues no
hay nada que obtener, por tanto: ¡¡¡Error al canto!!!
Aparte del error, te puedes fijar que "HolaPepe" sale
junto y que la longitud de la variable es cero.
Cuando asignamos una cadena vacía a un string dinámico, lo
dejamos "seco", es decir sin nada en el interior...
Lo mismo ocurre con los arrays, ya
sean de caracteres o numéricos.
Los estáticos siempre conservan el número de elementos, incluso
cuando se eliminan, (al menos eso es lo que parece), con Erase.
Aunque esto ya lo vimos, no está de más recordarlo: Al
"eliminar" con Erase un array
dinámico, lo eliminamos de la memoria, pero en los estáticos,
simplemente ponemos el contenido a cero, (o a cadenas vacias si
son de cadenas dinámicas).
Pruebalo:
Dim arrayEstaticoInteger(1 To 10) As Integer
Dim arrayEstaticoString(1 To 5) As String
Dim arrayDinamicoInteger() As Integer
Dim arrayDinamicoString() As String
Cuando se declaran los arrays con
el número de elementos que va a contener, siempre con
constantes, estos arrays son estáticos, porque siempre
contendrán ese número de elementos.
Sin embargo los dinámicos, se declaran sin decirles cuantos
elementos van a contener y después se usa Redim
o Redim Preserve para cambiar el número de
elementos.
Veamos un ejemplo de un tipo definido con un array estático:
Private Type t_colegas2
Nombre As String * 30
Edad As Integer
email(1 To 3) As String * 50
End Type
Aquí hemos definido un "campo" email con un array de tres elementos.
Recuerda que aunque los tipos definidos permitan tanto cadenas de longitud variable como arrays dinámicos, si ese tipo se va a usar para acceder a datos de un fichero aleatorio, su longitud siempre tiene que ser fija y coincidir con la longitud que se indicó a la hora de abrir ese fichero... si no tienes esta "precaución"... no accederás con "fiabilidad" a los datos contenidos en ese fichero... después no digas que no te advertí...
De todas formas, vamos a
comprobarlo...
Escribe este código en un form:
'Este código en las declaraciones del form
Option Explicit
Private Type t_colegas
Nombre As String * 30
Edad As Integer
email As String * 50
End Type
Dim unColega As t_colegas
Private Type t_colegaDinamico
Nombre As String
Edad As Integer
email As String
End Type
Dim unColegaDinamico As t_colegaDinamico
Private Sub Form_Load()
Dim nFic As Integer
nFic = FreeFile
Open "miscolegas.dat" For Random As nFic Len = Len(unColega)
'Asignamos los datos
With unColega
.Nombre = "Pepe"
.Edad = 22
.email = "pepe22@mundo.net"
End With
Put #nFic, 1, unColega
'ahora lo hacemos con el colega dinámico
With unColegaDinamico
.Nombre = unColega.Nombre
.Edad = unColega.Edad
.email = unColega.email
End With
'Aquí dará error:
Put #nFic, 2, unColegaDinamico
Close
End Sub
Ejecuta el programa y te encontrarás con un "bonito" error número: 59 Bad Record Length o La longitud de registro es incorrecta, si usas la versión castellana del Visual Basic. Lo que nos quiere decir este error es que no puedes grabar datos de una longitud diferente a la especificada a la hora de abrir el fichero.
Pero... ¿por qué? si,
aparentemente, la longitud es la misma...
Pues eso, que sólo es en apariencia... si en la ventana
"Inmediato" escribes esto, saldrás de dudas:
Print len(uncolega); len(uncolegadinamico)
El resultado será este:
82 10
En el primer caso, el del
coleguilla normal, lalongitud es la esperada: 82
Pero en nuestro amigo dinámico, la longitud es 10,
independientemente de que "en teoría" tenga
almacenados esos 82 caracteres del "estático". Lo que
ocurre es que al ser dinámico, el contenido de las variables de
caracteres se almacenan en otro sitio y lo único que hay en esas
variables es un "puntero" a la dirección de memoria en
la que están los datos almacenados... al menos ahora sabemos que
una variable de cadena de caracteres tiene una longitud de 4
bytes... creo que eso ya lo vimos en la entrega número dos o
tres... dónde hablamos de lo que ocupa cada variable... los
enteros (Integer) ocupan 2 bytes, independientemente de cómo
esté declarada la variable... lo mismo ocurre con los otros
datos numéricos.
Como te decía, si sabemos que la
longitud del registro es de 82 caracteres, podemos definir una
cadena de esa longitud y usarla para acceder a los datos.
Probemos esto otro:
Dim unaCadena As String * 82
'...
unaCadena = "Prueba de una cadena"
Put #nFic, 2, unaCadena
'...
Ahora si que funcionará.
Pero si esa variable está definida como String normal, no
funcionará...
Resumiendo: para acceder a los registros de un fichero abierto como Random, las variables usadas deben tener definida la longitud igual que el tamaño especificado a la hora de abrirlo.
Un poco de complicación: Vamos a
ver un ejemplo, "ilustrativo" más que práctico.
Ya he comentado que con una cadena de longitud fija podemos
acceder a un registro. Ahora comprobarás lo "cómodo"
que es usar los tipos definidos. Pero este ejemplo lo pongo para
que sepas cómo se almacenan los datos numéricos en una cadena
que se va a usar para guardar datos en un fichero de acceso
aleatorio.
Hemos "comprobado" que un Integer se almacena en dos
bytes... por tanto lo que se guarda en el disco es precisamente
eso: dos bytes. Cuando se usa un tipo definido, no te tienes que
preocupar de cómo se almacena, simplemente asignas el valor a la
variable numérica y del resto se ocupa el VB.
Viendo el ejemplo anterior, es
fácil almacenar un entero, si usamos un tipo definido, pero
¿cómo lo haremos si la variable en la que se almacenará los
datos es una cadena de longitud fija?
Para ello debemos "desglosar" los datos en distintas
partes:
Para el Nombre usaremos los primeros 30 bytes de la cadena, para
la edad los dos siguientes, es decir: bytes 31 y 32, para el
email desde la posición 33 hasta la 82, osea desde la 33 con 50
bytes de longitud.
Si escribes esto:
Dim unaCadena As String * 82 Dim elNombre As String * 30 Dim laEdad As String * 2 Dim elEmail As String * 50 Dim nFic As Integer Dim unaCadena As String * 82 Show nFic = FreeFile Open "miscolegas.dat" For Random As nFic Len = Len(unColega) elNombre = "Pepe de 23 años" laEdad = 23 elEmail = "Pepe23@mundo.net" unaCadena = elNombre & laEdad & elEmail Put #nFic, 2, unaCadena Close nFic
No conseguirás el resultado
esperado... en lugar de 23 años, tendrá: ¡¡¡ 13106 !!! Dudo
mucho que llegue a conseguir esa edad... ni aún siendo un
gnomo...
Si queremos guardar un número debemos convertirlo antes... el
problema es que "NO HAY FUNCIONES DE CONVERSIÓN"
Antes si que las había... cuando digo antes, me refiero al Basic
del MS-DOS.
Para cada tipo de dato numérico existían un par de funciones,
una para convertir el número en una cadena y el otro para
convertir la cadena en un número...
Y no me estoy refiriendo a las funciones que convierten los
números en letras y las cadenas en números... aunque pueda
parecerte una contradicción... no es lo mismo convertir un
número en una cadena normal que en una cadena para almacenar en
el disco como si de un número se tratase...
A saber, STR o CSTR convienten un
número en una cadena, es decir que si el número es 23, lo
convierten en "23" en el caso de CSTR y en "
23" si se usa STR, fíjate en el espacio que hay antes del 2
en el segundo caso.
Pero cuando se debe convertir un número en una cadena de 2
bytes... la cosa cambia...
Y no te confundas... no pienses que si usas CSTR lo tienes
solucionado... porque en el ejemplo este de "23" está
claro... pero y si el número es 1998? Tendriamos una cadena de 4
caracteres...
Como te decía, en los tiempos del
MS-DOS, existían las funciones MKI$ y CVI para convertir los
números enteros; MKL$ y CVL para los enteros largos, MKS$ y CVS
para los "singles" y MKD$ y CVD para los Double. No
busques estas funciones... porque no están...
Aunque podemos fabricarnoslas... pero, como no es plan de
"romperse" el coco con una chorradilla de estas...
sólo vamos a usar el ejemplo de los números enteros.
¿Cómo se usarían?
En el ejemplo anterior hariamos esto:
elNombre = "Pepe de 23 años" laEdad = Mki(23) elEmail = "Pepe23@mundo.net" unaCadena = elNombre & laEdad & elEmail Put #nFic, 2, unaCadena
La función se haría así:
Private Function Mki(ByVal unInteger As Integer) As String
Dim sLoByte As String
Dim sHiByte As String
Dim iChar As Integer
iChar = unInteger \ 256
sHiByte = Chr$(iChar)
iChar = unInteger Mod 256
sLoByte = Chr$(iChar)
'Devolvemos el valor
Mki = sLoByte & sHiByte
End Function
Que complicación ¿verdad?
Pues como estas... muchas más... pero eso antes, en el MS-DOS...
desde que hay "mogollón" de espacio de
almacenamiento... he perdido de vista muchas de estas cosas de
"manejo" de números a "bajo nivel"...
Pero antes había que ahorrar cuantos bytes se pudieran...
La cuestión es que se divide el
número en dos partes, la alta que se consigue dividiendo el
entero entre 256 y la baja, que es el resto que queda... después
de haberlo dividido por 256... que de eso es de lo que se encarga
el MOD...
Después se convierten esos valores en dos bytes usando el
CHR$... se unen... y sin necesidad de agitarlo... conseguimos el
"batido" que queremos... por tanto, lo asignamos al
valor que devolverá la función... (recuerda que una función
devuelve un valor cuando se asigna ese valor a su nombre...)
Bien... un lio... ¿verdad?
Pues ahora más lios...
¿Cómo se asigna esto al revés? Es decir: ¿Cómo se convierte
una cadena de 2 bytes en un entero?
Con los tipos definidos no hay que hacer nada... ya sabes, que
hace la conversión automáticamente.
Pero si usamos una cadena de longitud fija... ya es otro
cantar...
Vamos a ver la declaración de la función "equivalente" al CVI del viejo Basic del MS-DOS:
Private Function Cvi(ByVal unaCadena As String) As Integer
Dim sLoByte As String
Dim sHiByte As String
sLoByte = Left$(unaCadena, 1)
sHiByte = Right$(unaCadena, 1)
'Devolvemos el valor
Cvi = Asc(sLoByte) + Asc(sHiByte) * 256
End Function
No voy a entrar en detalles, así
que paso a un ejemplo "completo" para ver estos
resultados.
Si vas a comprobar cómo "trabajan" alguna de estas
funciones usando "puntos de interrupción", es decir
que quieres que el VB se detenga en una línea determinada, (para
ello deberás posicionarte en la línea, que no debe ser un
comentario, y pulsar F9, al llegar a esa línea el Visual se
detiene), deberás cambiar la propiedad Autoredraw del form y
ponerla a TRUE, de esta forma el contenido del Form (el que se
imprime dentro del Form_Load), se mantiene...
'Esto escribelo en el Form_Load
Dim nFic As Integer
Dim unaCadena As String * 82
Dim laEdad23 As Integer
Show
laEdad23 = 23
nFic = FreeFile
Open "miscolegas.dat" For Random As nFic Len = Len(unColega)
'Asignamos los datos
With unColega
.Nombre = "Pepe"
.Edad = 22
.email = "pepe22@mundo.net"
End With
Put #nFic, 1, unColega
Dim elNombre As String * 30
Dim laEdad As String * 2
Dim elEmail As String * 50
elNombre = "Pepe de 23 años"
laEdad = Mki(laEdad23)
elEmail = "Pepe23@mundo.net"
unaCadena = elNombre & laEdad & elEmail
Put #nFic, 2, unaCadena
Get #nFic, 1, unColega
With unColega
Print
Print "Colega 1:"
Print .Nombre
Print .Edad
Print .email
End With
'Si se lee así, no hay problemas
Get #nFic, 2, unColega
With unColega
Print
Print "Colega 2:"
Print .Nombre
Print .Edad
Print .email
End With
'De esta manera está la cosa más complicada...
Get #nFic, 2, unaCadena
Print
Print "Colega 2:"
Print Mid$(unaCadena, 1, 30)
Print Cvi(Mid$(unaCadena, 31, 2))
Print Mid$(unaCadena, 33, 50)
Observa que aunque el segundo dato
se haya guardado usando una cadena de longitud fija, (unaCadena),
se puede leer tanto con un tipo definido, si es de la misma
longitud, claro, como con la cadena de longitud fija.
El problema es que tenemos que "desglosar" el contenido
de esa cadena... Recuerda que te comenté que cada uno de los
"campos" del registro ocupa un espacio determinado...
osea que tienen una longitud fija... por eso hay que usar el
Mid$, para tomar cada uno de los "trozos" de esa
cadena.
El Mid$ funciona de la siguiente
forma:
Mid$ (cadena, posición_de_inicio, numero_de_caracteres)
Lo que significa que devolverá el número de caracteres
indicados por numero_de_caracteres empezando por
la posición: posición_de_inicio. En caso de
que no se especifique el número de caracteres, devolverá toda
la cadena desde la posición indicada hasta el final de la misma.
Y ya que estamos con estas
funciones... voy a explcarte las dos usadas en la función CVI:
Left$ y Right$
El Left$ toma de una cadena los caracteres que se le indiquen,
empezando por la izquierda.
Right$ hace lo mismo, pero empieza a contar desde la derecha.
Unos ejemplos:
Left$("Hola Mundo", 4) devolverá
"Hola", es decir los 4 primeros
caracteres.
Right$("Hola Mundo", 4) delvolverá "undo", porque son los cuatro caracteres que hay a la derecha...
El Left$ se puede sustituir por
Mid$ de la siguiente forma:
Mid$("Hola Mundo", 1, 4) es decir:
empezando por el primer caracter, dame cuatro...
Sin embargo esto otro:
Mid$("Hola Mundo", 4) nos dará:
"a Mundo", o lo que es lo mismo: desde
la posición cuarta, todo lo que haya en la cadena.
Y si quieres imprimir cada uno de los caracteres de una cadena, prueba esto:
Dim i As Integer
Dim unaCadena As String
unaCadena = "Hola Mundo"
For i = 1 To Len(unaCadena)
Print Mid$(unaCadena, i, 1)
Next
Lo que se hace aquí es un bucle para cada uno de los caracteres de la cadena, esto se sabe con LEN, que devuelve la longitud de una cadena y con el Mid$, vamos tomando todos los caracteres de uno en uno. Ya que le decimos que nos muestre el caracter que está en la posición i... sólo muestra uno, porque esa es la cantidad que le indicamos que nos devuelva...
¡UF! Creo que algunas veces se me
va la olla... y se me olvidan cosas que... creyendo que he
explicado... las uso...
En fin... la cuestión es que ahora sabes unas instrucciones
nuevas...
Y ya que estamos...
Veamos cómo se puede usar también MID$, lo que ocurre es que
esta "función" también es una
"instrucción", al igual que ocurría con INPUT, según
se use delante o detrás del signo igual, se convierte en
función o en instrucción.
Ya sabes que una función devuelve un valor y se puede usar en una expresión, pero una instrucción "hace" algo y no devuelve ningún valor ni se puede usar en una expresión.
En el ejemplo de guardar los registros, se usaron tres variables para almacenar los datos en el fichero:
Dim elNombre As String * 30
Dim laEdad As String * 2
Dim elEmail As String * 50
elNombre = "Pepe de 23 años"
laEdad = Mki(laEdad23)
elEmail = "Pepe23@mundo.net"
unaCadena = elNombre & laEdad & elEmail
Put #nFic, 2, unaCadena
Pues esto mismo se puede hacer de esta otra forma:
Mid$(unaCadena, 1, 30) = "Prueba de una cadena"
Mid$(unaCadena, 31, 2) = Mki(laEdad23)
Mid$(unaCadena, 33, 50) = "pepe23@mundo.net"
Put #nFic, 2, unaCadena
Es decir, al igual que la función con el mismo nombre, la instrucción MID$ sustituye en "unaCadena" los caracteres indicados por el inicio y la longitud por los que están después del signo igual...
Creo que me he pasado... bueno, esto al final viene bien... ya que así tenemos otra entrega "medio" preparada... ya que de la que tenía prevista de 7 páginas "manuscritas" sólo he usado 2 y poco más...
Para completar esta "extraña" entrega... extraña por "no prevista"... vamos a "rematarla" con unos ejercicios, que en este caso serán de manejo de cadenas con las funciones que acabamos de ver...
Los ejercicios:
1- Haz que se muestren los
caracteres de una cadena al revés.
Por ejemplo, si la cadena es "Hola Mundo", se deberá
imprimir: "odnuM aloH"
Que es útil si queremos hacer carteles para que se vean al
derecho al mirar por el retrovisor del coche... (por decir algo)
2- Usando esta misma
cadena, es decir "Hola Mundo", dividela en las dos
palabras.
Se supone que deberá servirte para cualquier frase, así que no
hagas nada "fijo".
Lo que tienes que hacer es devolver en una cadena todos los
caracteres hasta el primer espacio y el resto en otra cadena.
Para esto, si quieres, puedes usar el Left$ y el Mid$... al menos
para la primera palabra.
Y ya está... no te voy a complicar más la vida... que ya vendrán complicaciones posteriores.
Pulsando en este link tienes las soluciones.
Para terminar, sólo pedirte disculpas por haberme/haberte "liado"... pero... eso es lo que hay... 8-)
Y como no es plan de perder la
costumbre de pedirte que hagas un comentario de la entrega que
acaba de terminar... aquí tienes el link para que me hagas saber que te ha
parecido...
A estas alturas no tendría que recordarte que ese link
sólo es para hacer comentarios de esta entrega o del curso en
general... así que no te voy a decir que no apreveches
el link para hacerme consultas...
Nos vemos.
Guillermo
![]()