Arrastrar automáticamente el valor de un campo de una tabla a otro campo de otra tabla en función del valor de varios campos.

Tengo la tabla PRECIARIO que contiene diferentes precios en el campo IMPORTE dependiendo de la EMPRESA, la CATEGORÍA Y los TIPO DE HORAS:

Por otro lado tengo la tabla REGISTROHORAS que tiene el campo IMPORTEUNIDAD que dependiendo de los campos EMPRESA-CATEGORIA Y TIPO me tendría que poner el importe de la tabla PRECIARIO. En esta tabla probé en importeUnidad que fuese un campo de búsqueda de la tabla PRECIARIO, pero así sólo consigo un desplegable con los importes y la idea era que los pusiese de forma automática según los campos EMPRESA, CATEGORIA Y TIPO.

Respuesta
1

Una función de dominio resuelve la situación:

Importeunidad = DLookup("importe", "Preciario", "Empresa= '" & empresa & "' And Categoria = '" & Categoria & "' And [tipo de horas] = '" & Tipo & "'")

Segun el entorno de aplicacion, los datos de referencia pueden ser:

Empresa ==> Me.Empresa 

Categoria ==> Me.categoria

[tipo de horas] ==> Me.Tipo ////

Curiosidad: es [tipo de horas] o es tipodehoras

¿Pero donde se puede poner esa función de dominio? En el campo de la tabla entiendo que no. De tabla a tabla creo que no es posible ¿no? Tiene que ser a través de un formulario. Ya le cambié el nombre al campo mejor tipodehoras

Puedes utilizarlo en la ventana de VBA (en un evento), como origen de datos para un cuadro de texto (copiando a partir de la igualdad) o en una consulta (en la que en lugar de la igualdad se le pondrían los dos puntos) y se le añaden corchetes a los nombres de los campos:

En VBA y en un evento en el que ya se pueda acceder Empresa/Categoría/Tipo se le asigna a un cuadro de texto de nombre ImporteUnidad

Importeunidad = DLookup("importe", "Preciario", "Empresa= '" & Me.empresa & "' And Categoria = '" & Me.Categoria & "' And [tipo de horas] = '" & Me.Tipo & "'")

En el modo diseño del formulario se le asigna como origen de datos a un cuadro de texto así:

= DLookup("importe", "Preciario", "Empresa= '" & [empresa] & "' And Categoria = '" & [Categoria] & "' And [tipo de horas] = '" & [Tipo] & "'")

Y en una consulta (en el modo diseño, en una columna nueva) así:

Importe_Unidad: DLookup("importe", "Preciario", "Empresa= '" & [empresa] & "' And Categoria = '" & [Categoria] & "' And [tipo de horas] = '" & [Tipo] & "'")

En este ultimo caso no seria extraño que Access corrigiese los nombres de los campos añadiéndoles los de sus tablas de origen.


                    

2 respuestas más de otros expertos

Respuesta
1

Andrés, a menos que un formulario esté abierto sobre el otro es mucho más cómodo insertar o actualizar un(os) campo(s) de una tabla que sea origen del otro formulario. Me explico, vamos a suponer que quieres que en el control ImporteUnidad te aparezca el valor de Importe teniendo en cuenta la empresa, categoría y tipodehora. En cualquier evento, por ejemplo, al recibir el enfoque( aunque puede ser en cualquier otro) del cuadro de texto ImporteUnidad

Importeunidad=dlookup("importe","preciario","empresa='" & me.empresa & "' and Categoría='" & me.Categoria & "' and TipodeHora='" & me.tipo & "'")

De tabla a tabla no es posible ¿no? Quiero decir en valor por defecto del campo no es posible poner la función dlookup por ejemplo, tiene que ser en formulario a traves de VBA. Es que el problema que tengo, al hacerlo por formulario es que ya diseñé varios formularios para tener que meter sólo la cantidad de horas. No sé si me explico cree un formulario general con varios accesos así ya no tengo que ir seleccionando en todos los registros. Por ejemplo uno con Empresa XXX que sea jefe de equipo, que tenga horas normales y que la cantidad de horas  sean 8 lo pongo todo por defecto en un formulario y simplemente tengo que teclear los días que trabajó en un formulario continuo. El problema es que con lo precios/unidad me di cuenta después que también los debía registrar en la tabla registros, sino dentro de unos años si quiero sacar un histórico de precios por horas me va poner todo con los importes de precios que tenga el último año. 

Al no saber como es la construcción no puedo darte una respuesta concreta, pero, por ejemplo, si tengo una tabla Sueldos, con, por ejemplo

Cargo... Sueldo

Capataz... 1000

Peón             800

Etx

En la tabla Empleados con por ejemplo

Nombre-----------Fecha-------------Cargo---------Sueldo

Pepe                01/01/2020      Peón             800

Etc

