Como eliminar campos de una tabla en access

Tengo una tabla con 2 campos que tiene la siguiente info:

Nombre                  Id de Pedido   (estos son los 2 campos)

condición               cliente

juan perez              2

juan diaz                 3

condición                no cliente

maria perez            4

maria diaz              5

condición               cliente 

juana lopez            6

La tabla contiene muchos registros y lo que necesito es ELIMINAR todos los registros de los No Clientes de la tabla, ¿sería con un loop? Alguna idea que me puedan ayudar, desde ya muy agradecido !

3 respuestas

Respuesta
1

Una SQL para eliminar los registros que cumplan la condición de que el contenido del campo sea un valor numérico
Opciones:

CurrentDb.Execute "Delete * From [aqui-el-nombre-de-la-tabla] Where Val ([Id de Pedido]) = 0"
CurrentDb.Execute "Delete * From [aqui-el-nombre-de-la-tabla] Where IsNumeric ([Id de Pedido])"

CurrentDb.Execute y DoCmd.RunSQL son equivalentes, pero no genera mensajes por lo que no se necesita manipularlos.

Val ([Id de Pedido]) = 0 ....  la función VAL extrae del campo el valor numérico (devuelve cero si no hay dígitos en al inicio)

IsNumeric ([Id de Pedido]) ... La función IsNumeric devuelve un Verdadero / Falso si el contenido del campo no se puede evaluar como numero o el campo no existe/localiza.

Enrique antes que nada Muchas gracias. TE cuento que el problema que tengo es que la tabla es bastante rara y necesito eliminar los registros desde una línea que dice Condición No cliente, desde ahí para abajo todos los registros hasta que encuentre una línea que diga Condición Cliente.

Todos esos registros que quedan en el medio son los que quiero eliminar y luego que siga recorriendo la tabla hasta que vuelva a encontrar otra línea que diga Cond No cliente y borrar todos lo registros debajo hasta que nueva mente aparezca un campo que diga Condición Cliente y ahí pare y borre todo eso .

No se si fui claro.

Muchas gracias!

Lo que solicitas solo se puede garantizar si el orden es invariable (y no parece que exista un orden).
Si el origen real fuera un listado en TXT seria más sencillo, pero si es lo único disponible ...

Pregunta:
¿Seria válido el crear una tabla y traspasar los grupas de registros de tipo 'cliente'?.
(Copiándolos, el original quedaría intacto)
Si es válido sugiere un nombre para la nueva tabla (y el nombre de la actual), porque se requiere VBA y no se que dominio tienes sobre ese entorno a momento actual.

Si el proceso se va a repetir lo crearía como una función a la que se la pasarían dos parámetros (datos), el nombre de la tabla que cede los datos y el de tabla destino (se asumen que los nombres de los campos y las condiciones se mantienen constantes).

Anoto algo más.
¿El dato numérico se respeta o se remunera?, si esta relacionado con otra tabla debería respetarse.
Todos las datos serán clientes + ID, el registro que los delata no se traspasa a la nueva tabla.

El listado original es un txt que lo importo en una tabla, luego de sacarle varios caracteres . Como dices, no existe un orden.

El nombre de la tabla actual es APEFALL y la nueva tabla ser[ia CLIENTES.

GRACIAS

Escribí algo así pero me da error, tampoco es que esté seguro de que vaya a estar bien...

Private Sub Elimina_EXCLIENTES()


Dim rst As DAO.Recordset 'Creas la variable recordset
Set rst = CurrentDb.OpenRecordset("APEFALL") '
If rst.RecordCount = 0 Then GoTo Salida 
rst.MoveFirst 
Do
Do While APEFALL.APELLIDO_NOMBRE = " CLI - CLIENTE" 
If APEFALL.APELLIDO_NOMBRE = " EXC - EXCLIENTE" Then
CurrentDb.Execute "Delete * From APEFALL"
rst.MoveNext 
End If
Loop
Loop Until APEFALL.APELLIDO_NOMBRE = " CLI - CLIENTE"

Salida: 
rst.Close
Set rst = Nothing
End Sub

Trabajando con el original se minimizan los errores.
(La alternativa es añadir un autonumérico en la tabla 'APEFALL', no importa el valor numérico, solo nos interesa la numeración correlativa para mantener el orden original)

Este tipo de importaciones suele ser reiterativo, por lo que aporto la función con dos versiones, una requiere nombres (para crear diferentes tablas, por ejemplo por años), la otra asume los nombres actuales.

La que solicita nombres se utiliza así : Extraer ("APEFALL ", "CLIENTES")

Public Function Extraer(Torigen$, Tdestino$)
Dim Xcondicion As Boolean, Tbl_Temp As DAO.Recordset
Set Tbl_Temp = CurrentDb.OpenRecordset(Torigen, , dbReadOnly)
With Tbl_Temp
If .RecordCount = 0 Then Exit Function
.MoveLast: .MoveFirst
Xcondicion = IIf(!id_de_pedido = "cliente", -1, 0)
Do Until .EOF
If !nombre = "condición" Then Xcondicion = IIf(!id_de_pedido = "cliente", -1, 0): .MoveNext
If Xcondicion Then CurrentDb.Execute "Insert into " & Tdestino & " (nombre, id_de_pedido) Values ('" & !nombre & "', '" & !id_de_pedido & "')"
.MoveNext
Loop
.Close
Set Tbl_Temp = Nothing
End With
End Function

La que no solicita nombres se utiliza asi :  Extraer  ()

Public Function Extraer()
Dim Xcondicion As Boolean, Tbl_Temp As DAO.Recordset
Set Tbl_Temp = CurrentDb.OpenRecordset("APEFALL", , dbReadOnly)
With Tbl_Temp
If .RecordCount = 0 Then Exit Function
.MoveLast: .MoveFirst
Xcondicion = IIf(!id_de_pedido = "cliente", -1, 0)
Do Until .EOF
If !nombre = "condición" Then Xcondicion = IIf(!id_de_pedido = "cliente", -1, 0): .MoveNext
If Xcondicion Then CurrentDb.Execute "Insert into Clientes (nombre, id_de_pedido) Values ('" & !nombre & "', '" & !id_de_pedido & "')"
.MoveNext
Loop
.Close
Set Tbl_Temp = Nothing
End With
End Function

El resultado obtenido (con los datos publicados)
nombre          id_de_pedido
juan perez            2
juan diaz              3
juana lopez          6

Consulta cualquier duda y si ofreces un trozo del TXT original se puede prescindir de la tabla APFALL por innecesaria.

¿No seria interesante vaciar la tabla APFALL tras procesarla para evitar duplicados si se ejecuta más de una vez con los mismos datos? ... Innecesario si la tabla Clientes esta indexada sin duplicados pero ...

Parece que nos hemos cruzado, leeré lo ultimo que has publicado.

Creo que podrás reutilizar lo que he publicado para adaptarlo al entorno real, pero si algo te despierta curiosidad ... tu mismo.

¡Mil Gracias! 

Excelente Enrique !!! Me ha funcionado perfecto, era justo lo que necesitaba.

Te estoy muy agradecido, impecable tu ayuda !!!!!

Respuesta
1

Le dejo este ejemplo, no requiere crear más tablas, solo mediante código adiciono un campo auxiliar que llamo "tomar" tipo byte para marcar los registros que debo eliminar.

TABLA ORIGINAL

TABLA ACTUALIZADA

CODIGO DE LA FUNCIÓN (Lo puede cambiar como un procedimiento)

Public Function retira()
 Dim db As Database
 Dim rs As Recordset
 Dim strAux As String
 Dim flag As Boolean
 Set db = CurrentDb
   'Adiciono un campo auxiliar
   CurrentDb.Execute "ALTER TABLE tblClientes ADD COLUMN tomar BYTE;"
   CurrentDb.TableDefs.Refresh
 Set rs = db.OpenRecordset("tblClientes")
 Do Until rs.EOF
   If rs!APELLIDO_NOMBRE = "EXC - CLIENTE" Then
     flag = True
     rs.Edit
     rs!tomar = 1
     rs.Update
     rs.MoveNext
   End If
   If rs!APELLIDO_NOMBRE <> "CLI - CLIENTE" And flag = True Then
     rs.Edit
     rs!tomar = 1
     rs.Update
     rs.MoveNext
   Else
     flag = False
     rs.MoveNext
   End If
 Loop
 rs.Close
 Set rs = Nothing
 'Retiro los NA:
  CurrentDb.Execute "DELETE FROM tblClientes WHERE LEFT(DOCUMENTO,2)='" & "NA'"
 'Retiro los registro elegidos en el campo auxiliar tomar
  CurrentDb.Execute "DELETE FROM tblClientes WHERE tomar=1"
 'Elimino el campo auxiliar tomar
   CurrentDb.Execute "ALTER TABLE tblClientes DROP COLUMN tomar;"
   CurrentDb.TableDefs.Refresh
End Function

En caso que no quiere crear por código el campo "tomar" puede crearlo directamente en diseño de tipo byte y suprimir las líneas que lo crea y elimina de la función,

Si quiere el ejemplo puede solicitarlo a [email protected], favor en el asunto anotar la consulta.

Cambie esta línea

Set rs = db.OpenRecordset(" tblClientes") por

Set rs = db.OpenRecordset("Select * FROM tblClientes ORDER BY idpedido")

Para evitar error 3021 "No hay un registro activo"

Respuesta
1

No dices desde donde quieres eliminarlo, si desde un formulario o una consulta de eliminación. Vamos a suponer que es desde un formulario. En cualquier evento, por ejemplo al hacer clic de un botón, puedes poner

Docmd.setwarnings false

docmd.runsql"delete * from Nombredetutabla where [Id de pedido] ="" No cliente """

Lo de set Warnings es para que no te aparezca la dichosa ventana de "Va a eliminar..."

Vamos a suponer que es desde una consulta

Donde yo pongo pais tu tienes que poner el campo Id de Pedido y debajo, donde yo pongo Como "Alemania" tu tienes que poner Como "No cliente"

He supuesto que te refieres a eliminar registros

Es que me expresé mal...la tabla se ve así tal como la mostré, el nombre del campo es Id de Pedido

y en ese campo tenemos 1, 2, 3, cliente, no cliente, 4 ,5 6

Nombre                  Id de Pedido   (estos son los 2 campos)

condición               cliente

juan perez              2

juan diaz                 3

condición                no cliente

maria perez            4

maria diaz              5

condición               cliente 

juana lopez            6

y quiero que la tabla me quede resultado:

Nombre                  Id de Pedido   (estos son los 2 campos)

juan perez              2

juan diaz                 3

juana lopez            6

que serían solamente los clientes reales...es una tabla rara, sí, pero es la que tengo que trabajar...lo que tengo que hacer es eliminar las líneas que dicen condición cliente, condición no cliente, y todos los registros que van debajo de no cliente hasta que vuelva a aparecer el registro cliente 

Muchas gracias 

Pues es como te he dicho. Lo que hace la instrucción de VB o la consulta de eliminación es, valga la redundancia, eliminar de la tabla todos aquellos registros en que el valor del campo Id de Pedido sea No cliente.

¡Gracias! 

Pero es que no son los registros en los que dice No cliente los que tengo que eliminar, sino que son los que tienen una numeración y que están debajo de ese registro

Chico, la culpa es mía, estaba obsesionado. Basta conque pongas

Docmd.runsql"delete * from nombretabla where [id de pedido]<>""No cliente """

Corrijo, por fin leí, lo que tenía que eliminar. Ponlo como

Docmd.runsql"delete * from tabla where [id de pedido]<>""cliente"""

Es decir, elimina todos aquellos registros en que Id de pedido sea distinto de Cliente

Aca te paso una imagen de como se ve mi tabla, porque es dificil explicarlo...Lo que necesito eliminar son todos los registros que est[an entre la fila EXC-EXCLIENTE y la fila  CLI-CLIENTE

Escribí esto pero no me funciona, a ver si me puedes ayudar

Private Sub Elimina_EXCLIENTES()


Dim rst As DAO.Recordset 'Creas la variable recordset
Set rst = CurrentDb.OpenRecordset("APEFALL") '
If rst.RecordCount = 0 Then GoTo Salida 
rst.MoveFirst 
Do
Do While APEFALL.APELLIDO_NOMBRE = " CLI - CLIENTE" 
If APEFALL.APELLIDO_NOMBRE = " EXC - EXCLIENTE" Then
CurrentDb.Execute "Delete * From APEFALL"
rst.MoveNext 
End If
Loop
Loop Until APEFALL.APELLIDO_NOMBRE = " CLI - CLIENTE"

Salida: 
rst.Close
Set rst = Nothing
End Sub

¿Entonces de Id de Pedido nada de nada? Hubiera sido mucho más fácil empezar con la imagen

Si tengo la tabla Tabla1 como

Y un formulario con un botón, ya dije que no sería necesario, por que se podría poner en cualquier otro evento

En el evento Al hacer clic del botón le pongo

Private Sub Comando48_Click()
DoCmd.RunSQL "delete * from tabla1 where apellido_nombre <>""cli - cliente"" and apellido_nombre <> ""ex - excliente"""
End Sub

De forma que cuando lo pulso me deja la tabla como

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas