¿Cómo Duplicar ciertos campos en un formulario?
Tengo 4 tablas asociadas (adjunto imagen) y necesito que en el FORMULARIO basado en la TABLA ASOCIO –CONDUCTORES, además de que siempre este vacío al abrir el formulario ( Que ya.. Lo solucione con el código Docmd. Gotorecord,, acnewrec), me permita duplicar ciertos campos
2 respuestas

Isabel, por lo que dices de que vaya a un nuevo registro se entiende que el formulario es dependiente de la tabla. En ese caso no necesitarías el botón de guardar, ya que Access, si no le dices nada en contra, automáticamente te guarda los valores en la tabla. Dicho esto, ¿porqué no elegir las "repeticiones" en lugar de tener que escribirlas. Mira, si tengo el formulario Tabla1 basado en la tabla del mismo nombre y relleno los campos que dices. En el combinado Elegir selecciono que me añada tres registros más con esos datos
En el momento que selecciono el 3, me deja la tabla( le he puesto que no rellene los campos de abajo)
Y el formulario se va al siguiente registro( el primero que tiene los campos vacíos)
El código del evento Después de actualizar del combinado Elegir es
Private Sub Elegir_AfterUpdate() DoCmd.SetWarnings False DoCmd.RunCommand acCmdSaveRecord Dim i As Byte For i = 1 To Elegir DoCmd. RunSQL "insert into tabla1(pais, fecha, horaingreso, horasalida, realizo)values(pais, fecha, horaingreso, horasalida, realizo)" Next Me.Requery DoCmd.GoToRecord , , acNext End Sub
Además, en el evento Al activar registro del formulario le tengo puesto
Private Sub Form_Current()
Elegir = ""
End Sub
De todas formas, como creo que tienes mi correo, si tienes alguna pega, mándame un mensaje y te envío el ejemplo.
- Compartir respuesta


