** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - Autocompletar un campo
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoAutocompletar un campo

 Responder Responder
Autor
Mensaje
apstoni Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 09/Octubre/2010
Localización: España
Estado: Sin conexión
Puntos: 367
Enlace directo a este mensaje Tema: Autocompletar un campo
    Enviado: 24/Noviembre/2015 a las 19:24
Hola. He visto que la mayoría de programas de contabilidad tienen una ayuda en la introducción de datos de determinados campos. Una de ellas es que al introducir la cuenta contable escribes 43.1 y al darle al enter automáticamente te rellena el campo con la cuenta completa 43000001, o sea, rellena después del punto con ceros hasta convertir el campo de 8 dígitos.
Alguien me puede dar una idea para hacerlo.
Apstoni
Arriba
emiliove Ver desplegable
Moderador
Moderador


Unido: 16/Junio/2009
Localización: Mexico
Estado: Sin conexión
Puntos: 4927
Enlace directo a este mensaje Enviado: 24/Noviembre/2015 a las 19:52
Pues muy fácil, si ya tienes los nombres solo tienes que crear una campo en una consulta y agregar mas o menos esto:
Left([Cuenta],3) & "." & Int(Right([Cuenta],6))
 
Donde cuenta es el nombre de la cuenta del 43000001
 
Saludos.
Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 24/Noviembre/2015 a las 23:20
Creo que una correcta forma de lograr eso consistiría en localizar el punto decimal y (en base al tamaño predeterminado de la cuenta que es fijo) rellenar el hueco con ceros.

Ello permitiría asociarlo a cualquier nivel de desglose (de forma automática) y admitiría cualquier numero de cuenta en su rango.

Algo como (para una contabilidad de nueve caracteres en las cuentas):
xxx = Left(xDato,Instr(xDato,".")-1) & String(9 - Len(xDato)+ 1, "0") & Mid(xDato,InStr(xDato,".") +1)

Arriba
apstoni Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 09/Octubre/2010
Localización: España
Estado: Sin conexión
Puntos: 367
Enlace directo a este mensaje Enviado: 25/Noviembre/2015 a las 10:22
He probado y me da el error '5' en tiempo de ejecucion - argumento o llamada a procedimiento no válido.

Me.CTAAPU = Left([CTAAPU], InStr([CTAAPU], ".") - 1) & String(8 - Len([CTAAPU]) + 1, "0") & Mid([CTAAPU], InStr([CTAAPU], ".") + 1)

¿Podría ser porque el campo CTAAPU está definido como Entero Largo?
Apstoni
Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 25/Noviembre/2015 a las 13:38
La teoría dice que si no se va a sumar, restar o efectuar cualquier calculo matemático, ser de tipo numérico no es una necesidad.

Si a eso se añade que el dato del que se esta tratando es un código, código que es de una longitud constante, código que implica una sección en cada subconjunto (y que comienza por la izquierda) ..... define a ese campo como un campo de tipo texto.

Ahora bien, si por el resto de diseño se necesita que sea numérico, solo se ha de copiar ese texto (el contenido del campo en edición) en una variable de tipo String y a partir de eso .....

Basta que al finalizar la recreación de ese código (que será un texto) se le aplique la función VAL para que pueda introducir como numero en su destino.
Arriba
VIMIPAS Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 06/Enero/2006
Localización: ESPAÑA
Estado: Sin conexión
Puntos: 5218
Enlace directo a este mensaje Enviado: 25/Noviembre/2015 a las 16:39
Hola buenas tardes a todos.

Creo que estás tratando de "emular" a lo que se hace en ContaPlús.

Pero para ello hay que tener en cuenta que es lo que realmente hace ese programa.

El programa en sí te permite hacer lo que tu indicas con el ., pero lo que hace a continuación es ofrecer (depende de donde esté ubicado, parece que estás en apuntes del diario) la cuenta, siempre que en su conversión y comprobación exista, por lo que te sustituirá:

43.1 por 43000001 y entonces comprobará si existe, en caso de que existe la pone en la columna de las cuentas y tu sigues escribiendo en el campo del texto (nota de a que corresponde el asiento).

Pero acabo de probar tu ejemplo (he montado una mínima "tablacuentas" y he hecho esto:

Private Sub BUSCA_CTA_AfterUpdate()'Utilizo un control de texto distinto del de la tabla
''APSTONI:'Me.CTAAPU = Left([CTAAPU], InStr([CTAAPU], ".") - 1) & String(8 - Len([CTAAPU]) + 1, "0") & Mid([CTAAPU], InStr([CTAAPU], ".") + 1)
'''VIMIPAS a partir de aquí
Dim HacerCuenta As String 'Para hacer la composición deseada

'Divide y vencerás, es mejor paso a paso, así localizas antes el error
HacerCuenta = Left(Me.BUSCA_CTA, InStr(Me.BUSCA_CTA, ".") - 1)
MsgBox "hacercuenta paso 1 (" & HacerCuenta & ")"
HacerCuenta = HacerCuenta & String(8 - Len(Me.BUSCA_CTA) + 1, "0")
MsgBox "hacercuenta paso 2 (" & HacerCuenta & ")"
HacerCuenta = HacerCuenta & Mid(Me.BUSCA_CTA, InStr(Me.BUSCA_CTA, ".") + 1)
MsgBox "hacercuenta paso 3 (" & HacerCuenta & ")"


Dim ExisteCuenta As Variant'Para ver si existe esa cuenta en la tabla
ExisteCuenta = DLookup("CTAAPU", "TABLACUENTAS", "CTAAPU = '" & HacerCuenta & "'")
If ExisteCuenta Then
MsgBox "LA CUENTA si, EXISTE, mirela (" & ExisteCuenta & ")"
'Poner aquí el código oportuno para hacer lo que proced hacer a  continuación
'En mi caso he puesto otro control de texto al que llamo encontrada y:
Me.ENCONTRADA = ExisteCuenta 'Este es el otro control de texto que he usado para la prueba

Else
MsgBox "Pues la cuenta aún no se ha creado... (" & ExisteCuenta & ")"
'Poner aquí el código oportuno para hacer lo que proced hacer a  continuación, será distinto del código anterior
'Ahora lo utilizo de otra forma
Me.ENCONTRADA = "NO EXISTE CUENTA PEDIDA" 'Este es el otro control de texto que he usado
'Tal vez aquí quisieras crearla. Entonces abrirías un formulario para añadir todos los datos
End If

End Sub


Como verás tengo un campo en la tabla que llamo como tu: CTAAPU, pero en el formulario he usado dos controles distintos de la tabla para hacerlo correr.

Échale un ojo y ya nos cuentas.

Saludos

Edito para añadir que el campo CTAAPU que yo he creado es del tipo texto con longitud 8.

Como ejemplo:

TABLACUENTAS
CTAAPU
41010002
43000001
43010001
52000003
52010003


Editado por VIMIPAS - 25/Noviembre/2015 a las 16:41
Gracias
Arriba
apstoni Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 09/Octubre/2010
Localización: España
Estado: Sin conexión
Puntos: 367
Enlace directo a este mensaje Enviado: 27/Noviembre/2015 a las 16:56
De esta manera funciona perfectamente.

Private Sub CTAAPU_AfterUpdate()
Dim HacerCuenta As String 'Para hacer la composición deseada
HacerCuenta = Left(Me.CTAAPU, InStr(Me.CTAAPU, ".") - 1)
HacerCuenta = HacerCuenta & String(8 - Len(Me.CTAAPU) + 1, "0")
HacerCuenta = HacerCuenta & Mid(Me.CTAAPU, InStr(Me.CTAAPU, ".") + 1)
'Comprobamos que existe la cuenta
Dim ExisteCuenta As Variant
ExisteCuenta = DLookup("IDCTA", "CUENTAS", "IDCTA = '" & HacerCuenta & "'")
If ExisteCuenta Then
Me.CTAAPU.Value = HacerCuenta
Me.NOMCTA = DLookup("NOMCTA", "CUENTAS", "IdCTA = '" & CTAAPU & "'")
Forms("ASIENTOS").Controls("SubAPUNTES").Form.Controls("DESAPU").SetFocus
Else
If MsgBox("CUENTA INEXISTENTE" & vbCrLf & "Quieres darla de alta: " & cuentanueva, vbYesNo) = vbYes Then
        DoCmd.OpenForm "CUENTAS"
        DoCmd.GoToRecord , , acNewRec
        Forms!CUENTAS!IdCTA = CTAAPU
        Forms!CUENTAS!NOMCTA.SetFocus
        Else
        End If
End If
'Buscamos el saldo acumulado de la cuenta
Dim NOMBRECTA As Double
Dim TDEBE As Double
Dim THABER As Double
Dim TSALDO As Double
NOMBRECTA = Nz(Me.CTAAPU, 0)
TDEBE = Nz(DSum("DEBEAPU", "APUNTES", "CDBL(CTAAPU) = " & CDbl(NOMBRECTA)), 0)
THABER = Nz(DSum("HABERAPU", "APUNTES", "CDBL(CTAAPU) = " & CDbl(NOMBRECTA)), 0)
TSALDO = TDEBE - THABER
Forms("ASIENTOS").Controls("Texto58").Value = TSALDO
'Asignamos la fecha del asiento a la fecha del apunte
Me.FECAPU = Forms("ASIENTOS").Controls("FECASI").Value
Forms("ASIENTOS").Controls("SubAPUNTES").Form.Controls("DESAPU").SetFocus
End Sub

El problema lo tengo que cuando verifica la cuenta y no existe y si no la quiero crear, quiero que me borre el contenido del campo y se vuelva posicionar en  [CTAAPU] otra vez preparado para entrar nuevamente otra cuenta. Le pongo lo siguiente pero no se queda en [CTAAPU]:
If MsgBox("CUENTA INEXISTENTE" & vbCrLf & "Quieres darla de alta: " & cuentanueva, vbYesNo) = vbYes Then
        DoCmd.OpenForm "CUENTAS"
        DoCmd.GoToRecord , , acNewRec
        Forms!CUENTAS!IdCTA = CTAAPU
        Forms!CUENTAS!NOMCTA.SetFocus
        Else
        Me.CTAAPU = ClearConntent
        Forms("ASIENTOS").Controls("SubAPUNTES").Form.Controls("CTAAPU").SetFocus

        End If
End If


Apstoni
Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 27/Noviembre/2015 a las 18:08
Aprecio que se ha modificado el tipo de dato de 'CTAAPU' (de continuar con el dato original, un simple: Val(HacerCuenta) hubiera bastado), pero lo correcto es que sea un dato alfanumérico.

No entiendo porque si se hace referencia a 'CTAAPU' con 'Me.' (Me.CTAAPU) se complique referenciando a ese mismo objeto (que tiene el foco y es 'local') con su referencia absoluta: Forms("ASIENTOS").Controls("SubAPUNTES").Form.Controls("CTAAPU")

Para borrar el contenido un simple Me.CTAAPU = "" debería bastar y para no salir del objeto (a Me.CTAAPU me refiero) se activa el evento EXIT (un apostrofe es suficiente como contenido) y se ejecuta un Me.CTAAPU.Exit, True (que implicaría enviarlo al evento Exit con el parámetro CANCEL activado).

Como curiosidad ¿esto reporta algo que no sea perder tiempo?:
.....
HacerCuenta = Left(Me.CTAAPU, InStr(Me.CTAAPU, ".") - 1)
HacerCuenta = HacerCuenta & String(8 - Len(Me.CTAAPU) + 1, "0")
HacerCuenta = HacerCuenta & Mid(Me.CTAAPU, InStr(Me.CTAAPU, ".") + 1)
.....

Arriba
apstoni Ver desplegable
Asiduo
Asiduo
Avatar

Unido: 09/Octubre/2010
Localización: España
Estado: Sin conexión
Puntos: 367
Enlace directo a este mensaje Enviado: 27/Noviembre/2015 a las 22:31
Reporta que si eres contable es muy práctico teclear 57.1 y que te lo convierta a 57000001, eso contando que el plan contable lo tengas estructurado con 8 dígitos, imagínate si lo tienes estructurado en 12 como las grandes empresas utilizan. Básicamente te ahorras de teclear y ahorras también tiempo.
Apstoni
Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 28/Noviembre/2015 a las 00:03
Porque se hace eso lo conozco (de hecho has copiado 'a tu manera' la expresión que publique, como las contabilidades mantienen el numero de dígitos todos los años, es por lo que no he utilizado una variable o una expresión que 'contase los digitos'.

La pregunta era:
¿Qué supuestas ventajas aporta el trocear una expresión que al final hay que encolar para que sea útil?....

En las cocinas creo que a esa técnica la llaman 'desestructurar', cuando el huevo por accidente se convierte en tortilla que ni es tortilla: un huevo frito 'desestructurado'
Arriba
VIMIPAS Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 06/Enero/2006
Localización: ESPAÑA
Estado: Sin conexión
Puntos: 5218
Enlace directo a este mensaje Enviado: 28/Noviembre/2015 a las 16:15
Hola y buenas tardes a todos.

Primeramente Enrique agradecer esto: Me.CTAAPU.Exit, True

Sigue siendo un placer aprender de tí.

Por cierto ¿cómo lo harías tu lo de:

HacerCuenta = Left(Me.CTAAPU, InStr(Me.CTAAPU, ".") - 1)
HacerCuenta = HacerCuenta & String(8 - Len(Me.CTAAPU) + 1, "0")
HacerCuenta = HacerCuenta & Mid(Me.CTAAPU, InStr(Me.CTAAPU, ".") + 1)

¿podrías echarnos otra mano?.

Gracias siempre.

Saludos.


Editado por VIMIPAS - 28/Noviembre/2015 a las 16:15
Gracias
Arriba
E. Feijoo Ver desplegable
Moderador
Moderador


Unido: 16/Abril/2004
Localización: España
Estado: Sin conexión
Puntos: 19948
Enlace directo a este mensaje Enviado: 28/Noviembre/2015 a las 16:47
Comienza a ojear el hilo desde su inicio y veras que 'su' solución no es mas que la solución que propuse (solo la 'desestructuro')

Tercer mensaje del hilo:
Algo como (para una contabilidad de nueve caracteres en las cuentas):
xxx = Left(xDato,Instr(xDato,".")-1) & String(9 - Len(xDato)+ 1, "0") & Mid(xDato,InStr(xDato,".") +1)


La solución aplicada:
Dim HacerCuenta As String 'Para hacer la composición deseada
HacerCuenta = Left(Me.CTAAPU, InStr(Me.CTAAPU, ".") - 1)
HacerCuenta = HacerCuenta & String(8 - Len(Me.CTAAPU) + 1, "0")
HacerCuenta = HacerCuenta & Mid(Me.CTAAPU, InStr(Me.CTAAPU, ".") + 1)



Analiza ambas expresiones y saca conclusiones (basándose en que cada cosa que se ordena ejecutar a una maquina requiere 'su porción de tiempo')
Arriba
VIMIPAS Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 06/Enero/2006
Localización: ESPAÑA
Estado: Sin conexión
Puntos: 5218
Enlace directo a este mensaje Enviado: 28/Noviembre/2015 a las 23:55
Hola de nuevo.

Perdona Enrique, pero te interpreté mal y no supe expresarme cuando puse las tres filas para desarrollar lo mismo que tienes tu (la diferencia entre 8 -APSTONI- y 9 -ENRIQUE- caracteres de la cuenta da igual para el caso), y es por eso que tu me lo has vuelto a exponer lo mismo que antes.

Detallo pues que cuando puse los tres renglones para hacer lo mismo que en un renglón es por la sencilla razón de que apostoni decía que cuando ponía tu código le daba "error 5 en tiempo de ejecución".

Si te fijas en mi código, dije: 'Divide y vencerás

Pretendía que apostoni se diera cuenta de forma mas directa en cual de los tres renglones estaba el error.

Que por cierto, da ese error si cuando escribes la cuenta "no colocas un punto".

Por último Enrique en cuanto a lo que te pedía que nos pusieras el "como lo harías tu", no me refería a lo que ya habías puesto, sino a si pensabas que podría ponerse de otra forma, pues nos tienes acostumbrado a usar la función Format de muchas y muy buenas formas, de hecho yo acabo de aplicarlo de otra forma y le dejo un nuevo comentario a APOSTONI, para que no use Dlookup 2 veces seguidas.

Aquí dejo esto:

Private Sub BUSCA_CTA_AfterUpdate()
''''E. FEIJOO:xxx = Left(xDato, InStr(xDato, ".") - 1) & String(9 - Len(xDato) + 1, "0") & Mid(xDato, InStr(xDato, ".") + 1)'Cuenta con 9 dígitos
''''APOSTONI:Me.CTAAPU = Left([CTAAPU], InStr([CTAAPU], ".") - 1) & String(8 - Len([CTAAPU]) + 1, "0") & Mid([CTAAPU], InStr([CTAAPU], ".") + 1)'Cuenta con 8 dígitos

''''VIMIPAS
Dim HacerCuenta As String
Dim Punto As Integer
Punto = InStr(Me.BUSCA_CTA, ".")
If Punto > 0 Then
'''ojo al 9 que pongo aquí, no es que me haya confundido con 9 de Enrique, sino que ya cuento con el dígito del ., y aquí quedará descontado.
    HacerCuenta = Left(Me.BUSCA_CTA, Punto - 1) & Format(Val(Mid(Me.BUSCA_CTA, Punto + 1)), String(9 - Punto, "0"))
Else
    HacerCuenta = Me.BUSCA_CTA & String(8 - Len(Me.BUSCA_CTA), "0")
End If


'Si necesito dos valores del registro, no tengo porque hacer 2 Dlookup, me basta con un recordset así:
'Dim ExisteCuenta As Variant
'ExisteCuenta = DLookup("CTAAPU", "TABLACUENTAS", "CTAAPU = '" & HacerCuenta & "'")
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("select ctaapu, nomcta from tablacuentas")
rs.FindFirst "CTAAPU = '" & HacerCuenta & "'"
If Not rs.NoMatch Then 'Dos negaciones afirman: Sí que existe pues la cuenta
'If ExisteCuenta Then
'Poner aquí el código oportuno para hacer lo que proced hacer a  continuación
'En mi caso he puesto otro control de texto al que llamo encontrada y:
Me.ENCONTRADA = rs!CTAAPU
Me.nombreCTAENCONTRADA = rs!NOMCTA
Else
'Apostoni: lo que ya tienes hecho y lo que indica Enrique finalmente debe rematar esto que sigue de la forma que tu lo tienes
'Poner aquí el código oportuno para hacer lo que proced hacer a  continuación, será distinto del código anterior
'.......
End If

rs.Close
Set rs = Nothing
End Sub

Enrique, disculpa y gracias de nuevo.

Saludos


Editado por VIMIPAS - 28/Noviembre/2015 a las 23:58
Gracias
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable