** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - Función que no hace lo correcto
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Función que no hace lo correcto

 Responder Responder
Autor
Mensaje
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 354
Opciones de entrada Opciones de entrada   Gracias (0) Gracias(0)   Cita Goliat2000 Cita  ResponderRespuesta Enlace directo a este mensaje Tema: Función que no hace lo correcto
    Enviado: 22/Julio/2021 a las 15:51
Estimados amigos, necesito someter a vuestra consideración y ayuda una función de código que, si bien funciona correctamente, no consigo que implementar que haga todo lo que tiene que hacer.

 Entrando en materia, se trata de una BD para una colección de sellos de las antiguas colonias españolas (Dependencias Postales). Cada dependencia se la identifica con un número correlativo y los sellos de cada dependencia igual pero con el identificativos de su dependencia. (Dependencia nº 1 y sello nº 1; dependencia nº 1 y sello 87, etc).

 La función pretende y consigue en parte, es extraer de la tabla sellos, todos aquellos que no están marcados como “Obtenido”; es decir, extraer los “sellos que faltan” para escribirlos en otra tabla que se llama “FALTASCOLONIAS”. Dicha tabla de FALTASCOLONIAS, tiene 28 campos por cada registro (Un campo IdColo que es el identificativos de cada dependencia, y 27 restantes por cada letra del alfabeto, salvo la Ch que se consideraría como dos letras).

 La función extrae de la tabla sellos, el identificativos de cada dependencia y todos los números de ésa dependencia que se corresponden con sellos que faltan de esa dependencia en la colección.

 Como en la tabla FALTASCOLONIAS, no hay ningún registro, el primer For de la función no puedo poner AddNew porque me da error de Edit (no se puede editar un registro que no existe); sin embargo, con Edit, edita los campos del primer registro (el que va a ser primer registro), y va copiando; cuando llega a la letra Z y si sigue habiendo números faltantes a copiar, vuelve a editar todos los campos de un nuevo registro, y así sucesivamente.

 El problema surge cuando, una vez acabados, por ejemplo, los sellos faltantes de la Dependencia núm. 1, debería seguir escribiendo en un nuevo registro, pero ya con la dependencia núm. 2 (o la que correspondiere) en el campo IdColo, y escribir los nuevos números faltantes en los correspondientes campos (letras) del nuevo registro. PERO NO HACE ESTO, lo que hace es reeditar lo anteriormente escrito, y reescribe los campos con los datos de la dependencia núm. 2, cuando debería aumentar los registros de la tabla; es decir, en la tabla deberían quedar todos los sellos faltantes de todas las dependencias postales e identificados por el campo IdColo.

 Por más vueltas y cambios que he realizado, no consigo implementar esto. Por favor, si algún miembro del foro puede indicarme cual es el error que cometo o que código me falta para conseguir de dejar afinada la función, le estaré muy agradecido.

 Seguidamente, os paso la función en cuestión para su examen. Un saludo, gracias a todos y un muy buen feliz día.

 Function ExtraerFaltanteNuevoColonia()

Dim Letras As String

Dim Letra

Dim byX, byZ, byW, byDependencias As Byte

Dim NUM, NUMBis As Integer

Dim intNSellos As Integer

Letras = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"

NUM = 0

NUMBis = 0

intNSellos = 0

 'byZ es la variable que recoge el número de Dependencia Postal para el bucle For de buscar

'los sellos faltantes de cada Dependencia.

'byDependencias es la variable numérica que recoge el número total de Dependencias Postales Españolas,

'que tienen sellos faltantes en la colección.

'intNSellos es la variable que recoge el número total de sellos faltantes en cada dependencia postal


 byDependencias = DCount("[IdColo]", "[conDependenciasFALTAS]")

 

'La variable byDependencias cuenta el número de Dependencias Postales que tienen faltas

'de sellos nuevos mostrando el número que la identifica IdColo

 

If byDependencias = 0 Then Exit Function

 

'Si ninguna Dependencia tiene faltas, se abandona la función

'El siguiente SELECT, abre la tabla de sellos de ex colonias españolas o Dependencias Postales

