Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Procesar 8000 registros (https://www.clubdelphi.com/foros/showthread.php?t=67960)

harvicoco 16-05-2010 04:56:43

Procesar 8000 registros
 
Amigos, tengo una pequeña duda, tengo 3 tablas en SQL que son una de Datos, Cabecera y Detalle basicamente; creo un objeto TADOQuery y realizo una consulta, a continuación tengo que realizar un proceso de facturacion de acuerdo a los datos, y para ello tengo 5 procedimientos que realizan el proceso de facturación, ellos son los siguientes:
1.- Factura consumo
2.- Factura beneficios
3.- Factura créditos
4.- Factura cobros indefinidos
5.- Inserta la Factura a la tabla

Todo me funciona 100 puntos, el unico problema es que tarda 1 hora y solo esta realizando los procedimientos 1, 2 y 5; imaginense si hago los otros dos mas.
Como utilizo un DataModule para las tablas tenia un par de tablas con parametros de facturacion y accedia a ellas en la facturacion de cada registro, al ver eso cree un type record con los parametros de la facturacion una sola vez y lo utilizo dicho type record y ya no las tablas de parametros, pero lastimosamente solo me bajo 10 min de tiempo a lo mucho.
Entonces mi consulta es. ¿Existe alguna forma de agilizar mi proceso de facturación, se me ocurre quizas utilizando alguna estructura de datos o quizas haciendolo en el mismo SQL con procedimientos almacenados o alguien sabe de alguna forma en que lo pueda hacer mas rapido?
Gracias de antemano.

marcoszorrilla 16-05-2010 10:04:06

8000 Registros no son muchos, tendrás que describir con más detalle que es lo que haces y poner el código y componentes que utilizas para ver si alguien puede ayudarte.


Un Saludo.

harvicoco 18-05-2010 04:19:55

Aqui va algo del codigo
Código Delphi [-]
 
procedure TFFACTURACION.BitBtn3Click(Sender: TObject);
Begin
    Try
        If MessageDlg('¿Está seguro(a) que desea FACTURAR el PERIODO'+IntToStr(intMesPer)+'-'+IntToStr(intAnoPer)+'?',
            mtConfirmation, [mbYes, mbNo], 0) = mrYes then
        Begin
            DM.BD.BeginTrans;
            strPerFac:=CerosIzquierda(intMesPer,2)+'-'+IntTostr(intAnoPer);
            intTcbFac:=DM.GetTcbFac;
            If DM.GetDosifica(1,intNroAut,intNroRen,strFecLim,strKeyDos) Then
                If FacturarEmpresa Then
                Begin
                    ShowMessage('¡El PROCESO DE FACTURACIÓN FINALIZÓ CORRECTAMENTE!.');
                    DM.BD.CommitTrans;
                End
                Else
                Begin
                    ShowMessage('¡El PROCESO DE FACTURACIÓN FALLÓ!.');
                    DM.BD.RollbackTrans;
                End;
        End;
    Except on E:Exception do
        Begin
            DM.BD.RollbackTrans;
            ShowMessage(E.Message);
        End;
    End;
End;
 
Ese es el procedimiento del boton que realiza el proceso
 
function TFFACTURACION.FacturarEmpresa: Boolean;
Var strSQL,strNroFac:String;
    intTotFac,intTotIva:Real;
    i:Integer;
begin
    Try
        With QCONTRATOS do
        Begin
            ObtenerParametros(1,1,1);
            strSQL:='SELECT *,S.NROSER FROM SIIELE.LECTURAS ,SIIELE.CTOGRL C, SIIELE.CTOSER S ';
            strSQL:=strSQL+'WHERE C.NROCTO=S.NROCTO AND L.NROCTO=C.NROCTO AND L.NROFAC IS NULL AND ';
            strSQL:=strSQL+'L.MESPER='+IntToStr(intMesPer)+' AND L.ANOPER='+IntToStr(intAnoPer);
            strSQL:=strSQL+' ORDER BY C.NROCTO';
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
            First;
            While Not EOF do
            Begin
                intPosVec:=0;i:=1;
                While intPosVec=0 do
                Begin
                    If vecParFac[i].NomPla=QCONTRATOS.FieldByName('CODPLA').AsString Then
                        intPosVec:=i
                    Else
                        i:=i+1;
                End;
                strNroFac:=CerosIzquierda(intMesPer,2)+IntToStr(intAnoPer)+CerosIzquierda(intNroAct,4);
                intTotFac:=0;intTotIva:=0;
                If FacturarServicio(QCONTRATOS,strNroFac,intTotFac,intTotIva) Then
                    If FacturarLeyes(QCONTRATOS,strNroFac,intTotFac,intTotIva) Then
                        If FacturarCreditos(QCONTRATOS,strNroFac,intTotFac,intTotIva) Then
                            If FacturarIndefinidos(QCONTRATOS,strNroFac,intTotFac,intTotIva) Then
                                If InsertarFactura(QCONTRATOS,strNroFac,intTotFac,intTotIva) Then
                                Begin
                                    ActualizarLectura(QCONTRATOS,strNroFac);
                                    intNroAct:=intNroAct+1;
                                    intNroRen:=intNroRen+1;
                                    Next;
                                End
                                Else
                                Begin
                                    Result:=False;
                                    Exit;
                                End
                            Else
                            Begin
                                Result:=False;
                                Exit;
                            End
                        Else
                        Begin
                            Result:=False;
                            Exit;
                        End
                    Else
                    Begin
                        Result:=False;
                        Exit;
                    End
                Else
                Begin
                    Result:=False;
                    Exit;
                End;
            End;
        End;
        Result:=True;
    Except on E:Exception do
        Begin
            Result:=False;
            ShowMessage(E.Message);
        End;
    End;
end;

ESE ES EL PROCESO QUE REALIZA TODA LA FACTURACION
 
function TFFACTURACION.FacturarServicio(Q:TADOQuery;strNroFac:String;Var intTotFac,intTotIVA:Real): Boolean;
Var
    intTotCon,intCanMin,intCanDem:Integer;
    intPreMin,intPreKws,intPreDem:Real;
begin
    Try
        intCanMin:=0;intPreKws:=0;
        //CONSUMO MINIMO
        If  vecParFac[intPosVec].CanMin>0 Then
        Begin
            intCanMin:=vecParFac[intPosVec].CanMin;
            intPreMin:=vecParFac[intPosVec].PreMin;
            InsertarDetalle(strNroFac,'MINENE',Q.FieldByName('CODEMP').AsInteger,
                Q.FieldByName('CODSER').AsInteger,intPreMin,1,intTotFac,intTotIVA);
        End;
        //CONSUMO EXCEDENTE
        If Q.FieldByName('CONLEC').AsInteger>intCanMin Then
        Begin
            intTotCon:=Q.FieldByName('CONLEC').AsInteger-intCanMin;
            intPreKws:=vecParFac[intPosVec].PreKws;
            InsertarDetalle(strNroFac,'KWSENE',Q.FieldByName('CODEMP').AsInteger,
                Q.FieldByName('CODSER').AsInteger,intPreKws,intTotCon,intTotFac,intTotIVA);
        End;
        //CONSUMO DEMANDA
        If Q.FieldByName('DEMLEC').AsInteger>0 Then
        Begin
            intCanDem:=Q.FieldByName('DEMLEC').AsInteger;
            intPreDem:=vecParFac[intPosVec].PreDem;
            InsertarDetalle(strNroFac,'DEMENE',Q.FieldByName('CODEMP').AsInteger,
                Q.FieldByName('CODSER').AsInteger,intPreDem,intCanDem,intTotFac,intTotIVA);
        End;
        //PENALIZACION BAJO FACTOR DE POTENCIA
        If Q.FieldByName('MULLEC').AsInteger>0 Then
        Begin
            intTotCon:=Q.FieldByName('MULLEC').AsInteger;
            InsertarDetalle(strNroFac,'BFPDIG',Q.FieldByName('CODEMP').AsInteger,
                Q.FieldByName('CODSER').AsInteger,intPreKws,intTotCon,intTotFac,intTotIVA);
        End;
        Result:=True;
    Except on E:Exception do
        Begin
            Result:=False;
            ShowMessage(E.Message+'SERVICIO'+Q.FIeldByName('NROCTO').AsString);
        End;
    End;
end;

ESTE FACTURA EL SERVICIO
 
function TFFACTURACION.FacturarLeyes(Q:TADOQuery;strNroFac:String;Var intTotFac,intTotIVA:Real): Boolean;
Var
    intTotBen,intMtoLey,intPreMin,intPreKws,intPreDem:Real;
    intTotCon,intCanMin,intCanLey,intValLey,i,intCanDem:Integer;
    Aplica:Boolean;
begin
    Try
        intTotBen:=0;
        intTotCon:=Q.FieldByName('TOTCON').AsInteger;
        For i:=1 to vecParFac[intPosVec].CanLeyes do
        Begin
            intCanMin:=0;intCanDem:=0;
            intPreMin:=0;intPreKws:=0;intPreDem:=0;
            Aplica:=False;
            //SI CONTRATO TIENE LEY DE VEJEZ
            If (vecParFac[intPosVec].vecLeyes[i].NomLey='LEY1886') and
                (EsLey1886(Q.FieldByName('NROCTO').AsString)) Then
                Aplica:=True
            Else
                //SI CONTRATO CUMPLE LA CONDICION DE TARIFA DIGNIDAD
                If (vecParFac[intPosVec].vecLeyes[i].NomLey='TARDIG')and
                    (intTotCon<=DM.TLEYES.FieldByName('APLCAN').AsInteger) Then
                    Aplica:=True
                Else
                    //SI APLICA ALUMBRADO PUBLICO
                    If vecParFac[intPosVec].vecLeyes[i].NomLey='ALUPUB' Then
                        Aplica:=True;
            If Aplica Then
            Begin
                intCanLey:=vecParFac[intPosVec].vecLeyes[i].CanLey;
                intValLey:=vecParFac[intPosVec].vecLeyes[i].ValLey;
                //SI APLICA AL MINIMO
                If vecParFac[intPosVec].vecLeyes[i].AplMin='S' Then
                Begin
                    intCanMin:=vecParFac[intPosVec].CanMin;
                    intPreMin:=vecParFac[intPosVec].PreKws;
                End;
                //SÎ APLICA AL CONSUMO
                If vecParFac[intPosVec].vecLeyes[i].AplCon='S' Then
                Begin
                    intCanDem:=Q.FieldByName('DEMLEC').AsInteger;
                    intPreKws:=vecParFac[intPosVec].PreKws;
                    intPreDem:=vecParFac[intPosVec].PreDem;
                End;
                //CONDICION DE LA LEY
                If vecParFac[intPosVec].vecLeyes[i].ConLey='HASTA' Then
                Begin
                    If intTotCon>intCanLey Then
                        intMtoLey:=(intPreMin*intValLey/100)+((intCanLey-intCanMin)*intPreKws*intValLey/100)
                    Else
                        intMtoLey:=(intPreMin*intValLey/100)+((intTotCon-intCanMin)*intPreKws*intValLey/100);
                End
                Else If intTotCon>intCanMin Then
                        intMtoLey:=(intPreMin*intValLey/100)+((intTotCon-intCanMin)*intPreKws*intValLey/100)+((intCanDem*intPreDem)*intValLey/100)
                    Else
                        intMtoLey:=(intPreMin*intValLey/100)+((intCanDem*intPreDem)*intValLey/100);
                //SI ES UN BENEFICIO
                If vecParFac[intPosVec].vecLeyes[i].EsBene='S' Then
                    intTotBen:=intTotBen+intMtoLey;
                //SI APLICA LOS BENEFICIS
                If vecParFac[intPosVec].vecLeyes[i].AplBen='S' Then
                    intMtoLey:=intMtoLey-(intTotBen*intValley/100);
                //SI SE COBRA AL DEBITO O AL CREDITO
                If vecParFac[intPosVec].vecLeyes[i].TipCob='DEB' Then
                    intMtoLey:=intMtoLey*(-1);
                //INSERTA EL ITEM A LA FACTURA
                InsertarDetalle(strNroFac,vecParFac[intPosVec].vecLeyes[i].CodItm,Q.FieldByName('CODEMP').AsInteger,
                    Q.FieldByName('CODSER').AsInteger,intMtoLey,1,intTotFac,intTotIva);
            End;
        End;
        Result:=True;
    Except on E:Exception do
        Begin
            Result:=False;
            ShowMessage(E.Message+'LEYES'+DM.TLEYES.FieldByName('NROCTO').AsString);
        End;
    End;
end;
ESE FACTURA LAS LEYES

BASICAMENTE ESE ES EL CODIGO DE LOS DOS PROCESOS MENCIONADOS ANTERIORMENTE, SI ALGUIEN TUVIERA UNA OBSERVACION AGRADECERIA QUE ME LA HICIERAN SABER


La franja horaria es GMT +2. Ahora son las 16:23:26.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi