FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Facturas con consecutivos con acceso a varias terminales
Posts: 141
Joined: Fri Feb 15, 2019 01:37 PM
Facturas con consecutivos con acceso a varias terminales
Posted: Thu Aug 26, 2021 10:58 AM

Buena como puede controlar uno, cuando varias personas intentan guardar una factura en el mismo instante en mysql o en sql. Intente con un contador en una tabla pero siempre se crea varias con el mismo numero cuando se intenta acceder al mismo tiempo desde 2 pc. Hay alguna forma o algun algoritmo para controlar eso y que se asignen consecutivos validos sin perder consecutivos en el camino?. Osea bloquear el registro, cuando el termine lib茅ralo, para que otro lo tome, sin perder el consecutivo.

Diciendo de otra forma, para que me entienda:
Estoy generando un consecutivo trayendo el 煤ltimo de la tabla y sumandole 1, el problema es que si se realiza la petici贸n mas de una vez al mismo tiempo, el c贸digo seria el mismo para las peticiones que se hagan.

Gracias por la atenci贸n prestada.

Adolfredo Martinez

Posts: 8515
Joined: Tue Dec 20, 2005 07:36 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Thu Aug 26, 2021 11:11 AM
Jo茫o Santos - S茫o Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Thu Aug 26, 2021 04:21 PM

Adolfredo:

No te sirve un campo auto incrementable para el n煤mero de folio? y
tal vez apoy谩ndote en una transacci贸n

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Thu Aug 26, 2021 05:22 PM
Code (fw): Select all Collapse
STATIC FUNCTION Cobr_Grabar( lNuevo )
   LOCAL lGrabado := FALSE
   LOCAL cWhere

   oServer:lThrowError := TRUE

   TRY

      oServer:BeginTransaction()

      IF lNuevo .and. ( nNumero := IncCount( "control", "cont_cobr" ) ) > 0
         oServer:Insert2( "cobradores", { { "num_cobr"  , nNumero    }, ;
                                          { "nombre"    , cNombre    }, ;
                                          { "cedula"    , cCedula    }, ;
                                          { "ciudad"    , cCiudad    }, ;
                                          { "direccion" , cDireccion }, ;
                                          { "telefonos" , cTelefonos }, ;
                                          { "fdi"       , dFechaI    }, ;
                                          { "activo"    , lActivo    }, ;
                                          { "fdr"       , dFechaR    }, ;
                                          { "nota"      , cNota      } } )
      ELSE
         cWhere := "num_cobr=" + Var2Str( nNumero )
         oServer:Update2( "cobradores", { { "nombre"    , cNombre    }, ;
                                          { "cedula"    , cCedula    }, ;
                                          { "ciudad"    , cCiudad    }, ;
                                          { "direccion" , cDireccion }, ;
                                          { "telefonos" , cTelefonos }, ;
                                          { "fdi"       , dFechaI    }, ;
                                          { "activo"    , lActivo    }, ;
                                          { "fdr"       , dFechaR    }, ;
                                          { "nota"      , cNota      } }, cWhere )
      ENDIF

      oServer:Commit()
      oQryCobr:Refresh()
      lGrabado := TRUE

   CATCH oError
      ShowError( oError )
      oServer:Rollback()
   END

   oServer:lThrowError := FALSE

   IF lGrabado
      IIf( lNuevo, ( oBrw:GoBottom(), oBrw:Refresh() ), oBrw:RefreshCurrent() )
   ELSE
      oBrw:GoTop()
   ENDIF

RETURN lGrabado



Code (fw): Select all Collapse
FUNCTION IncCount( cTable, cField )
   LOCAL oQryTmp
   LOCAL nCount := 0

   oQryTmp := oServer:Query( "SELECT " + cField + " FROM " + cTable + " FOR UPDATE" )

   IF oQryTmp:RecCount() >= 0
      nCount := oQryTmp:FieldGet( 1 ) + 1
      oServer:Execute( "UPDATE " + cTable + " SET " + cField + " = " + Var2Str( nCount ) )
   ENDIF

   oQryTmp:End()

RETURN nCount



CREATE TABLE `control` (
`cont_usua` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`cont_ruta` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`cont_cobr` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`cont_clie` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`cont_pres` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`cont_abon` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`cont_docu` BIGINT(10) UNSIGNED NOT NULL DEFAULT '0',
`my_recno` BIGINT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`my_recno`) USING BTREE
)
COLLATE='latin1_spanish_ci'
ENGINE=InnoDB
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 141
Joined: Fri Feb 15, 2019 01:37 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Fri Aug 27, 2021 12:06 AM

Gracias por responder.

Carlos Vargas, gracias por esa l铆neas de c贸digo, me pondr茅 a la mano, les avisare como me fue.

Posts: 141
Joined: Fri Feb 15, 2019 01:37 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Sat Sep 04, 2021 09:47 PM

Con el ejemplo de Carlos, logre solucionar el problema del consecutivo de la factura. Pero tengo otra inquietud:

Como logro si dos terminales la A: esta insertando o borrando Facturas del cliente 100. Pero en la terminal B: selecciono el mismo cliente pero haciendo otra actividad ya sea borrando una factura o modific谩ndola. Como logro bloquear el terminal B, hasta que termine la terminal A. mando le un mensaje que esta ocupada por otro usuario. Para cuando entra la terminal B, ya encuentre la modificacion hecha por la terminal A.

Posts: 346
Joined: Mon Oct 05, 2009 03:35 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Wed Sep 08, 2021 01:47 PM
Estimado:

lo que yo utilizo en SQL es un campo l贸gico (0-1) como una bandera, terminal A: toma el registro y le cambio el estado a ese campo inmediatamente a 0 (ocupado) y cuando termino los cambios realizados en el registro le devuelvo el estado 1 (Activo), entonces en la terminal B verifica el estado de este campo antes de hacer cualquier cosa en el registro.

lo otro es realizar procedimiento almacenado en la base de datos estableciendo SET TRANSACTION ISOLATION LEVEL READ COMMITTED que es lo que permite bloquear temporalmente registros en una base de datos SQL

busca en internet como utilizarlo hay varios LEVEL para analizar y utilizar

Espero que te sirva

Saludos
SkyPe: armando.lagunas@hotmail.com

Mail: armando.lagunas@gmail.com
Posts: 141
Joined: Fri Feb 15, 2019 01:37 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Wed Sep 08, 2021 05:42 PM

Gracias Armando.

Me pondr茅 mano a la obra, soy nuevo en esto de Mysql, gracias algunos amigos del f贸rum, he salido adelante.

Posts: 851
Joined: Sun Nov 09, 2014 05:01 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Wed Sep 08, 2021 10:31 PM
Saludos Adolfredo.

Yo lo hago asi y nunca he tenido problemas. Funciona con cualquier numero de estaciones en la red.

Code (fw): Select all Collapse
聽 聽 聽 cTabla:= _cPrefijo+'_docventa' 聽//nombre de tu tabla


聽 聽 聽 cQuery:=''
聽 聽 聽 cQuery:="SELECT * FROM "+ cTabla 聽+ " FOR UPDATE; " 聽// seleccionamos el UNICO registro de la tabla con la clausula FOR UPDATE
聽 聽 聽 oQuery:= _oSqlConex:Query( cQuery ) 聽 聽 聽 聽 聽 聽聽 聽 聽聽// este "FOR UPDATE" hace un bloqueo y ninguna otra estacion puede accesar 
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽// mientras se 聽realiza la operacion de sumar uno al consecutivo y tomarlo
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 // en variable de memoria

聽 聽 聽 nNumeroFactura:=oQuery:numero_factura+1 聽 聽 聽 聽 聽聽聽 聽// Sumamos 1 al valor del contador guardado en la tabla 聽 聽 聽 聽 

聽 聽 聽 cQuery:=''
聽 聽 聽 cQuery:="Update "+cTabla+" Set " 聽 聽 聽 聽 聽 聽 聽 聽聽 聽聽// aqui actualizamos el valor del campo en la tabla ya incrmentado en 1
聽 聽 聽 cQuery+="numero_factura:="+alltrim(str(nNumeroFactura))+"; "

聽 聽 聽 _oSqlConex:Execute( cQuery 聽 聽)
聽 聽 聽 聽
聽 聽 聽 _oSqlConex:End 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽 聽 聽 聽 聽聽 聽聽 // al cerrar la conexcion, se libera el registro para los demas usuarios.


La clausula FOR UPDATE es la que hace toda la magia. Por supuesto, siempre debes hacer el SELECT primero.
En mi caso uso una tabla con un solo registro por eso el SELECT no lleva un WHERE, puedes adaptarlo a tu situacion.
"Los errores en programaci贸n, siempre est谩n entre la silla y el teclado..."



