• Lunes 12 de Mayo de 2025, 19:36

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - Nebire

Páginas: 1 ... 5 6 [7] 8 9 ... 29
151
VB .NET / Re: dudas, pasando de 2003 al 2008
« en: Sábado 7 de Noviembre de 2009, 15:04 »
Tienes una función que devuelve un valor buleano... (as boolean) y tu función lo que hace es eliminar registros.... como sabe qué devolver ?, cmd.executenonquery  devuelve el número de filas eliminadas, luego si filas tiene un valor mayor que 0 significa que borró registros, luego debe devolver true, por el contrario si filas devuelve  0 no se borró ningún registro, quizás no encontró coincidencias..) por tanto devuelve false...

Podrías cambiar para que en vez de devolver un buleano devuelve un long, es decir que devuelva el número de registros borrados, en cuyo caso deberías cambiar esas 5 líneas por : return filas

La última línea apuntada por la  raya roja, forma parte del la estructura try y quiere decir

Código: vb.net
  1.  
  2. Intenta ' try
  3.     esto ' cmd.... el código que tienes
  4. pero si falla ' catch = caza
  5.     dime que pasó
  6. de todas formas haya o no error' finally  ' esta parte no aparece , es opcional.
  7.     ejecuta esto
  8. fin intenta
  9.  
  10.  

Dicho a las claras le está indicando que si se produce un error, genere el error , te aparecería una ventana indicándote el error producido, por ejemplo:  no existe la tabla, la bd no está abierta, etc....

Por cierto no son comentarios son líneas de código....

152
VB .NET / Re: Sugerencias
« en: Sábado 7 de Noviembre de 2009, 14:52 »
Uno programador (o que se pretende tal) sin imaginación... es como una rueda cuadrada... será todo lo rueda que quiera, pero, ...no 'rueda'...

153
VBA / Re: funcion para esperar
« en: Sábado 7 de Noviembre de 2009, 14:46 »
En el foro hay bastantes mensajes con dicho contenido... por qué no usas el buscador ?...

Yo he mismo he puesto varias veces ejemplos de código.... bysca palabras como pausa , temporizador, etc...

Son sólo 4 líneas, pero si tu no quieres perder tiempo en buscarlo, yo tampoco voy a molestarme en ponértelas...

154
Bien, si ya sabes poner puntos y líneas (por ti solita/o) ya se te puede ayudar...

Para utilizar un sistema de cordenadas debes usar la propiedad scale

Por ejmplo:
Código: Visual Basic
  1.  
  2. picture1.scale(-100,-100)-(200,200)
  3.  
  4.  
Aquí le hemos dicho que el sistema de cordenadas tiene 200 unidades de ancho por 200 unidades de alto, y que las unidades van desde -100 en el eje de cordenadas x a: (-100 + 200), para el eje y le indicamos lo mismo que para el eje x.

Qué unidades son ?... las unidades son del sistema indicado en picture1.scalemode, por tanto si previo al código anterior le añades (delante o detrás de la línea indicada):
Código: Visual Basic
  1.  
  2. picture1.scalemode = vbpixels
  3.  
  4.  
...ahora ya sabes que las unidades son en píxeles...
Ahora practica poniendo líneas y puntos...
quiero verte poner código y alguna imagen, en tu siguiente intervención (para ver como vas y prosperas) sólo entonces te ayudaré a realizar rotaciones y demás...

saludos y al tajo.

155
Seguridad y Criptografía / Re: duda de un principiante
« en: Sábado 7 de Noviembre de 2009, 09:28 »
Cita de: "elusuario"
A esto pregunto: cual es el problema de que todos los mensajes sean cifrados/descifrados mediante un algoritmo sin clave, siempre y cuando el algoritmo no sea conocido?
Saludos.
Perdona que tarde en contestarte pero llevo un par de semanas con escaso tiempo libre...

Básicamente, ya te han contestado los compañeros... no obstante me extiendo para que te 'florezcan' idean bullendo en el cerebro y esperando que lo encuentres interesante....

Un algoritmo sin clave no es otra cosa que un algoritmo que dentro de si encierra las 'claves' de su funcionamiento, y donde no queda nada fuera de él, por tanto, es sólo cuestión de tiempo que o bien se desemsamble el código o bien que se analicen los mensajes cifrados con mensajes conocidos. En la práctica puede y suele recurrirse a una mezcla de ambas técnicas para reventar el algoritmo. Una vez roto el algoritmo el mismo carece de utilidad práctica y a lo sumo, sólo, puede ofrecer ya interés 'cultural'.

Un algoritmo sin clave no obstante tiene su campo de utilidad y no es totalmente inútil. Simplemente se trata de conocer los escenarios donde esto resulta práctico. De un modo resumido el escenario clásico para estos algoritmos son 2, uno es aquel en el que la transmisión del mensaje no resulta interceptable (o difícilmente interceptable), imagina la correspondencia postal entre 2 amantes... por ejemplo. Y otro escenario es aquél donde el objetivo no es realmente mantener cifrado un mensaje sino cólo velado... un ejemplo práctico de esto es por ejemplo los pasatiempos de una revista de ocio, donde se necesita que la respuesta esté velada a la vista, pero que a la vez pueda resolverse sin gran dificultad, en esto ejemplo yo puedo enfrentarme a un rompecabezas y si cansado de no resolverlo quiero ver cual es la respuesta, puedo de un modo fácil hallar la misma que aparece a la vista. Un algoritmo de este tipo es el ya  clásico Rot13 (guglea un poco para ver detalles de su simplicidad y su practicidad, basado en una simple sustitución reversible.

Pueden crearse:
1 )  algoritmos sin clave en la forma, que la clave no requiera ser transmitida más que una única vez.
2 ) Así mismo pueden crearse algoritmos en los que se requiere clave, pero que no requieran transmitir la clave.
3 ) También pueden crearse algoritmos en los que la clave es de 1 sólo uso y no requiere ser enviada previamente al destinatario.
Muchos de estos algoritmos se creran exclusivamente para una tarea o tiempos determinados, por lo que su fuerza reside entre otras cosas en que no se desarrolla una gran cantidad de mensajes con el facilitar un estudio para intentar y lograr la rotura del algoritmo, en otros casos sólo importa que el algoritmo no sea roto en un plazo dado, luego ya no importa.
Voy a disertar brevemenete de por donde andan las ideas de estos algoritmos:

1 - Un algoritmo que requiere clave pero que sólo se transmite una vez, típicamente no contiene 1 única clave si no una tabla de claves. La fuerza del algoritmo radica en que no se necesita contínuamente enviar claves, de hecho al hacerlo una única vez el envío de la clave puede dotársele de fuertes medidas de seguridad, la tabla de claves se envía antes de enviar ningúnmensaje si la tabla es interceptada no se utiliza y se envía otra tabla. Una vez la tabla en poder del/los destinatarios (normalmente en estos casos los destinatarios son estáticos y de alguna manera sino conocidos si reconocidos), es cuando puede utilizarse el algoritmo. El mensaje cifrado provee un sistema para determinar que clave de la que tiene la tabla debe emplearse ó puede haber un modelo prefijado de antemano para usar las claves de la tabla, por ejemplo basado en la fecha de emisión del mensaje cifrado podría determinarse que clave se utiliza, o quizás el tamaño del mensaje módulo x o de modo más simple empezando por una y luego correlativas.
En este sistema la tabla de claves no es por sí missma un sistema totalmente abierto, las claves pueden tener tamaños irregulares y pueden lerse vertical, horizontal diagonalmente o a saltos, etc... incluso una selección cuasi aleatoria que se sugiere en base a interpretar una parte del mensaje cifrado. esto es cuando recibo el mensaje cifrado ejecuto el algoritmo recoge el mensaje y me arroja unos valores, esos valores pueden corresponder con filas y columnas que determinan los valores (consultando la tabla) que se deben introducir para descifrar el mensaje.

Un escenario de estos tipos de algoritmos son como se indicaba más arriba usos determinados o determinados por el tiempo. Por ejemplo en un escenario de guerra, se desea enviar órdenes desde el alto mando a una avanzadilla, un posible mensaje podría ser 'atacar si está presente el general. Retirarse en caso contrario.' esta orden puede tener una validez de posiblemente 1 día 1 semana, después de ese tiempo ( es decir después de haber atacado o haberse retirado) ya no importa que se descifre el mensaje, si la tabla de claves se creó específicamente para una misión y esta ha durado una semana será difícil que sea resuelto el sistema  en ese plazo... para una próxima misión la tabla será distinta y posiblemente el algoritmo también.

2 - Hay algoritmos que requieren clave, pero que no necesitan ser enviadas. Este tipo de algoritmos están orientados hacia un lugar en el que existe un clima de confianza. el mejor modo de entenderlo es exponer un ejemplo del escenario, supongamos que tenemos una pequeña empresa tecnológica, nuestra labor se desarrolla en un ambiente de bolsa, somos conscuientes de que podemos ser espiados en todo momento, nuestros mensajes pueden ser interceptados con relativa facilidad pero aún así necesitamos enviarnos mensajes, uno está en Copenhague y otro en Tokyo: un mensaje cifrado tiene por contenido 'compra 500.000 acciones de Lunex, a no más de 5.5', junto a éste mensaje cifrado acompaña este mensaje no cifrado: ' ¿ te reservo mesa para el viernes en Silos ? '. aparentemente no guarda relación el mensaje cifrado con el mensaje abierto, en realidad nos está recordando que clave debemos usar, una clave podría ser: 'Silos cerró el año pasado' aunque esto resulta obvio dentro de las opciones posibles, en cualquier caso es indiscutible que está relacionado con un supuesto local llamado Silos, tal vez simplemente no esté rememorando un hecho que tanto él como yo vivimos, no existe clave como tal sólo yo puedo descifrar el sentido de ese mensaje, la clave no consta en ningún sitio nu ha sido transmitida... Imaginemos por un caso para nuestro ejemplo que ese loca no existe, existe otro llamado de cualquier manera, donde se les atendió mal y tuvieron que irse a otro local, luego allí bromeaban con que si el local debería llamarse "SI LO Se no vengo...' e imaginemos que a consecuencia de ese acontecimiento el que estáen copenhage conoció a su mujer 'Margarita', entonces la clave puede simplemente ser esa... el que recibe el mensaje no necesita clave explícitamente porque tiene capacidad para interpretar el mensaje y deducir la clave, otro ojos mirando les resultará imposible deducir que algo que simplemente no guarda coherencia para aquellos que no vivieron ese momento.

Este escenario es el que dió lugar a la clave pública y la clave privada, es el escenario más arriesgado, aquél donde tu mensaje puede y posiblemente será interceptado, como esto mismo supone un gran riesgo se impone un sistema especialmente fuerte y resistente. Naturalmente pueden diseñarse todavía algoritmos más sencillos para escenarios similares donde no haya en juego 'secretos de empresa'... y donde la clave publica y la clave privada sean en la forma:  ¿ te reservo mesa para el viernes en Silos ? ' .

3 - Hay algoritmos que donde la clave es de 1 sólo uso, la eficacia de éste sistema es que no requiere memorizarse por lo que no se pone en riesgo a la persona ante posibles amenazas. Actualmente la mayoría de algoritmos de este tipo son para hacer login en alguna parte, más que para descifrar un contenido, aunque paulatinamente es de prever que esto se extienda, dado el problema que supone hoy día memorizar 500 contraseñas para todo.
Los algoritmos con los que se está más familiarizado es con los conocidos como Captcha, que son una simple verificación para evitar robots. Los bancos han empezado a usar también algoritmos de este tipo para evitar riesgos a sus clientes.

