Actualizar todos los registros de una tabla a partir de otra con Vba

As).

Soy nuevo en access y tengo un problemita con la copia y actualización de datos de una tabla de access (Productos) a partir de otra (ProductosTemp), que contiene los mismos campos.

No puedo emplear una consulta de borar todos los registros, pues la tabla Productos esta relacionada con otras y elimina los registros en cascada.

Quisiera que me actualice los datos existentes en todos los campos y si el registro no existe en la tabla Productos me lo copie de la tabla ProductosTemp

He empleado este código para actualizar pero me genera un error, además me falta el código para agregar el procucto si no existe en la tabla actual.

SQL = "UPDATE Productos SET Nombre = ' ProductosTemp.Nombre ', Descripcion = ' ProductosTemp.Descripcion ', Marca = ' ProductosTemp.Marca ',"
SQL = SQL & " Precio_Compra = ProductosTemp.Precio_Compra, Precio_Venta = ProductosTemp.Precio_Venta, Precio_VentaMay = ProductosTemp.Precio_VentaMay, TipoIva = ' ProductosTemp.TipoIva ',"
SQL = SQL & " Stock = ProductosTemp.Stock, Stock_Minimo = ProductosTemp.Stock_Minimo, Ubicacion = ' ProductosTemp.Ubicacion ', TasaDia = ProductosTemp.TasaDia,"
SQL = SQL & " Categoria = ' ProductosTemp.Categoria ', Unidad = ' ProductosTemp.Unidad ' WHERE Productos.Cod_Productos = ' ProductosTemp.Cod_Productos ' "
CurrentDb. Execute SQL, dbFailOnError

Si alguien me puede ayudar, eternamente agradecido.

1 respuesta

Respuesta
1

Claro que lo puedes hacer con consultas, otra cosa es que no quieras.

Por ejemplo, tengo la tabla Productos

Y tengo la tabla ProductosTemp

Puedes ver que hay cuatro artículos que sí están en la tabla Productos y tres nuevos

Si construyo una consulta de actualización como

Cuando la ejecuto, sólo me modifica aquellos registros comunes

Por otro lado si la consulta de datos anexados la hago como

Y la ejecuto

Me ha añadido los tres nuevos.

No hagas caso al idproducto, porque para la imagen he eliminado muchos registros de la tabla Productos.

Por cierto, en caso de que lo que vayas a insertar de la tabla ProductosTemp sean los mismo campos que los de la tabla Productos y los campos se llaman igual podrías poner simplemente

Docmd.runsql" Insert into Productos select * from productostemp.......

En vez de ir campo a campo

Gracias Julián por responder.

¿Y si quisiera hacerlo con Vba? Pasa que lo quiero en un botón en el evento al hacer click, y realiza otras instrucciones previas.

En la instrucción que tenías puesta, en realidad estás ejecutando una consulta. Fíjate en que le pones Execute Sql. El lenguaje SQL es el que se emplea en las consultas.

Si tengo una tabla Productos

Y la tabla ProductosTemp como la tenía antes. En un formulario pongo un botón

Al pulsarlo

Y el código del botón es( como el nombre del producto ya está en la tabla ¿Para qué lo voy a actualizar?)

Private Sub Comando191_Click()
DoCmd.SetWarnings False
DoCmd.RunSQL "UPDATE Productos INNER JOIN ProductosTemp ON Productos.IdProducto = ProductosTemp.IdProducto SET Productos.PrecioKilo = [productostemp].[preciokilo]"
DoCmd.RunSQL "INSERT INTO Productos ( NombreProducto, PrecioKilo)SELECT ProductosTemp.NombreProducto, ProductosTemp.PrecioKilo FROM ProductosTemp LEFT JOIN Productos ON ProductosTemp.[NombreProducto] = Productos.[NombreProducto]WHERE (((Productos.NombreProducto) Is Null))"
End Sub

Pero, ya te digo que es la misma instrucción que se ejecuta en las consultas.

Personalmente, si de verdad voy a actualizar o insertar, no esperaría a terminar la tabla ProductosTemp y luego pulsar el botón. A medida que en el formulario que rellena los registros de esa tabla, en el último control de un registro, o en otro evento pondría algo como

If nz(dcount("*", "productos","nombreproducto='" & me.nombreproducto & "'"))>=1 then

docmd.runsql"update productos set preciokilo=" & me.preciokilo & " where idproducto=" & me.idproducto & ""

else

Docmd. Runsql"!insert into productos(nombreproducto, preciokilo, categoría,...)values(nombreproducto, preciokilo, categoría,...)"

End if

¡Gracias Julián..! Voy a probar y te comento.

Casi mejor, sería que pusieras una imagen de cada tabla, para ver si hay diferencias en los campos, y se podría poner el código correcto.

Buenas noches.. He logrado integrar el código que me enviaste de la forma mas sencilla para mis conocimientos (muy pocos).

En resumen lo que necesito hacer es lo siguiente:

1) La tabla de Productos la exporto (copio) a una base de datos externa porque el jefe quiere chequearla en casa y actualizar algunos campos ( Nombre, PreciosCompra, PreciosVenta, etc). Además de agregar nuevos productos.

2) Al llegar a la oficina, el jefe me pasa el archivo con la tabla modificada y debo actualizar (Importarla) a la base de datos principal.  Inicialmente lo que hacia era copiar todos los registros directamente a la tabla Productos (Borraba todos los registros con DELETE e insertaba con INSERT INTO ) de la base de datos principal. Pero la tabla Productos esta relacionada con la tabla detalles de Facturas, Entradas, etc con Integridad Referencial, que al borrar los Productos automáticamente me elimina los registros relacionados con esa tabla en la BD. 

