Anda di halaman 1dari 9

APOSTILA BIZUS - ADVPL

Diferenas entre datas


Abaixo algumas funes para obter diferenas entre datas ( inclusive em meses ).
DaySum( dDate , nDays ) //Soma Dias em Uma Data
DaySub( dDate , nDays ) //Subtrai Dias em Uma Data
MonthSum( dDate , nMonth ) //Soma Meses em Uma Data
MonthSub( dDate , nMonth ) //Subtrai Meses em Uma Data
YearSum( dDate , nYear ) //Soma Anos em Uma Data
YearSub( dDate , nYear ) //Subtrai Anos em Uma Data
DateDiffDay( dDate1 , dDate2 ) //Apura Diferenca em Dias
DateDiffMonth( dDate1 , dDate2 ) //Apura Diferenca em Meses
DateDiffYear( dDate1 , dDate2 ) //Apura Diferenca em Anos
DateDiffYMD( dDate1 , dDate2 ) //Retorna Array contendo a Diferenca de Anos/Meses/Dias
entreduas Data

MSExecAuto

Objetivo
Fazer manuteno automtica (incluso, alterao e excluso) das rotinas de manipulao de dados do
sistema, automatizando o processo de entrada de dados sem a necessidade de desenvolver rotinas
especificas.
Aplicao
Esta tecnica aplicada em todas as verses Protheus.
Vantagens
1) Interface : Os dados de entrada so enviados a rotina em forma de campos e conteudos (array) e desta
forma no necessario a apresentao de nenhuma inteface ao usurio.
2) Segurana : A utilizao de rotinas automticas aumenta consideravelmente a segurana do sistema, uma
vez que utiliza as validaes padres e diminui os problemas causados por atualizao de verso ou incluso
de customizaes nas rotinas padres do sistema.
3) Agilidade no processo : Aumenta consideravemente o tempo de desenvolvimento das customizaes que
necessitam de entrada de dados. Exemplo: Importao de pedido de venda.
Procedimentos
Existem duas maneiras de utilizar a rotina automatica, sendo elas:
1. Sem Interface
2. Com Interface
Para a utilizacao da rotina automatica sem interface deve-se, configurar o ambiente utilizando-se o comando
PREPARE ENVIRONMENT e chamar diretamente o nome da funo.
Exemplo:
User Function IncProd()
Local aRotAuto := {}

Local nOpc := 3 // inclusao


Private lMsHelpAuto := .t. // se .t. direciona as mensagens de help para o arq. de
log

Private lMsErroAuto := .f. // necessario a criacao, pois sera //atualizado quando


houver
// alguma incosistencia nos parametros
PREPARE ENVIRONMENT EMPRESA '99' FILIAL '01' MODULO 'FAT'
Begin Transaction
aRotAuto:= {{'B1_COD' ,'1010' ,Nil},;
{'B1_DESC' ,'Produto teste',Nil},;
{'B1_TIPO' ,'PA' ,Nil},;
{'B1_UM' ,'UN' ,Nil},;
{'B1_LOCPAD' ,'01' ,Nil},;
{'B1_PICM' ,0 ,Nil},;
{'B1_IPI' ,0 ,Nil},;
{'B1_PRV1' ,100 ,Nil},;
{'B1_LOCALIZ' ,'N' ,Nil},;
{'B1_CODBAR' ,'789888800001' ,Nil}}
MSExecAuto({|x,y| mata010(x,y)},aProduto,nOpc)
If lMsErroAuto
DisarmTransaction()
break
EndIf
End Transaction
If lMsErroAuto
/*
Se estiver em uma aplicao normal e ocorrer alguma incosistencia nos parametros
passados,mostrar na tela o log informando qual coluna teve a incosistencia.
*/
Mostraerro()
Return .f.
EndIf
Return .t.

Funo que retorna as decries das mensagens de erro do Protheus em Portugus

Funo que retorna as decries das mensagens de erro do Protheus em Portugus


#INCLUDE "RWMAKE.CH"
#INCLUDE "PROTHEUS.CH"
User Function DescErro(_nr)
Local cMensagem := ""
Do Case
case _nr ==
-1 ; cMensagem:='
case _nr ==
0 ; cMensagem:='
case _nr ==
1 ; cMensagem:='
case _nr ==
2 ; cMensagem:='
case _nr ==
3 ; cMensagem:='
case _nr ==
4 ; cMensagem:='
case _nr ==
5 ; cMensagem:='
durante atravessando o caminho. '
case _nr ==
6 ; cMensagem:='
case _nr ==
7 ; cMensagem:='

A operao falhou ou erro indefinido '


sucesso da operao '
(Cdigo de erro inesperado) '
Caminho / Arquivo no encontrado '
(Cdigo de erro inesperado) '
Bad file descriptor '
Muitas ligaes simblicas encontradas
Endereo errado. '
Falta de memria. '

Funo que retorna todas as imagens de botes do Protheus

Funo que retorna todas as imagens de botes do Protheus

No reparem na funo foi feita as pressas, hehehe


#include "protheus.ch"
User Function ImgBotoes()
Local a1Buttons := {}
DEFINE MSDIALOG oDlg TITLE "Imagens para botes EnchoiceBar" FROM 000, 000
PIXEL
AADD(a1Buttons, { "AFASTAME" ,{||oDlg:End()}, "AFASTAME"} )
AADD(a1Buttons, { "ALTERA" ,{||oDlg:End()}, "ALTERA"} )
AADD(a1Buttons, { "AMARELO" ,{||oDlg:End()}, "AMARELO"} )
...
EnchoiceBar(oDlg, {||oDlg:End()}, {||oDlg:End()},,a14Buttons)
ACTIVATE MSDIALOG oDlg CENTERED
Return

TO 600, 900

Enviando e-mail atravs de rotinas

O envio de e-mails pelo Protheus algo bem simples, desde que todas as informaes necessrias tenham
sida registradas nos parametros corretamente.
1) O usurio de ter o e-mail configurado na cadastro de usuarios (SIGACFG).
2) Configurar o parmetro MV_RELSERV com o endereo SMTP do servidor de e-mails da empresa
3) Na finalizao do atendimento informar a conta e a senha do usuario no servidor de e-mails.
Ex: Conta: admin@empresa.com.br
Senha: 1234
Segue abaixo uma funo bem simples para envio:
#include
#include
#include
#include

"protheus.ch"
"apwebsrv.ch"
"apwebex.ch"
"ap5mail.ch"

User function enviar(cMailDe,cMailPara,cAssunto,cCorpo)


local
local
autenticao
local
local
LOcal
local
local
local

cServer
lAutentic

:= getMV('MV_RELSERV') //endereo SMTP


:= getMV('MV_RELAUTH') //utilize em caso de necessidade de

cAccount
:= getmv('MV_RELACNT') //conta
cPassword := getMV('MV_RELAPSW') //senha
cQL
:= CHR(13) + CHR(10)
cRemoteip
:=
Getclientip()
cRemoteComputer :=
GetComputerName()
lConectou := .f.

// conecta com o servidor de e-mail


CONNECT SMTP SERVER cServer ACCOUNT cAccount PASSWORD cPassword
lConectou
mailAuth(cAccount, cPassword)
If lConectou
cCorpo += cQL + cQL +
"==========================================================="

Result

cCorpo += cQL + " Enviado por: " + cUsername


cCorpo += cQL + " Computador: " + cRemoteComputer
cCorpo += cQL + " IP: " + cRemoteip
cCorpo += cQL +
"==========================================================="
SEND MAIL FROM cMailDe TO cMailPara SUBJECT cAssunto BODY cCorpo FORMAT TEXT
RESULT lEnviado
if !lEnviado
alert("ALERTA: No foi possivel enviar a mensagem") //, pois ocorreu o
seguinte erro: " + sMensagem + ".")
else
alert("E-mail transmitido com sucesso para " + cMailPara +"!")
endif
else
alert("No foi possivel executar sua solicitao, pois no houve
resposta do servidor de e-mail."+cQL+cQL+"Informe ao Administrador do Sistema!")
return .f.
Endif
DISCONNECT SMTP SERVER Result lDisConectou
Return

Usando mBrowser com tabela temporria

Alguns colegas me perguntaram como se utiliza o mbrowse para mostrar o resultado de tabelas temporrias,
segue abaixo um exemplo, existem outras maneiras, mas este um bem simples.

#include "topconn.ch"
#include "protheus.ch"
User Function _fMBROWSE()
Local cArquivo
Local cQuery
Private cCadastro
Private aRotina
:= {}
Private _aArqTmp
:= {}
Private aTitulos
:= {}
Private aIndexQRY
:= {}
Private cPerg
:= 'REST002'
Private cDelFunc := ".F."
CriaSx1(cPerg)
cCadastro

:= "[REST002] - Etiqueta de Produtos"

Pergunte(cPerg,.T.)
AADD(aRotina,{"Imprimir Etiqueta","U_fResumo2(QRY->B1_COD)",0,6})
_aArqTmp:= {}
AADD(_aArqTmp,{"B1_CODMES"
,
"C",TamSx3("B1_CODMES")[1], 0})
AADD(_aArqTmp,{"B1_SUFIXO"
,
"C",TamSx3("B1_SUFIXO")[1], 0})
AADD(_aArqTmp,{"B1_COD"
,
"C",TamSx3("B1_COD")[1]
, 0})
AADD(_aArqTmp,{"B1_DESC"
,
"C",TamSx3("B1_DESC")[1] , 0})
AADD(aTitulos,{"Equivalente",
,"","C","",""})
AADD(aTitulos,{"Sufixo"
,
,"","C","",""})
AADD(aTitulos,{"Produto"
,
,"","C","",""})
AADD(aTitulos,{"Descrio" ,
,"","C","",""})

"B1_CODMES"

, "@!",

TamSx3("B1_CODMES")[1]

, 0,

"B1_SUFIXO"

, "@!", TamSx3("B1_SUFIXO")[1]

, 0,

"B1_COD"

, "@!", TamSx3("B1_COD")[1]

, 0,

"B1_DESC"

, "@!", TamSx3("B1_DESC")[1]

, 0,

cQuery := " SELECT B1_CODMES,B1_SUFIXO,B1_COD,B1_DESC "


cQuery += " FROM " + RETSQLNAME("SB1") + " SB1 "
cQuery += " WHERE B1_FILIAL = '"+xFilial("SB1")+"' AND "
cQuery += " SB1.D_E_L_E_T_ != '*' "
if(!empty(mv_par02))
cQuery += " AND B1_COD >= '"+mv_par01+"' AND B1_COD <= '"+mv_par02+"' "
endif
cQuery += " ORDER BY B1_CODMES,B1_SUFIXO,B1_COD "
cQuery := ChangeQuery(cQuery)
cArquivo := CriaTrab(_aArqTmp,.T.)
dbUseArea(.T.,,cArquivo,"QRY",.F.,.F.)
SQLToTrb(cQuery,_aArqTmp,"QRY")
Index on QRY->B1_CODMES+QRY->B1_SUFIXO+QRY->B1_COD To &cArquivo
DbSelectArea("QRY")
QRY->(dbSetOrder(1))
QRY->(dbGoTop())
mBrowse(,,,,"QRY",aTitulos)
dbCloseArea("QRY")
fErase(cArquivo+".*")
Return

Static Function CriaSx1(cPerg)


PutSx1(cPerg,"05","Produto de ?" ,"" ,""
,"mv_ch1","C",09,0,0,"G","","SB1","","","mv_par01")
PutSx1(cPerg,"06","Produto at?" ,"" ,""
,"mv_ch2","C",09,0,0,"G","","SB1","","","mv_par02")
return

Identificando a quantidade de vencimentos da planilha financeira no Pedido de Vendas

Hoje precisei descobrir quais eram os vencimentos de acordo com a condio de pagamento no Pedido de
Venda
Pesquisa daqui, pesquisa dali e achei um pequena funo chamada Condicao()
Condicao(nTotPed,cCondPag,,dEmissao)

onde:
nTotPed = Total do Pedido
cCondPag = Codigo da Condio de Pagamento
dEmissao = Data de Emisso
Exemplificando:

User Function
Local
Local
Local
Local
Local
Local
Local
Local
Local
Local

MFAT001A()
i
nDias
:= 0
nQtde
:= 0
aParcelas := {}
dVencto
:= CTOD("")
cCondPag := M->C5_CONDPAG
cTipo
nTotPed := 0
dEmissao := M->C5_EMISSAO
dParc1:=dParc2:=dParc3:=dParc4:= CTOD("")

cTipo := POSICIONE("SE4",1,xFilial("SE4")+cCondPag,"E4_TIPO")
nTotPed := iif(Inclui,1,getTotPed(SC5->C5_NUM) )
If cTipo != "9"
aParcelas := Condicao(nTotPed,cCondPag,,dEmissao)
For i := 1 to Len(aParcelas)
If aParcelas[i][1] > dVencto
nDias += aParcelas[i][1] - dEmissao
nQtde++
dVencto:= aParcelas[i][1]
EndIf
Next

Else

dParc1
dParc2
dParc3
dParc4

:=
:=
:=
:=

M->C5_DATA1
M->C5_DATA2
M->C5_DATA3
M->C5_DATA4

If !Empty(dParc1)
nDias += dParc1 - dEmissao
nQtde++
else
Alert("Voc escolheu a condio de pagamento do tipo
9"+chr(10)+chr(13)+"Informe a data da 1 Parcela!")
nDias := 0
endif
If !Empty(dParc2)
nDias += dParc2 - dEmissao
nQtde++
endif
If !Empty(dParc3)
nDias += dParc3 - dEmissao
nQtde++
endif
If !Empty(dParc4)
nDias += dParc4 - dEmissao
nQtde++
endif
EndIf
nDias := nDias / nQtde
Return(nDias)

/
***************************************************************************************
***************************
static function getTotPed( cCodPed )
retorna o valor total do pedido de vendas
***************************************************************************************
**************************/
static function getTotPed( cCodPed )
// retorno da funcao
local nRet := 0
// total do pedido
local nTotSc6 := 0
// total de desconto
local nTotDes := 0
// area
local aArea := getArea()
// posiciona o SC6 para calcular o valor total do pedido
SC6->(dbSetOrder(1))
SC6->(dbSeek(xFilial("SC6") + cCodPed))
// loop sobre os itens do pedido
while ( SC6->C6_FILIAL == xFilial("SC6") ) .and. (SC6->C6_NUM == cCodPed) .and. (!
SC6->(eof()))
// acumula a soma do valor dos itens
nTotSc6 += SC6->C6_VALOR
// verifica o desconto
if ( SC6->C6_PRUNIT == 0 )

else

nTotDes += SC6->C6_VALDESC

nTotDes += A410Arred(SC6->C6_PRUNIT * SC6->C6_QTDVEN,


"C6_VALOR") - A410Arred(SC6->C6_PRCVEN * SC6->C6_QTDVEN, "C6_VALOR")
endIf
// proximo registro
SC6->(dbSkip())
endDo
// acumula
nTotSc6 -=
nTotDes +=
nTotDes +=
nTotSc6 -=

o desconto no pedido
SC5->C5_DESCONT
SC5->C5_DESCONT
A410Arred(nTotSc6 * (SC5->C5_PDESCAB / 100), "C6_VALOR")
A410Arred(nTotSc6 * (SC5->C5_PDESCAB / 100), "C6_VALOR")

// ajusta o valor de retorno


nRet := nTotSc6
// restaura a area
restArea(aArea)
return nRet

Anda mungkin juga menyukai