De entrada, decirte que éste es el foro de vb6, el de NEt está mas arriba... pero bueno ya lo moverá algún moderador si se percata de ello.
También señalarte que con las etiquetas Geshi, has hecho la mitad, le has puesto el 'code', pero te falta asignarle al VBNET, desplegando el combo, s epuede buscar. No se indica el lenguaje específico, cuando no sigue ningún lenguaje esecífico, pero si es así, es preferible usarlo, porque se colorea basado en su sintaxis y resulta más cómodo de leer...
Iba a ir al asunto que trata, pero visto lo visto, procede primero una larga crítica sobre aspectos que conviene usar correctamente...
Por ejemplo la forma de nombrar variables y métodos, más que nada para enseñarte a hacerlo correctamente....
- Una varible, propiedad, debe llevar por nombre SIEMPRE lo que en la gramática del español se llama NOMBRE COMUN.... porque son eso, nombres... Valor, Temperatura, Edad, Año, etc... En cambio si son constantes (valores preconfigurados, conviene además que lleven un adjetivo. Ejemplo: ColorRojo= hex0000FF ColorAzul= HexFF0000)
- Los métodos, en cambio son verbos... Imprimir(esto)... Ordenar(lalista)... Añadir(UnItem)... Vaciar(), etc...
- Aunque el lenguaje lo admita, no uses las barras bajas para dar nombres a tus variables, en general se deben dejar para las constantes y sobretodo son usados por los eventos de objetos instanciados...
...que el propio lenguaje crea así. Como una medida de evitar en lo posible la coincidencia con métodos que los usuarios pudieran tener... Aunque es harto difícil que un método que uno cree venga a llamarse igual que la suma de un "nombre instancia de objeto" + "nombre de evento del objeto instanciado", no es infalible.... siguiendo la norma de "nombre instancia de objeto" + "_" + "nombre evento", se puede garantizar la ausencia de duplicidad de nombres de métodos y con ello la conflictividad,
pero solo si a cambio el propio programador se aplica su parte no usando barras bajas en los nombres.
Usar nombre, no usar verbo ni barra baja, en nombres de variables, propiedades, etc...
Dim ingrese_butacas As Byte
Dim CantidadButacas as Byte ' o también CantidadButacasReservadas
Usar verbo, no nombre ni barra baja en nombres de métodos y funciones.
Sub Ingreso_butacas(...)
Sub IngresarButacas(...)
Luego está línea es muy deficiente:
Ingreso_butacas("Ingrese numero de butacas a reservar: ", ingrese_butacas)
Aparte del nombre del método ya comentado y de la variable pasada en el segundo parámetro... resulta que no precisa ser pasado ningún parámetro.
El primero porque si el método va a recibir siempre la misma cadena de texto, ese parámetro (el texto), puede yacer en el propio método, no perdiendo tiempo en pasarlo desde fuera, además se aísla más claramente el método y si a futuro hay que cambiar el texto, basta buscar la función y cambiar el texto ahí... ahora si decides cambiar el texto y el método es llamado desde 20 sitios, tendrías que cambiarlo en los 20 sitios).
El segundo parámetro también sobra... a la entrada siempre es 0 y es usado para devolución (por referencia), y como es un método y por tanto no devuelve nada, lo razonable es que se convierta en una función y devuelva dicho valor...
Luego esa línea y el propio método serán cambiados mucho mejor así:
CantidadButacas = IngresarButacas()
private function IngresarButacas() as byte
dim msj as string = "Ingrese numero de butacas a reservar: "
Dim cantidad as byte ' ingreso
' ...
' ....
Devolver cantidad
End function
La siguiente crítica es que siempre que se solicita a un usuario un valor, un algo en general, debe dársele la oportunidad de cambiar de opinión o corregir/confirmar... imagina que quisera poner 4, pero por error hubiera tecleado 44 (a veces la pulsación de teclas tienen un tiempo de repetición inesperado por el usuario, y sin darse cuenta su pulsación genera dos pulsaciones.... que le exigen por ejemplo tener que introducir 44 nombres, DNIs, (que ni siquiera tiene, ni sabe), etc... sería inaceptable... imagina si introduje 4444...
En tu caso, como limitas a 4 el valor máximo, por ahí corriges cierta parte, pero todavía dejas al aire si pone 0...
Con esas ideas en mente, rediseñamos, la función para ser más coherente y certera con la propia realidad cotidiana.
private function IngresarButacas() as byte
dim msj1 as string, msj2 as string
Dim cantidad as byte ' ingreso
Dim Confirmacion as boolean
msj1 = "Ingrese numero de butacas a reservar (máximo 4, 0 para abortar) "
msj2 = "Confirme si está de acuerdo con el valor ingresado (0=Cambiar, 1=Conforme)" ' el valor se ve en la consla justo en la línea previa
Do
Do
Console.WriteLine(msj1)
cantidad = Console.ReadLine()
Loop While (cantidad > 4)
Console.WriteLine(msj1)
Confirmacion = (Console.ReadLine() = 1)
Loop while Confirmacion=false
Return Cantidad
End function
A la devolución de la función debes verificar si el valor devuelto es 0 (Abortar), en cuyo caso se sale de la función y no se hace nada más.
Si un valor 0 no es admisible, en el bucle dentro de la función debe condicionarse a repetirse "While ((Cantidad=0) or ( Cantidad>4)) " (tambien "Until ((cantidad>=1) and (Cantidad<=4)) " )
Lo siguiente es que si se debe obtener los DNI, se aproveche la misma función para solicitarlo...
Naturalmente entonces ahora procede cambiar el nombre de la función para que qrefleje mejor lo que hace: IngresarDatos o mejor aún ReservarEntradas
Otro punto a resolver es que si se aportan más de un DNI, no hay ningún sustrato para almacenarlos, es decir el nuevo valor entrado sobrescribe el valor previo... Si la cantidad máxima de reserva es 4, procede declarar un array de 4 elementos a nivel del módulo (es un valor pequeño, no hay problema en ocupar algo más de espacio, si a cambio nos resuelve cuanlquier número entre 1 y 4 ).
private dim Identificaciones(0 to 3) as uint32
private function IngresarDatos() as byte
dim msj1 as string, msj2 as string, msj3 as string
Dim cantidad as byte ' ingreso
Dim Confirmacion as boolean
dim i as byte, j as byte, k as byte
msj1 = "Ingrese numero de butacas a reservar (máximo 4, 0 para abortar) "
msj2 = "Confirme si está de acuerdo con el valor ingresado (0=Cambiar, 1=Conforme)"
msj3 = "Ingrese DNI persona {0} (un valor positivo mayor que 0)"
' 1º Ingresar cantidad de butacas...
Do
Do
Console.WriteLine(msj1)
cantidad = Console.ReadLine()
Loop While (cantidad > 4)
If Cantidad = 0 ) then exit function ' ABORTAR....
Console.WriteLine(msj2)
Confirmacion = (Console.ReadLine() = 1)
Loop while (Confirmacion=false)
' 2º Ingresar DNI
for i= 0 to cantidad-1
do
do
Console.WriteLine(msj3, i)
k = Console.ReadLine() '
loop while (k<1) ' se exige que sea positivo y razonablemente mayor que 0
' Verificamos que no esté repetido (comprobando con los valores anteriores ya entrados
Confirmacion = TRUE
for j= 0 to i-1
if (k = Identificaciones(j) ) then
Confirmacion = FALSE
exit for
end if
next
loop While (Confirmacion=False) ' se vuelve a preguntar mientras se repita el valor entrado...
Identificaciones(i) = k
next
Return Cantidad
End function
Respecto de la segunda parte, declaras como se reparte el teatro, pero no señalas que pide el problema...
Y en cuanto a la última cuestión...
Cuando algo es lineal y finito suele recurrirse a un array.
Si las eliminaciones e inserciones serán contínuas, redimensionar un array constantemente no es admisible a tales casos se suele usar listas enlazadas, donde las inserciones y eliminaciones tienen un coste fijo y admisible.
Si las búsquedas priman sobre el resto, debe considerarse que métodos se disponen para proveer solución rápida, para textos y sobretodos cuando son en cantidad enorme, una tabla hash, es iremplazable, el coste de búsqueda es unitario al de acceso aleatorio en un array + el tiempo de hashear el texto a buscar.
Nuevamente si la cantidad es pequeña, un array puede valer, pero redimensionar 1 millón de elemtnos cada vez que se añade o elimina no es práctica... para cantidad pequeñas vale.
Una técnica con arrays es declarar un tamaño mínimoy cuando se alcanza duplicarlo, pero eaunque es válido para añadidos, noes igualmente válido si hay eliminaciones.
Cuando los datos a almacenar son algo más complejos que un simple datos suele recurrirse a una simple estructura que mantenga los datos, en tu caso del ejemplo dado es lo más apropiado.
private structure DatosButaca
DNI as uint32
Butaca as short 'si están numeradas del 1 al x vale un número, si tiene fila y asiento, lo siguiente
' Usa butaca o esto de aquí abajo, no ambas cosas
Fila as byte
Asiento as Byte
end structure
Bin CantidadReservas as byte
Dim Entradas(0 to 3) as DatosButaca ' aunque se declaren 0 a 3, solo se ocupan la cantidad que señala 'CantidadReservas
Si los datos requieren cierta manipulación, la propia estructura puede contener métodos para adecuar los datos...
Cuando los datos van a precisar ciertos métodos genéricos (como ordenar), puede recurrirse a colecciones genéricas o específicas que reúnan los cometidos que precisamos... no puede darse una indicación precisa, porque cada caso debe tratarse y considerarse individualmente.
Si los datos serán bastante complejos y los métodos de las colecciones nos resultan inútiles (no los vamos a usar), o bien los queremos usar, pero no se adecúan al modo en que precisamos, toca crearse una clase que albergue el tipo de datos específico y dotarle de métodos propios, incluso una clase que sea una colección y que almacene tipos primarios (array), estructuras, clases... e incluso si una colección se aproxima a lo que queremos hacer si la colección deja extender métodos, podríamos crear tales métodos y para el resto (inserciones, eliminaciones, búsquedas, cuenta, iterar) utilizar los métodos extendidos (ésto último suele ser a menudo más rápido que construir una colección propia desde cero...
El punto d epartida siempre ha de ser el array, y si no resulta suficiente ver si un array de estructuras, etc...
En fin, no puede darse una regla genérica, solo aproximaciones, orientaciones, pero cada caso debe estudiarse según sus propias circunstancias... cantidades que puede albergar, concurrencia de acceso a ítems, si prolifran las búsquedas, las inserciones, las eliminaciones... el tipo de datos/datos almacenados y qué se va a hacer con tales datos... aunque las colecciones suelen compartir métodos comunes, cada cual tiene sentido explícito para ciertas cosas y otras para otros (si no para qué hacer distintas implementaciones)...
Para saber sobre cada cual de las colecciones, lo mejor es visitar la página de Mocosoft (MSDN)... y leer, que para eso está... carece de sentido hacer un copy-paste de allí, ni tampoco tiene sentido que uno tenga que hacer un resumen de cada colección... el trabajo de aprendizaje exige leer por tu cuenta y no que te den todo mascado de 'segunda mano'...
Si aclaras que te reclama el problema en la segunda parte, miro de hecharte un pequeño cable...