3) Lo que se me ocurrió fue copiar  la nueva  tabla de Productos que trae el jefe, a una tabla  temporal que llame ProductosTemp para facilitar la actualización directamente en mi base de datos principal y no desde una base de datos externa (me pareció muy complicado), y agregar los nuevos productos que el jefe ingreso por su cuenta.

A continuación como quedo el código:

Dim RutaFicheroO As String
            Dim RutaFicheroD As String
            Dim SQL As String
            RutaFicheroO = Me.txt_RutaOrigen
            RutaFicheroD = Me.txt_RutaDestino
            DoCmd.SetWarnings False
            CurrentDb.Execute "DELETE * FROM ProductosTemp IN '' ';PWD=CT801;DATABASE=" & RutaFicheroD & "'"
            CurrentDb.Execute "INSERT INTO ProductosTemp IN '' ';PWD=CT801;DATABASE=" & RutaFicheroD & "' SELECT * FROM Productos IN '' ';PWD=CT801;DATABASE=" & RutaFicheroO & "' ", dbFailOnError
            SQL = "UPDATE Productos INNER JOIN ProductosTemp ON Productos.Cod_Productos = ProductosTemp.Cod_Productos SET Productos.Nombre = [ProductosTemp].[Nombre], Productos.Descripcion = [ProductosTemp].[Descripcion], Productos.Marca = [ProductosTemp].[Marca],"
            SQL = SQL & " Productos.Precio_Compra = [ProductosTemp].[Precio_Compra], Productos.Precio_Venta = [ProductosTemp].[Precio_Venta], Productos.Precio_VentaMay = [ProductosTemp].[Precio_VentaMay], Productos.TipoIva = [ProductosTemp].[TipoIva],"
            SQL = SQL & " Productos.Stock = [ProductosTemp].[Stock], Productos.Stock_Minimo = [ProductosTemp].[Stock_Minimo], Productos.Ubicacion = [ProductosTemp].[Ubicacion], Productos.TasaDia = [ProductosTemp].[TasaDia],"
            SQL = SQL & " Productos.Categoria = [ProductosTemp].[Categoria], Productos.Unidad = [ProductosTemp].[Unidad]"
            DoCmd.RunSQL (SQL)
            DoCmd.RunSQL "INSERT INTO Productos SELECT * FROM ProductosTemp"
            MsgBox " Tabla Productos Importada correctamente. ", vbInformation, "Aviso"

Espero entienda la explicación del caso y pueda darme alguna sugerencia mas acertada.

Saludos cordiales.

Si la tabla que te devuelve el jefe, ProductosTemp es la misma que Productos, pero con algunos registros modificados y otros añadidos, lo más rápido, sencillo y lógico( ya que por lo que veo los campos se llaman igual) es borrar los registros de la tabla Productos y añadirle TODOS los registros de la tabla ProductosTemp. Sería

docmd.setwarnings false

docmd.runsql"delete * from Productos"

docmd.runsql"insert into Productos select * from productosTemp"

Simplemente eso.

Buenas tardes.. precisamente eso lo hacia anteriormente pero como la tabla Productos esta relacionada con otras tablas con integridad referencial (Actualizar y eliminar en cascada) me borra los registros de los detalles de Entradas, Facturas, Devoluciones, etc...

Creo yo que como tengo el código me funciona para lo que necesito en este momento. Cualquier cosa rara que pase te comento. 

Agradecido por tomarse el tiempo de responder.

Me ha dado un desmayo al ver la ventana Relaciones. Mira tengo una base de facturación donde puedes ver las tablas, formularios que hay

Y las únicas relaciones que hay entre las tablas es

Y eso porque van a trabajar juntas como formulario y subformulario. Pero de ahí a relacionarlas con la tabla Productos, tal como lo has puesto, me tienes que perdonar, pero es un disparate. Si eliminas un producto, lo eliminas de la tabla Ventas y te digo ¿es qué no lo has vendido?. Claro que sí. Estarías falseando las ventas, las facturas, etc. Mira, te pongo el ejemplo de siempre. Tu llamas a un taxi. Llega y es un modelo Mercedes. ¿Tienes alguna relación con el taxista? No, cuando te ha llevado le pagas y si te he visto no me acuerdo. Tienes alguna relación con la casa Mercedes. Ninguna. Los has usado y adiós muy buenas. En el caso, por ejemplo, de la tabla Detalleventa, tiene un campo Idproducto, pero no tienen relación ninguna con el idproducto de la tabla Productos. Los productos son lo que son y al venderlos o al comprarlos, lo único que puede variar son sus existencias y el precio.

Permíteme un consejo, no dejes que Access dicte lo que puedes hacer. Dile tú lo que quieres hacer. Es como si usaras un coche Tesla sin conductor, si el ordenador falla te estrellas y no puedes decidir nada. Es preferible que el coche haga lo que tu quieres.

Si quieres, repito, si quieres, mándame un mensaje, sólo el mensaje y te envío el ejemplo mío.

Si lo haces, en el asunto del mensaje pon tu alias Golfredo, ya que si no sé quien me escribe ni los abro.

Gracias Julian por los consejos. Como te dije al principio, soy nuevo en Access y he aprendido a traves de tutoriales, videos, ejemplos que se encuentran en la red.  Pues trato de adaptarme a ese tipo de información, la experiencia me irá enseñando lo que es bueno o malo en el buen sentido de la palabra.

Pues si me interesa tu ejemplo. Así logró optimizar mi aplicación, todos los dias trabajo en ello y de verdad son pocas personas dispuestas a enseñar.

Mi correo es [email protected] 

Un abrazo.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas