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

1 comentario :

  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

    ResponderEliminar