Ola Amigos . Estou com problema programa Especifico, preciso fazer soma campos tabela ped-item, porem esta muito lentro para trazer o resultado. Se alguém puder me dar alguma dica de como posso melhorar a performance deste programa ? Segue código Fonte do calculo.: ASSIGN i-int[4] = 0 i-int[5] = 0 i-int[6] = 0. FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant WHERE ped-venda.dt-implant >= DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)) AND ped-venda.dt-implant <= ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) ) AND ped-venda.dt-cancela = ? AND ped-venda.nome-abrev <> "LIMER-CART" , EACH natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES : FOR EACH ped-item OF ped-venda NO-LOCK WHERE ped-item.vl-preuni > 0 , EACH ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" : ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */ IF ped-venda.dt-implant = i-data THEN DO: ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */ END. END. END. ASSIGN cMensal:SC
Olá, Primeiro de tudo retire todas essas funções da cláusula WHERE. Se vc tem que tratar estas variáveis de data faça antes de execura o "FOR EACH". Trate as datas e jogue os valores em variáveis. Código: dt-imp-ini = DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)). dt-imp-fim = ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) ). Com estas variáveis vc vai tratar o campo dt-implant. Outra coisa é vc não fazer acesso a dados quando vc não necessita deles. Por exemplo, vc acessa a natur-oper mas não precisa dos registros que está colocando na memória (o buffer). Vc só precisa verificar o registro e tratar um campo. Ao invés de usar: Código: EACH natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES Vc deve usar: Código: AND (CAN-FIND(EACH natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES)) O mesmo exemplo acima se aplica a tabela ITEM. Siga o mesmo modo de tratamento. Vc não precisa do registro então não o deve colocar na memória. Usando o CAN-FIND vc verifica o registro sem acesso na memória o que vai deixar seu programa mais rápido. Expero que isso já ajude. Trombini
Trombini fiz teste, poderia verificar pra mim, pois, ganho foi de apenas 2 segundos, estava levando 8 segundos para fazer for each , agora 6 segundos, sera que eu fiz certo, segue novo código.Agora completo. DEF VAR i-int AS INTEGER EXTENT 12 INITIAL 0. DEF VAR i-data AS DATE INITIAL 01/31/2013. DEF VAR i-dt-ini AS DATE INITIAL ?. DEF VAR i-dt-fim AS DATE INITIAL ?. DEFINE VAR i-hora AS CHAR EXTENT 12 INITIAL "". ASSIGN i-hora[3] = STRING(TIME,"hh:mm:ss"). FIND FIRST esparam-vendas WHERE esparam-vendas.cod-estabel = "1" AND esparam-vendas.ano = INT(YEAR(i-data)) AND esparam-vendas.cancelado = NO NO-LOCK NO-ERROR. IF AVAIL esparam-vendas THEN DO: ASSIGN i-int[1] = 1 i-int[2] = 0 i-int[3] = 0. REPEAT: IF i-int[1] = 13 THEN LEAVE. ASSIGN i-int[2] = i-int[2] + esparam-vendas.quantidade[i-int[1]]. ASSIGN i-int[1] = i-int[1] + 1. END. ASSIGN i-int[3] = ( IF INT(MONTH(i-data)) = 12 THEN INT( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))) ELSE INT( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))) ). ASSIGN i-hora[4] = STRING(TIME,"hh:mm:ss") . FOR EACH ems2ft.calen-prod NO-LOCK WHERE ems2ft.calen-prod.cod-estabel = "1" AND ems2ft.calen-prod.data >= DATE("01/" + STRING(MONTH(i-data),"99" ) + "/" + STRING(esparam-vendas.ano) ) AND ems2ft.calen-prod.data <= ( IF INT(MONTH(i-data)) = 12 THEN DATE( DATE("01/01/" + STRING(esparam-vendas.ano + 1 ) ) - 1 ) ELSE DATE( DATE("01/" + STRING( INT( MONTH(i-data) + 1 ),"99") + "/" + STRING(esparam-vendas.ano) ) - 1 ) ) AND ems2ft.calen-prod.tipo-dia <> 1 : ASSIGN i-int[3] = i-int[3] - 1. END. ASSIGN i-hora[5] = STRING(TIME,"hh:mm:ss"). ASSIGN i-int[4] = 0 i-int[5] = 0 i-int[6] = 0 i-dt-ini = DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)) i-dt-fim = ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) ) i-hora[1] = STRING(TIME,"hh:mm:ss") . FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant WHERE ped-venda.dt-implant >= i-dt-ini AND ped-venda.dt-implant <= i-dt-fim AND ped-venda.dt-cancela = ? AND ped-venda.nome-abrev <> "LIMER-CART" : IF CAN-FIND(FIRST natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES ) THEN DO: FOR EACH ped-item OF ped-venda NO-LOCK WHERE ped-item.vl-preuni > 0 : IF CAN-FIND(FIRST ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" ) THEN DO: ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */ IF ped-venda.dt-implant = i-data THEN DO: ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */ END. END. END. END. END. ASSIGN i-hora[2] = STRING(TIME,"hh:mm:ss"). DISP i-int[3] ' Qt Dias' SKIP i-int[4] ' Mes' SKIP i-int[5] ' Dia' SKIP i-hora[1] 'Inicial ' SKIP i-hora[2] 'Final' SKIP i-hora[3] 'Inicio Programa' SKIP i-hora[4] 'Apos Repeat' SKIP i-hora[5] 'Apos \Calendario' . END.
Código: DEF VAR i-int AS INTEGER EXTENT 12 INITIAL 0. DEF VAR i-data AS DATE INITIAL 01/31/2013. DEF VAR i-dt-ini AS DATE INITIAL ?. DEF VAR i-dt-fim AS DATE INITIAL ?. DEFINE VAR i-hora AS CHAR EXTENT 12 INITIAL "". ASSIGN i-hora[3] = STRING(TIME,"hh:mm:ss"). FIND FIRST esparam-vendas WHERE esparam-vendas.cod-estabel = "1" AND esparam-vendas.ano = INT(YEAR(i-data)) AND esparam-vendas.cancelado = NO NO-LOCK NO-ERROR. IF AVAIL esparam-vendas THEN DO: ASSIGN i-int[1] = 1 i-int[2] = 0 i-int[3] = 0. REPEAT: IF i-int[1] = 13 THEN LEAVE. ASSIGN i-int[2] = i-int[2] + esparam-vendas.quantidade[i-int[1]]. ASSIGN i-int[1] = i-int[1] + 1. END. ASSIGN i-int[3] = ( IF INT(MONTH(i-data)) = 12 THEN INT( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))) ELSE INT( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano))) ). ASSIGN i-hora[4] = STRING(TIME,"hh:mm:ss") . FOR EACH ems2ft.calen-prod NO-LOCK WHERE ems2ft.calen-prod.cod-estabel = "1" AND ems2ft.calen-prod.data >= DATE("01/" + STRING(MONTH(i-data),"99" ) + "/" + STRING(esparam-vendas.ano) ) AND ems2ft.calen-prod.data <= ( IF INT(MONTH(i-data)) = 12 THEN DATE( DATE("01/01/" + STRING(esparam-vendas.ano + 1 ) ) - 1 ) ELSE DATE( DATE("01/" + STRING( INT( MONTH(i-data) + 1 ),"99") + "/" + STRING(esparam-vendas.ano) ) - 1 ) ) AND ems2ft.calen-prod.tipo-dia <> 1 : ASSIGN i-int[3] = i-int[3] - 1. END. ASSIGN i-hora[5] = STRING(TIME,"hh:mm:ss"). ASSIGN i-int[4] = 0 i-int[5] = 0 i-int[6] = 0 i-dt-ini = DATE("01/" + STRING(MONTH(i-data),"99") + "/" + STRING(esparam-vendas.ano)) i-dt-fim = ( IF INT(MONTH(i-data)) = 12 THEN ( DATE("01/01/" + STRING(esparam-vendas.ano + 1 )) - 1 ) ELSE ( DATE("01/" + STRING(INT(MONTH(i-data) + 1),"99") + "/" + STRING(esparam-vendas.ano)) - 1 ) ) i-hora[1] = STRING(TIME,"hh:mm:ss") . FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant WHERE ped-venda.dt-implant >= i-dt-ini AND ped-venda.dt-implant <= i-dt-fim AND ped-venda.dt-cancela = ? AND ped-venda.nome-abrev <> "LIMER-CART" : IF CAN-FIND(FIRST natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES ) THEN DO: FOR EACH ped-item OF ped-venda NO-LOCK WHERE ped-item.vl-preuni > 0 : IF CAN-FIND(FIRST ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" ) THEN DO: ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */ IF ped-venda.dt-implant = i-data THEN DO: ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */ END. END. END. END. END. ASSIGN i-hora[2] = STRING(TIME,"hh:mm:ss"). DISP i-int[3] ' Qt Dias' SKIP i-int[4] ' Mes' SKIP i-int[5] ' Dia' SKIP i-hora[1] 'Inicial ' SKIP i-hora[2] 'Final' SKIP i-hora[3] 'Inicio Programa' SKIP i-hora[4] 'Apos Repeat' SKIP i-hora[5] 'Apos \Calendario' . END.
Olá, Quando eu sugeri utlizar o CAN-FIND foi para o fazer dentro da clásula WHERE. Ficaria como abaixo. E já que vc vai mexer neste código verifique se não há outros indices que lhe ajudem. Se não houver não há muito o que fazer. Creio que ficará um pouco mais rápido assim. Código: FOR EACH ped-venda NO-LOCK USE-INDEX ch-implant WHERE ped-venda.dt-implant >= i-dt-ini AND ped-venda.dt-implant <= i-dt-fim AND ped-venda.dt-cancela = ? AND ped-venda.nome-abrev <> "LIMER-CART" AND CAN-FIND(FIRST natur-oper OF ped-venda NO-LOCK WHERE natur-oper.emite-duplic = YES ), EACH ped-item OF ped-venda NO-LOCK WHERE ped-item.vl-preuni > 0 AND CAN-FIND(FIRST ITEM OF ped-item NO-LOCK WHERE ITEM.fm-codigo <> "070" ): ASSIGN i-int[4] = i-int[4] + ped-item.qt-pedida . /* Mes */ IF ped-venda.dt-implant = i-data THEN ASSIGN i-int[5] = i-int[5] + ped-item.qt-pedida . /* Dia */ END.