'con todos los que faltan en la colección de todas las Dependencias

               Set bd = CurrentDb()

              Set rct = bd.OpenRecordset("SELECT DISTINCT tblSellosColonias.IdColo From tblSellosColonias WHERE (((tblSellosColonias.Obtenido) = False))" _

                    & " ORDER BY tblSellosColonias.IdColo WITH OWNERACCESS OPTION;")

                  rct.MoveLast

                  rct.MoveFirst

 'Con el siguiente bucle while, se recorren una a una todas las Dependencias postales con sellos faltantes; la variable byW recoge el número identificativo de la

'Dependencia Postal, NUMBis cuenta el número de sellos faltantes de la Dependencia que se está comprobando y, si existen (porque byDependencias ya lo comprobó)

'se abre nuevamente una consulta filtrada por el identificativo de la Dependencia, para proceder a copiar el identificativo de la Dependencia y los números de

'sellos Edifil faltantes en la tabla FALTASCOLONIAS.

              Do While Not rct.EOF

                   For byZ = 1 To byDependencias

                       byW = rct![IdColo]

                       NUM = NUM + 1

                       NUMBis = DCount("[IdCatalogo]", "SQL3", "[IdColo]= " & byW & "")

                       intNSellos = DCount("[IdCatalogo]", "[conFALTANUEVOCOLONIAS]", "[IdColo]=" & byW & "")

             

                          SQL = "SELECT FALTASCOLONIAS.IdColo, FALTASCOLONIAS.A, FALTASCOLONIAS.B, FALTASCOLONIAS.C, FALTASCOLONIAS.D," _

                               & "FALTASCOLONIAS.E, FALTASCOLONIAS.F, FALTASCOLONIAS.G, FALTASCOLONIAS.H, FALTASCOLONIAS.I, FALTASCOLONIAS.J," _

                               & "FALTASCOLONIAS.K, FALTASCOLONIAS.L, FALTASCOLONIAS.M, FALTASCOLONIAS.N, FALTASCOLONIAS.Ñ, FALTASCOLONIAS.[O]," _

                               & "FALTASCOLONIAS.P, FALTASCOLONIAS.Q, FALTASCOLONIAS.R, FALTASCOLONIAS.S, FALTASCOLONIAS.T, FALTASCOLONIAS.U," _

                               & "FALTASCOLONIAS.V, FALTASCOLONIAS.W, FALTASCOLONIAS.X, FALTASCOLONIAS.[Y], FALTASCOLONIAS.Z From FALTASCOLONIAS" _

                               & " WITH OWNERACCESS OPTION;"

                         

                           SQL2 = "SELECT tblSellosColonias.IdColo, tblSellosColonias.IdCatalogo, tblSellosColonias.Obtenido" _

                                 & " From tblSellosColonias WHERE (((tblSellosColonias.IdColo)=" & byW & ") And ((tblSellosColonias.Obtenido) = False))" _

                                 & "ORDER BY tblSellosColonias.IdColo, tblSellosColonias.IdCatalogo WITH OWNERACCESS OPTION;"               

                           Set bd = CurrentDb()

                           Set rst = bd.OpenRecordset(SQL, dbOpenDynaset)

                               rst.MoveFirst

                           Set rc = bd.OpenRecordset(SQL2, dbOpenDynaset)

                               rc.MoveLast

                               rc.MoveFirst

                              

'Este primer while con For, recorre las letras del alfabeto (que son campos de cada registro, total 27, ya que la Ch no se puede contar)

'edita los campos, y va colocando el valor que recoge de la tabla sellos de colonias, en la tabla de faltas.

                                Do While Not rc.EOF

                                      For byX = 1 To Len(Letras)

                                         Letra = Mid(Letras, byX, 1)

                                               rst.Edit

                                               rst![IdColo] = byW

                                               rst(Letra) = rc![IdCatalogo]

                                               rst.Update

                                               rc.MoveNext

                                               intNSellos = intNSellos – 1

 