Mientras no cambie los valores de la tabla Sueldo, seguirán cobrando lo mismo todos los meses. Cuando cambie el sueldo de un cargo, los registros nuevos de la tabla Empleados llevarán ese valor, los viejos seguirán con los valores que tenían.

Si el día de mañana quieres hacer un histórico de la evolución de sueldos, los tienes en la tabla Empleados.

Hasta ahí correcto, por eso añadí el campo importeUnidad en la tabla registro horas. El problema es que me tiene que poner ese importe de forma automática al poner la empresa-categoría- y tipo. Pero no sé como gestionarlo.

Pues como te decía, lo puedes poner en cualquier evento. Vamos a suponer que el orden por el que rellenas es precisamente el que citas. En el evento Después de actualizar del cuadro de texto Tipo puedes poner la instrucción. De forma que cuando hayas "escrito o elegido" el tipo y pulses Enter, automáticamente te pone en ImporteUnidad el valor.

Personalmente, pero esto es cosa mía, pondría el control ImporteUnidad del formulario como punto de tabulación = No y bloqueado, para que no se pueda cambiar el valor, que sólo pueda estar el calculado.

¡Gracias! Ok, conseguido. Pero matizar para los que no entienden mucho como yo, que lo hice desde Formulario y con código VBA. No de tabla a tabla cómo pretendía.

Respuesta
1

Le complemento con este ejemplo, pero utilizando SQL. Se obtiene el importe unidadad multiplicando por a cantidad

Eventos del formulario

Evento Antes de actualizar

Private Sub Form_BeforeUpdate(Cancel As Integer)
 If IsNull(Me.Empresa) Then
    MsgBox "Falta la empresa", vbInformation, "Cuidado.."
    Me.Empresa.SetFocus
    Exit Sub
 End If
  If IsNull(Me.Categoria) Then
    MsgBox "Falta la categoria", vbInformation, "Cuidado.."
    Me.Categoria.SetFocus
    Exit Sub
 End If
 If IsNull(Me.Tipo) Then
    MsgBox "Falta  el tipo", vbInformation, "Cuidado.."
    Me.Tipo.SetFocus
    Exit Sub
 End If
 If Cantidad = 0 Then
    MsgBox "Falta la cantidad", vbInformation, "Cuidado.."
    Me.Categoria.SetFocus
    Exit Sub
 End If
 Me.ImporteUnidad = vrimporte(Empresa, Categoria, Tipo, Cantidad)
End Sub

Evento Después de actualizar del campo Cantidad

Private Sub Cantidad_AfterUpdate()
 If IsNull(Me.Empresa) Then
    MsgBox "Falta la empresa", vbInformation, "Cuidado.."
    Me.Empresa.SetFocus
    Exit Sub
 End If
  If IsNull(Me.Categoria) Then
    MsgBox "Falta la categoria", vbInformation, "Cuidado.."
    Me.Categoria.SetFocus
    Exit Sub
 End If
 If IsNull(Me.Tipo) Then
    MsgBox "Falta  el tipo", vbInformation, "Cuidado.."
    Me.Tipo.SetFocus
    Exit Sub
 End If
 If Cantidad <= 0 Then
    MsgBox "Falta la cantidad", vbInformation, "Cuidado.."
    Me.Cantidad.SetFocus
    Exit Sub
 End If
 Me.ImporteUnidad = vrimporte(Empresa, Categoria, Tipo, Cantidad)
 

FUNCIÓN A NIVEL DE MODULO

Public Function vrimporte(strEmpresa As String, strCategoria As String, StrTipoHora As String, intCantidad As Integer) As Currency
  Dim strSQl As String
  Dim rs As DAO.Recordset
  strSQl = "SELECT Preciario.Empresa" & vbCrLf
  strSQl = strSQl & "           , Preciario.Categoria" & vbCrLf
  strSQl = strSQl & "           , Preciario.TipoDeHoras" & vbCrLf
  strSQl = strSQl & "           , Preciario.Importe" & vbCrLf
  strSQl = strSQl & "        FROM Preciario" & vbCrLf
  strSQl = strSQl & "       WHERE Preciario.Empresa='" & strEmpresa & "'" & vbCrLf
  strSQl = strSQl & "         AND Preciario.Categoria='" & strCategoria & "'" & vbCrLf
  strSQl = strSQl & "         AND Preciario.TipoDeHoras='" & StrTipoHora & "'" & ";"
  Set rs = CurrentDb.OpenRecordset(strSQl)
  If rs.BOF And rs.EOF Then
    vrimporte = 0
  Else
    vrimporte = rs.Fields("Importe") * intCantidad
  End If
  rs.Close
  Set rs = Nothing

¿Por qué utilizo SQL? Porque cuando trabaje sin tablas vinculadas y se conecte a un servidador de datos com MySql o PostgreSQL NO sirve DLOOKUP().

La estructura de la tabla Preciario no es la ideal, toda vez que puede crear tablas independientes para Empresas, Categoria y Tipos de hora. Es mucho más practico.

Esto es una idea

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas