Вы находитесь на странице: 1из 12

Documento: Guia de boas prticas - Estrutura de programas

Define as regras de nomeao de programas e as estruturas dos principais programas da Linha Microsiga Protheus

A Linha Microsiga Protheus possui um padro de construo de programa. O padro inicia-se pelo nome do programa. Os programas da Linha Microsiga Protheus devem possuir 7 (sete) dgitos e duas extenses possveis, conforme demonstrado abaixo:

XXX Y NNN.PR? XXX o prefixo do mdulo da linha Microsiga Protheus, exemplo: GPE para o mdulo de Gesto de Pessoal, PON para o mdulo de Ponto Eletrnico,FAT para o mdulo de Faturamento, etc. o cdigo que identifica a operao do programa. Utilize A para programas de formulrios ou processamento, C para programas de consulta e Rpara programas de relatrio e X para programas de biblioteca. Cdigo seqencial do programa. Mantenha o padro de numerao de 10 em 10 e relacione as operaes de programa similares. Exemplo: GPEA010 Cadastros de funcionrios, GPEA020 Cadastro de pessoas, GPEA030 Cadastro de formulas, GPER010 Relatrio de funcionrios, GPER020 Relatrio de pessoas, GPER030 Relatrio de formulas. Utilizamos dois tipos de extenses para programas, PRG ou PRX. Utilize PRG para programas de interface no grfica e PRX para programas de interface grfica.

NNN

PR?

No altere o padro de nomes ou crie um prprio, vrias caractersticas do Framework da Linha Microsiga Protheus so ativadas pelo padro de nomes.

Padro de construo para programas de formulrio


Os programas de formulrio so divididos em seis sees, a saber: Seo do Browse Seo do Menu de operaes da rotina Seo da Regra de negcio Seo da Interface Seo de Validao Seo Opcional de gravao Seo Opcional das demais funcionalidades do formulrio Na Seo do Browse definimos o Alias principal do formulrio, a descrio da rotina e outras opes relativas ao modo de visualizao dos registros da tabela, tais como: Filtros, Perguntas, Legenda e Opes do padro de operao disponveis.