'El siguiente If, cuando llega al último campo del registro, añade uno nuevo y comienza nuevamente por el campo de letra A y así sucesivamente.

                                                If Letra = "Z" Then

                                                  rst.AddNew

                                                  rst.Update

                                                  rst.MoveNext

                                                  byX = 0

 

'Con el siguiente ElseIf, lo que pretendo PERO QUE NO CONSIGO, es que cuando todos los sellos faltantes de una Dependencia concreta, se hayan copiado 'a la tabla de FALTASCOLONIAS, añada un nuevo registro y vuelta a empezar.

'Añade un registro al final de la tabla, pero el código lo que hace al volver a empezar, es reescribir el anterior registro y en todos sus campos 'con los nuevos valores de las siguientes Dependencias que el primer For muestra.

                                               ElseIf intNSellos = 0 Then

                                                  rst.AddNew

                                                  rst.Update

                                                  byX = 0

                                               End If

                                                 If rc.EOF Then

                                                    Exit For

                                                   Exit Do

                                                 End If

                                      Next

                                Loop

                                        If byZ = byDependencias Then

                                          Exit Function

                                        End If

                        rct.MoveNext

                      Next

                Loop

         

                              If Not rc Is Nothing Then

                                    rc.Close

                                 Set rst = Nothing

                                    rst.Close

                                 Set rct = Nothing

                                    rct.Close

                              End If                           

 'Lo que el código debe de hacer es, escribir en la tabla, una de tras de otra y con el identificativo de cada Dependencia Postal, todos los sellos

 'que faltan en la colección de cada una de las Dependencias postales. El informe posterior, serán varios folios dónde, detallados por Dependencia

 'Postal, aparezcan todos los números de catálogo faltantes de sellos de cada Dependencia.

 

Muchas gracias, aunque sólo lo hayas leído.
Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 6479
Opciones de entrada Opciones de entrada   Gracias (0) Gracias(0)   Cita mounir Cita  ResponderRespuesta Enlace directo a este mensaje Enviado: 22/Julio/2021 a las 20:22
Hola!

Prueba utilizar la siguiente instrucción al principio del código:-

On Error Resume Next

De esta forma obvia el error y sigue con insertar registros (AddNew)

Editado por mounir - 22/Julio/2021 a las 20:23
Un Saludo.
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Opciones de entrada Opciones de entrada   Gracias (0) Gracias(0)   Cita javier.mil Cita  ResponderRespuesta Enlace directo a este mensaje Enviado: 23/Julio/2021 a las 10:48
aparte de lo comentado deberías definir todas las variables que te faltan por definir

Sin entrar en detalle en el algoritmo de la función deberías corregir esta linea de código

Donde pones
 intNSellos = intNSellos 1

Deberias poner
 intNSellos = intNSellos - 1

Hay un error , has puesto un guion largo () y debería ser el signo menos (-)

 




Editado por javier.mil - 23/Julio/2021 a las 11:03
Arriba
Goliat2000 Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 11/Noviembre/2014
Localización: Madrid
Estado: Sin conexión
Puntos: 354
Opciones de entrada Opciones de entrada   Gracias (0) Gracias(0)   Cita Goliat2000 Cita  ResponderRespuesta Enlace directo a este mensaje Enviado: 24/Julio/2021 a las 10:34
Hola y buenos días. Gracias Mounir y Javier por contestar, muy agradecido. Os comento la solución que he encontrado. Con relación a intNSellos, el guión alto ha salido al copiar el post en el foro, ya que en la función es un signo menos. Con relación a al indicación de Mounir "On Error Resume Next", eso también lo tengo implementado pero no lo copie en el post porque para las pruebas, lo tenía inhabilitado y por eso no pensé que eso fuera el error. La solución ha venido cuando he cambiado de lugar la sentencia SQL (la de la tabla FALTAS COLONIAS), y tras tomar el primer valor del primer while, pongo un AddNew, y todo funcionó correctamente. Voy a dejar posteado toda la función corregida por si a alguien le pudiera venir bien y de acuerdo a la filosofía del foro, que me parece muy acertada. Feliz día para todos, y el post puede darse por cerrado.

Function ExtraerFaltanteNuevoColonia()
Dim Letras As String
Dim Letra
Dim byX, byZ, byW, byDependencias As Byte
Dim NUM, NUMBis As Integer
Dim intNSellos As Integer
Letras = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"
NUM = 0
NUMBis = 0
intNSellos = 0
'byZ es la variable que recoge el número de Dependencia Postal para el bucle For de buscar
'los sellos faltantes de cada Dependencia.
'byDependencias es la variable numérica que recoge el número total de Dependencias Postales Españolas,
'que tienen sellos faltantes en la colección.
'intNSellos es la variable que recoge el número total de sellos faltantes en cada dependencia postal

On Error GoTo Err_HayError

byDependencias = DCount("[IdColo]", "[conDependenciasFALTAS]")
'La variable byDependencias cuenta el número de Dependencias Postales que tienen faltas
'de sellos nuevos mostrando el número que la identifica IdColo
If byDependencias = 0 Then Exit Function
'Si ninguna Dependencia tiene faltas, se abandona la función
'El siguiente SELECT, abre la tabla de sellos de ex colonias españolas o Dependencias Postales
'con todas los Dependencias Postales en las que faltan sellos en la colección.
SQL = "SELECT FALTASCOLONIAS.IdColo, FALTASCOLONIAS.A, FALTASCOLONIAS.B, FALTASCOLONIAS.C, FALTASCOLONIAS.D," _
                               & "FALTASCOLONIAS.E, FALTASCOLONIAS.F, FALTASCOLONIAS.G, FALTASCOLONIAS.H, FALTASCOLONIAS.I, FALTASCOLONIAS.J," _
                               & "FALTASCOLONIAS.K, FALTASCOLONIAS.L, FALTASCOLONIAS.M, FALTASCOLONIAS.N, FALTASCOLONIAS.Ñ, FALTASCOLONIAS.[O]," _
                               & "FALTASCOLONIAS.P, FALTASCOLONIAS.Q, FALTASCOLONIAS.R, FALTASCOLONIAS.S, FALTASCOLONIAS.T, FALTASCOLONIAS.U," _
                               & "FALTASCOLONIAS.V, FALTASCOLONIAS.W, FALTASCOLONIAS.X, FALTASCOLONIAS.[Y], FALTASCOLONIAS.Z From FALTASCOLONIAS" _
                               & " WITH OWNERACCESS OPTION;"
              Set bd = CurrentDb()
              Set rct = bd.OpenRecordset("SELECT DISTINCT tblSellosColonias.IdColo, tblSellosColonias.Obtenido From tblSellosColonias" _
                    & " WHERE (((tblSellosColonias.Obtenido) = False))ORDER BY tblSellosColonias.IdColo WITH OWNERACCESS OPTION;")
              Set rst = bd.OpenRecordset(SQL, dbOpenDynaset)

'Con el siguiente bucle while, se recorren una a una todas las Dependencias postales con sellos faltantes; la variable byW recoge el número identificativo de la
'Dependencia Postal, NUMBis cuenta el número de sellos faltantes de la Dependencia que se está comprobando y, si existen (porque byDependencias ya lo comprobó)
'se abre nuevamente una consulta filtrada por el identificativo de la Dependencia, para proceder a copiar el identificativo de la Dependencia y los números de
'sellos Edifil faltantes en la tabla FALTASCOLONIAS.
                Do While Not rct.EOF
                      For byZ = 1 To byDependencias
                          byW = rct![IdColo]
                          NUM = NUM + 1
                          rst.AddNew
                          NUMBis = DCount("[IdCatalogo]", "SQL3", "[IdColo]= " & byW & "")
                          intNSellos = DCount("[IdCatalogo]", "[conFALTANUEVOCOLONIAS]", "[IdColo]=" & byW & "")
        
                          
                           SQL2 = "SELECT tblSellosColonias.IdColo, tblSellosColonias.IdCatalogo, tblSellosColonias.Obtenido" _
                                 & " From tblSellosColonias WHERE (((tblSellosColonias.IdColo)=" & byW & ") And ((tblSellosColonias.Obtenido) = False))" _
                                 & "ORDER BY tblSellosColonias.IdCatalogo WITH OWNERACCESS OPTION;"
                                        
                           Set bd = CurrentDb()
                           Set rc = bd.OpenRecordset(SQL2, dbOpenDynaset)
                               rc.MoveLast
                               rc.MoveFirst
                               
