En Visual Basic hay instrucciones para manejar estructuras, como no...
Pero no en la forma que indicas, sino prefijándolas tú en el código.
En teoría hacer lo que deseas lo más parecido que se puede hacer en VB6 es usando recursos de usuario en dicho caso cuando tus programas cambiaran sólo tendrías que editar el fichero de recursos, pero se me antoja que es un modo un poco engorroso. Siempre podrás usar el objeto collection para mantener estructuras dinámicas.
Para estructuras estáticas se usa el 'type' como definición de structuras ayudado por las 'enum' eraciones, para limitar valores... te describo con ejemplos su declaración y utilización.
En un módulo describes tu estructura (ver el code 1 de ejemplo) y luego con ella puedes usarla para leer o escribir en ficheros así como usarla internamente en el programa.
Declarar una estructura: un ejemplo que ilustra la diversidad y el anidado de estructuras...
public enum enumCategoria ' defino contantes fijas para usar como un tipo de datos.
especial=0
primera =1
segunda=2
tercera=3
end enum
public type infoCoordenadas ' ó private, si no se indica nada se entiende pública.
latitud as single
longitud as single
end type
public type infoLocalidad
población as string * 20
provincia as string * 20
coordenadas as infoCoordenadas
end type
public type infoEstrucutura ' se puede usar cualquier tipo de datos...
jamones as integer
chorizos as integer
paletas as integer
categoria as enumCategoria ' debe declararse previamente un tipo de usuario.
telefono as string * 9
origen as string * 16
localidad as infoLocalidad
end type
public type infoAño
estructura as infoEstructura
año as integer
end type
dim miEstructura as infoEstructura ' en el código se usará esta variable como una herencia de dicho tipo.
dim anuarioEstructura(0 to 99) as infoAño ' puede también ser creada una variable de estructura como una matriz de una o varias dimensiones....
' en este ejemplo puede verse la estructura final en infoaño, luego se ha creado una variable para utilizar sólo una estructura completa, típicamente para manejar estructuras sueltas y con carácter temporal, y luego la diemnsionada para llevar una cuenta basada en los años....
' Nota: las estructuras no precisan llamarse empezando por info... sólo es capricho mío, (que me permite recordar con mayor facilidad luego al usar una variable con el mismo nombre sin el 'info') puede usarse un nombre cualquiera de acuerdo a las reglas convenicionales de nombres de variables (no ser palabras reservadas, no empezar por números, etc...)
Luego de ser declaradas las estructuras y de ccrearse una variable que permita manejarla, ya podremos usarla, empezaremos por un ejemplo que toma los datos de controles de un formulario... que suponemos han sido rellenados por el usuario...
' nota: se omiten las supuestas líneas de control para claridad en el uso de las estructuras (que tendrían por objeto comprobar que los datos introducidos son correctos y dentro de los límites esperados, por ejemplo si se usara un campo para fecha se debería controlar que efectivamente es una fecha y que no refiere al año 3077... se entiende no ? )
public function recogeEstructuraDelFormulario() as infoEstructura ' debe devolver por tanto una estructura de infoEstructura, si en vez de una función usáramos una subrutina (sub), podríamos usar una variable global para la asignación de datos, usando la función aseguramos cierta encapsulación.
dim cerditos as infoEstructura
cerditos .jamones= sliderJamones.value
cerditos .chorizos=sliderChorizos.value
cerditos .paletas=sliderPaletas.value
with cerditos ' también puede usarse el 'with' para no teclear tanto.
.paletas=sliderPaletas.value ' esta línea es equivalente a la anterior (usando with)
.categoria = sliderCategoria.value
.telefono = textTelefono.text
.origen = textOrigen.text
.localidad.poblacion = textPoblacion.text
end with
with cerditos .localidad ' puedes usar with para ahondar en más niveles
.poblacion = textPoblacion.text ' esta línea es equivalente a la última
.provincia = textProvincia.text
.coordenadas.latitud = sliderLatitud.value /100 ' hemos supuesto un rango de 1-36000 de modo que al diviidir entre 100 tendremos 2 decimales
.coordenadas.longitud = sliderLongitud.value /100
end with
recogeEstructuraDelFormulario=cerditos ' es el valor de retorno...
end sub
este ha sido un ejemplo sencillo de recogida de datos de la misma estructura usada en la declaracion. Ahora simulamos que ha sido llamada para ser introducida en un año concreto... y guardar a un fichero.. eso sería otra función..
public sub buttonAñadirAño_click()
static añosCompletados as integer
dim añoActual as infoEstructura
dim guardado as boolean
if añosCompletados <> ubound(anuarioEstrucutra) then
añoActual = recogeEstructuraDelFormulario ' recogemos los datos del form
añoscompletados = añosCompletados +1
anuarioEstructura(añoscompletados ).estructura=añoActual ' se los asignamos
anuarioEstructura(añosCompletados ).año=añosCompletados
guardado = guardarEstructuraEnFichero(anuarioEstructura(añosCompletados),añosCompletados, "c:\cerdoIbericoSA.dat")
if guardado= true then
call resetEstructuraDelFormulario ' tomado los datos y verificados y metidos en la estructura final y guardado en fichero, se resetea el formulario
else
msgbox "No se pudo guardar la estrucutra del año correspondiente: " & añosCompletados & " en el fichero ocurrió algún tipo de error...", vbcritical, "Error al guardar en fichero..."
end if
end if
public function guardarEstructuraEnFichero(j as infoEstructura,año as integer, ruta as string) as boolean
dim n as integer
dim puntero as long
n=freefile
puntero= (len(j) * año) - len(j) +1 ' apunta al final del fichero o no, esto es, si queremos añadir al final deberá ser el último año metido y el puntero sería la longitud del fichero, pero siqueremos modificar un año concreto habrá que sobrescribir exactamente esa zona y no otra..esa pequeña fórmula lo permite.
on local error goto errorGuardar
open ruta for binary as #n
put #n, puntero, j ' pegar en: fichero, en posición, la estructura dada
close #n
guardarEstructuraEnFichero = true
exit function
errorGuardar:
end function
leer desde un fichero es similar a escribir... y podríamos usarlo para rellenar un reporte de un año cualquiera....
public function leerEstructuraDesdeFichero(año as integer) as boolean
dim n as integer
dim puntero as long
if año> ubound(anuarioEstructura then
call errorLeer(añoNoexiste) ' control de error de año, igaulmente debería usarse similar para valores fuera del rango inferior... se supone hecha la función errorLeer que devuelve un mensaje de acuerdo al error producido
exit function
end if
n=freefile
puntero= (len(infoEstructura) * año) - len(infoEstructura) +1
on local error goto errorLectura
open ruta for binary as #n
get #n, puntero, miEstructura ' usamos la estructura pública, para almacenar los datos, ya que la función la usamos para devolver si correcto o error, también podríamos usar un byref para devolverlo como parámetro desde la llamada...
close #n
leerEstructuraDesdeFichero= true
exit function
errorLectura: ' será si hay problemas al abrir el archivo o al leerlo
end function
evidentemente es posible leer o escribir cualquier parte de la estructura no es necesario que sea entera, en ese caso se debe calcular la posición absoluta de comienzo de la estructura y luego la posición relativa del campo ó campos...
Calcular la posición relativa es algo que resulta conveniente hacerlo como comentario directamente en la estructura (en su declaración), siguiendo la convención del tamaño de los datos... single= 4 bytes, integer=2 bytes, etc... de hecho quizás resulte más cómodo escribir o leer semiestructuras completas en vez de sólo un campo, así se simplifica el uso de cálculo de punteros relativos. Por ejemplo podemos crear una variable para contener datos de la localidad y actualizar sólo ese dato cuando cambie o haya error
dim direccion as infolocalidad
const punteroLocalidad =34
Ahora ya puede usarse funciones similares a las usadas hasta aquí para actualizar solo el registro de localidad (población provincia,etc...) al puntero del registro del año, habrá que sumarle entonces siempre el desplazamiento relativo hasta localidad que hemos acordado que es 34 (usando ANSI).