Fwh 19.06 32 bits + Harbour 3.2 + Borland 7.4 + MariaDB + TDolphin



Carora, Estado Lara, Venezuela.
Posts: 244
Joined: Fri Oct 28, 2005 06:29 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Thu Sep 09, 2021 12:47 PM
Hola Jose

Queria hacerte una pregunta porque me dejaste con dudas:


聽 聽 _oSqlConex:End 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽 聽 聽 聽 聽聽 聽聽 // al cerrar la conexcion, se libera el registro para los demas usuarios.


El registro se libera al cerrar _oSqlConex o al cerrar oQuery ???

Porque si tuvieras que cerrar la _oSqlConex deberias volver a reconectarte a cada rato para poder seguir trabajando.


Muchos saludos
Alejandro
Alejandro Cebolido

Buenos Aires, Argentina
Posts: 851
Joined: Sun Nov 09, 2014 05:01 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Thu Sep 09, 2021 07:02 PM

Saludos alejandro.

Hago mis sistemas para que puedan trabajar con datos hospedados tanto local como Remoto (en la nube).
Por eso mi filosofia de trabajo es:

1.- conectar
2.- consultar/actualizar
3.- desconectar

Localmente puedes tener una conexion con MYSQL largo rato o puedes configurarlo para eso, pero remotamente (en la nube) el servidor te desconecta a los 30seg. de inactividad. Por lo menos en el servidor que yo uso (hostgator).

Por eso conecto y desconecto a cada rato sin importar si estoy trabajando en cualquiera de las formas. Mis sistemas asi quedan listos para trabajar local o remoto y se configura al momento de instalarlos.

Cuando voy a hacer varias actualizaciones las hago con transacciones y alli conecto y desconecto solo una vez, ya que mientras se ejecutan las operaciones el servidor se mantiene activo.

Cuando utilizas FOR UPDATE se libera el registro al cerrar la conexcion, o al realizar un COMMIT en el caso de usar transacciones.

Disculpen por no haber colocado un ejemplo menos personalizado.
Gracias por la observacion.

Un Abrazo.

"Los errores en programaci贸n, siempre est谩n entre la silla y el teclado..."



Fwh 19.06 32 bits + Harbour 3.2 + Borland 7.4 + MariaDB + TDolphin



Carora, Estado Lara, Venezuela.
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Fri Sep 10, 2021 04:31 PM

Alejandro,
La idea es, si en lugar de cerrar la conexion, utilizas transacciones
al realizar el commit o el rollback, se libera el registro seleccionado con el SELECT ... FOR UPDATE...

salu2
carlos vargas

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Mon Sep 13, 2021 11:56 AM
armando.lagunas wrote:Estimado:

lo que yo utilizo en SQL es un campo l贸gico (0-1) como una bandera, terminal A: toma el registro y le cambio el estado a ese campo inmediatamente a 0 (ocupado) y cuando termino los cambios realizados en el registro le devuelvo el estado 1 (Activo), entonces en la terminal B verifica el estado de este campo antes de hacer cualquier cosa en el registro.

lo otro es realizar procedimiento almacenado en la base de datos estableciendo SET TRANSACTION ISOLATION LEVEL READ COMMITTED que es lo que permite bloquear temporalmente registros en una base de datos SQL

busca en internet como utilizarlo hay varios LEVEL para analizar y utilizar

Espero que te sirva

Saludos

Hola Armando.
Este tema siempre me ha intrigado y a veces me pongo a buscar info pero nunca llego a buen puerto. En tu caso lo tienes bien controlado ya que modificas la tabla. No me gusta mucho tener que modificar la estructura de datos para este fin pero se podr铆a aceptar como soluci贸n. Pero me surge una duda, si el terminal A toma el registro, cambias la bandera a 1 y se cierra el programa sin pasar por el proceso de guardar la ficha, que haces? por ejemplo se puede apagar el ordenador, error de ejecuci贸n, etc...

aqu铆 hay una buena charla que tuvimos hace meses al respecto: https://forum.modharbour.app/viewtopic.php?f=25&t=259
--------

驴 Y porque no ?

驴 And why not ?
Posts: 851
Joined: Sun Nov 09, 2014 05:01 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Mon Sep 13, 2021 04:06 PM
VictorCasajuana wrote:
armando.lagunas wrote:Estimado:

