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

Respuesta
1

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

Cambia la declaración de la variable miFiltro por

Dim miFiltro As String

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

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas