Como asociar para abrir formulario respecto a un id en concreto en access
Mi consulta es estoy realizando una bd para gestionar equipos informáticos, para mi empresa, y quiero dar de alta por ejemplo en una tabla TEquipos (id, nombre, ip), y ascociado a esto por ejemplo los componentes pc TComponentes(id, idEquipo, MAC, Procesador, Memoria, etc...) TFormateos (id, idEquipo, fecha) y asi con mas cosas.
Mi idea era crear un formulario sobre cada tabla y sobre el de TEquipos y crearles acceso mediante cmd a Componentes, formteos, etc.
Qué codigo he de desarrollar para abrir ese Formulario para asociarlo al registro que acabo de meter y que al abrir ese formualrio me lo asocie ya a ese registro para siempre? ¿Y cuándo quiera poder visualizar los datos de los componentes?
Se abrir un formulario filtrado por un id pero en este caso como aun no esta asociado al registro me da problemas el realizarlo ya que otras veces en mis aplicaciones tengo los formularios de las demás tablas como subformularios y asociados al meterlos por el id pero aquí si se puede quisiera hacerlo de esta forma ya que seria demasiada información para un formulario creo yo.
Si consideráis que hay otra forma mñas adecuada para hacerlo bien venida será.
1 respuesta
Entiendo que el proceso es:
1.- Creas un equipo en el form FEquipos
2.- De ahí tienes un botón para abrir FComponentes en un nuevo registro y rellenar la información, otro para abrir FFormateos en un nuevo registro y rellenar la información, y así con el resto de formularios.
Para hacer eso, en el botón que abre, por ejemplo, FComponentes, le generas el siguiente código:
...
Private sub
Dim elId as long
elId=nz(me.id,0)
If elId=0 then exit sub
docmd.openform "Nombre del formulario",,,,acformadd
Forms![Nombre del formularo].idEquipo.value=elId
End sub
...
Y listos.
A ver si te funciona.
¡Gracias! Neckitto si esa es la idea dar de alta un equipo y en el formulario que se da de alta tener los botones para cumplimentar los componentes, formateis etc...
y si tiene registros ya pues consultarlos.
en cuanto llegue a casa esta tarde lo pruebo y te digo.
Muchas gracias como siempre.
un saludo
Kike... me estás cambiando el argumento de la peli ;-)
Si quieres que si hay registros haga una cosa y si no los hay haga otra el código debe modificarse.
...
Private sub...
Dim elId as long
Dim hayRegistros as variant
elId=nz(me.id,0)
If elId=0 then exit sub
hayRegistros=dlookup("id","NombreTabla","idEquipo=" & elId)
If isnull(hayRegistros) then 'No hay nada de alta
docmd.openform "Nombre del formulario",,,,acformadd
Forms![Nombre del formularo].idEquipo.value=elId
Else 'Ya hay registros
docmd.openform "Nombre del formulario",,,"idEquitpo=" & elId
End sub
...
Te lo escribo de cabeza y creo que he acertado con las comas de los argumentos del docmd. Openform. Si no fuera así entiendo que no tendrías problemas para corregirlos, dado que si lo vas escribiendo en la condición verdadera del If vas poniendo comas hasta que te aparezca el intellisense con acFormAdd, y en la condición falsa del if vas escribiendo comas hasta que el intellisense te muestre "condición WHERE", y ahí le escribes el filtro.
A ver si te va bien.
¡Gracias! De nuevo y perdona por la confusión en el planteamiento de la pregunta.
Lo pruebo y te digo un saludo
Buenas tardes, he probado la estructuración que me has dado y funciona correctamente.
Ahora ya puestos mi pregunta es, a la hora de realizar una aplicación como esta que es lo más profesional o la mejor manera de hacerlo esta solución o subformularios dentro de formularios me explico:
1 creo formulario sobre TEquipos.
2 creo subFrmDatos sobre TDatos.
3 sobre TEquipos creo otro Formulario llamadado TDatos y le incluyo subFrmDatos creando una vinculación propia id con idEquipo.
Un saludo
Desde mi punto de vista no se trata que sea más "profesional" o menos; se trata de que la aplicación sea:
1.- Lo más simple e intuitiva (y cuando digo "simple e intuitiva" me refiero de cara al usuario; si es necesario usar códigos complejos evidentemente se usan y punto).
2.- Que una vez elegida una "manera de hacer las cosas" se procure mantener la misma en todas las facetas de la aplicación. Si se hace así el proceso de aprendizaje del programa por parte del usuario es mucho más sencillo y fácil que si le vas "mezclando estilos".
Es como si me pidieras: ¿Qué es mejor, un formulario en vista formulario o en vista de formularios continuos? Pues mi respuesta es: lo que creas que sea mejor en función de los datos que se deban manejar.
Si tienes una tabla principal y otra secundaria (por llamarlas de alguna manera) que se corresponderían con un formulario y un subformulario respectivamente, yo te diría que usaras formulario y subformulario, siempre y cuando los datos del subformulario se pudieran ver con claridad y no pareciera un pegote.
Si tienes varias tablas "secundarias" yo optaría por la opción de un formulario para cada tabla y de apertura desde el formulario "principal". Si a aquellos los sitúas emergentes (y modales, según el caso) lo que consigues es "guiar" al usuario para que rellene los datos siguiendo el camino que tú le has trazado (ya sabes que un formulario emergente -y modal- no permite trabajar más que en ese formulario, hasta que el usuario lo cierra).
Pero, de nuevo, volvemos a lo que te comentaba al principio: es el diseñador de la BD el que debe decidir, en función de la estructura de la BD y de los datos (y cantidad de los mismos), así como, por las características de la aplicación, lo que cree que es más "fácil e intuitivo" para el usuario final, qué sistema elige para la presentación de su aplicación.
Entiéndase todo lo anterior como mi opinión personal. Quizá haya alguien que opine diferente. :-) Ya sabemos que en la variedad está el gusto... je, je...
¡Gracias! Por todo como siempre, creo que voy aplicar este método ya que es menos costoso je je.
Un saludo
Buenas días neckkito, estoy usando este código para pasarle el id a los formularios y me funciona perfectamente pero en un caso no y creo que es un cambio de película no intencionado no contaba con el hasta que me paso, este es el código en cuestión:
Private Sub cmdFormateo_Click() Dim elId As Long Dim hayRegistros As Variant elId = Nz(Me.id, 0) If elId = 0 Then Exit Sub hayRegistros = DLookup("id", "TFormateos", "idEquipo=" & elId) If IsNull(hayRegistros) Then 'No hay nada de alta DoCmd.OpenForm "FFormateos", , , , acFormAdd Forms![FFormateos].idEquipo.Value = elId Else 'Ya hay registros DoCmd.OpenForm "FFormateos", , , "idEquipo=" & elId End If End Sub
El problema viene porque este es un form continuo y solo me pasa el id al primer registro, si quiero poner varios fechas para los formateos no me lo asocia.
Llevo un tiempo pegándome con ello, no recurrí a la primera.
Un saludo
Si es un form continuo tienes que abrir el formulario normalmente, sin filtro, y después filtrarlo, todo eso en el segundo bloque del if
Algo así como
...
Dim miFiltro as long
miFiltro="IdEquipo=" & elId
docmd.openform "NombreForm"
With Forms!NombreForm
.filter=miFiltro
.filteron=true
end with
end sub
...
He realizado esto como realmente te netendi:
Private Sub cmdFormateo_Click() Dim elId As Long Dim miFiltro As Long Dim hayRegistros As Variant miFiltro = "IdEquipo=" & elId elId = Nz(Me.id, 0) If elId = 0 Then Exit Sub hayRegistros = DLookup("id", "TFormateos", "idEquipo=" & elId) If IsNull(hayRegistros) Then 'No hay nada de alta DoCmd.OpenForm "FFormateos" With Forms!FFormateos .Filter = miFiltro .FilterOn = True End With Else 'Ya hay registros DoCmd.OpenForm "FFormateos", , , "idEquipo=" & elId End If
Con esto me da error 13 no coinciden los tipos
miFiltro = "IdEquipo=" & elId
Un saludo
C... ñ... Kike, piensa un poco antes de escribir...!
Creas el filtro igualándolo a la Id -> ¿Y de dónde sale la id?
Y después, en la siguiente línea, le das valor al id
Lo que no puedes hacer es filtrar por una variable ANTES de que le hayas dado valor.
Por otra parte, ¿cómo se te ocurre filtrar en la parte del bloque donde te dice que 'No hay nada de alta (joderrrr, que lo tienes escrito y todo en el comentario!)? Si no hay nada de alta, ¿qué diantres quieres filtrar?
Si no entiendes mínimamente los códigos que estás utilizando nunca vas a ser capaz de desarrollar un código, aunque te den la solución.
Mi rabieta no es porque no te salga; mi rabieta es porque da la sensación de que no te esfuerzas (por decirlo de alguna manera) en entender lo que estás haciendo (o lo que está haciendo el código).
Private Sub cmdFormateo_Click() Dim elId As Long Dim miFiltro As Long Dim hayRegistros As Variant elId = Nz(Me.id, 0) If elId = 0 Then Exit Sub hayRegistros = DLookup("id", "TFormateos", "idEquipo=" & elId) If IsNull(hayRegistros) Then 'No hay nada de alta docmd.openform "FFormateos",,,,acFormAdd Else 'Ya hay registros. Los abrimos filtrando la información en el f.continuo DoCmd.OpenForm "FFormateos" miFiltro = "IdEquipo=" & elId With Forms!FFormateos .Filter = miFiltro .FilterOn = True End With End If
Kike, no te enfades con mi "pronto", por favor. En el fondo la "rabieta" me viene porque, con el tiempo que llevas trasteando con Access, considero que estás más que capacitado para no cometer estos "fallos". ;-)
Te pido perdón tienes toda la razón del mundo en este momento, las ansias de acabarlo me pudieron, y no termino de razonar las cosas esta mañana, ni estas ni otras hoy.
Lo puse hay porque si no hay nada quiero que me lo cree asociado al id del equipo como hacíamos en el anterior código tantos registro como necesite asociar a ese equipo.
If IsNull(hayRegistros) Then 'No hay nada de alta DoCmd.OpenForm "FFormateos", , , , acFormAdd Forms![FFormateos].idEquipo.Value = elId
Si no hay registro creame un nuevo registro y pasale el valor del id al idEquipo.
Y en el else si los hay muéstrame solo donde coincida:
DoCmd.OpenForm "FFormateos", , , "idEquipo=" & elId
Fue en esto en lo que me base. si coloco el codigo como me lo pusiste ahora en tu ultima respuesta no me pasa el id al idEquipo, cuando meto registro queda a 0 y si lo vuelvo abrir no me muestra los que meti evidentemente.
Voy a darle vueltas a ver si consigo que funcione
Mil disculpas nuevamente
Un saludo
No me enfado ni me parece mal faltaría más incluso hasta lo entiendo, se que tengo muchos fallos por no fijarme muchas veces pero de verdad que me esfuerzo por aprender las cosas
Prueba este código:
Private Sub cmdFormateo_Click() Dim elId As Long Dim miFiltro As Long Dim hayRegistros As Variant elId = Nz(Me.Id, 0) If elId = 0 Then Exit Sub hayRegistros = DLookup("id", "TFormateos", "idEquipo=" & elId) If IsNull(hayRegistros) Then 'No hay nada de alta 'Abrimos el formulario en vista diseño y cambiamos su propiedad de vista DoCmd. OpenForm "FFormateos", acDesign,,,, acHidden 'Cambiamos la vista normal Forms!FFormateos.DefaultView = 0 'Cerramos guardando los cambios DoCmd. Close acForm, "FFormateos", acSaveYes 'Lo abrimos y le asignamos el id DoCmd. OpenForm "FFormateos",,,, acFormAdd Forms!FFormateos.IdEquipo.Value = elId Else 'Ya hay registros. Los abrimos filtrando la información en el f.continuo 'Abrimos el formulario en vista diseño y cambiamos su propiedad de vista DoCmd. OpenForm "FFormateos", acDesign,,,, acHidden 'Cambiamos la vista a f.continuo Forms!FFormateos.DefaultView = 1 'Cerramos guardando los cambios DoCmd. Close acForm, "FFormateos", acSaveYes 'Lo abrimos y filtramos DoCmd. OpenForm "FFormateos" miFiltro = "IdEquipo=" & elId With Forms!FFormateos .Filter = miFiltro .FilterOn = True End With End If End Sub
De todas maneras no tiene mucho sentido que quieras abrir un formulario para añadir un registro, asignándole el id que tienes en pantalla, y que el formulario donde añades lo abras en vista de formularios continuos, dado que sólo te va a asignar el id al primer registro.
Por eso te he cambiado la vista en función de si das de alta un nuevo registro o en función de si lo consultas, dado que así parece más lógico.
Ya me dirás.
Hola neckito he preparado un mini ejemplo para que veas cuando puedas con lo que quiero hacer, esta en el Formulario FEquipos los cmd Datos y Formateos tienes los códigos que me dijiste y el formtateo2 lo añadí yo para explicarme mejor ya que quizás no me estoy explicando correctamente la verdad.
http://www.filebig.net/files/6M6sSa5xqU
El código si hay datos en la tabla da error 13 no coinciden los tipos y señala esta línea
miFiltro = "IdEquipo=" & elId
Un saludo
Si ahora ya no da el error pero no puedo asignar nunca un segundo registro a ese equipo a no ser de forma manual, para no marearte lo haré incluyendo un subformulario asociado como en el ejemplo y añadiendo solo el campo id y ocultándolo, es menos "vistoso" pero creo que esta dando demasiada guerra je je.
Espero que no te enfades
Un saludo
Kike, no me enfado... je, je...
Lo único que veo es que estás "experimentando", lo cual no está mal. Pero si miras mi página web, en este artículo (artículo), lo primero que digo es que antes de empezar una BD lo que debe hacerse es tomar papel y lápiz.
Te has lanzado a hacer una aplicación sin diseñarla previamente ni tomar en consideración las implicaciones de cómo lo estás diseñando. Eso se ve en tu consulta, cuando te hago el comentario de "me cambias la película", y posteriormente en el hecho de que planteas tu consulta con formularios en vista formulario y después te metes con formularios continuos. Ese pequeño cambio modifica totalmente la manera de plantearse cómo hacer las cosas. Y, además, resulta que no quieres dar de alta un registro asignándole un id automático, tal y como planteabas, sino que quieres dar de alta una serie de registros con el mismo Id... ¿en qué quedamos? ¿Tienes realmente claro si quieres añadir o consultar, o por el contrario quieres un mix de las dos opciones? Esto, una vez más, da la sensación de falta de planificación.
¿Te has parado a pensar que quizá te sería más cómodo tener un menú para dar de alta los equipos, las formaciones, etc, y desde ahí tener un combo para elegir el dato (ese famoso Id que te trae de cabeza)? Y si el Id no existe en la web tienes un ejemplo de cómo "dar de alta en form desde form".
¿Te has planteado separar, por ejemplo, la función de dar de alta registros, con lo cual utilizarías formularios en vista formulario, y la función de consultar registros, con lo cual sí quizá sería más útil usar formularios continuos?
En fin... que creo que si sigues por ese camino al final te vas a encontrar una BD donde querrás hacer cosas y no podrás, o tendrás que usar retruécanos complicados, para conseguirlo, porque no estará bien diseñada.
Evidentemente te digo lo anterior sin ánimo de crítica, sino porque veo que quizá tendrías que replantearte algunas cosas antes de seguir adelante con la BD. Y esto, como es lógico, es sólo una opinión personal.
Como diría un tal Neckkito: un saludo, y... ¡Suerte! ;-)
Buenas noches Neckkito, en cuanto a lo de los Formateo de los ordenadores (lo quise hacer en un formulario continuo porque pueden hacerse varios a cada equipo a lo largo del año y tener un histórico) si que les asigno un id automático cada vez que hago un registro lo que pretendo es además asignarles el id del equipo para que casa Formateo este asignado a un equipo.
Ejemplo:
id:4
Nombre Equipo: kike-pc
I.P: 10.00.0.00
Luego en el cmd Formateo:
id:1, idEquipo4, Fecha: 23/8/15 Nombre: kike Obs, No funciona bien
id:40, idEquipo4, Fecha: 12/1/16 Nombre: Pedro Obs, Se colgaba
y lo de consultar es por el dia de mañana quisiera saber cuando fue la ultima vez que se formateo.
Estoy seguro que tienes razón porque de esto sabes muchísimo más que yo y me sentare a diseñarla de nuevo en un papel teniendo en cuenta todas las cuestiones que me dan problemas ahora que me puse hacerlo de esta manera.
Quizás sea más recomendable dar los formateos de cada ordenador creando solo un registro de cada vez y l de consultarlo mejor hacerl desde un consulta en otro formulario. como bien dices despiezar la bd en partes.
Muchas gracias por todo como siempre
Un saludo
Aunque se puede plantear tu situación de múltiples maneras, lo que implica múltiples diseños, sólo quería "hacerte ver" que, ahora que yo sé EXACTAMENTE (por exagerar... pongamos eso en términos relativos) lo que necesitas me resulta muy "sencillo" (también en términos relativos) plantear una solución para tu BD. Y como lo he podido planificar fíjate que utilizo mucho menos código y mucho menos complejo de lo que hemos estado discutiendo en este hilo.
Te remito pues a una posible solución en esta BD de ejemplo que te he preparado. Insisto en que "es sólo una posible manera" de enfocar el tema: http://www.mediafire.com/download/ufksi41wedbha7z/BorradorKikeEquipos.zip
Ya me dirás si te convence (o no).
Un saludo. Neckkito
¡Gracias! Muchísimas gracias Neckkito este ejemplo es más sencillo y me vale perfectamente para lo que necesito realizar.
Gracias nuevamente.
Una cosa más me ha preguntado un amigo una cosa de access esta empezando a trastear también como hacer referencia desde un campo del subformulario a un valor del formulario, yo le he dicho esto pero me dice que no le funciona.
Para hacer refencia desde el Form al SubForm
Me!Subform1.Form!ControlName ó Forms!NombreForm.NombresubFrm.Form.Control
y desde el Subform al Form esto:
Me.Parent!ControlName.Propiedad
Es así o se lo estoy diciendo mal, me dice que es para coger un valor de un campo
Se lo estás diciendo bien. Yo utilizo otra notación, pero es lo mismo:
me.NombreSubForm.Form.NombreControl.Propiedad
Y al revés
Me. Parent. Nombrecontrol. Propiedad
Que revise los nombres de sus controles, que una cosa es cómo los llamas y otra cosa es cómo realmente se llaman.
Y me alegra que te sirva el ejemplo.
No lo olvides: planifica, planifica y planifica ;-)
Gracias porque no tenia donde probarlo y se lo dije de memoria, algo voy reteniendo je je.
Cuando este terminado te lo daré para la web.
Un saludo
Buenos días Neckkito le he dicho este código al chico que te comente ayer y me dice que le da error yo busco y no veo que puedo estar haciendo mal:
Private Sub cmdSalir_Click() On Error GoTo Err_Cerrar_Click If IsNull(Forms!FServVoluntarios.subFrmServVoluntarios.Nombre.Value) Then DoCmd.RunCommand acCmdUndo End If DoCmd.Close acForm, Me.Name, acSaveNo DoCmd.OpenForm "FMenu" Exit_Cerrar_Click: Exit Sub Err_Cerrar_Click: MsgBox Err.Description Resume Exit_Cerrar_Click End Sub
También le di esta opción:
If IsNull(Me.subFrmServVoluntarios.Form.Nombre.Value) Then
y le dice que la opción de Deshacer no esta disponible. El cmd esta en el formulario y quiere que si el campo nombre del subform no esta cubierto no guarde el registro. Llevo un rato cambiando cosas y no se si habra algo mal
Te voy a decir lo que no estás haciendo bien:
- Utilizar un hilo de un foro de un tema para tratar temas que no tienen nada que ver con ese hilo.
- Pensar con acierto que es un placer ayudarte, pero no considerar si no es un abuso que te arregle los problemas de otros
- Hablarme de errores sin dar los detalles del número de error, descripción del error, al depurar qué línea marca en amarillo... En pocas palabras: "doctor, doctor... me duele el cuerpo. ¿Qué puedo tomar?" Pues haz tú un diagnóstico con esta información, a ver si eres capaz.
Dicho lo anterior un par de cosas:
1.- El código, sintácticamente, es correcto.
2.- Si el código es sintácticamente correcto hay que analizar el entorno. Desconozco esa información.
3.- El acSaveYes/acSaveNo se aplica a modificaciones en diseño del formulario, no a la gestión de los registros. En pocas palabras; que si con eso intentas no guardar el registro vas apañado.
4.- El aviso de que "la Opción de deshacer no está disponible ahora" se gestiona a través del control de errores, cogiendo el número de error que devuelve y tratándolo.
Poco más puedo decirte.
Saludos. Neckkito
- Compartir respuesta