lo que yo utilizo en SQL es un campo l贸gico (0-1) como una bandera, terminal A: toma el registro y le cambio el estado a ese campo inmediatamente a 0 (ocupado) y cuando termino los cambios realizados en el registro le devuelvo el estado 1 (Activo), entonces en la terminal B verifica el estado de este campo antes de hacer cualquier cosa en el registro.

lo otro es realizar procedimiento almacenado en la base de datos estableciendo SET TRANSACTION ISOLATION LEVEL READ COMMITTED que es lo que permite bloquear temporalmente registros en una base de datos SQL

busca en internet como utilizarlo hay varios LEVEL para analizar y utilizar

Espero que te sirva

Saludos

Hola Armando.
Este tema siempre me ha intrigado y a veces me pongo a buscar info pero nunca llego a buen puerto. En tu caso lo tienes bien controlado ya que modificas la tabla. No me gusta mucho tener que modificar la estructura de datos para este fin pero se podr铆a aceptar como soluci贸n. Pero me surge una duda, si el terminal A toma el registro, cambias la bandera a 1 y se cierra el programa sin pasar por el proceso de guardar la ficha, que haces? por ejemplo se puede apagar el ordenador, error de ejecuci贸n, etc...

aqu铆 hay una buena charla que tuvimos hace meses al respecto: https://forum.modharbour.app/viewtopic.php?f=25&t=259


Hola Victor, saludos.

Veo que el tema es recurrente, por lo que me tome el tiempo para hacer dos ejemplos sencillos que a mi me han funcionado muy bien. Jamas he tenido problema con mis sistemas en este aspecto.

Lo primero es aclarar que toda la magia la hace la instruccion SELECT.. FOR UPDATE... y esto significa 3 cosas:

1.- Siempre hay que hacer un SELECT... FOR UPDATE previo al UPDATE ... SET eso es lo que nos va a bloquear el registro seleccionado.
sin permitir que nadie mas tenga acceso a el.

2.- Para que SELECT... FOR UPDATE funcione debemos tener el AUTOCOMMIT en 0 (OFF o FALSE) segun la version de mysql o mariadb.
si no se desea tener configurado de manera permanente, se puede activar o desactivar mientras hacemos la operacion.

3.- En caso de no querer usar el AUTOCOMMIT, la otra opcion mas comoda y tambien valida, es usar una transaccion. El caso o gusto particular de cada quien indicara
cual sistema usar, si AUTOCOMMIT o TRANSACCION.

Aca dejo los ejemplos:

USANDO AUTOCOMMIT

Code (fw): Select all Collapse
# include FIVEWIN.CH

Function Fnct_Prueba()

聽 聽Local oQuery, cQuery, cTabla
聽 聽Local nNuevoNumero
聽 聽
聽聽 _oSqlConex:=TDolphinSrv():New( _cHost, _cUser, _cPasswordUser,,, _cDataBase,bSQLCnxErr() ) 聽// mis variables de conexion son publicas. 
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽聽 聽// cada quien debe manejar esta parte
聽 聽if 聽_oSqlConex:lError 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽聽 聽 // segun su forma de trabajar.
聽 聽 聽 _oSqlConex:End()
聽 聽 聽 return .f.
聽 聽endif
聽 聽 
聽 聽cQuery := "SET AUTOCOMMIT=0 ; " 聽 聽 聽 聽 聽 聽 聽 聽 聽 // colocamos el AUTOCOMMIT temporalmente en 0 (desactivado)
聽 聽oQuery := _oSqlConex:Execute( cQuery 聽 聽) 聽 聽 聽 聽 // de esta forma AUTOCOMMIT funciona solo con la sesion actual
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽 聽 聽 聽 聽 聽 // en caso de que no este configurado por defecto
聽 聽 聽
聽 聽cTabla := _cPrefijo+'_docventatemp'
聽 聽 
聽 聽cQuery := ''
聽 聽cQuery := "SELECT numerotemp_documento FROM "+ cTabla +" FOR UPDATE ; " 聽 // hacemos el SELECT... FOR UPDATE para bloquear la fila de
聽 聽oQuery := _oSqlConex:Query( cQuery ) 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽// 聽la tabla
聽 聽 
聽 聽nNuevoNumero:=oQuery:numerotemp_documento+1 聽 聽// aumentamos en 1 el contador consecutivo
聽 聽
聽聽 cQuery :=''
聽 聽cQuery :="Update "+cTabla+" Set "
聽 聽cQuery +="numerotemp_documento:="+alltrim(str(nNuevoNumero))+" ; " 聽 聽 聽聽// actualizamos la tabla
聽 聽_oSqlConex:Execute( cQuery 聽)
聽 聽 
聽 聽//msginfo('Stop') 聽 聽// activar si se desea chequear la tabla con phpmyadmin, heidi, navicat, etc. durante el proceso.
聽 聽
聽 聽cQuery:="commit ; " 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽聽 聽 // hacemos commit para actualizar la tabla.
聽 聽oQuery:= _oSqlConex:Execute( cQuery 聽 聽 ) 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 
聽 聽cQuery := "SET AUTOCOMMIT=1 ; " 聽 聽 聽 聽 聽 聽 聽 聽 聽聽// Colocamos el autocommit de nuevo a su estado activo 聽 聽 聽 聽 聽
聽 聽oQuery := _oSqlConex:Execute( cQuery 聽 聽) 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽
聽 聽 _oSqlConex:End() 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽// cerramos la conexion