La respuesta que le dan es muy acertada pero cuando la tabla tiene campos calculados pueden existir problemas, acá le dejo un código de uno de los programadores más reconocidos en VBA Allen Browne.
Explicación.
Los pasos
Para implementar este consejo en su formulario:
Abra un nuevo módulo.
En Access 95 - 2003, haga clic en la ficha Módulos de la ventana Base de datos y haga clic en Nuevo.
En Access 2007 y posteriores, haga clic en la cinta Crear, haga clic en el icono situado a la derecha del grupo Otros y elija Módulo.Copie el código a continuación y péguelo en el nuevo módulo.
Compruebe que Access comprende el código eligiendo Compilar en el menú Depurar.
Guárdelo con un nombre como Module1. Cierre la ventana de código.
Abra el formulario en la vista diseño.
Abra la hoja Propiedades, asegurándose de que está mirando las propiedades del formulario (no las de un cuadro de texto).
En la ficha Evento del cuadro Propiedades, establezca la propiedad Antes de insertar en:
[Procedimiento de evento]Haga clic en el botón Generar (...) junto a esta propiedad. Access abre la ventana de código.
Configure el código de la siguiente manera:
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim strMsg As String
Call CarryOver(Me, strMsg) If strMsg <> vbNullString Then
MsgBox strMsg,
vbInformation End If
End SubSalvar.
Repita los pasos 5 a 9 para cualquier otro formulario.
Si hay campos específicos que no desea transferir, agregueel nombre de los controles entre comillas dentro de los corchetes, con comas entre ellos. Por ejemplo, para dejar los campos Notes y EmployeeID en blanco, use:
Call CarryOver(Me, strMsg, "Notes", "EmployeeID")
Public Function CarryOver(frm As Form, strErrMsg As String, ParamArray avarExceptionList()) As Long On Error GoTo Err_Handler 'Purpose: Carry over the same fields to a new record, based on the last record in the form. 'Arguments: frm = the form to copy the values on. ' strErrMsg = string to append error messages to. ' avarExceptionList = list of control names NOT to copy values over to. 'Return: Count of controls that had a value assigned. 'Usage: In a form's BeforeInsert event, excluding Surname and City controls: ' Call CarryOver(Me, strMsg, "Surname", City") Dim rs As DAO.Recordset 'Clone of form. Dim ctl As Control 'Each control on form. Dim strForm As String 'Name of form (for error handler.) Dim strControl As String 'Each control in the loop Dim strActiveControl As String 'Name of the active control. Don't assign this as user is typing in it. Dim strControlSource As String 'ControlSource property. Dim lngI As Long 'Loop counter. Dim lngLBound As Long 'Lower bound of exception list array. Dim lngUBound As Long 'Upper bound of exception list array. Dim bCancel As Boolean 'Flag to cancel this operation. Dim bSkip As Boolean 'Flag to skip one control. Dim lngKt As Long 'Count of controls assigned. 'Initialize. strForm = frm.Name strActiveControl = frm.ActiveControl.Name lngLBound = LBound(avarExceptionList) lngUBound = UBound(avarExceptionList) 'Must not assign values to the form's controls if it is not at a new record. If Not frm.NewRecord Then bCancel = True strErrMsg = strErrMsg & "Cannot carry values over. Form '" & strForm & "' is not at a new record." & vbCrLf End If 'Find the record to copy, checking there is one. If Not bCancel Then Set rs = frm.RecordsetClone If rs.RecordCount <= 0& Then bCancel = True strErrMsg = strErrMsg & "Cannot carry values over. Form '" & strForm & "' has no records." & vbCrLf End If End If If Not bCancel Then 'The last record in the form is the one to copy. rs.MoveLast 'Loop the controls. For Each ctl In frm.Controls bSkip = False strControl = ctl.Name 'Ignore the active control, those without a ControlSource, and those in the exception list. If (strControl <> strActiveControl) And HasProperty(ctl, "ControlSource") Then For lngI = lngLBound To lngUBound If avarExceptionList(lngI) = strControl Then bSkip = True Exit For End If Next If Not bSkip Then 'Examine what this control is bound to. Ignore unbound, or bound to an expression. strControlSource = ctl.ControlSource If (strControlSource <> vbNullString) And Not (strControlSource Like "=*") Then 'Ignore calculated fields (no SourceTable), autonumber fields, and null values. With rs(strControlSource) If (.SourceTable <> vbNullString) And ((.Attributes And dbAutoIncrField) = 0&) _ And Not (IsCalcTableField(rs(strControlSource)) Or IsNull(.Value)) Then If ctl.Value = .Value Then 'do nothing. (Skipping this can cause Error 3331.) Else ctl.Value = .Value lngKt = lngKt + 1& End If End If End With End If End If End If Next End If CarryOver = lngKt Exit_Handler: Set rs = Nothing Exit Function Err_Handler: strErrMsg = strErrMsg & Err.Description & vbCrLf Resume Exit_Handler End Function Private Function IsCalcTableField(fld As DAO.Field) As Boolean 'Purpose: Returns True if fld is a calculated field (Access 2010 and later only.) On Error GoTo ExitHandler Dim strExpr As String strExpr = fld.Properties("Expression") If strExpr <> vbNullString Then IsCalcTableField = True End If ExitHandler: End Function Public Function HasProperty(obj As Object, strPropName As String) As Boolean 'Purpose: Return true if the object has the property. Dim varDummy As Variant On Error Resume Next varDummy = obj.Properties(strPropName) HasProperty = (Err.Number = 0) End Function
El código es lo suficientemente inteligente como para no intentar duplicar su AutoNumber o campos calculados, por lo que no necesita excluirlos explícitamente. Del mismo modo, si el formulario es un subformulario, los campos nombrados en LinkChildFields serán los mismos que el registro del que estamos copiando, por lo que tampoco es necesario excluirlos explícitamente.
Si quiere una explicación detalla visite esta página Sugerencias de Microsoft Access: Asignar valores predeterminados del último registro (allenbrowne.com)
Si no desea ver ningún mensaje de error,puede establecer la propiedad Before Insert del formulario en: =CarryOver([Form], "")
- Compartir respuesta