.....

En cualquier caso lo que debe quedarte claro es que la fuerza de un algoritmo debe recaer en la clave y no tanto en el algoritmo. La seguridad se sustenta en ese hecho. La seguridad basada en un algoritmo sólo resulta eficaz cuando no hay forma de disponer de 'copias' del algoritmo. Imagina una comunicación entre tu y yo, nuestro algoritmo puede llegar a ser incluso bastante simple comparado con lo existente, pero si nos pasamos los mensajes cifrados por mail, yuna vez en el poder del otro lo tomamos y los ciframos desciframos desde otro ordenador no conectado a internet que es el que tiene el algoritmo, la seguridad resulta bastante elevada, en cambio si el algoritmo es accesible, la seguridad decáe en picado... por eso la seguridad conviene que recaiga en las claves, esto lo independiza bastante de la fuerza del algoritmo que sabemos no son inviolables, cualquiera con los suficientes conocimientos de ensamblador puede destripar un algoritmo, naturalmente requiere su tiempo, pero se le supone al caso que si hay interés eso no va a faltar, a base de tener más gente metido en ello, amén de programas que 'deducen' gran parte de lo que se está haciendo... al respecto algoritmos creados en código 'espagueti' resultan más difíciles que si están programados estructuralmente...

156
Seguridad y Criptografía / Re: duda de un principiante
« en: Miércoles 4 de Noviembre de 2009, 01:10 »
No es exactamente así. Eso son consecuencias, aunque de hecho se aprovechan también para eso. La clave sirve para cifrar y descifrar el mensaje , punto. Luego, adicionalmente o de modo implícito '''agregarle seguridad al algoritmo y para verificar la autenticidad del mensaje''' son consecuencias, pero que pueden explotarse a propósito.
Si es cierto que las claves se idearon-inventaron con ese propósito (agregarle seguridad al algoritmo y para verificar la autenticidad del mensaje), sin embargo una vez hecho el algoritmo, no se puede prescindir de la clave, por tanto la clave es necesaria para cifrar y es (salvo que se diseñe el algoritmo expecíficamente de otro modo) también necesario para descifrar el mensaje.

El otro día estuve editando un artículo en wikipedia, concretamente versaba sobre transposición, échale un vistazo, el artículo es 'Escítala'. Verás que el cifrado utiliza una clave no a la moderna usanza, pero que está sobreentendida en el método usado. Traducido a un algoritmo la clave es un valor numérico.

Imagina una máquina que fabrica vasos de cristal... esa máquina es como un algoritmo de cifrado. Un vaso es un mensaje cifrado, la clave serían las especificaciones del vaso: volumne 10 cm cúbicos. Radio menor= 30 mm, radio mayor= 35 mm. altura= 65mm. grosor=.....  el mensaje sería el material en bruto : Material= vidrio, podría ser barro, podría ser cerámica, aluminio, etc... que es lo que se transforma... Este ejemplo no es totalmente acoplable, pero espero que si entiendas la idea de los parámtros que necesita la máquina para procesar el material, esos parámetros equivalen a la clave...

Imagina una máquina que no requiere parámetros, simplemente le pones el material y listo ella lo procesa, todos los vasos serían equivalentes... imagina otra máquina que tiene un selector, cada selector corresponde con un prototipo, por tanto la clave está inbuída en el algoritmo (la máquina tienes las especificaciones de cada uno de esos prototipos) y por tanto la clave en este caso se resume en reconocer el prototipo usado, el resto de datos residen en la propia máquina. Imagina que dicho selector de prototipos fuera intercambiable, entonces el propio selector sería una clave, habiendo varios selectores, necesitaríamos 2 datos, el selector usado y el prototipo elegido en dicho selector, cada selector tiene la 'firma' de todos los prototipos de vasos que se pueden seleccionar en él.

157
Seguridad y Criptografía / Re: duda de un principiante
« en: Jueves 29 de Octubre de 2009, 17:05 »
Cita de: "elusuario"
Hola, estoy empezando a leer articulos sobre criptografia y hay un par de cosas que todavia no entiendo. Se que son 2 preguntas tontas, pero no encontre un lugar que me las respondiera claramente:

1.- Que es exactamente una clave de cifrado?
2.- Por que es necesaria? No es suficiente con el algoritmo?

Saludos y gracias.

1 - Una clave de cifrado es el 'molde' que se ha utilizado para el cifrado y luego para descifrarlo. En la respuesta a tu 2ª pregunta lo verás más claro con el sencillo ejemplo propuesto.

2 - Imagina un texto como 'Todos los días me levanto a las 7' queremos cifrarla. supongamos que nuestro algoritmo es extremadamente sencillo y lo único que hace es alterar el orden de las letras, cada x letras la siguiente adelanta a dichas... por tanto nuestra clave de descifrado se reduciría a una cifra, x. X es la clave para descifrar el texto codificado. Si la clave elegida es 3, el texto anterior una vez cifrado sería: 'oTodos lis dmas ee ltvan o a las 7'  para que se vez claro, primero marco las letras implicadas: 'Todos los días me levanto a las 7' , por tanto para 'descifrar' el texto codificado necesitamos la clave, que en nuestro caso es el carácter '3', que el algoritmo debe utilizar para hacer reversible el texto cifrado.
La clave es necesaria porque de ese modo podemos ofrecer más seguridad variando la clave, si nuestro algritmo no dispusiera de clave significa que o bien laclave es única y fija (imagina que todos los textos cifrados lo fueran con la clave '3' de nuestro algoritmo) o bien la clave está oculta en el propio texto cifrado.

En este último caso significa que hay una clave única (inbuída en el algoritmo) que oculta la clave dentro del propio texto cifrado. Estos casos suponen una evidente falta de seguridad al ser exclusivamente dependientes del algoritmo. Aparte con éste último si el texto cifrado es interceptado, puede ser manipulado y no podríamos siquiera saber que ha sdo remplazado... capto el texto cifrado y lo sustituyo por otro, que yo he cifrado como la clave es universal, el que lo recibe lo descifrará igualmente pero el contenido descifrado no es el original. Al requerir una clave si el texto cifrado es interceptado y remplazado por otro al yo intentar descifrarlo resultará ilegible (usando mi clave correcta), con lo que puedo hacer otras cosas: informar, reclamar un nuevo envío más seguro,etc...

158
Hardware / Re: Problema al quemar DVD
« en: Jueves 29 de Octubre de 2009, 16:31 »
Cita de: "Programming C++"
Pues tengo una grande problema con mi dvd writter y es que no me quema ningun tipo de dvd

este es la descripsion q me dio el everest

Descripción del controlador   HL-DT-ST DVDRRW GCA-4164B

Descripción del controlador   TWXYFGL NWLMRW1U7K1 SCSI CdRom Device
Es muy posible que tengas un virus, los hay que atacan las unidades de DVD. Ya me he encontrado con alguno.

Si formateas podrías ver que funciona perfectamente ... de nuevo.
No hace falta que formatees para verificarlo, basta que desconectes el disco duro actual e insertes uno vacío (uno viejo que no uses y en el que quepa al menos la instalación del S.O.) lo formateas e instalas el S.O. luego tu programa de grabación de CD-DVD y haces la prueba.. si funciona correctamente entonces como te decía un virus tiene 'secuestrada' tu unidad. En el improbable caso de que siga sin funcionar quizás esté dañado el hardware de la unidad, lo más típico aparte de la suciedad de la lente que te indica Moskito es que la lente esté desajustada. Por supuesto primero mira de ver si hay cables flojos.

159
Inteligencia Artificial / Re: backjumping
« en: Domingo 25 de Octubre de 2009, 16:25 »
El backjumping es un algoritmo derivado del backtracking, de hecho la principal diferencia (y por tanto su ventaja) radica en que el backtracking cuando falla, retrocede un nivel para continuar la búsqueda, mientras que backjumping puede retroceder varios niveles. Esta diferencia se percibe en un rendimiento mayor en el espacio de búsqueda.

Citar
el problema es que los ejemplos que vienen en las hojas que me has pasado son iterativos y yo los necesito recursivos.
Si tienes el algoritmo iterativo, no debería serte difícil convertirlo a recursivo. El resto del  post incide en esto.

Un algoritmo iterativo guarda referencias antes de entrar en el bucle, al salir del bucle puede asignar la referencia localizada en el bucle o desestimar y quedarse con la referencia previa. Entonces para convertirlo en iterativo lo que necesitamos es poder utilizar esta capacidad fuera de la llamada, para esto lo más adecuado es disponer de una función adicional que envuelve a esta, es decir el código dentro del bucle sería lo que exclusivamente formaría la función y lo que está fuera del bucle (delante y detrás) es lo que queda en la función principal de la llamada.

Intentaré reflerjarlo en un sencillo esquema:

Sea un procedimiento que se invoca para realizar un cálculo cualquiera, que necesita un recorrido (en el sentido de repetir) para arrojar el resultado. siendo iterativo sería algo como esto:

Código: Text
  1.  
  2. Procedimiento Calculo(ListaParametrosCalculo)
  3.      Establecimiento inicial de valores       (a)  
  4.  
  5.  
  6.      Iniciar bucle     comprobar condicionantes de repetición del bucle                                 (b)                
  7.           Calcular...                                                                              
  8.      fin bucle
  9.  
  10.  
  11.     pasos posteriores, a veces es sólo una devolución.         (c)
  12. Fin calculo
  13.  
  14.  

Como se ve hay 3 elementos claramente diferenciados: (a) - Establecer valores para las variables del entorno antes de nada, normalmente lo mínimo, es validar los parámetros de entrada.  (b) -  realizar el bucle (si procede) calculando y comprobando si persiste la iteración. Y (c) - tratamiento posterior a la salida del bucle. Esta parte, puede o no, existir y en muchos casos se reduce a una simple asignación de devolución (quizás formateando el datov quizás comparandolo con el dato previo al bucle ).

Para recrear el algoritmo de forma  recursiva necesitamos (haciéndolo del modo más simple y claro) 2 procedimientos en vez de uno. La razón es que al llamarse a si mismo, no debe cambiar estados ajenos al interior del bucle, por eso un procedimiento es el paso (b) del procedimiento iterativo y otro los pasos (a) y (c) del procedimiento iterativo. en medio de estos pasos se hace una única llamada al paso (b), por tanto conserva extactamente los mismos pasos... luego es (b) quien se reinvoca a si misma las veces que precise.

El esquema sería por tanto este:
Código: Text
  1.  
  2. Procedimiento Calculo(ListaParametrosCalculo)
  3.      Establecimiento inicial de valores                        ( a)
  4.          llamada a CalculoRecursivo(Listaparametros)        <-------- (b) ahora es una ÚNICA llamada a un procedimiento
  5.     pasos posteriores, a veces es sólo una devolución. ( c)
  6. Fin Calcculo
  7.  
  8. Procedimiento CalculoRecursivo(ListaParametros)  (b)
  9.         comprobar condicionantes de repetición del bucle        
  10.                   calcular...                                                 (b-1)
  11.                   CalculoRecursivo(listaparametros)              (b-2)    <--------  ahora es una llamada a si mismo, es iterativo
  12.          fin comprobar
  13. Fin CalculoRecursivo
  14.  
  15.  