return nNuevoNumero 聽 聽 // nNuevoNumero es el numero asignado a la nueva factura que estamos emitiendo ...



Usando Transacciones

Code (fw): Select all Collapse
# include FIVEWIN.CH

Function Fnct_Prueba()

聽 Local oQuery, cQuery, cTabla
聽 Local nNuevoNumero

聽 _oSqlConex:=TDolphinSrv():New( _cHost, _cUser, _cPasswordUser,,, _cDataBase,bSQLCnxErr() ) 聽// mis variables de conexion son publicas. 聽
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽// cada quien debe manejar esta parte 聽
聽 if _oSqlConex:lError 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 聽 聽 聽 // segun su forma de trabajar.
聽 聽 _oSqlConex:End()
聽 聽 return .f.
聽 endif
聽 聽
聽 _oSqlConex:BeginTransaction() 聽 聽 // comenzamos la transaccion
聽 聽 聽
聽 cTabla := _cPrefijo+'_docventatemp'

聽 cQuery := ''
聽 cQuery := "SELECT numerotemp_documento FROM "+ cTabla +" FOR UPDATE ; " 聽 // hacemos el SELECT... FOR UPDATE para bloquear la fila de
聽 oQuery := _oSqlConex:Query( cQuery ) 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽聽 // 聽la tabla
聽 聽 聽 聽 聽 聽
聽聽nNuevoNumero:=oQuery:numerotemp_documento+1 聽 聽 // aumentamos en 1 el contador consecutivo
聽 聽
聽聽cQuery :=''
聽 cQuery :="Update "+cTabla+" Set "
聽 cQuery +="numerotemp_documento:="+alltrim(str(nNuevoNumero))+" ; " 聽 聽 聽 // actualizamos la tabla 聽 聽 聽
聽 _oSqlConex:Execute( cQuery 聽)
聽 聽
聽 //msginfo('Stop') 聽 聽// activar si se desea chequear durante el proceso.
聽 聽
聽 _oSqlConex:CommitTransaction()

聽 _oSqlConex:End() 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 // cerramos la conexion


return nNuevoNumero 聽 聽 // nNuevoNumero es el numero asignado a la nueva factura que estamos emitiendo ...


En ambos casos, el registro se libera al ejecutarse el COMMIT.

Esto es solo una idea de como lo hago, cada quien puede adaptarlo a su modo.

Espero haber ayudado. Quizas algun colega le consiga fallas o pueda sugerir mejoras. Todo es bienvenido. Pero como comento, jamas he tenido problemas con esta manera de obtener consecutivos sin que se repitan, no importa el numero de estaciones que accesen al mismo tiempo la tabla.
"Los errores en programaci贸n, siempre est谩n entre la silla y el teclado..."



Fwh 19.06 32 bits + Harbour 3.2 + Borland 7.4 + MariaDB + TDolphin



Carora, Estado Lara, Venezuela.
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Facturas con consecutivos con acceso a varias terminales
Posted: Tue Sep 14, 2021 06:28 AM

Vale, me hab铆a confundido. Pensaba que el bloqueo que comentabas al principio ( 0 en el campo l贸gico ) lo utilizabas cuando un usuario, por ejemplo, abr铆a una ficha para modificar los datos, para que el resto de usuarios no pudiesen modificar dicha ficha o al menos saber de su edici贸n por otro usuario.
Lo que expones es correcto, pero ya es a nivel de transacciones dentro de un proceso autom谩tico el cual no est谩 controlado por el usuario.

--------

驴 Y porque no ?

驴 And why not ?