Numeros consecutivos

934 views
Skip to first unread message

Marcelo Barberis

unread,
Feb 1, 2013, 1:22:18 PM2/1/13
to publicesvfoxpro
Estimados señores
Queria consultarles como puedo hacer para generar un id consecutivo en un campo de tipo caracter.
de esta forma: SECTOR0001, SECTOR0002, SECTOR0003...
Si tengo por ej 3 registros y elimino 1 por decirle SECTOR0002, entonces tendria 2 registros, SECTOR0001, SECTOR0003 y el proximo seria SECTOR003 en ese caso como podria hacer esa verificacion para que no me repita el codigo.
De antemano gracias por cualquier comentario al respecto.

--
Ing. Marcelo Barberis Gutierrez
Sistemas Informaticos Inc
Villa Montes - Bolivia
Telef.: +591-76831064

Antonio.xt

unread,
Feb 1, 2013, 1:29:36 PM2/1/13
to publice...@googlegroups.com

Hay de 2 maneras.

1) Obtener el mayor del numero de la clave, por ejemplo: MAX(RIGHT(clave,4)) y al resultado le agregas 1, aunque aqui esta el riesgo de que elimines el ultimo y te va a volver a generar el mismo numero.

2) Guardar el consecutivo en una tabla creada exclusivamente para esos numeros, y cada vez que realices un alta le asignas a tu clave el valor del campo de esa tabla, y al terminar guardas ese valor +1

Saludos...

Ricardo Pina

unread,
Feb 1, 2013, 1:30:22 PM2/1/13
to Grupo VFP
Hola Marcelo
 
Puedes guardar en otra tabla el último número utilizado, o sino ir al ultimo registro y recuperar el último número y en ambos casos sumarle uno
 
Saludos
 
--
            

                   Ricardo Pina

Desarrollo y Servicios Informáticos

                  Profesionales
               www.dsip.com.ar

 

 

Irwin Rodriguez

unread,
Feb 1, 2013, 1:33:16 PM2/1/13
to publice...@googlegroups.com
Hola Marcelo, adjunto una rutina que suelo usar para generar los códigos correlativos.

Espero te sirva de algo.

Saludos!!!
--
Ing. Irwin Rodríguez
Consultor Informático
0412-521.06.79
 

Antes de imprimir este documento piense bien si es necesario hacerlo, el árbol que servirá para hacer el papel tardará 7 años en crecer. 

 
NOTA: La información mostrada en este mensaje es de caracter Confidencial y está dirigida unicamente a los contactos señalados en el encabezado; si el lector de este correo no es el destinatario del mismo, se le notifica que cualquier copia o distribución queda totalmente prohibida. Si usted ha recibido este mensaje por error, por favor notifique inmediatamente al remitente por este mismo medio y bórrelo de su sistema.
gencodalf.prg

Luis Maria Guayan

unread,
Feb 1, 2013, 1:38:35 PM2/1/13
to publice...@googlegroups.com
Mira estas 2 opciones:

1. Buscas el máximo valor en la tabla y le incrementas 1 (si eliminaste el
SECTOR0002 no hay problema porque el máximo es SECTOR0003 y el siguiente le incremento 1 y sería SECTOR0004)

2. Mira este artículo de PortalFox que tiene una técnica simple y funcional:

-- Números consecutivos para nuestras tablas --
http://www.portalfox.com/article.php?sid=1466


Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

Marcelo Barberis