User Function COMP023_MVC() Local oBrowse oBrowse := FWmBrowse():New() oBrowse:SetAlias( 'ZA3' ) oBrowse:SetDescription( 'Albuns' ) oBrowse:Activate() Return NIL Tenha por hbito utilizar legendas no Browse caso haja sinalizadores no Browse. Por padro devem-se utilizar cores disponveis por framework (BR_AMARELO, BR_AZUL, BR_BRANCO, BR_CINZA, BR_LARANJA, BR_MARRON, BR_PINK, BR_PRETO, BR_VERDE, BR_VERMELHO, entre outros). Cores adicionais podem causar problemas para daltnicos. Na Seo do Menu de operaes da rotina definimos quais operaes estaro disponvel para o usurio final. As opes mais comuns so: Pesquisa, Incluso, Alterao, Visualizao e Excluso. Static Function MenuDef() Local aRotina := {} ADD OPTION aRotina Title 'Pesquisar' Action 'PesqBrw' OPERATION 1 ACCESS 0 ADD OPTION aRotina Title 'Visualizar' Action 'VIEWDEF.COMP023_MVC' OPERATION 2 ACCESS 0 ADD OPTION aRotina Title 'Incluir' Action 'VIEWDEF.COMP023_MVC' OPERATION 3 ACCESS 0 ADD OPTION aRotina Title 'Alterar' Action 'VIEWDEF.COMP023_MVC' OPERATION 4 ACCESS 0 ADD OPTION aRotina Title 'Excluir' Action 'VIEWDEF.COMP023_MVC' OPERATION 5 ACCESS 0 ADD OPTION aRotina Title 'Imprimir' Action 'VIEWDEF.COMP023_MVC' OPERATION 8 ACCESS 0 ADD OPTION aRotina Title 'Copiar' Action 'VIEWDEF.COMP023_MVC' OPERATION 9 ACCESS 0 Return aRotina Na Seo da Regra de negcio definimos a estrutura do formulrio, como as tabelas dele se relacionam e quais so as funes de validao para cada estrutura e para todo o formulrio. Tenha como hito inserir a validao correta em cada uma das estruturas. Na validao de campo, valide apenas o campo e evite validar mais de um campo no mesmo bloco. Na validao da estrutura de campos, valide as dependncias dos campos da estrutura. Na validao do formulrio, valide a dependncia das estruturas do formulrio. No h necessidade de repetio de validao. Esta seo utilizada para muitos fins e evolui constantemente, por conta disto ela no deve ter chamadas de interface e os campos podem ser informados em qualquer ordem e no necessariamente na ordem esperada, por isto a regra de validao citada acima to importante. Proteja o seu cdigo dos eventos que um usurio possa realizar. Static Function ModelDef() // Cria a estrutura a ser usada no Modelo de Dados Local oStruZA3 := FWFormStruct( 1, 'ZA3', /*bAvalCampo*/, /*lViewUsado*/ ) Local oStruZA4 := FWFormStruct( 1, 'ZA4', /*bAvalCampo*/, /*lViewUsado*/ ) Local oStruZA5 := FWFormStruct( 1, 'ZA5', /*bAvalCampo*/, /*lViewUsado*/ ) Local oModel // Cria o objeto do Modelo de Dados oModel := MPFormModel():New( 'COMP023M', /*bPreValidacao*/, /*bPosValidacao*/, /*bCommit*/, /*bCancel*/ ) // Adiciona ao modelo uma estrutura de formulrio de edio por campo oModel:AddFields( 'ZA3MASTER', /*cOwner*/, oStruZA3 ) // Adiciona ao modelo uma estrutura de formulrio de edio por grid oModel:AddGrid( 'ZA4DETAIL', 'ZA3MASTER', oStruZA4, /*bLinePre*/, /*bLinePost*/, /*bPreVal*/, /*bPosVal*/, /*BLoad*/ ) //oModel:AddGrid( 'ZA5DETAIL', 'ZA4DETAIL', oStruZA5, /*bLinePre*/, /*bLinePost*/, /*bPreVal*/, /*bPosVal*/, /*BLoad*/ )

oModel:AddGrid( 'ZA5DETAIL', 'ZA4DETAIL', oStruZA5, { |oMdlG,nLine,cAcao,cCampo| COMP023LPRE( oMdlG, nLine, cAcao, cCampo ) }, /*bLinePost*/, /*bPreVal*/, /*bPosVal*/, /*BLoad*/ ) // Faz relaciomaneto entre os compomentes do model oModel:SetRelation( 'ZA4DETAIL', { { 'ZA4_FILIAL', 'xFilial( "ZA4" )' }, { 'ZA4_ALBUM' , 'ZA3_ALBUM' } } , ZA4->( IndexKey( 1 ) ) ) oModel:SetRelation( 'ZA5DETAIL', { { 'ZA5_FILIAL', 'xFilial( "ZA5" )' }, { 'ZA5_ALBUM' , 'ZA3_ALBUM' }, { 'ZA5_MUSICA', 'ZA4_MUSICA' } } , ZA5->( IndexKey( 1 ) ) ) // Liga o controle de no repetio de linha oModel:GetModel( 'ZA4DETAIL' ):SetUniqueLine( { 'ZA4_MUSICA' } ) oModel:GetModel( 'ZA5DETAIL' ):SetUniqueLine( { 'ZA5_INTER' } ) // Adiciona a descrio do Modelo de Dados oModel:SetDescription( 'Modelo de Albuns' ) // Adiciona a descrio do Componente do Modelo de Dados oModel:GetModel( 'ZA3MASTER' ):SetDescription( 'Dados do Album' ) oModel:GetModel( 'ZA4DETAIL' ):SetDescription( 'Dados das Musicas do Album' ) oModel:GetModel( 'ZA5DETAIL' ):SetDescription( 'Interpretes das Musicas do Album' ) Return oModel Na seo de interface definimos os elementos grficos que sero utilizados no formulrio e a relao que estes elementos tm, como a seo de regra de negcio. Os elementos grficos mais comuns so a FormField e a FormGrid. Apesar desta seo permitir outros elementos grficos, evite utiliz-los, durante as constantes mudanas de verso e release da linha Microsiga Protheus pode haver necessidade de retrabalho, o que no ocorre para os elementos do Framework citados. Outra razo para no usar outros elementos grficos est na dificuldade de customizao lembre-se que o maior argumento de venda da Linha Microsiga Protheus a flexibilidade, sendo assim uma interface no flexvel ir causar retrabalho por solicitao do cliente. //------------------------------------------------------------------Static Function ViewDef() // Cria a estrutura a ser usada na View Local oStruZA3 := FWFormStruct( 2, 'ZA3' ) Local oStruZA4 := FWFormStruct( 2, 'ZA4' ) Local oStruZA5 := FWFormStruct( 2, 'ZA5' ) // Cria um objeto de Modelo de Dados baseado no ModelDef do fonte informado Local oModel := FWLoadModel( 'COMP023_MVC' ) Local oView