No es necesario que te señale que el comrpobante de recursión o iteración pueden ir tanto delante, detrás como en medio, conforme se precise para el estado interno de las variables.

Con estas indicaciones deberías ser capaz de convertir cualquier procedimiento iterativo en recursivo y viceversa.

p.d.: Para comprender bien el algoritmo backjumping, yo te sugeriría que lo aplicaras por ejemplo al problema de las 8 reinas... Con posiciones prefijadas, para facilitar entender como evoluciona.

160
Visual Basic para principiantes / Re: Codificación Hamming
« en: Martes 20 de Octubre de 2009, 18:48 »
Bienvenido al foro a pesar de tu mala entrada...

1 - Has resucitado un post de hace 15 meses. Los post antiguos sólo deben ser resucitados por quienes hacen preguntas sobre el mismo no alguien que va a responder a alguien que no está  a la escucha.

2 - El foro es de Visual Basic, no de C, es imperativo si se pone código que éste sea en VB, preciamente existen foros de diferentes lengujaes para que esto sea así.

161
Visual Basic 6.0 e inferiores / Re: Calcular Dias
« en: Martes 20 de Octubre de 2009, 18:43 »
las funciones de fecha están dentro de VBA más exactamente sobre el módulo DateTime
. Puedes omitir VBA e incluso DateTime, porque son funciones globales, no obstante cuando no te acuerdas de la función en concreto a usar, al escribir datetime, elintelllisense despliega la lista de funciones del módulo...
Código: Visual Basic
  1.  
  2. Private Sub Form_Load()
  3.     Dim f1 As Date, f2 As Date
  4.    
  5.     f1 = DateTime.Now
  6.     f2 = "22 noviembre 2007"
  7.     MsgBox "Dias entre fechas: " & DateTime.DateDiff("d", f2, f1)
  8. End Sub
  9.  
  10.  

El resto de cosas que preguntas, son elementales, si no sabes como hacerlo vas por mal camino. De todos modos hay bastantes hilos que tratan de pasada temas afines, por ejemplo te sugiero este post: viewtopic.php?f=143&t=40556 también puedes buscar otros más usandoel buscador del foro.

162
Visual Basic 6.0 e inferiores / Re: combobox + listbox + relacion con tabla
« en: Domingo 18 de Octubre de 2009, 15:51 »
De entrada no me quedaba claro si querías 'controlar un rentacar' o  si querías crear un control de usuario orientado a un rentacar, porq lo que dices en la línea 'estoy tratando de hacer 1 control de una rentacar '.... No obstante como eres principiante y no hay referencias explícitas y no cambia en nada le código que necesitas asumo que es lo primero... hacer un control de un rentacar queriendo indicar controlar un erntacar (en VB hay algo llamado control, de forma que cuando uno dice quiero hacer un control de... da pie a pensar en que se refiere a un control de usuario (que es cosa de programación) frente a un control como acción del verbo controlar...

Hecha la aclaración, paso a explicarte.
Te cuesta lograr lo que quieres porque tu base de datos básicamente está incompleta (amén de que puedas diseñarla mejor, como alegas que sólo es un ejercició para adquirir conocimientos, pasaremos por alto esto último para ceñirnos en completar tu BD), por tanto ahora viene un pequeño 'rollo', explicativo aclarativo que espero que te ilustre.

Una base de datos puede comportarse como sabes para reflejar lo que típicamente se conoce como 'altas' y 'bajas'. Esto de altas y bajas no es otra cosa que cambiar el estado de un dato, y más concretamente (para conocerse como alta y baja) está ceñido a solo 2 estados (a veces a 1 tercero que en tu caso sería conveniente contemplarlo auqnue casi siempre puede ser asumido en uno de los otros 2 estados anteriores... Estos 2 estados como puedes intuir son 'Si' y 'No'; cierto/falso,; 0/1; 0/255; etc... Esto en la práctica implica elegir entre 2 modelos de diseñar el funcionamiento de tu base de datos, el primer modo afecta a un campo de la tabla, el segundo modo afecta a todo el registro, se debe elegir uno u otro modelo independientemente, ahora en situaciones críticas, es más efectivo elegir un modo o el otro de acuerdo a como se utilice la base de datos, cantidad de conexiones, frecuencia de uso, cantidadde registros, cantidad de cambios, datos compartidos entre varios clientes, etc...

Ahora te aclaro estos modos (luego vuelve a repasar este párrafo anterior que te quedará más claro después de leer este otro). Cuando un usuario (de la BD) elige un modelo de vehículo ( ahora ya vamos a referirnos a cosas concretas para que te sea más fácil entenderlo) lo que debemos haceres ir a la base de datos y cambiar (ACTUALIZAR) el estado del modelo elegido (supongo que está regido en base a su matrícula (esto es, Matriicula es la clave principal de esa tabla, si en tu BD de ejemplo sólo tienes modelos, no importa, tanto en cuanto no haya modelos repetidos, si los hay, entonces hay que establecer una diferenciación y para ello lo mejor dado el caso sería incluir un campo matrícula que identifica cada objeto (vehículo) en particular). Es decir si un cliente eligió el modelo X cuando pasas el modelo X al listbox , también debes cambiar el estado para que la BD refleje el nuevo estado a 'NO'.  Para ser más exactos esto debería hacerse sólo cuando el cliente confirma al usuario (digamos que el cliente es el que alquila el vehículo y el usuario el operario de la rentacar que está atendiendo al cliente) que definitivamente se queda con 'esos' modelos. Lo normal es que los clientes estén dudoosos, te digan si, luego, ...añade ese, luego, ...quita aquél, ...este tiene un color feo cambiámelo por el de antes... y así... no vamos a sobrecargar la base de datos con cada cambio de parecer del cliente, sólo lo haremos una vez, y sólo si el cliente al final 'firma y paga' y sólo con los modelos elegidos, el resto de cambios del 'capricho' del cliente, sólo se harán a nivel de interfaz.

NOTA: Supongo que lo que llamas 'patente' es lo que yo designo como 'matrícula'.

Como ves hemos indicado que cambiamos el dato del campo disponible asociado al modelo. (Es decir lo hemos dado de 'baja' cuando el cliente ha elegido definitivamente el modelo X). Esto es suficiente cuando nuestra BD no tiene mucho trabajo. Si nuestra base de datos tiene mucho trabajo exige que en las búsquedas deba filtrar por el campo disponibilidad 'And Flota.Disponibilidad = "si"'... voy a asumir (cosa que nunca me gusta) que el objeto Tabal_rantacar es un objeto AdoDc o AdoDB, entonces en tu bucle Do ... While not ...EOF debes modificar la línea de añadido como te indico:
 
Código: Visual Basic
  1.  
  2. ' Esta línea... :
  3. cmb_vehiculos.AddItem tabla_rentacar("modelo")
  4.  
  5. ' debe fijarse dentro de un condicional, tal que así:
  6. if  tabla_rentacar("modelo").Value="si" then
  7.     cmb_vehiculos.AddItem tabla_rentacar("modelo")
  8. end if
  9.  
  10. ' importante: antes de llenar el combo previamente hay que vaciarlo
  11.  
  12.  

cuando una base de datos va a tener mucho trabajo, es más óptimo tener 2 tablas que contienen los mismo campos (pero el campo dispobilidad ha desaparecido), este campo se ve reflejado ahora en 2 tablas y las tablas se llamarían por ejemplo: FlotaActiva y FlotaInactiva, entonces cuando se de de baja un modelo lo que se haría sería tomar el registro del modelo X y añadirlo a la tabla FlotaInactiva, luego eliminarlo de la tabla FlotaActiva. Y viceversa, cuando el cliente entregue el modelo localizar el modelo en el registro de la tabla FlotaInactiva, copiarlo y añadirlo a la tabla FlotaActiva y luego eliminarlo de la tabla FlotaInactiva. El resultado es que el rendimiento de la BD es mayor (esto se nota cuando la BD tiene mucha carga de trabajo si no es el caso no se nota), por que sólo tiene que buscar sin tener que filtrar, lo mismo cuando vuelcas la tabla a un control, por ejemplo tu combo, no necesitas filtrarlo por 'if  tabla_rentacar("modelo").Value="si"  then', sino que tomarías todos tal como venías haciendo. 10 millones de registros implica 10 millones de preguntas (una por cada registro), si sabemos que la tabla SOLO tiene vehículos disponibles, la pregunta sobra y por tanto nos ahorramos 10 millones de preguntas. Espero que hayas captado la idea.

Te hablaba de un tercer estado, éste estado por ejemplo es modelo: 'Averiado'  y que al caso puede considerarse como 'no' disponible. Nuevamente si manejaras millones de registros y este valor fuera muy grande implicaría un retraso, por ejemplo cuando el cliente entrega el vehículo al localizar el modelo estamos preguntando a vehículos averiados si es el modelo que entrega el cliente, para darlo nuevamente de alta, pero sabemos que nunca vas a ser un vahículo averiado, por eso una tabla llamada FlotaAveriada, trabajaría con respecto de FlotaInactiva de forma similar a lo que hace FlotaActiva con FlotaaInactiva... imagina estos casos: Un cliente ha tenido un golpe contra una farola, una grúa se desplaza y se entrega en el taller, el del taller debe buscar el modelo x en la tabla FlotaInactiva y mudarlo a la tabla FlotaAveriada, y así consta que el Modelo está entregado, si se dejara en FlotaInactiva podría pensarse que elcliente aún lo tiene en su poder, por tanto si se utiliza 3 tablas, sería conveniente cambiar el nombre de la flotaInactiva por el de Flotaalquilada, pués si en un momento queremos conocer el 'estado' de un modelo debe devolver su estado actual si sólo tenemos 2 tablas, estado nos dirá 'si, 'no' están disponibles, pero si queremos por ejemplo saber si un modelo no ha sido entregado o no, esto no es suficiente, los averiados obran en nuestro poder pero estándo inactivos parece que estuvieran alqulados y que el cliente no lo entregó aún, luego realizar la pertinenete factura para cobrar sería complicado determinarlo y puede dar pie a situaciones de equívoco, esto es fácil de evitar si se mantiene una 3ª tabla FlotaAveriada y para clarificar FlotaInactiva sería conveniente cmabiarlo a FlotaAlquilada...

Espero que toda la parrafada, te resulte útil a la hora de diseñar tablas, y si bien para modelos de prácticas y aprendizaje esto no tiene importancia, pero existe la posibilidad de que se convierta en vicio o que uno piense: 'siempre me lo enseñaron así y siempre me funcionó' y por ello tener bajo rendimiento cuando se nos presenta un caso de una BD con mucho trabajo.

También quiero aclararte otro punto, al trabajar con ADODC ( ADODB, ADOR,etc...), es conveniente hacer que el recordset esté ordenado, porque entonces pueden hacerse búsquedas binarias y entonces si que el rendimiento se eleva, además en el uso de 'controles dependientes', como es tu caso (al usar un combo), puedes referirte a registros en el combo que coinciden con registros en el recordset, lo que significa que puedes emplear su índice (en el recordset sería leer o establecer absoluteposition) que es todavía más efectivo que buscar incluso aunque sea una búsqueda binaria. Para que esto sea así, tu combo también debe tener la propiedad sort establecida a true. (sólo el combo que recibe el volcado de la BD no el combo donde se transfieren los modelos que el cliente elige, éste es mejor que el orden sea en el que se introducen.

Para ordenar el recordset tienes que modificar la línea de conexión, seguramente tengas algo como 'Select * from Flota' pués ahora deberías cambiarlo a: 'Select * from Flota OrderBy Modelo' ,( porque es el modelo lo que añades al combo).

Para que esto último se aplique correctamente, es necesario tener en cuenta otro tipo de cosas, por ejemplo si el recordset aloja tanto los modelos disponibles como los que no, el índice del combo no reflejará correctamente el índice del recordset si lo hemos filtrado, entonces tenemos 3 soluciones posibles:
1 O bien mantenemos 2 tablas (como se indicó más arriba)  .. es lo más fácil y lo más cómodo.
2 O bien eliminamos el filtro al obtener los ítems del recordset para añadirlos al combo, pero a cambio tenemos 'desactivar' los modelos nos disponibles.
3 O bien utilizamos la propiedad Itemdata (del combo) , para retener el índice posicional dentro del recordset.

Termino el post detallando acerca de estas 3 posibilidades:
1  Al mantener tablas separadas para los elementos disponibles y  los no disponibles, se toma el recordset completo, no necesitamos filtrarlo y por tanto todo lo dicho sobre sortby (para el recordset) y sorted (para el combo) es válido.

2 Dado que un combo no permite 'desactivar' elementos individuales, deberíamos remplazar el combobox por un listbox y a dicho listbox cambiar la propiedad style a Checkbox, al rellenar la lista lo que haríamos sería seleccionar el elemento indicando si el modelo está disponible o no. Esto se debe complementar con un filtro, de modo que cuando el cliente elija un modelo de verificarse que no sea un elemento 'no seleccionado'. Algo de código para recoger este caso sería...
Código: Visual Basic
  1.  
  2. public function RellenarListamodelos as boolean
  3.     dim k as long
  4.     if not (tabla_rentacar is nothing) then
  5.         tabla_rentacar.movefirst
  6.         lista_vehiculos.clear    ' ojo: hemos cambiado un combo por un list, en el combo style tiene diferente significado y no tiene propiedad selected
  7.         do While Not tabla_rentacar.EOF
  8.             lista_vehiculos.AddItem tabla_rentacar("modelo")
  9.                 if  tabla_rentacar("modelo").Value="si" then lista_vehiculos.Selected(k)=true
  10.             k=k +1
  11.            tabla_rentacar.MoveNext
  12.         Loop
  13.         RellenarListamodelos =true
  14.     End if
  15. end sub
  16.  
  17.  
Este 2º método tiene en contra que al mostrar modelos tanto disponibles como no, despista al usuario, hace la lista más larga de lo necesario (imagina 120 modelos seguidos no disponibles, el usuario se cansaría de hacer scroll para localizar modelos disponibles).

3  Este método es el más sencillo de aplicar tal como tiene la Bd (además en este podrías omitir ordenar el combo y el recordset, aunque si hay que hacer búsquedas en el recordset (moverse de modo diferente a movenext, moverfirst, etc..., esto es usando 'find'), entonces siempre interesará tenerlo ordenado para poder hacer búsquedas binarias.), de entrada seguimos fltrando , el combo sólo se rellena con modelos disponibles tal como te indicaba en los primeros códigos... Para vincular correctamente los elementos del combo junto con los registros del recordset, utilizamos la propiedad itemdata del combo (list) que sirve precisamente para esto.
Código: Visual Basic
  1.  
  2. public function RellenarListamodelos as boolean
  3.     dim k as long
  4.     if not (tabla_rentacar is nothing) then
  5.         tabla_rentacar.movefirst
  6.         cmb_vehiculos.clear
  7.         k=0
  8.         do While Not tabla_rentacar.EOF
  9.             if  tabla_rentacar("modelo").Value="si" then
  10.                 cmb_vehiculos.AddItem tabla_rentacar("modelo")
  11.                 cmb_vehiculos.itemdata(cmb_vehiculos.listcount)-1)=k
  12.             end if
  13.             k=k +1
  14.            tabla_rentacar.MoveNext
  15.         Loop
  16.         RellenarListamodelos =true
  17.     End if
  18. end sub
  19.  
  20.  

Usando este 3º modo, cuando copiemos el valor del combo al listbox que ha elegido el cliente también debemos copiar el valor de itemdata. Cuando el cliente finalmente pulse el botón aceptar (vamos que paga y alguila los modelos elegidos) es cuando actualizamos y para ello usamos los itemdata que reflejan el nº de registro del recordset. Un posible código (simplificado) que hace esto sería:
Código: Visual Basic
  1.  
  2. ' dar de baja los modelos elegidos por el cliente
  3. Private Sub ComAlquilar_Click()
  4.     Dim k As Long
  5.    
  6.     For k = 0 To Combo1.ListCount
  7.        ' nos movemos al registro que refiere al modelo que eligió el usuario
  8.        tabla_rentacar.absoluteposition = Combo1.ItemData(k) ' ojo: no confundir itemdata con listindex
  9.        
  10.        ' cambiamos el valor del campo...
  11.        tabla_rentacar.fields("modelo").Value = "no"
  12.     Next
  13.    
  14.     ' actualizar de nuevo el combo para que sólo contenga modelos disponibles
  15.     Call RellenarListamodelos
  16. End Sub
  17.  
  18.  
Esto sólo funcionará bien si el recordset no ha sido modificado, si se eliminaron o añadieron registros, no funcionará en dicho caso habrá que moverse por el recordset usando 'find' para posicionarse sobre el registro correcto, para hacer el cambio oportuno.

Hay muchas más cosas que decir, pero la verdad, me da pereza responder temas de bases de datos porque es tan amplio y cada circunstancia lleva aparejada tantas condiciones y los posteadores omiten tantos datos  y demás cosas que una pregunta simple por un supuesto error se acaba convierto en una cacería de errores por lo general por falta de formación y los posts se hacen larguísimos para explicar los entresijos de cada detalle con claridad... para muestra este mismo post.

Saludos.

163
Imagina que un proyecto es una casa... entonces en este símil imaginario, cada formulario se entendería como una habitación...

Tantas habitaciones tiene tu casa, tantos formularios tiene tu aplicación... Ahora imagina quieres pasar de una habitación a otra, al respecto decimos que hay habitaciones con puerta y habitaciones sin puerta.

Tu queja es que cuando accedes a otra habitación no se cierra la puerta... piensa, al acceder a otra habitación que haces ?... desde la habitación en la que estás, abres la puerta para acceder a la otra habitación, luego una vez dentro es tu responsabilidad cerrar o no la puerta desde esa habitación. Si se cerrara automáticamente, la queja y el remedio sería peor... cómo puede el sistema saber si tudeseas que la puerta se cierre  o no ?. No puede, luego eres tu quien si lo necesitas debe cerrar la puerta.

La habitaciones sin puerta diríamos que son formularios modales y las habitaciones con puerta son no modales (formularios asíncronos). Una habitación sin puerta debe entenderse como una estancia (alacena, almacén, armario) al que accedes haces lo que quieras y luego necesariamente tienes que regresar por donde has entrado, normalmente recoges algo y regresas... for ejemplo un msgbox, un inputbox o un commondialog para elegir colores, fuente, fichero ú opciones de impresión... formulario del progreso de una acción, formularios 'about' y en general todos los formularios de opciones, que actúan como una caja de herramientas (donde sólo tienes que elegir cosas, seleccionar detalles, etc... pero que por si mismo sólo tienen una funcionalidad específica y claramente delimitada).  Las habitaciones con puerta son habitaciones en las que entras y te quedas en ellas.

Depende de ti decir si una habitación tiene o no tiene puerta formX.show (??????) y por tanto si es síncrono o no, si es síncrono (no tiene puerta no puedes cerrarla, es como si se cerrara automáticamente sola alsalir de ella), si es síncrono, puedes cerrarla pero lo tienes que hacer tú.

Al cerrar la puerta debemos entender que cierras el formulario del que provienes y al abrirla que abres un formulario al que deseas ir desde el que estás.

Abrimos una puerta, estás en form1
formX.show
Cerramos la puerta tras entrar: ahora estás en formX, pero el código es mejor que lo pongas en form1 justo después del formX.show
unload me (ó me.hide, sólolo ocultamos)
Si el código lo pones en formX , debes saber que puerta estás cerrando, imagina que tienes 10 formularios (en esta casa imaginaria, cada habitación está comunicada con todas las demás en teoría, luego según tu proyecto, esto será verdad o no, según el diseño). si accedes desde el form3, y deseas cerrarlo desde el FormX debes saber desde que puerta has entrado, en realidad nuestra casa imaginaria sólo tiene  1 única puerta vengas de donde vengas, es más como en un hotel donde sales al pasillo te diriges a la habitación deseada y la abres, sabes que entras, pero la habitación en la que entras no sabe de donde vienes (no le consta ninguna referencia), por eso lo mejor es que desde la habitación que sales una vez salido, cierres ....  no cerrar desde la habitación en la que entras.

Hay otro caso aparte, un formulario MDI , es como el hotel entero, y particularmente actúa como el recibidor de un hotel. Esto es desde las habitaciones del hotel no puedes cerrar el hotel... desde los formularios hijos del Formulario MDI, no puedes cerrar el formulario MDI, o mejor dicho si lo haces se cierra también todos los formularios hijos... incluído él.

Si no lo acabas de entender dime donde te pierdes...

p.d.: yo no mando emails a nadie y no es buena práctica ir dejando colgado tu email al público... ¿¿¿ tu dejas copia de tu tarjeta de identidad y/o tu teléfono por toda la ciudad en tu quehacer diario ?????.

164
VBA / Re: Duda filtro y cambiar de fila
« en: Jueves 15 de Octubre de 2009, 17:05 »
Bueno, hay cosas que sigo sin entender, son detalles que sólo tu sabes.

No obstante eso no quita para te pueda indicar una línea de trabajo....

Yo te expongo un código que luego debes completar y adaptar a tus necesidades. Como no he podido descargar hasta hoy los otros 2 ficheros (tras descargar el fichero *.plf el 'gigasize' me indicó que alcancé el límite),  ... pués no he visto que lo trabajas todo en excel.

Hay partes que está comentada y parte que tiene código, te lo meto todo en un archivo rar, lo abres y lo miras detenidamente, para hacerc cambios hazlos sobre una copia,a así quedando este intacto, podrás volver a ver el original cuando lo necesites. Obviamente tendrás que modificarlo bastante para adaptarlo a excel.... Sin embargo está bastante comentado, como para que puedas hacer un seguimiento casi completo  sin perderte.

De todas formas te lo voy comentando por encima...

Tenemos un formulario, tiene 3 botoners, uno de iniciar y otro de detener, el tercero sólo aparece si ocurre aalgún error inesperado, el resto de la interfaz sólo tiene propósitos de aclarar el estado del proceso.

Los estados posibles son EnEspera de iniciarse(a fin de cuentas parado) , petición de inicio, inicio, petición de parada, parado.
Cuando el estado es petición de inicio, el timer se pone en marcha e invoca un método de una clase que es quien realiza todo el trabajo. Si tiene éxito dispara un evento 'procesando', entonces el estado pasa a ser iniciado. si ocurre un error el estado pasa a ser parado.
Cuando se pulsa el botón de parar, el estado se establece en petición de parada, la parada sólo ocurre cuando se termine de procesar los datos actuales. cuando esto ocurre se dispara un evento de terminado.

Estos botones 'fluctuan' ,  con el disparo de dichos eventos (procesando y terminado) habilitándose/desahbilitándose y cambio el color de fondo de los mismos, lo cual está controlado de modo general por el timer...

Cuando se inicia la aplicación se crea una instancia de la clse 'Trnsformar'  y se invoca una función de ésta, la idea es que en esa función busquees el fichero inicial de entrada, debes también asignar las rutas a las variables de dichos archivos (entrada y salida)

El resto de la interfaz son el propio timer y 2 shapes, para indicar estados... adicional al estado que marcan los botones, para distinguir la fluctuación de los botones del estado global.

Como el código del formulario es bastante 'sencillo', creo que no necesita más comentario
El código del formulario  es éste:
Código: Visual Basic
  1.  
  2. Private Procesando As Boolean
  3. Private WithEvents Transforma As Transformar
  4. Private Reintentos As Byte
  5.  
  6. Private Const Carmin As Long = &HE0E0F0
  7. Private Const Verdin As Long = &HE0F0E0
  8.  
  9. ' inicia un intento de paro o puesta en marcha del proceso
  10. ' la notificación de paro sólo sucederá cuando se termine el actual
  11. ' bloque de operaciones en curso.
  12. Private Sub ComProceso_Click(Index As Integer)
  13.     ' color de transición, tras un evento de transforma ya se cambiarán a su color adecuado
  14.     If Index = 0 Then
  15.         ComProceso(0).BackColor = Verdin
  16.         ComProceso(0).Enabled = False
  17.     ElseIf Index = 1 Then
  18.         ComProceso(1).BackColor = Carmin
  19.         ComProceso(1).Enabled = False
  20.     End If
  21.    
  22.     Timer1.Enabled = (Index = 0)
  23.     ShaEnMarcha.Visible = Timer1.Enabled
  24. End Sub
  25.  
  26. ' regresa los cambios operados ante error al modo operativo normal
  27. Private Sub ComResetError_Click()
  28.     ComResetError.Enabled = False
  29.     ComResetError.Visible = False
  30.     ShaError.Visible = False
  31.     ComProceso(0).Enabled = True
  32.    
  33.     ShaEnMarcha.Visible = True
  34.     Timer1.Enabled = True
  35. End Sub
  36.  
  37.  
  38.  
  39. ' esto es lo primero que se va a ejecutar cuando se inicie la aplicación.
  40. ' prepara los controles y valores....
  41. Private Sub Form_Initialize()
  42.     Set Transforma = New Transformar
  43.     Reintentos = 0
  44. End Sub
  45.  
  46.  
  47. ' realiza hasta 12 intentos
  48. Private Sub Form_Load()
  49.     Dim Ok As Boolean
  50.    
  51.     Timer1.Enabled = False
  52.     Timer1.Interval = 30000
  53.     Do While Reintentos < 12
  54.         If Not (Transforma Is Nothing) Then
  55.             If Transforma.InicializarProceso = True Then
  56.                 Ok = True
  57.                 Exit Do
  58.             Else
  59.                 ' avisar, algo no está conforme a lo que necesitamos
  60.                 ' ver descripción de InicializarProceso
  61.             End If
  62.         Else
  63.             Reintentos = Reintentos + 1
  64.             ' pausa de 3 segundos y reintentamos
  65.             Call Pausa(3)
  66.            
  67.             Set Transforma = New Transformar
  68.         End If
  69.     Loop
  70.    
  71.    
  72.     Reintentos = 0
  73.     If Ok = False Then
  74.         MsgBox "Ocurrió un error, no se consiguió inicializar el proceso..."
  75.         Unload Me
  76.     Else
  77.         ' el sistema está listo para comenzar.... sin embargo espera a que se pulse  el botón de comienzo.
  78.         ComProceso(0).Enabled = True
  79.         ComProceso(1).Enabled = False
  80.         ComResetError.Enabled = False
  81.         ComResetError.Visible = False
  82.         ShaError.Visible = False
  83.     End If
  84. End Sub
  85.  
  86. ' antes de cerrar intentamos ver si es posible terminar el proceso actual (si estaba en marcha)
  87. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  88.     If Timer1.Enabled = True Then
  89.         ' petición de terminar
  90.         Call ComProceso_Click(1)
  91.        
  92.         MsgBox "Hay una operación en curso intentaremos esperar a que termine... antes decerrar."
  93.         Me.Hide  ' lo ocultamos para evitar que insista y al final recurra a medidas drásticas sin darle tiempo a terminar y guardar el resultado.
  94.         Do
  95.             DoEvents
  96.         Loop While Procesando = True
  97.     End If
  98.     Set Transforma = Nothing
  99. End Sub
  100.  
  101. Private Sub Form_Terminate()
  102.     Timer1.Enabled = False
  103.     Set Transforma = Nothing
  104. End Sub
  105.  
  106.  
  107. Private Sub Timer1_Timer()
  108.     If Procesando = False Then
  109.         Procesando = True
  110.         Transforma.Procesar
  111.     End If
  112. End Sub
  113.  
  114.  
  115. '================================================
  116. '======== eventos de el objeto Transforma =======
  117.  
  118. Private Sub Transforma_Procesando()
  119.     ComProceso(0).Enabled = False
  120.     ComProceso(0).BackColor = vbGreen
  121.     ComProceso(1).Enabled = True
  122.     ComProceso(1).BackColor = Carmin
  123.     Beep
  124.     Call Pausa(1)
  125.     Beep
  126. End Sub
  127.  
  128. Private Sub Transforma_Terminado()
  129.     Procesando = False
  130.     ComProceso(1).Enabled = False
  131.     ComProceso(1).BackColor = vbRed
  132.     ComProceso(0).Enabled = True
  133.     ComProceso(0).BackColor = Verdin
  134.     Beep
  135.     Call Pausa(1)
  136.     Beep
  137. End Sub
  138.  
  139. Private Sub Transforma_ParoError()
  140.     Timer1.Enabled = False
  141.     ShaEnMarcha.Visible = False
  142.     ShaError.Visible = True
  143.     ComResetError.Enabled = True
  144.     ComResetError.Visible = True
  145.    
  146.     Call Transforma_Terminado
  147.     ComProceso(1).Enabled = False
  148.    
  149.     MsgBox "Ha ocurrido un error inesperado..."
  150.     ' otras acciones posibles
  151.     '  acciones...
  152. End Sub
  153.  
  154.  
  155. ' realiza una pausa con los segundos especificados antes de continuar
  156. '  esto es aproximado... no es un tiempo exacto. puede fluctuar 200 milisegundos
  157. Private Sub Pausa(ByVal Segundos As Byte)
  158.     Dim t As Single
  159.    
  160.     t = Timer
  161.     Do
  162.         DoEvents
  163.     Loop While Timer - t < Segundos
  164. End Sub
  165.  
  166.  

La clase se compone de algunas enumeraciones, yo sólo he puesto la de 'eventos', que parece la más obvia y una matriz que se correponde indice a indice con esta enumeración. el resto de enumeraciones que precisares podrías tratarlas del mismo modo.

He tratado cada 'linea' como una estructura, supuse que tu idea inicial era guardarlo como fichero, te texto plano... Cyuando el timer entra en marcha, invoca una función de la clase que se dedica a procesar, hay bastante descripción detallada que señala los pasos que se deben seguir, naturalmente ni está completo ni es obligatorio, deberás añadir, quitar y modificar de acuerdo a tus necesidades, yo sólo te proveo una orientación...

Esa función determina si el fichero en seguimiento ha variado de tamaño, a fin de determinar si se debe seguir leyendo del mismo, intuyo que algo al final de  un archivo debe ser indicador de que el archivo está completo, a falta de ello verificar el tamaño es una opción (más pobre pero que sirve). Si el fichero estuviera completo, se debe localizar el siguiente, se llama a una función que realiza esa labor.

Una vez localizado el fichero (si es otro distinto del anterior) se llama a una función que lee el contenido del actual archivo de entrada. Lo leemos todo de una vez (vb6 puede leer perfectamente incluso 10Mb. en menos de 1 sg.) y lo troceamos en líneas, asumimos que cada línea está separada de la siguiente por un retorno de carro y avande de línes (CR= CarryReturn , LF= Line Feed) ó vbCrlf en vb6. Esta función devuelve por referencia el número de líneas contenidas. Si el fichero no está al inicio se posiciona el cursor en la posición actual de lectura, antes de leerlo, lógicamente y guardamos el cursor de lectura tras tomar los datos, luego se cierra el archivo y se devuelve la matriz de líneas

Tras tomar la matriz de líneas si lineas -1 (error ocurruid) ó 0 (no hay texto ???) dispara un evento de error y sale de la función, en otro caso se invoca a otra función, la que va a realizar la transformación de estas líneas en las que tu quieres.

La función que formatea las líneas, está a medio codificar, hay datos que yo no tengo y lógicamente no se en base a que han detomar una u otra constante, a mi la línea, por ejemplo: '2009.05.04 15:42:28 MESSAGE    PLY0023,23,3,~CM100GEN', no me dice gran cosa, es de asumir que el código de mensaje responde a un manual de operativa de la máquina , yo he tratado las fechas (sesupone que la fecha de inicio de una operación es la fecha de finalización de la anterior), y  he calculado  la duración usando una funcion de fecha, para totalizar segundos. El resto de esta función son sugerencias, por ejemplo verás un bloque 'select case', donde debes procesar la parte de 'mensaje', imagino que el resto de texto a la derecha se interpreta de modo uniforme de acuerdo a ese 'mensaje'.

finalmente en la misma función indicada anteriormente, te ofrezco 2 funciones de salida a fichero (es loque creía que tenías que hacen antes de descargar estos ficheros de excel). Nota que la salida en binario siempre será más rápida y cómoda pero ofrece un fichero ilegible a la vista si lo abres con el 'bloc de notas' (igual que sucede si abres un archivo excel con el mismo 'bloc de notas'), un 2º método te ofrece guardarlo en formato de cadena, es siempre más lento, porque  tiene que hacerse a través de un bucle línea a línea.

No obstante esta (última) salida es aceptable para excel... excel permite importar ficheros de texto, interpretando como fila de excel cada línea de fichero e interpretando como columna cada dato separado de otro. con esto tienes pués 2 caminos a seguir para crear tus archivos excel, tomar todo el código y adaptarlo, completarlo a tu proyecto actual o crear un nuevo proyecto, completar este que ten envío y luego importar a excel el fichero ya elaborado, las 'fórmulas'  que tengas en excel, te siguen valiendo... Sólo cambia el método de adquisición de datos.

El código de la clase es éste:
Código: Visual Basic
  1.  
  2. Private Enum EventosMaquinaIn
  3.     EVENTO_AVERIA = -1
  4.     EVENTO_ENTRADA = 0
  5.     EVENTO_PARADA = 1
  6.     EVENTO_MARCHA = 2
  7.     EVENTO_REDUCE_VELOCIDAD = 3
  8. End Enum
  9.  
  10.  
  11. Private Type LineaSalida
  12.     id As Long
  13.     Inicio As Date
  14.     Fin As Date
  15.     Duracion As Integer
  16.     ' eventoEspecificado as string
  17.     Evento As String  ' se toman de la  matriz EventosMaquinaOut
  18.     Maquina As String
  19.     Motivo As String
  20. End Type
  21.  
  22. ' nótese que las cadenas se hacen coincidir en índices con EventosMaquinaIn
  23. '  los valores se generan al crear la clase: ver Class_Initialize
  24. Private EventosMaquinaOut(-1 To 3) As String
  25.  
  26. Private s_LinAnterior As LineaSalida
  27. Private p_FicheroEntrada As String
  28. Private p_FicheroSalida As String
  29.  
  30. Private s_cursorEntrada As Long
  31. Private s_CursorSalida As Long
  32.  
  33. Private s_TamañoEntrada As Long
  34. Private s_Id As Long
  35. Private s_Maquina As String
  36.  
  37.  
  38. Public Event Procesando()
  39. Public Event Terminado()
  40. Public Event ParoError()
  41.  
  42.  
  43. Public Property Get FicheroSalida() As String
  44.     FicheroSalida = p_FicheroSalida
  45. End Property
  46.  
  47. Public Property Get FicheroEntrada() As String
  48.     FicheroEntrada = p_FicheroEntrada
  49. End Property
  50.  
  51.  
  52. ' esto debería invocarse cuando se arranca el programa antes de ejecutarse nada
  53. '  para hacer esas cosas que sólo ocurrirán una única vez al principio.
  54. Public Function InicializarProceso() As Boolean
  55.     ' leemos de un fichero estado.txt
  56.     '   si no existe se crea.
  57.     '  pero si ya existe leemos
  58.     '   donde quedamos la vez anterior, esto es si quedó un fichero sin terminar (suponiendo que esto interese)
  59.    
  60.     ' si estamos interesados en devolver algún estado devolvemos true, o false según convenga o cambiamos el tipo de devolución
  61.     '  si queremos devolver otro tipo de dato.
  62.    
  63.     ' si deseamos decidir si empezar, o resetear el archivo de estado previo, deberíamos establecer un parámetro a la función.
  64.    
  65.     ' antes de devolver nos aseguramos de ver y asignar laos valores para las variables:
  66.     '  p_ficheroentrada y p_ficherosalida
  67.    
  68.     InicializarProceso = True
  69. End Function
  70.  
  71. Public Function Procesar()
  72.     Dim Texto() As String
  73.     Dim Lineas As Long
  74.    
  75.     ' si existe p_ficheroEntrada luego
  76.          s_TamañoEntrada = FileLen(p_FicheroEntrada)
  77.     '     si tamaño del fichero es mayor que p_cursorentrada luego (se ha escrito nuevo contenido)
  78.     '
  79.     '       (continuamos con la lectura, esto es en el siguiente apartado)
  80.     '     el tamaño es el mismo  ' nada que procesar, se está esperando a que la máquina realice operaciones o  está terminado ?
  81.     '         (necesitamos saber cuando un fichero está terminado: ¿ obbsstop indica esto ?)
  82.     '         si sabemos que está terminado luego (debemos buscar el siguiente fichero)
  83.     '             localizado = llamar a función: BuscarSiguienteEntrada
  84.     '             si localizado False luego  (  no hay ficheros de entrada pendientes)
  85.     '                 raiseevent Terminado
  86.     '                 exit function
  87.     '             fin condición: localizar siguiente fichero
  88.     '         si sabemos que no está  terminado (debemos esperar)
  89.     '             raiseevent Terminado
  90.     '             exit function
  91.     '         fin condicion: de lo que sabemos
  92.     '     fin condicion: Tamaño no varía
  93.     ' no existe fichero entrada
  94.     '     localizado = llamar a función: BuscarSiguienteEntrada
  95.     '     si localizado False luego  (  no hay ficheros de entrada pendientes)
  96.     '           raiseevent Terminado
  97.     '           exit function
  98.     '     fin condición: localizar siguiente fichero
  99.     ' fin condicion: existe fichero entrada
  100.    
  101.    
  102.      Texto = TomarContenidoFicheroEntrada(Lineas) ' ( llamar a función tomar contenido de fichero de entrada)
  103.      If Lineas < 1 Then ' -1= (ocurrió un error), 0=  se leyó el fichero pero parece que no contiene texto  ????
  104.         RaiseEvent Terminado
  105.         Exit Function
  106.     Else     ' lineas es mayor que (hay líneas que procesar)
  107.         Call ConvertirLineas(Texto) '    llamamos a otra función para tratar las líneas (sólo por claridad y sencillez de modificar las funciones)
  108.         RaiseEvent Terminado
  109.     End If ' fin condición hay líneas de texto leídas
  110. End Function
  111.  
  112.  
  113. ' localiza el siguiente fichero que genera la máquina para ser procesado
  114. Private Function BuscarSiguienteEntrada() As Boolean
  115.     ' si localiza un ficheo
  116.     '    p_ficheroentrada= ElficheroEncontrado
  117.     '    s_cursorentrada= 1
  118.     '    cerramos ficherosalida
  119.     '    s_cursorSalida=1
  120.     '    creamos y abrimos nuevoFichero de salida
  121.     '    p_Ficherosalida = ElNuevoficherosalida ' elegir el nombre y la ruta, supuestamente basado en el nombre y ruta del de entrada
  122.     '
  123.     '    s_Maquina= "fiber-1" ' se supone que tú debes saber como obtener este dato.
  124.     '
  125.     '    devuelve True
  126.     ' no localiza un nuevo fichero (quizás la máquina esté parada, o está en medio  de un largo proceso y no escribe hasta el ´termino)
  127.     '    Devolver false
  128.     ' fin condicion: localizar fichero
  129. End Function
  130.  
  131. Private Function TomarContenidoFicheroEntrada(ByRef Lineas As Long) As String()
  132.  
  133.     ' abrimos el fichero
  134.     ' posicionamos el crusor
  135.     ' leemos hasta el final del archivo
  136.     ' Troceamos el texto en líneas
  137.     ' Devolvemos el texto
  138.    
  139.     Dim ff As Integer
  140.     Dim Texto As String
  141.     Dim txt() As String
  142.    
  143.     On Local Error GoTo ErrorTomar
  144.    
  145.     Texto = String(s_TamañoEntrada - p_cursorentrada + 1, " ")
  146.     ff = FreeFile
  147.     Open p_FicheroEntrada For Binary As #ff
  148.         Get #ff, p_cursorentrada, Texto
  149.     Close #ff
  150.    
  151.     Texto = Trim$(Texto)
  152.     If Texto <> "" Then
  153.         If InStr(1, Texto, vbCrLf) > 0 Then
  154.             txt = Split(Texto, vbCrLf)
  155.             Texto = ""  ' liberamos memoria
  156.             Lineas = UBound(txt) + 1
  157.             TomarContenidoFicheroEntrada = txt
  158.             Erase txt  ' liberamos memoria
  159.         Else
  160.             Lineas = 1
  161.             redim txt(0 to 0)
  162.             Txt(0)=texto
  163.            TomarContenidoFicheroEntrada = txt
  164.             Texto=""
  165.             erase txt
  166.         End If
  167.     Else
  168.         Lineas = 0
  169.     End If
  170.     Exit Function
  171.    
  172. ErrorTomar:
  173.     Close #ff
  174.     RaiseEvent ParoError
  175.     'MsgBox "Error al leer fichero de entrada: " & vbCrLf & _
  176.     'Err.Number & "  " & Err.Description, vbCritical
  177.    
  178.     Lineas = -1
  179. End Function
  180.  
  181.  
  182.  
  183. Private Sub ConvertirLineas(ByRef Lineas() As String)
  184.     ' iniciamos bucle
  185.     '     procesamos línea a línea
  186.     '     eventuualmente según la cantidad de parámetros de cada línea debe procesarse aparte
  187.     ' terminamos bucle
  188.    
  189.     ' abrimos fichero de salida
  190.     '     posicionamos el cursor de salida
  191.     '     escribimos contenido
  192.     ' cerramos fichero de salida
  193.    
  194.     Dim k As Long, n As Long
  195.     Dim Salida() As LineaSalida
  196.     Dim Linea() As String
  197.     Dim txt As String
  198.    
  199.     ReDim Salida(-1 To UBound(Lineas))  ' ojo: insertamos la línea usada la última vez del proceso anterior como la línea -1
  200.     Salida(-1) = s_LinAnterior
  201.    
  202.     For k = 0 To UBound(Lineas)
  203.         Linea = Split(Lineas(k), " ") ' el divisor es un espacio
  204.        
  205.         Salida(k).Maquina = s_Maquina ' se supone que al cargar el fichero siguiente se obtiene ese valor que presumiblemente es constante para el mismo fichero.
  206.        
  207.         Salida(k).id = Salida(k - 1).id + 1
  208.         Salida(k).Fin = Replace(Linea(0), ".", "-") & " " & Linea(1) '
  209.         Salida(k).Inicio = Salida(k - 1).Fin
  210.         Salida(k).Duracion = DateDiff("s", Salida(k).Fin, Salida(k).Inicio)
  211.        
  212.         ' importante: al guardar el fichero en modo binario, resulta ilegible si abrimos luego el archivo para leerlo, si queremos
  213.         '  que sea legible (a la vista) debemos hacerque todos los campos de la estructura sean cadenas de texto
  214.         ' entonces deberíamos declarar al menos 2 datos de fecha a nivel de la función
  215.        
  216.         ' por ejemplo:
  217.         ' estas 3 líneas iría antes del bucle
  218.         '   Dim Ini As Date, Fin As Date, id As Long
  219.         '   id = Val(Salida(-1).id)
  220.         '   fin= salida(-1).Fin
  221.         ' estas líneas irían dentro del bucle sustituyendo a las previas
  222.         '   Ini = Fin
  223.         '   Fin = Replace(Linea(0), ".", "-") & " " & Linea(1)
  224.         '   Salida(k).Duracion = CStr(DateDiff("s", Fin, Ini))
  225.         '   Salida(k).Fin = CStr(Fin)
  226.         '   Salida(k).Inicio = CStr(Ini)
  227.         '   id = id + 1
  228.         '   Salida(k).id = CStr(id)
  229.        
  230.        
  231.         ' estos datos se supone que tienes que interpretar las constantes que aparecen en las líneas
  232.         '  podrían meterse enuna enumeración o no con y una matriz asociada con ello nos podríamos ahorramos el select case en algunos casos
  233.         Select Case Trim$(Linea(2))
  234.             Case "MESSAGE"
  235.                 Salida(k).Evento = "?"
  236.                 Salida(k).Motivo = "?"
  237.             Case "COMMENT"
  238.                 Salida(k).Evento = "?"
  239.                 Salida(k).Motivo = "?"
  240.             Case "MATERIALFP"
  241.                 Salida(k).Evento = "?"
  242.                 Salida(k).Motivo = "?"
  243.             ' más casos
  244.                 'Salida(k).Evento = "?"
  245.                 'Salida(k).Motivo = "?"
  246.             ' ................
  247.         End Select
  248.     Next
  249.     s_LinAnterior = Lineas(UBound(Lineas))
  250.    
  251.     Erase Lineas ' liberamos memoria
  252.    redim preserve Salida(0 to ubound(salida)) ' eliminamos la línea previa -1 que añadimosprevio al bucle.   
  253.  
  254.     ' qué queremos hacer con las salida ???.
  255.     ' si sólo lo queremos escribir a fichero
  256.        
  257.     ' escribiendo en modo binario (ilegible a la vista).
  258.     Open p_FicheroSalida For Binary As #ff
  259.         'Loc(ff) = s_CursorSalida
  260.         'Put #ff, , Salida
  261.         Put #ff, s_CursorSalida, Salida  ' tiene la ventaja de que escribe estructuras, matrices y matrices de estructura con 1 sola línea.
  262.         s_CursorSalida = Seek(ff)
  263.     Close #ff
  264.    
  265.     ' alternativamente puedes escribirlo como texto y usando un bucle (es totalmente legible a la vista)
  266.     Open p_FicheroSalida For Output As #ff
  267.         Loc(ff) = s_CursorSalida
  268.         With Salida(k)
  269.             For k = 0 To UBound(Salida)
  270.                 Print #ff, .id, .Inicio, .Fin, .Duracion, .Evento, .Maquina, .Motivo
  271.             Next
  272.         End With
  273.         s_CursorSalida = Seek(ff)
  274.     Close #ff
  275.     Erase Salida ' liberamos memoria
  276. End Sub
  277.  
  278.  
  279. Private Sub Class_Initialize()
  280.     EventosMaquinaOut(-1) = "AVERIA"
  281.     EventosMaquinaOut(0) = "ENTRADA"
  282.     EventosMaquinaOut(1) = "PARADA"
  283.     EventosMaquinaOut(2) = "MARCHA"
  284.     EventosMaquinaOut(3) = "VELOCIDAD REDUCIDA"
  285. End Sub
  286.  
  287.  
  288.  

Considero que tienes bastante materia como para poder completar tu proyecto.  :beer:  Si tienes alguna duda, consulta, pero sé explícito y no des por hecho que la ¿ troqueladora ? , ¿ torno ? , la hemos fabricado nosotros ni tampoco el programa que la maneja  :ph34r:  ?. Mejor si son preguntas concretas, las preguntas genéricas dispersan mucho la respuesta...

envío y luego edito para adjuntar el fichero:

165
VBA / Re: Duda filtro y cambiar de fila
« en: Miércoles 14 de Octubre de 2009, 17:20 »
Te he leído 3 veces y no acabo de terminar de entenderte del todo.... tu te explicas como dando por hecho que conocemos la 'máquina' esa y que estamos familiarizados con lo que hace...

Supongo que a instruccción te refieres a cada línea ahí escrita, y supongo (por que no lo indicas) que dichas líneas proceden de un archivo de texto ¿...?, luego hablas de columnas que yo no veo, por lo que asumo (ya me dirás si acierto) que cada columna debe ser el texto definido entre 2 espacios. Para terminar, en el texto encabezado indicas: (solo quiero leer a partir de donde lo dejó la ultima vez) pero luego previo al último párrafo dices (y quiero algo como esto)... entonces cuál de las 2 cosas quieres ?... nuevamente asumo (no se si acierto) que esta 2ª idea nace como una posible respuesta a la 1ª...

Entonces para poder ayudarte de la forma más óptima dime exactamente cual es el problema raíz, deja aparte de momento las posibles soluciones, dime si lo que haces es:
a -  leer el contenido de un fichero, trabajas en el y si
b -  lo modificas o no, y si luego
c -  más tarde ese mismo fichero ha sido escrito añadiendo contenido al final,

...y es por eso que quieres 'revisar' desde la vez anterior... porque si esto es así, la solución sería bastante más fácil de loque te puedas imaginar.

Si en cambio lo quieres es
d - alterar un texto para que tenga otro 'aspecto' pués acláralo,

si esto 2º es resultado para solucionar lo 1º es trabajo inútil,ahora si
e-  es obligatorio hacer esa cambio, entonces es un nuevo y  2º problema.

Defínelo claramente... plis. al menos confirmando a,b,c,d,e...

166
Visual Basic 6.0 e inferiores / Re: Cargar Combos
« en: Miércoles 14 de Octubre de 2009, 16:58 »
Ok.

Añadimos un módulo al proyecto (siempre que se comparte código entre 2 o más formularios interesará  tener funciones disponibles desde ellos), al iniciar el proyecto invocamos una función que es la que recoge datos para una matriz, metemos en una matriz datos referentes alos combobox que comparten el mismo contenido. Los combobox que no comparten el mismo contenido no tiene aliciente incluirlos.

Para que repares en el código he separado la carga de los combos de igual contenido para que sea llamado desde un botón en el formulario 1,( llena 1 combo del formulario 1 y 2 combos del formulario 2). La carga de los combox que son diferentes se hace desde la función inicial.

El origen de los datos no importa, yo he provisto para los combos compartidos que el origen se tome desde una constante ( de países) que figura en el formulario 1, pero igual podrías tomarlo de un fichero o de un bucle con inputbox...

Los combos que tienen diferente contenido no queda más remedio que llenarlos 1 a uno, por tanto para que puedan llenarse desde la misma función en dicha función debe proveerse el contenido que se ha de alojar en ellos. En dicho sentido he 'simulado' 3 orígenes diferentes, un combo utiliza una contantes cuyo contenido es una cadena que contiene nombres de animales separados por comas,  haciendo un 'split' ya tenemos una matriz. La siguiente es una matriz declarada in situ, elemento e elemento. El tercer combo se rellena con una matriz de longs cuyo contenido se ha recreado obteniendo aleatoriamente valores en el rango 1-100 millones.

Estudia el código, pruébalo y si te queda alguna duda consulta, aunque no he utilizado nada que resulte complicado de entender. Luego haz una copia del proyecto y modifícalo a tus necesidades (conviene que dejes una copia sin alterar para consultar si 'de repente' algo falla.

Te adjunto el código enun archivo comprimido en rar a continuación (envío y edito porque antes se me ha bloqueado y he tenido que rescribir todo el post de nuevo).

167
Visual Basic 6.0 e inferiores / Re: Busqueda en otro Formulario
« en: Miércoles 14 de Octubre de 2009, 10:52 »
Guau... así andamos ????

Esa línea no es textual. Conoces alguna instrucción parecida a eso? :  Persona=....
Ahí lo que te indico es que debes asignar a la estructura Persona los datos que has obtenido de la BD después de realizar la query.

Esto puede ser una asignación manual o una función, eso ya  a tu gusto.. Pero eres tú quien debe rellenar ese código, porque eres tú quien sabe que datos manejas y cómo los manejas, yo no tengo detalles ni de tu base de datos ni de la llamada a la base de datos (ni tampoco los necesito, para explicarte tus dudas).

Yo no puedo saber si Persona.Edad (por poner un caso) lo tienes declarado como byte, como integer o como string, para darte explicaciones no importa, yo puedo ponerlo como byte, como integer o como string, que más dá... tu tienes que adaptar mis explicaciones y el código a tus necesidades, no copiar y pegar. Para adaptarlo correctamente es necesario que entiendas como funciona. Hay veces que para adaptarlas basta con copiar y pegar, y hay veces que  adaptar implica modificar todo o parte... esa línea tienes que adaptarla según tengas implementado la bd con los objetos que uses para manejarla.

Por ejemplo si trabajaras la bd desde un datagrid, bastaría asignar a la estructura los campos (columnas) que tiene la estructura en común con la tabla, tomando para ello la fila deseada. ..... por eso, esto depende de cómo tengas implementado tú  el trabajo con los datos.

Si andas realmente perdido, expón el código de llamada a la DB y en qué tipo de objeto vas a recibir/almacenar el resultado y entonces,  podría, ayudarte a completar esa línea de código. Aunque son detalles, que en principio no son el problema planteado en el hilo.

Tema aparte, si me das algunos detalles de qué objetos estás usando, tal vez pueda sugerirte alguna opción más asequible...

168
VBA / Re: Abrir archivo texto mas reciente
« en: Domingo 11 de Octubre de 2009, 21:49 »
Tu aplicación debe estar controlada por un temporizador, un control tinmer con el intervalo puesto a 30000 (milisegundos).
En el evento de consumo del timer, debes poner una llamada al procedimiento que realiza la labor.

El procedimiento lo  que hará será tomar los ficheros que hay en la carpeta. Para  esto será útil disponer de un objeto filesystyemobject (añades una referencia del Microsoft Scripting Runtime), y algunos subobjetos de éste. Un objeto folder y 2 objetos file, uno para recorrer el bucle y el otro para asignación cuando se comparen fechas yéste sea más reciente.
se hace un : set elFolder = fso.getfolder(ruta)
y a continuación un bucle: for each f in elfolder.files ....
A partir de aquí puedes hacer una de 2 cosas, fiarte del nombre de archivo que (como indicas) contiene una especificación de fecha en su nombre, o no fiarte de dicho nombre y preferir la fecha de creación, o modificación del fichero.

Se trata por tanto, en este bucle de localizar el de fecha más reciente, una vez localizado (ya fuera del bucle) hace una llamada al procedimiento que tiene que operar con el fichero pasándole preciamente el objeto file. y ahí ya trabajas  con él.

Debes tener algunas cosas en cuenta...
- por ejemplo  si la aplicación que elabora los ficheros los tiene bloqueados hasta que termina de utilizarlos, no podrás usarlo, entonces tendrás que utilizar el fichero justo anterior a éste e ir por tanto siempre un fichero por detrás... si hay más de una aplicación escribiendo ficheros en esa carpeta esto te exigirá esmerarte más en recoger el archivo deseado.
- Si tardas más de los 30segundos en localizar y manipular el archivo se te iría acumulando trabajo y memoria, para evitar que el proceso se atasque, sería conveniente disponer de un portero en el timer, si no has terminado de operar con el fichero actual, sale del timer sin buscar el siguiente fichero, dándole otro plazo de 30sg.

- Si la carpeta contiene infinidad de archivos y/o son de diferente tipo, tal vez te interese más utilizar un objeto filelistbox y sobre el estableces un filtro. De entrada el filtro sería sobre la extensión de archivo. ' *.plf' y después dado que el propio nombre incluye datos relativos, a la fecha del  proceso deberías ir actualizando este filtro, por ejemplo si el último fichero fue 2009_05_04 15_42_28 YF00D.plf  y sabemos que cada hora al menos se crean 2 (por poner una cifra) entonces tomas como filtro la longitud del fichero que has usado, hasta el patrón del fivhero anterior '2009_05_04 15*.plf , nota el asterisco. Si la lista queda vacía sin duda ha cambiado la hora de 15 a 16, siempre que ocurra esto retiramos el último carácter al patrón de filtro anterior al asterisco, esto hasta que a lo sumo llegue el salto al año, una vez que se encuentra la lista con contenido el siguiente patrón de filtro volverá a ser el nombre del fichero entero menos el último campo (la referencia de pieza ignoro el patrón que sigue por tanto ahí deberás asegurarte tú), con este filtro, lo que consigues es que la lista de ficheros sea muy pequeña y por tanto sólo tendrás que localizar entre esta lista el más reciente. En este caso el cometido del timer será primero actualizar el fltro del filelistbox, como se ha comentado hasta que la lista tenga al menos 1 fichero.  Eso si en este caso cuando arrancas la aplicación el primer fichero debe localizarse fuera del uso del timer, no tienes más remedio que recorrer toda la lista completa para localizar el más reciente, luego ya se usará ese nombre como filtro en las sucesivas llamadas.  Ahora bien si sólo hay 40 ó 50 ficheros en la carpeta no habría diferencia entre usar el filesystemobject y el filelistbox

Ten en cuenta que el filelistbox, filtra la lista de ficheros que en realidad no es otra cosa que recorrer los ficheros de dicha carpeta y ver si el nombre cumple el patrón, algo que igualmente podrías hacer con el filesystemobject, no obstante el filelistbox te ahorra trabajo en ese sentido. Si la lista de ficheros es muy grande habría de mirarse si resulta conveniente ir pasando ficheros a otra carpeta, a fin de que esta lista siempre sea lo más pequeña posible...

Saludos.

169
Visual Basic 6.0 e inferiores / Re: Cargar Combos
« en: Domingo 11 de Octubre de 2009, 20:43 »
Para darte la respuesta adecuadamente debes responder 3 preguntas.

1 - ¿¿¿ Los combobox de un formulario son distintos entre si o todos tiene el mismo contenido ???.
2 - ¿¿¿ Cada formulario tiene exactamente los mismos combobox o cada formulario tiene diferente número y contenido ???.
3 - ¿¿¿ Los combobox de cada formulario forman una matriz ???.

170
Visual Basic 6.0 e inferiores / Re: Cargar Combos
« en: Domingo 11 de Octubre de 2009, 20:41 »
mensaje duplicado...

171
Diseño de Algoritmos / Re: Cortes de Control Dobles
« en: Domingo 11 de Octubre de 2009, 13:01 »
A este paso, a la línea de código :
Código: Text
  1.  
  2. a = b + 5
  3.  
  4.  
... le van a  acabar llamando algoritmo de asignación.

Tu supuesto problema, llamado como algoritmo, te cierra las puertas para entender algo que sin el nombre de algoritmo, cae por su lógica.
Si tienes pongamos una lista de objetos, para recorrerlos todos necesitas un bucle. Si después necesitas acceder a cada objeto para obtener uno a uno los subelementos de una lista de dicho elemento, pués no tienes más remedio que crear un 2º bucle que respecto del primero se dice que está anidado. Entender esto es lógica, darle tratamiento de algoritmo, lo hace misterioso e importante al profesor, que parece que te va a revelar misterios insondables para el cerebro humano.

Por ejemplo imagina que tienes una imagen. Y quieres aplicar un efecto o un filtro a la imagen , vamos a suponer que deseas variar la luminancia.
Necesitarías en primer lugar colocar un bucle para recorrer las filas. Como cada fila tiene una cantidad de píxeles fijo (como toda área rectangular), necesitas añadir un 2 º bucle para recorrer las columnas (píxeles individuales de cada fila). Es dentro de este bucle donde tendrás acceso a los componentes RGB de cada píxel, para modificar la luminancia.

Si nadie te habla de 'algoritmo  de corte' , cualquiera encuentra la solución de como resolverlo, porque ES OBVIO, que tienes que crear 2 bucles anidados incluso un 3º si decides tratar los valores RGB de cada píxel, como una matriz de 3-4 bytes. Ahora bien si te dicen 'debes resolverlo con el algoritmo tal...', pués salvo que tengas muy claro que la referencia al algoritmo es una 'parida', te quedarás bloqueado por que supuestamente a priori, nadie conoces los entresijos de un algoritmo cuyo nombre le resulta desconocido, aunque la realidad, es que, es al darle nombre cuando te han bloqueado y te han vuelto más ignorante de lo que de base puedas ser.

Estructurar el conocimiento es necesario para manejarlo y entenderlo, pero reclamar nombres para cada organización posible de pocos elementos enfanga el conocimiento porque resultan como puertas a cada paso. Si desde la colina se ve el sendero que lleva  hasta el valle resulta estúpido poner carteles indicativos de 'por aquí se llega hasta el valle', pués transitar así sólo te hace ir de descubrimiento en descubrimiento de cada cartel como si estuvieras ciego y no pudieras ver por ti mismo que en todo momento el camino entero queda expuesto a la vista. Los carteles sólo son necesarios al llegar a cruces de caminos, especialmente si no se ve el destino, éste no  reúne ninguno de los 2 casos.

El algoritmo subyacente es la iteración, lo demás es marear la perdiz.

...en mi tierra a esto se le llama buscarle las 5 patas al gato.

172
Visual Basic 6.0 e inferiores / [Utilidad] Mastermind
« en: Viernes 9 de Octubre de 2009, 22:29 »
Juego del mastermind. Se incluye el ejecutable. el codigo fuente. (version actualizada)

En la descarga del archivo se incluye un txt con el manual que igualmente es accesible desde un boton del programa.

Cualquier error o duda que surja con el programa podeis avisarme con un mensaje personal o si es posible por esta pagina mejor.

El juego esta programado en Visual Basic 6.0 y responde a una conversacion del foro sobre dicho tema.

Aparte de la logica del juego tiene de interes el uso de \'arrastrar y soltar\' que se utiliza en el juego y donde facilmente se observa su potencial y la facilidad de control de dicha funcion.

El codigo del juego ha sido diseñado sin usar complejidades. no se utiliza ninguna funcion API ni se utilizan mas controles que los estandard que aparecen en el entorno de Vb6 por defecto a fin de que sea asequible para los principiantes. Se han dejado a proposito  varias areas para que puedan ser optimizadas.

El diseño grafico del juego parte de un simple lienzo gris (con gradiente) al que se le ha aplicado una textura de madera modificada para parecer corcho despues se le ha aplicado un efecto \'boton\' primeramente interno usando un perfil determinado y luego esterno sin perfil  usando  un color caoba para acompañar a la textura. Las sucesivas cajas se han creado de la misma forma partiendo del lienzo inicial al tamaño conveniente. Las imagenes finalmente se han superpuesto juntas para formar el tablero base.

Cada boton se compone de 3 imagenes creadas del mismo modo el texto esta inserto como imagen la imagen \'down\' es la imagen \'on\' espejada vertical y horizontalmente los textos se han añadido al final de la imagen  la imagen \'off\' es un negativo de la imagen \'on\'.

Para las bolas se crearon 2 en photoshop  de una de ellas han salido el resto aplicando el efecto \'colorear\' la bola blanca es la 2ª creada y de ella se ha sacado la negra ya que no era posible sacar con calidad adecuada la blanca y la negra partiendo de la 1ª.

Para que el juego no sea excesivamente rapido y a la vez sea distrai­do se ha proporcionado una pequeña animacion en forma de \'cortinilla\' que se va desplazando a medida que se rellenan lineas.



Autor: NEBIRE

173
Visual Basic 6.0 e inferiores / [Utilidad] Próximamente pondré el código fuente
« en: Viernes 9 de Octubre de 2009, 19:39 »
Vaya tenía un poco olvidado este tema.

en cuento encuentre un poco de tiempo libre localizo los archivos fuente los comento y los subo...

Se detectó un pequeño error que no obstante ocurría con escasa frecuencia.

174
Visual Basic 6.0 e inferiores / Re: Busqueda en otro Formulario
« en: Viernes 9 de Octubre de 2009, 10:51 »
Es irrelevante cuantos formularios tengas... y cuantos botones buscar tengas.
En todo momento nos estamos refiriendo sólo a 2 formularios, el que llama y al que quieres llamar y sólo nos importa un botón buscar, auqél que localiza en la tabla correspondiente los datos de persona.

Al pulsar ese botón tu realizas una consulta a la BD ( con la cédula como criterio de búsqueda). Por tanto es este mismo procedmineto donde debes hacer la asignación de los datos recibidos a la estructura persona, (o llamar al procedimiento que lo haga).

El asunto ya te lo he aclarado, creo yo, que lo suficiente, si le das muchas vueltas es posible que te acabes liando, como el gato que juega con el ovillo de lana. Así te lo resumo para que no veas cosas raras

Solo hay 3 pasos:
1 Un procedimiento llama a la base de datos y obtiene unos datos
2 Ese mismo u otro procedmiento coloca los datos obtenidos en una variable que es accesible como mínimo desde este formulario y desde el formulario que mostrará el resultado. Esto signiiifica que pueden ser 3 ubicaciones (lógicas), una variable pública de tipo persona que esté o en  uno de los 2 formularios o en un móodulo.
3 El formulario que lo va a mostrar toma la estructura persona y la vuelca en unos textbox, labels, msgbox, dictado por voz, o lo que quieras.

Ya está, no hay nada más. No le añadas complicaciones, es así de sencillo.
Después, sólo he indicado, que mis explicaciones son simplemente una guía que tu debes adaptar a la situación específica de tu proyecto hay diferentes formas de manejar datos, en explicaciones es más sencillo indicar estructuras, luego uno quizás use un objeto TableDef o cualquier otro tipo de objeto. Tú tienes que tomar la idea, no necesariamente tomarlo al pie de la letra.

Dos objetos sólo pueden comunicarse entre sí, si ambos conocen ó reconocen un objeto (o ruta de objetos) accesible por ambos. Hoomer Simpson sólo podrá enviar una carta a King-Kong, si conoce el domicilio de King-Kong o si conoce a alguien que conoce el domicilio de King-Kong y actúa de intermediario. La variable Persona en el módulo es ese intermediario, FormConsulta tiene acceso al módulo (que actúa como una oficina postal, almacena el paquete en la caja adecuada a su contenido) y mete los datos en un el paquete adaptado a 'Persona', luego le manda un mensaje a formExhibir y le dice, oye te he mandado un paquete lo tienes donde hemos acordado (la oficina postal x)... y formExhibir va a la oficina postal y recoge el paquete 'Persona' abre el contenido y hace con ello lo que quiera hacer... incluso podría modificarlo y enviarlo de vuelta...

Más no te puedo decir, es cuestión tuya que lo entiendas o no. Yo espero haberme expresado con la suficiente claridad, para que sea que si, que lo has entendido.

p.d.: colocar enlaces es un derecho reservado a los usuarios cuando tienen un mínimo de mensajes publicados... no recuerdo el nº,  es una pequeña medida para evitar spam... No obstante no es necesario que envíes imágenes, en mi anterior mensaje mis dudas eran porque me parecía extraño que no sepas añadir un módulo de código al proyecto. Un principnate lo primero que debería de hacer con el entorno de vb es familiarizarse con el menú del programa...

Saludos.

175
Visual Basic 6.0 e inferiores / Re: Busqueda en otro Formulario
« en: Viernes 9 de Octubre de 2009, 00:40 »
Si no he entendido mal...

En un formulario tienes un botón que invoca a un 2º formulario (pongamos que se llama formBusqueda). Y es desde este desde elcual realizas la búsqueda...

Si esto es correcto, en este formulario va el código que ya te he indicado...

realizas la query, el resultado lo transformas a la estructura persona, y acto seguido invocamos el formulario de exhibición se forma síncrona.
Código: Visual Basic
  1.  
  2. ' ...
  3. Persona= buscar.... ' el resultado de la query la volcamos en esta estructura, habrá que hacerlo elemento a elemento.
  4. Tipo= TIPO_PERSONAS
  5. call FormExibirResultados.show(1)
  6. ' ...
  7.  
  8.  
Nota que volcar la devolución de la base de datos a una estructura, no es estrictamente necesario, es el modo que yo he elegido para mostrarte la EVOLUCIÓN del código (básicamente por que es más sencillo de entender y de escribir y porque no necesito entrar en el entresijo de detalles de tu programa, si ya tienes definida una estructura de datos y es accesible  desde el formulario de exhibición podría ser suficiente pasar por ejemplo el índice de un recordset. De todos modos no sale caro volcar el resultado devuelto a una estructura.

La última cuestión, no estoy seguro de haberte entendido ... me preguntas como insertas un módulo en el proyecto ???, de giaul modo que un formulario, una clase, una página de propiedades,etc... .... desde el menú proyecto 'Agregar módulo'. Si no te he entendido acláramelo...

Páginas: 1 ... 5 6 [7] 8 9 ... 29