unread,
Feb 1, 2013, 11:10:24 PM2/1/13
to publicesvfoxpro
Bueno gracias por sus comentarios y algo queria poner como aclaratoria y por que no uso la forma de crear una rutina de numeros consecutivos de la forma que lo exponen en portalfox debido a que esa forma estaria bien si todos los ID o codigo seria solo con numeros ej 00001, 00002 y el cual lo pondria como un procedimiento almacenado en la BD, en mi caso cada tabla le tengo que poner un identificativo y despues van los numeros, ej. SECTOR0001, SECTOR0002..., DIAGNOS001, DIAGNOS002..., VETER001, VETER002... y asi hay varias tablas que le pongo su identificativo y tambien asi me sugirieron mis jefes los que pagan.
En el otro tema que me estaba mareando era si tengo en mi tabla 3 registros total, ej SECTOR001, SECTOR002, SECTOR003, por ahi tengo que borrar un registro SECTOR002, en este caso mi tabla tendria 2 registros, y por logica haria contar todos los registros y ese numero le agregaria la palabra SECTOR y se me vino que cuando genere el siguiente codigo seria SECTOR003 y me estaria repitiendo de nuevo el codigo.
Bueno eso era mi inquietud

FidelJ

unread,
Feb 2, 2013, 7:10:47 AM2/2/13
to publice...@googlegroups.com
Puedes utilizar el procedimiento de PortalFox (L.M.Guayán) modificando la tabla propuesta. Le agregas un campo "prefijo" y cuando traes el valor 
RETURN ALLTRIM(PREFIJO)+Padl(LTrim(str(numero+1)),nEspacios,"0").

CREATE TABLE ADDBS(Ruta)+"NUMDORES" FREE ;
("IDOPER" C(3),;  && Codigo interno de operacion
"TABLA" C(20),;   && nombre de la tabla controladora
"PREFIJO" C(10),; && prefijo
"TIPO" C(1),;          && "C" Caracter, "N" numérico (tipo de numerador)
"CAMPO" C(10),;   && Campo de la tabla que contiene el ID
"ESPACIOS" N(2))  && Cantidad de caracteres que tiene el ID 
SELECT NUMDORES
INDEX ON IDOPER+PREFIJO TAG INUMDORES

El campo idoper permite que una misma tabla controle varios numeradores, donde la variante es el prefijo.
Por ejemplo, una tabla de facturas, en Argentina, tiene numeradores por punto de venta y código de comprobante ("01","06" etc). La tabla de cabeceras de facturas debe controlar tantos numeradores como combinaciones haya de Código de comprobante y punto de emisión.
Por ejemplo, el IDOPER para facturas "A", podrías ser "F01" y para facturas "B" "F06". Para cada IDOPER pueden existir hasta 9998 prefijos (numeradores), que corresponden al punto de emisión del comprobante.

El campo prefijo contendrá las descripciones SECTOR,DIAGNO,VETER ó nada. 

Supongamos una función que se llama Numere(), la convocatoria sería Numere(cIdoper+cPrefijo,.T.), y la rutina Numere() busca el primer parámetro en la tabla y devuelve el número incrementado en 1: Si el segundo parámetro es .T. guarda el nuevo valor (solicitud en el momento en que se graba la operación). Si el segundo parámetro es .F., no guarda el nuevo valor (lo tomo al principio de una operación, a modo orientativo).
eJ 
APPEND BLANK
Replace CODOPER WITH Numere("RST"+"SECTOR",.T.) ...  Suponiendo que "RST" es un IDOPER 
APPEND BLANK
Replace CODOPER WITH Numere("RST"+"DIAGNO",.T.) ...

El fundamento es exactamente el mismo que el publicado por L.M.G., atendiendo a algunas particularidades.

En la instalación ó mantenimiento, el sistema debe tener la rutina que rellena la tabla de numeradores,
En el mantenimiento puedes poner una rutina de reconstrucción de numeradores (total o parcial). 

Antonio.xt

unread,
Feb 2, 2013, 9:29:44 AM2/2/13
to publice...@googlegroups.com

Marcelo, no hay problema en usar para eso la rutina de PortalFox, ya que con eso consigues el siguiente numero y tu solo le agregas el prefijo o indicativo, por ejemplo "SECTOR", "DIAGNOS" o "VETER", segun sea el caso.

Ejemplo

lsIndicativo = "SECTOR"
lnNumeroSig = FuncionDePortalFox(lsIndicativo)
lsClave = lsIndicativo + PADL(ALLT(STR(lnNumeroSig)),4,"0")

Luis la Romana

unread,
Feb 2, 2013, 12:34:03 PM2/2/13
to publice...@googlegroups.com
Con esto yo creo una numeración alfanumérica,

ca=1100
dato=""
scan
  dato="0"+alltrim(str(ca))
  repla codclie with dato
  ca=ca+1 
endscan 

Dentro del scan podés meter una condicionante de repla si no existe.

Marcelo Barberis

unread,
Feb 3, 2013, 12:04:55 AM2/3/13
to publicesvfoxpro
Bueno deseo agradecerles por los comentarios que hicieron para resolver este tema, lo que hice es si utilizar el procedimiento que exponen en portalfox utilizando el procedimiento de Antonio.xt con unas lineas que aumente y resolvio el tema, y al final quedo asi.

lsIndicativo = "TSECTOR"
lnNumeroSig = nuevoID(lsIndicativo)
xntabla = 'SECTOR'
n = LEN(ALLTRIM(xntabla))
ntot = 10 - n
lsClave = xntabla + PADL(ALLT(STR(lnNumeroSig)),ntot,"0")
MESSAGEBOX(lsClave)

En este caso tengo un campo codsector en la tabla tsector que tiene una longitud de 10, por lo que recurri a contar la cantidad de letras que tiene el prefijo SECTOR y a eso le restaba la longitud del campo y eso lo pongo en la variable ntot.
Gracias por sus comentarios a todos.

HernanCano

unread,
Feb 3, 2013, 12:22:59 AM2/3/13
to publice...@googlegroups.com

>>> ej SECTOR001, SECTOR002, SECTOR003, .... y se me vino que cuando genere el siguiente codigo seria SECTOR003.

Dos veces lo dices y sinceramente no sé por qué lo dices.

Si ya existe el 003, el que sigue el el 004. ¿Cierto que después del tres está el cuatro?
No creo que deba explicarte por qué (matemáticamente hablando después del tres va el cuatro). Y si de tus datos hablamos, creo que es lo mismo: después del tres sigue el cuatro. Sinceramente no veo por qué sea diferente.


**** Alternativa **********
M.cPrefijo = "SECTOR"
select SECTORES
calculate max(CODSECTOR) to M.Ultimo

M.NumUltimo = substr(M.Ultimo,len(M.cPrefijo)+1)

M.SigUltimo = M.cPrefijo + padl(alltrim(str(val(M.NumUltimo)+1)),len(M.NumUltimo),"0")
********************************

¿Observas cómo te propongo obtener el último actualmente grabado?
Tip: el comando CALCULATE con su función MAX propia.
¿Se ajusta a tu necesidad?

Marcelo Barberis

unread,
Feb 3, 2013, 5:27:25 AM2/3/13
to publicesvfoxpro
Estimado amigo Hernan Cano
Gracias por tus comentarios y esta claro tu alternativa y esta perfecta para lo que tiene que hacer y te agradesco mucho tu interes al respecto y por colaborarme.
Bueno lo que intentaba mas o menos hacer notar era lo siguiente, yo tenia 3 registros con estos codigos SECTOR001, SECTOR002, SECTOR003 y ponia el caso que si yo eliminaba un registro el SECTOR002, entonces en mi tabla iba a tener 2 registros, SECTOR001, SECTOR003, lo que yo hacia es contar la cantidad de registros y lo llevaba a un variable, en este caso contando los registros la variable me daba 2, ahora a ese 2 le sumo 1 y me da 3 y teniendo este valor le agregaba SECTOR00 y me quedaba SECTOR003 y coincidia con el codigo que ya tenia ya guardado, bueno esa era mi inquietud al respecto, pero de todas manera con la ayuda y colaboracion de ustedes pude solucionar el tema.
Desde ya agradecido por sus aportes.

Claudio Luna

unread,
Feb 3, 2013, 1:33:45 PM2/3/13
to Comunidad de Visual Foxpro en Español
Marcelo,
Por lo que he leído en tu último post, queres evitar "huecos" en la numeración pero si queres  dar de baja los registros, se te va hacer muy difícil porque tendrías que renumerar desde el registro que borraste para adelante, se me ocurre lo más sencillo para evitar huecos en tu numeración es que pongas un campo lógico de Activo ="A" -activo y "B". BAJA, cuando lo das de baja cambias este campo.
Saludos
Claudio

HernanCano

unread,
Feb 3, 2013, 5:58:45 PM2/3/13
to publice...@googlegroups.com

Lo lamento, Claudio, pero la cosa no va por ahí.
Gracias por aportar.

mpulla

unread,
Feb 3, 2013, 10:53:56 PM2/3/13
to publice...@googlegroups.com

Hola Marcelo.

Haciendo unas pequeñas adaptaciones al código de portalfox, quedo así (faltan un par de validaciones pero si te sirve te toca implementarlas), pruébalo y nos comentas.

Saludos.
Mauricio

CREATE TABLE Ids ;
  (cTabla C(30) NOT NULL, ;
  nId I NOT NULL)
INDEX ON UPPER(cTabla) TAG cTabla


FUNCTION NuevoID(tcAlias, tiLen)
  LOCAL lcAlias, lnId, lnAreaAnt, lcReprAnt
  lnId = 0
  lnAreaAnt = SELECT()
  lcReprAnt = SET('REPROCESS')
  SET REPROCESS TO AUTOMATIC
  lcAlias = UPPER(ALLTRIM(tcAlias))
  IF NOT USED("Ids")
    USE Ids IN 0
  ENDIF
  SELECT Ids
  IF SEEK(lcAlias, "Ids", "cTabla")
    IF RLOCK()
      REPLACE nId WITH nId + 1 IN Ids
      lnID = Ids.nId
      UNLOCK
    ENDIF
  ELSE
      INSERT INTO Ids Values(lcAlias, 1)
    lnID = 1
  ENDIF
  SELECT (lnAreaAnt)
  SET REPROCESS TO lcReprAnt
  RETURN tcAlias + RIGHT('0000000000' + TRANSFORM(lnID), tiLen - LEN(tcAlias))
ENDFUNC

MESSAGEBOX(NuevoID('VETER', 10))

Marcelo Barberis

unread,
Feb 4, 2013, 7:33:59 AM2/4/13
to publicesvfoxpro
gracias por tu aporte.


2013/2/3 mpulla <jmaur...@yahoo.es>

Douglas Sánchez

unread,
Feb 4, 2013, 11:50:19 AM2/4/13
to publice...@googlegroups.com
Hola Marcelo, si te sirve de algo aca esta otra funcion, para numerar y que no tomar en cuenta los eliminados.

Function FINDCODBAR
*** ESTA FUNCION ENUMERA LOS CODIGO DE BARRIOS EN MANTENIMIENTO A CATALOGOS
Dimension WCOD(1, 1)
Select Max(CODBAR) From TblBarrios where !deleted() Into Array WCOD
If Type("WCOD") = "C"
    WCOD = Padl(Int(Val(WCOD))+1,3,"0")
Else
    WCOD = "001"
Endif
Set Deleted On
Return WCOD
Endfunc

Si la usas es
tunumero = findcodbar() e incluso lo podes poner en una tabla, al hacer

user tutabla luego
modi stru donde dice

Field validacion

default value: findcodbar()   && claro esto lo tenes que tener en set procedure tus_rutinas.prg

funciona si usas las tablas nativas de vfp.  

Saludes





2013/2/4 Marcelo Barberis <alexm...@gmail.com>



--
Ing. Douglas Sánchez Guillén
      Consultor Informatico
Claro: 505 88495476

Marcelo Barberis

unread,
Feb 4, 2013, 12:47:34 PM2/4/13
to publicesvfoxpro
Gracias por tu aporte, voy a tomarlo en cuenta.


2013/2/4 Douglas Sánchez <dougl...@gmail.com>
Reply all
Reply to author
Forward
0 new messages