// Remove campos da estrutura oStruZA4:RemoveField( 'ZA4_ALBUM' ) oStruZA5:RemoveField( 'ZA5_ALBUM' ) oStruZA5:RemoveField( 'ZA5_MUSICA' ) // Cria o objeto de View oView := FWFormView():New() // Define qual o Modelo de dados a ser utilizado oView:SetModel( oModel ) //Adiciona no nosso View um controle do tipo FormFields(antiga enchoice) oView:AddField( 'VIEW_ZA3', oStruZA3, 'ZA3MASTER' ) //Adiciona no nosso View um controle do tipo FormGrid(antiga newgetdados) oView:AddGrid( 'VIEW_ZA4', oStruZA4, 'ZA4DETAIL' ) oView:AddGrid( 'VIEW_ZA5', oStruZA5, 'ZA5DETAIL' ) // Criar "box" horizontal para receber algum elemento da view oView:CreateHorizontalBox( 'EMCIMA' , 20 ) oView:CreateHorizontalBox( 'MEIO' , 40 ) oView:CreateHorizontalBox( 'EMBAIXO', 40 )

// Criar "box" vertical para receber algum elemento da view //oView:CreateVerticalBox( 'EMBAIXODIR', 80, 'EMBAIXO' ) //oView:CreateVerticalBox( 'EMBAIXOESQ', 20, 'EMBAIXO' ) // Relaciona o ID da View com o "box" para exibio oView:SetOwnerView( 'VIEW_ZA3', 'EMCIMA' ) oView:SetOwnerView( 'VIEW_ZA4', 'MEIO' ) oView:SetOwnerView( 'VIEW_ZA5', 'EMBAIXO' ) //oView:SetOwnerView( 'VIEW_ZA5', 'EMBAIXODIR' ) // Liga a identificao do componente oView:EnableTitleView( 'VIEW_ZA3' ) oView:EnableTitleView( 'VIEW_ZA4', "MSICAS DO LBUM", RGB( 224, 30, 43 ) ) oView:EnableTitleView( 'VIEW_ZA5', "INTERPRETES DAS MSICAS", 0 ) // Liga a Edio de Campos na FormGrid //oView:SetViewProperty( 'VIEW_ZA4', "ENABLEDGRIDDETAIL", { 60 } ) //oView:SetViewProperty( 'VIEW_ZA5', "ENABLEDGRIDDETAIL", { 60 } ) // Acrescenta um objeto externo ao View do MVC // AddOtherObject(cFormModelID,bBloco) // cIDObject - Id // bBloco - Bloco chamado evera ser usado para se criaros objetos de tela externos ao MVC. //oView:AddOtherObject("OTHER_PANEL", {|oPanel| COMP23BUT(oPanel)}) //oView:SetOwnerView("OTHER_PANEL",'EMBAIXOESQ') Return oView Na seo de validao, voc deve inserir todas as funes utilizadas para validao dos formulrios. Tenha por padro, incluir uma validao para cada campo das tabelas e privilegie as funes de framework existentes, tais como: ExistCPO(), ExistChav(), Vazio(), NaoVazio(), Texto(), CGC(), Pertence(), Positivo()etc. Evite usar estas funes encapsuladas em uma funo, importante que elas estejam explcitas no dicionrio de dados, para que o Framework consiga traduzir o seu significado e apresentar um texto coerente para o usurio quando a funo help for acionada. A validao do campo deve ter como escopo somente a sua validao e nenhuma dependncia de outro campo. Caso necessrio utilize os atributos de Gatilho e AddRulesdo dicionrio de dados e evite simullos atravs de linhas de cdigo prpria. Para tratar as validaes com dependncia de campos, exemplo: banco, agncia e conta, utilize a validao da estrutura do formulrio que ela necessria, alm de um volume menor de cdigo, reduz-se a possibilidade de bug. O usurio pode freqentemente digitar os trs campos na seqncia e alterar algum aleatoriamente, prever isto uma tarefa tediosa e sem ganho em usabilidade. Tenha por costume nomear as estruturas de validao do formulrio seguindo o padro abaixo: Validao da estrutura FormField: *TudOk(), *TdOk() ou *tOk() Validao da estrutura FormGrid: *LinOk(), *LnOk() ou LOk() para validao das linhas do grid e *TudOk(), *TdOk() ou *tOk() para validao de todas as linhas. Validao do Formulrio: *TudOk(), *TdOk() ou *tOk() Separe muito bem aquilo que deve ser validado em uma linha da estrutura do FormGrid e aquilo que deve ser validado considerando-se todas as linhas. Apesar de parecer trivial, no considerar isto, tem sido um grande fator de retrabalho nos formulrios que apresentam a estrutura FormGrid por conta da lentido que acarreta quando h um nmero grande de linhas no formulrio. Por fim, considere aquilo que deve ser validado somando-se as estruturas existentes no formulrio.