'Este primer while con For, recorre las letras del alfabeto (que son campos de cada registro, total 27, ya que la Ch no se puede contar)
'edita los campos, y va colocando el valor que recoge de la tabla sellos de colonias, en la tabla de faltas.
                                Do While Not rc.EOF
                                      For byX = 1 To Len(Letras)
                                         Letra = Mid(Letras, byX, 1)
                                               rst.MoveLast
                                               rst.Edit
                                               rst![IdColo] = byW
                                               rst(Letra) = rc![IdCatalogo]
                                               rst.Update
                                               rc.MoveNext
                                               intNSellos = intNSellos - 1
'El siguiente If, cuando llega al último campo del registro, añade uno nuevo y comienza nuevamente por el campo de letra A y así sucesivamente.
                                               If Letra = "Z" And intNSellos > 0 Then
                                                  rst.AddNew
                                                  rst.Update
                                                  byX = 0
                                               ElseIf intNSellos = 0 Then
                                                  rst.AddNew
                                                  rst.Update
                                                  byX = 0
                                               End If
                                                 If rc.EOF Then
                                                    Exit For
                                                   Exit Do
                                                 End If
                                      Next
                                Loop
                                        If byZ = byDependencias Then
                                          Exit Function
                                        End If
                        rct.MoveNext
                      Next
                Loop
          
                               If Not rc Is Nothing Then
                                    rc.Close
                                 Set rst = Nothing
                                    rst.Close
                                 Set rct = Nothing
                                    rct.Close
                              End If
                              
Exit_HayError:
   Exit Function
Err_HayError:
  If Err.Number = 3075 Then
     MsgBox "Ha tecleado erróneamente, en módulo Extraer Nuevo Faltante Dependencias." & Chr(13) & Chr(10) & Chr(10) & "Intentelo de nuevo.", vbInformation + vbOKOnly, "Aviso de Error"
  ElseIf Err.Number = 3021 Or Err.Number = 94 Then
     MsgBox "El Dato tecleado NO ES VÁLIDO o no se encuentra registrado en la BD." & Chr(13) & Chr(10) & Chr(10) & "Intentelo de nuevo.", vbInformation + vbOKOnly, "Aviso de Error"
  Else
   MsgBox "Aviso Nº " & Err.Number & " Módulo Manejo de Faltas de Sellos Nuevos Dependencia Postal." & Chr(13) & Chr(10) & Err.Description, vbCritical + vbOKOnly, "Aviso de Error"
  End If
Resume Exit_HayError
   
End Function
                                                       
                                                        
Muchas gracias, aunque sólo lo hayas leído.
Arriba
javier.mil Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 10/Agosto/2005
Localización: España
Estado: Sin conexión
Puntos: 4830
Opciones de entrada Opciones de entrada   Gracias (0) Gracias(0)   Cita javier.mil Cita  ResponderRespuesta Enlace directo a este mensaje Enviado: 24/Julio/2021 a las 13:29
Sin entrar a valorar si la funciona se puede mejorar ,......... y para aquellos usuarios que quieran re-utilizar tu código deberías poner las Variables que faltan y corregir las variables mal definidas


VARIABLES QUE FALTAN POR DEFINIR
Dim bd As DAO.Database
Dim rct As DAO.Recordset
Dim rst As DAO.Recordset
Dim rc As DAO.Recordset
Dim SQL As String
Dim SQL2 As String



VARIABLES QUE HAY DEFINIR CORRECTAMENTE
Por ejemplo cuando No defines una variable Access lo interpreta como una variable del tipo VARIANT
Dim Letras As String
Dim Letra As String
Dim byX As Byte, byZ As Byte, byW As Byte, byDependencias As Byte
Dim NUM As Integer, NUMBis As Integer
Dim intNSellos As Integer




Editado por javier.mil - 24/Julio/2021 a las 13:34
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable