Adaptar código para crear un Numero ID consecutivo VBA EXCEL

Un compañero del foro me ha ayudado con un código pero no logro adaptarlo a mi excel.

El código consiste en crear de manera automática un código consecutivo que identifique el pedido. El formato me gustaría que fuera el que hay en la macro: 0000-año

Los datos están en una tabla llamada DATOS_TABLA en la columna A.
Además no hay una relación con el numero de fila (un mismo ID puede estar introducido varias veces porque puede hacer referencia a un mismo pedido).
Uso un form para introducir datos, la idea que tenia es que en un label llamado NUM_CONSECUTIU

Private Sub UserForm_Initialize()
ID_anterior = Range("A1").End(xlDown).Offset(0, 0).Select
num_consecutiu.Caption = NextID(ID_anterior)
End Sub
Public Function NextID(PreID As Long) As Long
Dim CrrtYr As Integer: CrrtYr = Year(Now)
Dim INCrement As String: INCrement = Left(CStr(PreID), Len(CStr(PreID)) - 4)
NextID = CLng(INCrement) + 1 & CrrtYr
End Function

Debería ir a la ultima celda con valores de la columna A (A9 en este caso), leer la celda, sumarle uno (0003-2019) e ir a la celda de abajo (A10 en este caso) y escribir el resultado de la la celda anterior +1 (0003-2019)

He intentado adptar este código pero no soy capaz, ¿qué hago mal?

3 Respuestas

Respuesta
1

Pol en mi respuesta te había dicho que cambiaras . Row por .Value justamente como en el código de Abraham (no por .Select) Si sigues las instrucciones te irá mejor :)

A modo general, mi punto de vista con respecto al comentario del Sr Abraham.

Las funciones son macros que ejecutan una operación recusable o reciclable. Y para mantener el código limpio se escriben a parte.

En tu caso puede ser aplicable, como te había dicho en mi respuesta: Si tu libro consta con mas hojas con otros tipos de ID que mas o menos tengan el mismo formato. Una única función te serviría para todos ellos, solo con llamarla.

El concepto de las funciones y de las clases es como le llamamos en Ingles:

Write once run anywhere

"Escribe una vez, ejecuta donde sea"

Las funciones son extremadamente útiles, porque a parte de que se pensaron para código, excel al ser una hoja de calculo, permite llamar la función en las celdas también.

Andy

Hola Andy, si tienes toda la razón. El problema es que no me funcionaba con value y no me saltaba ningún error, he intentado hacer unos cambios en el posicionamiento de la línea y no me ha funcionado, después he empezado a toquetear para ver si lograba encontrar el problema y creo que el .select ha sido uno de las pruebas que he hecho.
He abierto otra consultado porque creía que la anterior ya podía estar resuelta y que el problema no era del código sino mio.
Me he puesto otra vez a ello pero no se como hacer que el código funcione.
De momento con lo que ha dicho Abraham me funciona rápido y bien.
Me gustaría saber que estoy haciendo mal con las funciones porque lo he vuelto a intentar siguiendo tus pasos y no sucede nada (ni bueno ni malo).

Private Sub UserForm_Initialize()
ID_anterior = Range("A3").End(xlDown).Offset(0, 0).value
num_consecutiu.Caption = NextID(ID_anterior)
End Sub
Public Function NextID(PreID As Long) As Long
Dim CrrtYr As Integer: CrrtYr = Year(Now)
Dim INCrement As String: INCrement = Left(CStr(PreID), Len(CStr(PreID)) - 4)
NextID = CLng(INCrement) + 1 & CrrtYr
End Function

En este codigo que te paso he hecho la modificacion que empiece en la celda A3 ya que los encabezados estan en la A2 y los datos empiezan en la A3

Creo que la principal razón por la que no funciona es porque la pusiste en el modulo del formulario. Las funciones deberían ir en un modulo estándar.

Si la solución de abraham te funciona, dejalo así, como dice el dicho: si no esta roto no lo arregles. Quizás mi error fue darte una solución tan avanzada.