Na seo opcional de Gravao, crie funes do tipo Trigger. Gatilho ou Trigger um recurso de programao executado sempre que o evento associado ocorrer. Trigger um tipo especial de procedimento armazenado, que executado sempre que h uma tentativa de modificar os dados de uma tabela que protegida por ele. muito utilizada para ajudar a manter a consistncia dos dados ou para propagar alteraes em um determinado dado de uma tabela para outras. Um bom exemplo um gatilho criado para controle de quem alterou a tabela, nesse caso, quando a alterao for efetuada, o gatilho "disparado" e grava em uma tabela de histrico de alterao, o usurio e data/hora da alterao. No padro MVC os Triggers so chamados sempre que um registro do formulrio do Model for atualizado, neste caso o Trigger executado antes e depois do evento. No confunda os Triggers disparados pelo Model com os disparados pela interface View e contidos no dicionrio de dados. Um tem a funo de preencher um campo segundo uma regra e ou outro de atualizar os dados dentro de uma transao. O padro MVC de formulrio adotado pela Linha Microsiga Protheus realiza a gravao de todos os dados apresentados no Model do formulrio, cabe o desenvolvedor realizar a gravao dos acumulados ou fazer as tarefas de regra de negcio. Como exemplo, podemos citar o Pedido de Venda ( MATA410 ). O framework do padro MVC consegue gravar as tabelas SC5 Cabealho do Pedido de Venda e SC6 Itens do Pedido de Venda, porm falta realizar a gravao do SB2 Saldos em estoque, SA1 Cadastro de Cliente e SC9 Itens liberados do Pedido de Venda. SB2 e SA1 so atualizados por conta de dados estatsticos, j o SC9 possui toda uma regra para liberar o pedido, sendo disparado pela gravao de um campo no item do pedido de venda C6_QTDLIB. Para realizar esta operao, recomenda-se a criao de uma funo do tipo Trigger, conforme citado acima. Esta funo tem disponvel o registro da tabela que acabou de ser gravado, a operao que foi realizada ( Incluso, Alterao ou Excluso ) e o momento da chamada ( Antes ou Depois ). Isto possibilita ao desenvolvedor fazer as tratativas corretas em diversas situaes. Continuando em nosso exemplo, para realizar as atualizaes complementares do pedido de venda, o desenvolvedor poderia criar a funo MaAvalSC6(nOperation, lEstorna). Esta funo seria chamada antes e depois de gravar a tabela SC6. Quando for chamada antes e no for uma incluso, ela poderia estornar os dados estatsticos e as regras de negcio realizadas com o registro da tabela, haja vista que nenhuma operao de gravao foi feita. Chamada aps a gravao da tabela SC6, ela poderia atualizar os dados estatsticos e as regras de negcio dos novos dados. Por fim, as funes do tipo Trigger contam apenas com os dados dos registros do formulrio, no utilize variveis de memria e/ou evite utilizar variveis de ambiente. Na Seo Opcional das demais funcionalidades do formulrio crie as funes complementares da interface VIEW, tais como novos botes na barra de ferramenta ou outros componentes especficos da interface.

