9 de febrero de 2016

Desglose de billetes y monedas

Esta utilidad sirve para determinar la cantidad de billetes y monedas para el pago de salarios.

Partimos de dos tablas:

1. Una tabla con la denominación y el valor de los billetes y monedas disponibles. Esta tabla puede variar de acuerdo a los billetes y monedas disponibles en cada país o en el momento de efectuar el pago.

2. Una tabla con el listado de los nombres ó legajos y el importe a percibir.

Al principio del siguiente código se crean las dos tablas: "Cambio" con los valores disponibles, y "Sueldos" con los legajos e importes aleatorios.

Luego se recorre la tabla "Cambio" ordenada por el campo Valor en forma descendente (esto es premisa fundamental para el cálculo) y se crea una sentencia SELECT ... por cada valor, que añade una nueva columna por cada ciclo.
*-- Creo tabla de Billetes y Monedas disponibles
CREATE TABLE Cambio (Codigo C(8), Valor N(10,2))
INDEX ON Valor TAG Valor Descending
INSERT INTO Cambio (Codigo, Valor) VALUES ("B_100", 100)
INSERT INTO Cambio (Codigo, Valor) VALUES ("B_50", 50)
INSERT INTO Cambio (Codigo, Valor) VALUES ("B_20", 20)
INSERT INTO Cambio (Codigo, Valor) VALUES ("B_10", 10)
INSERT INTO Cambio (Codigo, Valor) VALUES ("B_5", 5)
INSERT INTO Cambio (Codigo, Valor) VALUES ("B_2", 2)
INSERT INTO Cambio (Codigo, Valor) VALUES ("M_1", 1)
INSERT INTO Cambio (Codigo, Valor) VALUES ("M_050", 0.50)
INSERT INTO Cambio (Codigo, Valor) VALUES ("M_025", 0.25)
INSERT INTO Cambio (Codigo, Valor) VALUES ("M_010", 0.10)
INSERT INTO Cambio (Codigo, Valor) VALUES ("M_005", 0.05)
INSERT INTO Cambio (Codigo, Valor) VALUES ("M_001", 0.01)

*-- Creo tabla de Sueldos (Salarios)
LOCAL ln
CREATE TABLE Sueldos (Legajo C(6), Importe N(12,2))
FOR ln = 1010 TO 1500 STEP 10
 INSERT INTO Sueldos (Legajo, Importe) VALUES (PADL(ln,6,"0"), RAND()*5000)
ENDFOR

*-- Begin
LOCAL lcSetPoint, llPrimeraVez, lcDeno, lcVal, lcSQL
 
lcSetPoint = SET("POINT")
llPrimeraVez = .T.
lcDeno = ""
lcVal = ""

*-- Creo cursor de resultados
SELECT Legajo, Importe FROM Sueldos INTO CURSOR Result

*-- Recorro tabla de Cambio
SET POINT TO "."
SELECT Cambio
SCAN ALL
  IF llPrimeraVez
    SELECT Legajo, Importe FROM Result INTO CURSOR Auxi
  ELSE
    lcSQL = [SELECT Result.Legajo, Auxi.Importe - ] + ;
      lcDeno + [*] + lcVal + [ AS Importe ] + ;
      [FROM Result ] + ;
      [INNER JOIN Auxi ON Result.Legajo = Auxi.Legajo ] + ;
      [INTO CURSOR Auxi]
    &lcSQL
  ENDIF
  lcSQL = [SELECT Result.*, ] + ;
    [INT(Auxi.Importe/] + ALLTRIM(STR(Cambio.Valor,10,2)) + ;
    [) AS ] + ALLTRIM(Cambio.Codigo) + ;
    [ FROM Result ] + ;
    [INNER JOIN Auxi ON Result.Legajo = Auxi.Legajo ] + ;
    [INTO CURSOR Result]
  &lcSQL
  lcDeno = ALLTRIM(Cambio.Codigo)
  lcVal = ALLTRIM(STR(Cambio.Valor,10,2))
  llPrimeraVez = .F.
ENDSCAN
SET POINT TO (lcSetPoint)

*-- Muestro cursor final de resultados
SELECT Result
BROWSE  

*-- End
Luis María Guayán

3 comentarios :

  1. Genial!! Ese lo programé yo hace 16 años... no lo tengo más, era fox 2.6. pero recuerdo que era muuuucho más largo. Lo mismo me pasó con el número y letra... los mios son largos...me falta sintetiza jajaja
    Gracias :). Aquí en méxico de obligó a pagar por transferencia bancaria... hace tiempo que ya no me piden algo parecido

    ResponderBorrar
  2. Este desglose funciona pero si le pones mas de 100 sueldos se. Bloquea el programa

    ResponderBorrar

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.