Desenvolvimento de Programas utilizando DDK2000 ThinTemplates + DBOs Sandro Kellermann de Carvalho Desenvolvedor Progress Acton
O que é DDK2000? DDK2000 Datasul Development Kit; Conjunto de Templates padrões para desenvolvimento; Arquitetura padrão do produto Datasul.
Arquitetura em Camadas Interface HTML Lógica de Negócio Banco de Dados Programa DDK WEB Datasul Business Objects EMS HR Programa DDK 2000
Vantagens da Arquitetura em Camadas Fomenta o reuso de software; Facilita a manutenção, devido a padronização; Códigos-fonte mais organizados, conseqüentemente.
Principais Características dos DBOs Centraliza as Regras de Negócio; Cada DBO corresponde a uma entidade (tabela); Métodos padrões para manipulação dos Registros; Override dos métodos padrões; Provê uma Pseudo orientação a objetos em Progress; Geralmente sua construção é feita em paralelo com as interfaces que o utilizarão.
Principais Templates de Interface ThinMaintenance Cadastro Simples; ThinMasterDetail Cadastro Pai X Filho; ThinZoom Pesquisa; ThinReport Relatório.
ThinMaintenance
ThinMasterDetail
ThinZoom
Antes de começar a desenvolver.. Colocar no propath o endereço x:\ddk2000 Incluir os arquivos thintemplates.cst e dbo.cst no use custom do AppBuilder:
Construindo um DBO O programa base é gerado automaticamente, através de um wizard Formado de um.p e uma include, que contém sua temptable de comunicação Template programa Base: AppBuilder -> New -> DBO Program Template include tt: AppBuilder -> New -> DBO Temp-Table Obs: Selecionar opção Procedures na tela new, para visualizar os templates de DBO
Nomenclatura Padrão DBO bo + dump-name da tabela +.p Exemplo: Tabela ord-prod Ordem de Produção Dump-name: in271 Nome do DBO: boin271.p Include TT: boin271.i
Construindo um ThinMaintenance Cadastro Simples AppBuilder -> New -> ThinMaintenance Definir Temp-table:
Construindo um ThinMaintenance Cadastro Simples AppBuilder -> New -> ThinMaintenance Definir Temp-table:
Construindo um ThinMaintenance Cadastro Simples Somente são dispostos em tela campos da tt e widgets de tela (fill-in, toggle-box, etc). Nunca campos do banco diretamente.
Construindo um ThinMaintenance Cadastro Simples Tamanho padrão dos campos fill-in: Altura: 0,88 Largura: deve ser suficiente para exibir todos os caracteres que o campo comporta. Definitions: Preencher os préprocessadores
Construindo um ThinMaintenance Cadastro Simples Procedure initializedbos: Fazer a chamada para os DBOs utilizados no programa. Substituir a chamada padrão dos DBOs por um run persistent simples: RUN spbo/bosp001.p PERSISTENT SET {&hdbotable}. Caso o programa vá navegar por todos os registros da tabela, não é necessário chamar o setconstraint. Setar o nome da Query que será aberta no DBO.
Construindo um ThinMaintenance Cadastro Simples Criar, no DBO, a abertura da query para a tela navegar. Exemplo: OPEN QUERY {&QueryName} FOR EACH {&TableName} NO-LOCK INDEXED- REPOSITION.
Construindo um ThinMaintenance Cadastro Simples Ajustar a procedure gotorecord. Trocar as definições <c d i><campo 1> pelos nomes dos campos pertencentes a chave da tabela. Na definição da frame fgotorecord, é possível ajustar o tamanho do fill-in da seguinte forma: c-state AT ROW 1.21 COL 17.72 COLON- ALIGNED VIEW-AS FILL-IN SIZE 5 BY.88
Construindo um ThinMaintenance Cadastro Simples Se for produto padrão, é necessário especial atenção para com os procedimentos de tradução na procedure gotorecord. Colocar abaixo da definição da frame gotorecord o código: run utp/ut-trfrrp.p (input frame fgotorecord:handle). {utp/ut-liter.i Vá_Para_Técnica_Estado *} assign frame fgotorecord:title = return-value.
Construindo um ThinMaintenance Cadastro Simples Pesquisa Chave Estrangeira: Campos que fazem referência a outras tabelas, devem trazer a descrição e possuir chamada para um programa de Pesquisa (Zoom). Exemplo Trigger leave campos chave estrangeira: {include/leave.i &tabela=nome-da-tabela &atributo-ref=campo-descricao-tabela-extrangeira &variavel-ref=fill-in-tela &where="ord-manut.nr-ord-produ = input frame fpage1 tt-mip-laudo.nr-ord-produ"}
Construindo um ThinMaintenance Cadastro Simples Os campos que possuem chamada de Zoom devem possuir a seguinte chamada no main block: Fill-in:load-mouse-pointer ("image/lupa.cur ). A trigger F5 do campo deverá conter a chamada do Zoom: {method/zoomfields.i &ProgramZoom="mnzoom\z01mn134.w" &FieldZoom1="nr-ord-produ" &FieldScreen1="tt-mip-laudo.nr-ord-produ" &Frame1="fPage1" &FieldZoom2="des-man-corr" &FieldScreen2="des-ordem" &Frame2="fPage1"} A trigger mouse-select-dbl-click, do campo, deverá conter a chamada: Apply F5 :U to self.
Construindo um ThinMaintenance Cadastro Simples Trigger Botão Zoom: Preencher com o nome do Zoom (Programa de Pesquisa). Criar as validações da tabela, no DBO procedure validaterecord. Parâmetro ptype, no validaterecord: create, update, delete.
Construindo um ThinMaintenance Cadastro Simples Validações básicas que devem haver na criação de um registro: - Campos pertencentes a chave devem ser diferentes de branco / nulo (?) - Não pode haver mais de um registro com mesma chave. Os erros são criados através da chamada: {method/svc/errors/inserr.i &ErrorNumber="3145" &ErrorType="EMS" &ErrorSubType="ERROR" &ErrorParameters="return-value"} No produto padrão, toda mensagem de erro deve ser cadastrada, e é representada por um número. Em específicos, pode ser usada a mensagem 17006. Toda string passada como parâmetro para a mensagem deve ser traduzida, ou seja, deve ser usada a ut-liter.i. Ex: {utp/ut-liter.i Código_do_Estado *}
Construindo um ThinZoom Pesquisa AppBuilder -> New -> ThinZoom Preencher os pré-processadores com nome das páginas, nome dos campos que serão faixas de pesquisa, etc. Cada página possui uma instância do DBO e uma temp-table independentes. Definir as temp-tables para as páginas do Zoom via AppBuilder
Construindo um ThinZoom Pesquisa Procedure initializedbos: fazer a inicialização dos DBOs para cada página do Zoom. Abaixo da chamada de cada DBO, é necessário criar uma chamada para o setconstraint daquela página e para o openquery. Exemplo: RUN setconstraintuf IN {&hdbotable1} (INPUT "":U, INPUT "ZZ":U) NO-ERROR. RUN openquerystatic IN {&hdbotable} (INPUT "UF":U) NO-ERROR. Manter a padronização de nomenclatura para query e setconstraint (exemplo: UF)
Construindo um ThinZoom Pesquisa Procedure openqueries: Preencher com os mesmos nomes das queries utilizados no initializedbos (Exemplo: UF). Procedure setconstraints: Substituir a palavra <Description> pelos nomes definidos para os setconstraint na initializedbos Os campos das faixas são gerados em tela dinamicamente, pelo template, conforme as definições feitas no Definitions. Assim, os valores para passar para os setconstraints são extraídos destes campos através de funções. Exemplo: RUN setconstraintcodigo IN {&hdbotable1} (INPUT fninirangecharpage(input 2, Input 1), INPUT fnendrangecharpage(input 2, Input 1)). Onde: - fninirangecharpage: Função que retorna o campo início da faixa, quando se trata do tipo caracter. - (Input 2, Input 1): Se trata de uma faixa da página 2, sendo que é a 1a faixa.
Construindo um ThinZoom Pesquisa Procedures returnfieldpage1, 2, x..: servem para retornar para o programa chamador o campo que está sendo pesquisado. Seu case deve ser completado com os principais campos da tabela em questão. Cada página do Zoom tem um returnfieldpagex correspondente.
Construindo um ThinZoom Pesquisa Triggers dos botões Implantar de cada página: devem ser completadas com o nome do programa de manutenção da tabela em questão. Definição dos campos dos browses de cada página do Zoom: - Definição da Query: - Entrar nas Propriedades do Browse (duplo-clique no browse) - Botão Query -> Selecionar Database Temp-Tables -> - Add a Temp-Table que será usada neste browse - desmarcar a opção Indexed Reposition -> - Selecionar a opção Sort (parte superior da página) - Selecionar a ordenação que o browse terá. Obs: Os campos pertencentes à chave primária e única da tabela deverão obrigatoriamente estar presentes na ordenação do browse. Obs 2: a mesma ordenação deverá ser usada na query definida no DBO, a seguir.
Construindo um ThinZoom Pesquisa Escolha dos campos do Browse: Na mesma tela das instruções anteriores, clicar em Fields, Add, e selecionar os campos desejados. Nesta tela, é possível editar a ordem dos campos, label, formato, etc. Ainda na tela de Propriedades do Browse, clicar em Advanced, e marcar as opções Column Movable e Column Resizable.
Construindo um ThinZoom Pesquisa Definição dos openqueries e setconstraints no DBO: SetConstraint: Criar no DBO uma procedure setconstraintxxx, onde Xxx é o nome do constraint definido anteriormente no Zoom. Esta procedure tem o objetivo de receber, como parâmetros, as faixas que servirão para a abertura da query, armazendando os valores em variáveis. Exemplo: DEF INPUT PARAM p-uf-ini AS CHAR NO-UNDO. DEF INPUT PARAM p-uf-fim AS CHAR NO-UNDO. ASSIGN c-uf-ini = p-uf-ini c-uf-fim = p-uf-fim. RETURN "OK":U. END PROCEDURE. Obs: as variáveis c-uf-ini devem ser definidas no Definitions, para que fiquem visíveis à procedure openquery.
Construindo um ThinZoom Pesquisa OpenQuery: Criar no DBO uma procedure openqueryxxx, onde Xxx é o nome da query definido anteriormente no Zoom. Esta procedure tem o objetivo fazer a abertura da query que alimentará o browse do Zoom. A query se utilizará das faixas informadas pelo setconstraint. Exemplo: OPEN QUERY {&QueryName} FOR EACH {&TableName} NO-LOCK WHERE {&TableName}.state >= c-uf-ini AND {&TableName}.state <= c-uf-fim BY {&TableName}.state INDEXED-REPOSITION. Obs: Aqui se faz necessário o uso da cláusula indexed-reposition. A cláusula by deve apresentar a mesma ordem utilizada na definição do sort do browse, definido no Zoom.
Construindo um ThinMasterDetail Cadastro Pai X Filho AppBuilder -> New -> ThinMasterDetail Possui uma tela base, na qual se navega pelos registros e se visualiza os registros filhos em browses nas páginas inferiores. Procedure initializedbos: Instanciar os DBOs da tabela pai e das tabelas filhas. No caso da tabela Pai, também deverá ser chamado, logo abaixo da instância do DBO, o openquery com a query que será base para navegação do Pai.
Construindo um ThinMasterDetail Cadastro Pai X Filho Fazer a definição das temp-tables Pai e Filhas, através do AppBuilder, definindo o campo r- rowid. Fazer a inclusão dos campos da temp-table pai no programa, semelhante a forma como foi feito no thinmaintenance. Fazer o preenchimento dos pré-processadores do Definitions de forma semelhante ao thinmaintenance.
Construindo um ThinMasterDetail Cadastro Pai X Filho Procedure gotorecord: fazer ajustes idênticos aos feitos no thinmaintenance. Procedure openqueriesson: Faz a abertura da query dos browses filhos, fazendo o link com o registro pai. A expressão <ParentName>, para a query de cada Filho, deve ser substituida por um nome que represente o pai. O template usará esse nome para procurar uma procedure, no DBO do Filho, para fazer a ligação com o DBO Pai. A expressão <QueryName> deverá ser substituida pelo nome da query que será aberta no DBO de cada Filho.
Construindo um ThinMasterDetail Cadastro Pai X Filho Browses Filhos: Deverão ser configurados de forma semelhante aos browses do thinzoom (seleção de campos, query, ordem). O DBO do Pai deverá possuir um openquery com o nome definido no initializedbos.
Construindo um ThinMasterDetail Cadastro Pai X Filho O DBO de cada filho deverá possuir uma procedure linktoxxx. Onde Xxx é o nome definido na procedure openqueriesson em substituição à expressão <ParentName>. Seguirá este exemplo: DEFINE INPUT PARAMETER phandle AS HANDLE NO-UNDO. RUN getkey IN phandle (OUTPUT pnr-ord-produ, OUTPUT pcd-tarefa, OUTPUT pcod-variavel). RETURN "OK":U. END PROCEDURE. Quando o programa navegar pela tabela Pai, o template chamará esta procedure a cada iteração, passando através do parâmetro phandle o handle do DBO da tabela Pai. Possibilitando, então, a chamada da procedure getkey, que retornará a chave do registro posicionado no instante.
Construindo um ThinMasterDetail Cadastro Pai X Filho O DBO filho deverá possuir uma procedure openqueryxxx, onde Xxx é o nome definido na procedure openqueriesson em substituição à expressão <QueryName>. Esta procedure deverá abrir a query do DBO apenas para os registros do pai posicionado no momento, sinalizado através da chave retornada através da procedure LinkToXxx.
Construindo um ThinMasterDetail Cadastro Pai X Filho Os botões de Incluir, Copiar e Alterar deste template são preparados para chamar uma tela a parte para executar o processo, tanto para o registro pai como para os registros filhos. Esta tela deve ser construída no template thinmaintenancenonavigation.
EXERCÍCIOS!!! Materiais para Consulta: Este ppt; Manual Thin Templates; Manual Construção DBOs; Manual Uso DBOs. Manuais disponíveis em x:\ddk2000\manual Lista de Exercícios e Base disponível em y:\treinamentoddk
OBRIGADO! Sandro Kellermann de Carvalho sandro.carvalho@datasul.com.br Este material é de propriedade da DATASUL S.A., sendo proibida a sua reprodução em qualquer meio, total ou parcial, sem aprovação por escrito. Todos os direitos estão reservados. A informação contida aqui é confidencial e não pode ser utilizada fora da empresa ou das franquias que fazem parte da nossa rede, não podendo ser divulgada para clientes, parceiros ou outra empresa ou indivíduo, sem o prévio consentimento de um diretor da DATASUL S.A. As opiniões expressas aqui estão sujeitas a modificação sem aviso prévio.