Padro de construo para programas de Consulta


No h um padro para a estrutura dos programas de consulta, dando ao desenvolvedor liberdade para utilizar a sua criatividade. Porm algumas regras devem ser seguidas: Consultas de formulrio devem seguir o paaro dos programas de formulrio, exemplo para aquelas aplicadas na gravao e validao. As interfaces de consulta devem ser rpidas, portanto se h procedimentos que demandam tempo, mas so opcionais, elas devem ser acionadas sob demanda, atravs de um boto na interface e ter uma rgua de processamento para indicar ao usurio uma expectativa de tempo, bem como a opo para cancelar a operao. O uso do objeto TreeView deve ser evitado e somente poder ser utilizado se o nmero de elementos definidos em todos os seus nveis for pequeno e no tende a crescer conforme a base de dados. Consultas que exportem dados devem seguir as regras de privilgio do cadastro de usurios.

Padro de construo para programas de Relatrios


Os programas de relatrio so divididos em trs sees e dois tipos, a saber: o o o o o Personalizveis Seo de inicializao Seo de definio do relatrio Seo de impresso No personalizveis ou customizados Seo de definio do relatrio Seo de impresso Um relatrio da linha Microsiga Protheus pode ser de dois tipos (Personalizveis e No personalizveis), conforme a necessidade de impresso. Porm, os no personalizveis devem ser utilizados apenas para manuteno do legado e em desenvolvimentos especficos, em que o cliente no pode alterar o layout do relatrio, como os relatrios legais ( DANFe, P1/P2/P8/P9, Dirio Geral, Razo Contbil, etc.).

Relatrios Personalizveis
Na seo de inicializao dos relatrios personalizveis, deve-se verificar se o relatrio possui o tipo No personalizvel disponvel e fazemos as chamadas apropriadas conforme o caso. Function () Local oReport If FindFunction("TRepInUse") .And. TRepInUse() //--------------------------------------// Interface de impressao //--------------------------------------oReport := ReportDef() oReport:PrintDialog() Else R3() EndIf Return Na seo de definio do relatrio, devem ser criados os componentes de impresso, as sees e as clulas, os totalizadores e demais componentes que o usurio poder personalizar no relatrio. Os dados fornecidos nesta seo so utilizados para montagem da interface padro do relatrio. Static Function ReportDef() Local oReport //--------------------------------------//Criacao do componente de impressao

//--------------------------------------// TReport():New // ExpC1 : Nome do relatorio // ExpC2 : Titulo // ExpC3 : Pergunte // ExpB4 : Bloco de codigo que sera executado na confirmacao da impressao // ExpC5 : Descricao // //--------------------------------------oReport := TReport():New(/*Nome do Relatrio*/,/*Titulo do Relatrio*/,/*Pergunte*/, {|oReport| ReportPrint(oReport)},/*Descricao do relatrio*/) //oReport:SetLandscape() oReport:SetTotalInLine(.F.) Pergunte(oReport:uParam,.F.) //--------------------------------------// Criacao da secao utilizada pelo relatorio // // TRSection():New // ExpO1 : Objeto TReport que a secao pertence // ExpC2 : Descricao da seao // ExpA3 : Array com as tabelas utilizadas pela secao. A primeira tabela // sera considerada como principal para a seo. // ExpA4 : Array com as Ordens do relatrio // ExpL5 : Carrega campos do SX3 como celulas // Default : False // ExpL6 : Carrega ordens do Sindex // Default : False // //--------------------------------------//--------------------------------------// Criacao da celulas da secao do relatorio // // TRCell():New // ExpO1 : Objeto TSection que a secao pertence // ExpC2 : Nome da celula do relatrio. O SX3 ser consultado // ExpC3 : Nome da tabela de referencia da celula // ExpC4 : Titulo da celula // Default : X3Titulo() // ExpC5 : Picture // Default : X3_PICTURE // ExpC6 : Tamanho // Default : X3_TAMANHO // ExpL7 : Informe se o tamanho esta em pixel // Default : False // ExpB8 : Bloco de cdigo para impressao. // Default : ExpC2 // //--------------------------------------oSection := TRSection():New(/*oReport*/,/*Nome da secao*/,/*{Tabelas da secao}*/,/*{Array com as ordens do relatrio}*/,/*Campos do SX3*/,/*Campos do SIX*/) oSection:SetTotalInLine(.F.) TRCell():New(/*oSection*/,/*X3_CAMPO*/,/*Tabela*/,/*Titulo*/,/*Picture*/,/*Tamanho*/,/*lPixel*/,/*{|| codeblock de impressao }*/) TRFunction():New(oSection:Cell(/*X3_CAMPO*/),/* cID */,"SUM",/*oBreak*/,/*cTitle*/,/*cPicture*/,/*uFormula*/,/*lEndSection*/,.F./*lEndReport*/,/*lEndPage*/) oSection2 := TRSection():New(oSection,/*Nome da secao*/,/*{Tabelas da secao}*/,/*{Array com as ordens do relatrio}*/,/*Campos do SX3*/,/*Campos do SIX*/) oSection2:SetTotalInLine(.F.) TRCell():New(/*oSection2*/,/*X3_CAMPO*/,/*Tabela*/,/*Titulo*/,/*Picture*/,/*Tamanho*/,/*lPixel*/,/*{|| codeblock de impressao }*/) TRFunction():New(oSection2:Cell(/*X3_CAMPO*/),/* cID */,"SUM",/*oBreak*/,/*cTitle*/,/*cPicture*/,/*uFormula*/,/*lEndSection*/,.F./*lEndReport*/,/*lEndPage*/) Return(oReport)

Na seo de impresso, deve-se controlar o fluxo do relatrio, executar as querys, filtros e a ordenao definido pelos parmetros do relatrio. Os parmetros do relatrio devem ser criados utilizando-se o Cadastro de Perguntas do dicionrio de dados da Linha Microsiga Protheus (SX1). O no uso do dicionrio pode criar problemas em agendamentos do relatrio, bem como outras caractersticas do produto. Static Function ReportPrint(oReport) Local cAliasQry := "" Local lQuery := .F. #IFNDEF TOP Local cCondicao := "" #ENDIF //--------------------------------------// Transforma parametros Range em expressao SQL //--------------------------------------MakeSqlExpr(oReport:uParam) //--------------------------------------// Filtragem do relatrio //--------------------------------------#IFDEF TOP //--------------------------------------// Query do relatrio da secao 1 //--------------------------------------lQuery := .T. oReport:Section(1):BeginQuery() BeginSql Alias cAliasQry SELECT * FROM %table:% XXX,%table:% YYY WHERE XXX_FILIAL = %xFilial:XXX% AND XXX.%NotDel% AND YYY_FILIAL = %xFilial:XXX% AND YYY.%NotDel% ORDER BY DAK_COD,DAK_SEQCAR,DAI_SEQUEN,DAI_PEDIDO EndSql //--------------------------------------// Metodo EndQuery ( Classe TRSection ) // Prepara o relatrio para executar o Embedded SQL. // ExpA1 : Array com os parametros do tipo Range //--------------------------------------oReport:Section(1):EndQuery(/*Array com os parametros do tipo Range*/) #ELSE dbSelectArea(cAliasQry) dbSetOrder(1) cCondicao := 'XXX_FILIAL == "'+xFilial("XXX")+'" ' oReport:Section(1):SetFilter(cCondicao,IndexKey()) oReport:Section(1):Section(1):SetRelation(/*{|| cExpSeek }*/,/*cAlias*/,/*Order*/,/*lSeek*/) oReport:Section(1):Section(1):SetParentFilter(/*{|| lQuery}*/) #ENDIF //--------------------------------------// Metodo TrPosition() // Posiciona em um registro de uma outra tabela. O posicionamento ser // realizado antes da impressao de cada linha do relatrio. // ExpO1 : Objeto Report da Secao // ExpC2 : Alias da Tabela // ExpX3 : Ordem ou NickName de pesquisa // ExpX4 : String ou Bloco de cdigo para pesquisa. A string ser macroexe// cutada. //--------------------------------------TRPosition():New(oReport:Section(1),/*cAlias*/,/*nOrder*/,/*{|| cSeek }*/) //--------------------------------------// Inicio da impressao do fluxo do relatrio //--------------------------------------oReport:SetMeter(cAliasQry->(LastRec())) If Mod1 oReport:Section(1):Print() Else

dbSelectArea(cAliasQry) While !oReport:Cancel() .And. !(cAliasQry)->(Eof()) oReport:Section(1):Section(1):Init() oReport:Section(1):Section(1):PrintLine() oReport:Section(1):Section(1):Finish() dbSelectArea(cAliasDAI) dbSkip() oReport:IncMeter() EndDo oReport:Section(1):Finish() oReport:Section(1):SetPageBreak(.T.) EndIf Return

Relatrios No Personalizveis
Os relatrios no personalizveis podem ser criados utilizando-se a TMsPrinter para os relatrios grficos e o par de funes SetPrint/SetDefault para os no-graficos. Independente do mtodo utilizado, os relatrios deste tipo devem utilizar o Cadastro de Perguntas do dicionrio de dados da Linha Microsiga Protheus (SX1). Segue exemplo de uma estrutura de relatrio no-grfico: #INCLUDE "PROTHEUS.CH" #DEFINE CHRCOMP If(aReturn[4]==1,15,18) Function () //---------------------------------------------------------------------------------------------------// Define Variaveis //---------------------------------------------------------------------------------------------------Local Titulo := STR0001 //"" // Titulo do Relatorio Local cDesc1 := STR0002 //"" // Descricao 1 Local cDesc2 := STR0003 //"" // Descricao 2 Local cDesc3 := STR0004 //"" // Descricao 3 Local cString := "" // Alias utilizado na Filtragem Local lDic := .F. // Habilita/Desabilita Dicionario Local lComp := .T. // Habilita/Desabilita o Formato Comprimido/Expandido Local lFiltro := .T. // Habilita/Desabilita o Filtro Local wnrel := "" // Nome do Arquivo utilizado no Spool Local nomeprog:= "" // nome do programa Private Tamanho := "G" // P/M/G Private Limite := 220 // 80/132/220 Private aOrdem := {} // Ordem do Relatorio Private cPerg := "" // Pergunta do Relatorio Private aReturn := { STR0005, 1,STR0006, 1, 2, 1, "",1 } //"Zebrado"###"Administracao" //[1] Reservado para Formulario //[2] Reservado para N de Vias //[3] Destinatario //[4] Formato => 1-Comprimido 2-Normal //[5] Midia => 1-Disco 2-Impressora //[6] Porta ou Arquivo 1-LPT1... 4-COM1... //[7] Expressao do Filtro //[8] Ordem a ser selecionada //[9]..[10]..[n] Campos a Processar (se houver) Private lEnd := .F.// Controle de cancelamento do relatorio Private m_pag := 1 // Contador de Paginas Private nLastKey:= 0 // Controla o cancelamento da SetPrint e SetDefault //---------------------------------------------------------------------------------------------------// Verifica as Perguntas Seleciondas //---------------------------------------------------------------------------------------------------Pergunte(cPerg,.F.) //---------------------------------------------------------------------------------------------------// Envia para a SetPrinter

//---------------------------------------------------------------------------------------------------wnrel:=SetPrint(cString,wnrel,cPerg,@titulo,cDesc1,cDesc2,cDesc3,lDic,aOrdem,lComp,Tamanho,,lFiltro) If ( nLastKey==27 ) dbSelectArea(cString) dbSetOrder(1) Set Filter to Return Endif SetDefault(aReturn,cString) If ( nLastKey==27 ) dbSelectArea(cString) dbSetOrder(1) Set Filter to Return Endif RptStatus({|lEnd| ImpDet(@lEnd,wnRel,cString,nomeprog,Titulo)},Titulo) Return(.T.) Static Function ImpDet(lEnd,wnrel,cString,nomeprog,Titulo) Local li := 100 // Contador de Linhas Local lImp := .F. // Indica se algo foi impresso Local cbCont := 0 // Numero de Registros Processados Local cbText := "" // Mensagem do Rodape // // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // 012345678901234567890123456789012345678901234567890123456789012345678901234567890123 456789012345678901234567890123456789012345678901234567890123456789012345678901234567 89012345678901234567890123456789012345678901234567890 Local cCabec1 Local cCabec2 dbSelectArea(cString) SetRegua(LastRec()) dbSetOrder(1) dbSeek(xFilial()) While ( !Eof() .And. xFilial()== ) lImp := .T. If lEnd @ Prow()+1,001 PSAY STR0007 //"CANCELADO PELO OPERADOR" Exit EndIf If ( li > 58 ) li := cabec(Titulo,cCabec1,cCabec2,nomeprog,Tamanho,CHRCOMP) li++ Endif dbSelectArea(cString) dbSkip() cbCont++ IncRegua() EndDo If ( lImp ) Roda(cbCont,cbText,Tamanho) EndIf Set Device To Screen Set Printer To If ( aReturn[5] = 1 ) dbCommitAll() OurSpool(wnrel) Endif MS_FLUSH() Return(.T.)

Padro de construo para programas de Processamento


Durante os anos esta foi estrutura que mais evolui na Linha Microsiga Protheus, no momento focaremos apenas no ultimo padro. Os programas de processamento tem uma estrutura simples, formada por trs elementos a saber: Setup Processamento Agendamento No Setup demonstra-se a interface padro fornecida pela funo FWGridProcess. Cabe ao desenvolvedor preencher corretamente os parmetros da rotina. A montagem desta interface feita com base no dicionrio de dados e pode variar conforme o caso. A apresentao dos parmetros do dicionrio de dados SX6 e tabelas padres SX5 esto vinculados ao cadastramento da rotina no TOTVSPARAM, responsvel pela sincronizao das rotinas e parmetros envolvidos. possvel definir at cinco rguas de processamento, porm recomenda-se no usar mais do que duas rguas. Function testeba() oGrid:=FWGridProcess():New("MATA330","teste","teste do processamento",{|lEnd| u_testeba1(oGrid,@lEnd)},"MTA330","u_testeba2") oGrid:SetMeters(2) oGrid:SetThreadGrid(5) oGrid:Activate() If oGrid:IsFinished() alert("fim") Else alert("fim com erro") EndIf Return Na seo processamento, apresenta-se o fluxo de controle da rotina, a atualizao das rguas e o controle de cancelamento do processamento. Function Testeba1(oGrid,lEnd) Local nX,nY oGrid:SetMaxMeter(4,1,"teste1") For nX := 1 To 4 oGrid:SetMaxMeter(10,2,"teste2") For nY := 1 To 10 If !oGrid:CallExecute("callexecute is load",Iif(nX==5.And.nY==10,0,1)) lEnd := .T. EndIf oGrid:SetIncMeter(2) If lEnd Exit EndIf Next nY If lEnd Exit EndIf oGrid:SetIncMeter(1) Next nX Return A seo de agendamento contm os dados que so informados ao Schedule da Linha Microsiga Protheus para o correto agendamento da rotina de processamento.

Static Function SchedDef() // aReturn[1] Tipo // aReturn[2] Pergunte // aReturn[3] Alias // aReturn[4] Array de ordem // aReturn[5] Titulo Return { R, PARAMDEF, SA1, {Codigo, Nome}, Ttulo }