No obstante te diré más o menos como YO organizo mis proyectos.

En el modulo de los formularios solo pongo códigos relacionados directamente con los controles. Textbox, combobox etc etc.

El resto todo en módulos.

Hago 1 modulo llamado funciones, y ahí coloco pequeñas funciones reusables como esta.

Luego en otros módulos el resto de la lógica de mi programa, todos los cálculos y computaciones que unirán pedazos de cada cosa para formar un único proyecto. A esto en programación se le llama precisamente "modularizacion". (Hay más conceptos que VBA no maneja muy bien)

Y en los módulos de clase pues mis clases.

Si mal no he entendido entonces en el formulario solo programas lo especifico y concreto que va hacer y en módulos aparte todas esas rutas o funciones que son más "genericas" y pueden usarse en más de un sitio.


La idea de hacerlo así seria ahorrar tiempo en la escritura del código, ¿hacer el código más minimalista y entendible no?
Creo que en cuanto termine este proyecto intentare reestructuralo con módulos y funciones para poder tener algo bien hecho.
Gracias de nuevo Andy por tus lecciones

Si, esa es la idea. A veces sin darnos cuenta tenemos, por ejemplo, varios controles que en alguna parte realizan la misma función, y copiamos y pegamos el código y tenemos el mismo código repetido varias veces en diferentes partes. Bueno esto no causa problemas a la hora de ejecutar el programa pero es un código difícil de "mantener" a la hora de arreglar cosas o hacer cambios.

Para eso están las funciones, es código que escribes una sola vez y lo ejecutas cuantas veces quieras en diferentes partes del proyecto, pasándole las variables por argumentos.

El pase de variables por argumentos puede sonar aterrador, pero es muy sencillo en realidad. Una vez que lo entiendes le encuentras mucha utilidad. Si te fijas, TODAS las funciones hechas por microsoft reciben parámetros por argumentos.

En este foro se suelen hacer preguntas directas al grano, ¿cómo hago tal cosa o tal otra cosa? Sin embargo, yo recomendaría hacer cursos o hacer preguntas teóricas, de simple curiosidad, y así es como se ira haciendo la luz al final del túnel. Con gusto te explicare cualquier concepto de programación en alguna duda que tengas en el futuro.

Si revisas mis respuestas encontraras unas pocas preguntas de este tipo, por ejemplo alguien una vez pregunto que eran los módulos de clase, otra persona pregunto que es mejor Range o Cells. Cosas así te van abriendo el entendimiento del lenguaje en general.

Respuesta
2

[Hola

Prueba así:

Private Sub UserForm_Initialize()
Dim UltimoValor As String
Dim x As Integer
UltimoValor = Cells(Rows.Count, 1).End(xlUp).Value
x = InStr(UltimoValor, "-")
num_consecutiu.Caption = Format(Val(Mid(UltimoValor, 1, x - 1)) + 1, "0000") & "-" & Year(Date)
End Sub

Una recomendación es tratar de entender los códigos que se te brinda, no solo copiar/pegar. Por cierto, en casos como el tuyo, una UDF no es necesaria.

Comentas

Abraham Valencia

Muchas gracias Abraham, me funciona correctamente. A medida de lo posible intento entender el código pero hay veces que es bastante complicado y no logro entenderlo al 100%.
Tu código funciona bien y es más fácil de interpretar y de leer, aunque he tenido que buscar un poco de información del Val y Mid para saber lo que son y hacen.
Muchas gracias de nuevo Abraham

Pues de nada.

Abraham Valencia

Respuesta
2

Ya tienes la solución que te ha dado Abraham, lo único que voy a decirte yo es que veas si es posible en lugar de tener el ID como 0000-año, pienses en tenerlo justamente al revés, ya que si tienes yyyy-0000

Simplemente lo puedes tener como números para que simplemente el siguiente sea el último más 1, algo más o menos así: 20190001, 20190002, etc y el guión se lo das con un formato de celdas: 0000"-"0000

Salu2

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas