TOTVS Datasul - 598 - Manual de Técnicas

Transcrição

TOTVS Datasul - 598 - Manual de Técnicas
Manual de Técnicas
Interface para WEB
Setembro/1999
Versão 1.19
Não homologado
Copyright © 1998 DATASUL S.A. Todos os direitos reservados.
Nenhuma parte deste documento pode ser copiada, reproduzida, traduzida ou
transmitida por qualquer meio eletrônico ou mecânico, na sua totalidade ou em
parte, sem a prévia autorização escrita da DATASUL S.A., que reserva-se o
direito de efetuar alterações sem aviso prévio. A DATASUL S.A não assume
nenhuma responsabilidade pelas conseqüências de quaisquer erros ou
inexatidões que possam aparecer neste documento.
DATASUL S.A.
Av. Santos Dumont, 831, Joinville, SC, CEP 89.222-900
i
Índice
CAPÍTULO 1
Introdução ............................................................................... 1
CAPÍTULO 2
Templates para WEB .............................................................. 3
Como utilizar o SWG .................................................................................... 3
Estilo Cadastro e Consulta Simples ............................................................... 6
Como construir o Cadastro Simples .............................................................. 7
Especificação Técnica – Cadastro Simples.................................................... 8
Includes utilizadas no Cadastro e Consulta Simples / Complexo ................ 14
Estilo Cadastro Complexo ........................................................................... 15
Como construir o Cadastro Complexo......................................................... 16
Especificação Técnica – Cadastro Complexo .............................................. 17
Estilo Pai x Filho ......................................................................................... 20
Especificação Técnica – Consulta PAI ........................................................ 21
Includes utilizadas no Consulta PAI ............................................................ 26
Especificação Técnica – Consulta Filho ...................................................... 26
Includes utilizadas no Consulta Filho .......................................................... 31
Especificação Técnica – Cadastro PAI SIMPLES/COMPLEXO................ 32
Especificação Técnica – Cadastro Filho SIMPLES/COMPLEXO.............. 38
Estilo Consulta Simples / Estilo Consulta Complexa .................................. 38
Estilo Vá Para .............................................................................................. 40
Especificação Técnica – Vá Para ................................................................. 41
Estilo Pesquisa / ZOOM .............................................................................. 45
Estilo Relatório ............................................................................................ 52
CAPÍTULO 3
Como usar uma BO .............................................................. 55
CAPÍTULO 4
Contexto de Sessão ............................................................. 57
Funcionamento ............................................................................................ 57
ii
CAPÍTULO 5
Contexto de Transação ........................................................ 61
Funcionamento............................................................................................. 62
Recuperando o número da última seqüência ............................................... 64
CAPÍTULO 6
Perfil do Usuário ................................................................... 65
Funcionamento............................................................................................. 65
CAPÍTULO 7
Consultas Relacionadas ...................................................... 67
CAPÍTULO 8
Uso de páginas de código ................................................... 69
Funcionamento............................................................................................. 69
CAPÍTULO 9
Customização de arquivos WebSpeed ............................... 71
Funcionamento............................................................................................. 71
CAPÍTULO 10
Utilitários ............................................................................ 73
WU-GRAF ................................................................................................... 73
CAPÍTULO 11
Tratamento de Erros ......................................................... 78
CAPÍTULO 12
Validações de Campos na WEB ...................................... 79
CAPÍTULO 13
API de BROWSE – wu-browse.p ...................................... 83
CAPÍTULO 14
Preferências do Usuário – wu-uspf.p.............................. 91
CAPÍTULO X...
Considerações Gerais ...................................................... 95
Includes do EMS 2 GUI............................................................................... 95
Label dos Campos no HTML´s.................................................................... 95
Controles para a não utilização de cache ..................................................... 96
Inclusão recursiva ........................................................................................ 96
Fechamento de janelas de inclusão de pai ................................................... 96
Validações em Geral .................................................................................... 96
Validação de Inicial e Final ......................................................................... 97
Validações em Relatórios ............................................................................ 97
Desenvolvimento Específico/Customizações .............................................. 97
Como fazer links para detalhe do registro ................................................... 98
Como habilitar/desabilitar campos nos HTML´s ......................................... 99
Utilizar a área do label do radio-set e check-box para click do mouse ........ 99
Botão de zoom para tabela estrangeira ...................................................... 100
Como selecionar um Texto via JavaScript................................................. 100
CAPÍTULO 1
Introdução
iii
Como definir nomes das FRAMES(Janelas): ............................................ 102
Blocos de Assign e funções do Webspeed................................................. 104
Programa de filho chamando um outro programa de Pai x Filho .............. 105
Selecionar , Inverter e Desmarcar CHECKBOX via JavaScript ............... 109
Como trazer em relatórios o servidor default do usuário ........................... 110
Como acrescentar um botão “Implantar” no Zoom ................................... 112
Utilização de Help na WEB........................................................................113
1
CAPÍTULO 1
Introdução
Definição
Este manual tem por objetivo relacionar as técnicas para construção de
programas de interface para WEB (verifique também o manual de técnicas de
BO´s).
Características
As principais características são:
Nomenclatura

o nome do programa deve ser “w” + nome do programa GUI
correspondente. Exemplo: wpd0501.w

o nome do HTML é o nome do programa “.w” correspondente + a
terminação “html”. Exemplo: wpd0501.html.

os programas criados para WEB devem estar em letras minúsculas.
Estrutura de Diretórios
A estrutura para diretórios deve ser desta forma:
1º Nível
2º Nível
<Diretório Produto> web/
3º Nível
Finalidade
app/
Contém os programas dos módulos (.w, .html, .i).
ccp/
pdp/
ctp/
...
adzoom/
unzoom/
Programas de zoom separados por aplicativos.
2
inzoom/
dizoom/
adgo/
Programas de VáPara (goto) separados por
aplicativo.
ungo/
ingo/
digo/
wimages/ Imagens utilizadas nos programas de interface da
web.
winclude/ Includes específicos para includes dos templates
web.
wutp/
Utilitários específicos para web.
Imagens
As imagens devem estar nos padrões .GIF OU .JPG.
Devem ser criadas sempre no diretório: WEB/wimages
A referência a imagens nos programas e htmls deve ser:
/ems20web/wimages/<nome-image>

Observação:
/ems20web/ é um alias que deve ser configurado no webserver para que as
imagens possam ser localizadas. Este alias deve ser inicializado com <dirbase>/web/ (dir-base é o diretório onde foi instalado as transações web).
Testes com Nestcape e Internet Explorer
Os programas para WEB são desenvolvidos utilizando como browsers padrão
o Nestcape e Internet Explorer.
Portanto, os programas devem ser testados nestes dois browsers, para garantir
o correto funcionamento dos programas nestes browsers padrão.
Se algum programa apresentar problema em um dos dois browsers, deve-se
procurar simplificar a interface de forma a solucionar o problema. Deve-se
procurar usar os recursos mais simples.
3
CAPÍTULO 2
Templates para WEB
Descrição
Os templates para WEB são gerados automaticamente usando a ferramenta
SWG. Após a geração inicial o programador passará então, a fazer as
implementações nos programas gerados.
Como utilizar o SWG
Descrição
Basicamente, para utilizar o SWG, devem ser seguidos os seguintes passos:
4

definir o estilo de programa que vai ser construído: cadastro simples,
cadastro complexo, pai x filho, etc.;

selecionar os campos que aparecerão no HTML;

especificar as características dos campos selecionados;

especificar os parâmetros do programa (nome externo, etc.);

gerar o programa;

fazer os ajustes necessários no programa (de acordo com o estilo).
Definição do Estilo do Programa
O programador deve definir junto ao analista qual o estilo do programa a ser
construído. De acordo com o estilo, será necessário fazer mais ou menos
coisas no SWG. Neste manual, estão os passos necessários para cada estilo.
Seleção dos campos para o HTML
Através da função de seleção devem ser definidos os campos que aparecerão
no HTML. Estes campos podem ser definidos diretamente no SWG ou através
da importação de um programa escrito com SmartObjects.
O SWG reconhece automaticamente os bancos conectados e então o
programador pode selecionar um banco para escolha das tabelas e campos.
Especificar as características dos campos selecionados
Para cada campo pode ser especificado alguma característica, tipo formato
(view-as) e alinhamento.
CAPÍTULO 2
Templates para WEB
Especificação dos parâmetros do programa
Na parte de parâmetros o programador deve especificar qual o nome do
programa a ser gerado, qual o programa de pesquisa e ‘vá para’, etc.
Dependendo do estilo deverão ser informados, mais ou menos, os parâmetros.
Geração do Programa
Após selecionar os campos e informar os parâmetros, o SWG poderá gerar o
programa. Será mostrado o nome e diretório onde o programa foi gerado.
Ajustes no programa
Depois de gerado pelo SWG, o programador deve fazer novos ajustes
diretamente no programa, haja visto que, o SWG não faz engenharia reversa,
ou seja, se for gerado novamente serão perdidas as alterações.
5
6
Estilo Cadastro e Consulta Simples
Definição
A principal característica de um Cadastro Simples é que todos os campos são
visíveis na área de trabalho.
CAPÍTULO 2
Templates para WEB
7
Como construir o Cadastro Simples
Selecionar os campos

selecione os campos e insira as variáveis que serão utilizados no Cadastro
Simples;

faça os ajustes necessários nos atributos dos campos;

ajuste a ordem dos campos.
Informar Parâmetros

escolher o Estilo Cadastro Simples;

selecionar os Botões que serão utilizados;

preencher o nome do programa. (Para programas web: wprograma);

preencher o nome do programa de Vá para. Informando o Método, Altura
e Largura;

preencher o nome do programa Pesquisa. Informando o Campo, Altura e
Largura.
Gerar o programa

através da opção de geração de programas do SWG gerar o fonte do
programa.
Alterações necessárias após a geração

se o programa que acabou de ser gerado não faz nenhuma referência a
outras tabelas, então está pronto o Cadastro Simples;

se o programa utiliza campos de outras tabelas (chaves estrangeiras), então
veja a técnica de ‘Como construir ZOOM’;

se houver alguma regra de navegação (classificação diferente, por
exemplo), então deverá ser customizada a query do BO que o programa
utiliza;
8
Especificação Técnica – Cadastro Simples
Arquivo HTML
<html>
<head>
<link rel="StyleSheet" type="text/css" href="/ems20web/padrao.css">
Arquivo de Estilos para o produto . É neste arquivo que se encontra as
configurações de cor , bordas , links e etc
<meta http-equiv="Cache-Control" content="No-Cache">
<meta http-equiv="Pragma"
content="No-Cache">
<meta http-equiv="Expires"
content="0">
Estas três Meta Tags são para eliminar o cache , isto é , o navegador não irá
utilizar cache .
</head>
<script language="JavaScript">
function inicializa() {
parent.document.title = 'Template de Cadastro Simples';
parent.panel("NGSACMDUROLHE","WCADSIMP 2.00.00.000");
}
</script>
Função Inicializa atribui ao documento um Título e os Botões do Painel
O significado de cada letra é:
N
Botões de Navegação
G
Go to / Vá Para
S
Search / Pesquisa
A
Add / Adicionar
C
Copy / Copiar
M
Modify / Modificar
D
Delete / Deletar
CAPÍTULO 2
Templates para WEB
9
U
Undo / Desfazer
R
Reset / Limpar
O
OK (Submit/Submeter)
H
Home
E
Exit
<body topmargin="0" leftmargin="0" onload="inicializa()">
<form method="post">
<input type="hidden" name="hid_chave">
<input type="hidden" name="hid_oper">
Estas duas variáveis são de controle dos templates . Onde são
armazenados o ROWID do registro corrente e a operação . Nos cadastros
e consultas o uso destes dois elementos é obrigatório . Atenção : Devem
ser declarados com os dois primeiros elementos do formulário .
<div align="center"> <p><br></p>
<center>
<table align="center" border="0" cellpadding="0" cellspacing="3" width="90%"
class="tableForm">
<tr>
<td class="barratitulo">
<!--BXLS-->Template de Cadastro Simples<!--EXLS-->
</td>
</tr>
<!—BXLS Palavra <!—EXLS É utilizado para que o Datasul Translation
Kit possa traduzir os programas para outras línguas .
<tr>
<td class="linhaForm" nowrap align="center"><br><center>
<fieldset>
<table align="center" border="0" cellpadding="0" cellspacing="1"
width="100%">
<tr>
10
<th align="right" class="linhaForm" nowrap width="40%">
<!--BXLS-->Código <!--EXLS-->:
</th>
<td class="linhaForm" align="left" nowrap width="60%">
<input type="text" size="5" maxlength="5" name="w_cod">
</td>
Nas Tags para colunas na tabela , deve-se especificar na <th> um width
=”40%” e a <td> um width=”60%” . Este é o valor default , se houver
necessidade é perfeitamente configurável . Mas lembre-se a tag <th> deve sempre
Ter um valor menos que a tag <td>
</tr>
</table>
</fieldset>
No código acima deve-se declarar os campos chaves do programa. Assim
todos os campos chaves ficarão no primeiro <FieldSet> .
<fieldset>
<table align="center" border="0" cellpadding="0" cellspacing="1"
width="100%">
<tr>
<th align="right" class="linhaForm" nowrap width="40%">
<!--BXLS-->Nome <!--EXLS-->:
</th>
<td class="linhaForm" align="left" nowrap width="60%">
<input type="text" size="40" maxlength="40" name="w_nome">
</td>
</tr>
</table>
</fieldset>
<p><br></center></td> </tr></table></center></div>
</form>
</body>
</html>
Todos os nomes de elementos de formulários devem começar com w_
nomedocampo.
CAPÍTULO 2
Templates para WEB
Arquivo .W
Definitions
&GLOBAL-DEFINE ttTable1
tt-tabela
 Definir o nome da Tabela temporária .
Exemplo :
&GLOBAL-DEFINE ttTable1
tt-customer
&GLOBAL-DEFINE hDBOTable1 boxx000
 Definir o nome da DBO que será utilizada.
Exemplo:
&GLOBAL-DEFINE hDBOTable1 bosp001
&GLOBAL-DEFINE DBOTable1
tabela
 Definir o nome da Tabela que a DBO utiliza .
Exemplo:
&GLOBAL-DEFINE DBOTable1
customer
&GLOBAL-DEFINE TableName tabela
 Definir o nome da Tabela que será utilizada .
Exemplo :
&GLOBAL-DEFINE TableName
customer
&GLOBAL-DEFINE PROGZO diretório/programa
 Definir o nome do programa de Search que será chamado .
Exemplo :
&GLOBAL-DEFINE PROGZO adzoom/wz01ad001.p
&GLOBAL-DEFINE TAMZOOM "000" "000"
 Definir a largura e altura (respectivamente) que a janela de Search terá .
Exemplo :
&GLOBAL-DEFINE TAMZOOM "500" "350"
11
12
&GLOBAL-DEFINE PROGGO diretório/programa
 Definir o nome do programa de Go to / Vá para .
Exemplo :
&GLOBAL-DEFINE PROGGO templates/wgoto.w
&GLOBAL-DEFINE TAMGO "000" "000"
 Definir a largura e altura (respectivamente) que a janela de Go to terá .
Exemplo :
&GLOBAL-DEFINE TAMGO "300" "250"
&GLOBAL-DEFINE THISNAME diretório/programa.w
 Definir o nome deste programa .
Exemplo :
&GLOBAL-DEFINE THISNAME templates/wcadsimp.w
Procedure Process-web-request
RUN diretório/programa PERSISTENT SET {&hDBOTable1}.
 Definir o diretório e nome da DBO que será utilizada .
Exemplo :
RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.
RUN openQueryStatic in {&hDBOTable1} (input "Main":u).

Definir as restrições (utilizando o Método de restrição) O Método de
restrição deve ser utilizado antes da abertura da Query.
 Definir qual a Query será aberta .
Exemplo :
RUN openQueryStatic in {&hDBOTable1} (input "Main":u).
Procedure assignFields



Definir quais os campos que serão validados com wi-datatype.i .
Verificar no Capítulo de Validações o funcionamento da wi-datatype.i
Fazer a associação entre as variáveis de tela (HTML) com a tabela
temporária .
if request_method = "POST" then DO WITH FRAME {&FRAME-NAME} :
CAPÍTULO 2
Templates para WEB
create {&ttTable1} .
{web/winclude/wi-datatype.i &dst="{&ttTable1}.cust-num" &type="integer"
&org="w_cust_num:screen-value"}
ASSIGN {&ttTable1}.name
= w_name:screen-value
{&ttTable1}.address = w_address:screen-value
{&ttTable1}.city
= w_city:screen-value
{&ttTable1}.state = w_state:screen-value
{&ttTable1}.sales-rep = w_sales_rep:screen-value
.
{web/winclude/wi-assign.i}
end.
RUN SUPER.
END PROCEDURE.
Procedure displayFields

Fazer a associação entre a tabela temporária e as variáveis de tela.
FIND FIRST {&ttTable1} NO-LOCK NO-ERROR.
DO WITH FRAME {&FRAME-NAME}:
ASSIGN w_cust_num:screen-value
= string({&ttTable1}.cust-num)
w_name:screen-value
= {&ttTable1}.name
w_address:screen-value
= {&ttTable1}.address
w_city:screen-value
= {&ttTable1}.city
w_state:screen-value
= {&ttTable1}.state
w_sales_rep:screen-value = {&ttTable1}.sales-rep
hid_chave:screen-value
= string({&ttTable1}.rRowid)
.
END.
END PROCEDURE.
13
14
Includes utilizadas no Cadastro e Consulta Simples / Complexo
{dbo\boXX999.i {&ttTable1}}
Include que define o nome da tabela temporária na Interface .
{method\dbotterr.i}
Includes Utilizadas para a integração da Interface com a DBO .
{web/winclude/wi-datatype.i}
Includes para fazer a validação de Tipo de Dado .
{web/winclude/wi-assign.i}
Include que joga os valores da Interface para a DBO e recebe , se
houverem , os erros .
{web/winclude/wi-error.i}
Verifica se houveram erros na temp-table de erros e se houver gera o
código Javascript necessário para montar a tela de erro .
{web/winclude/wi-enafied.i}
Habilita e Desabilita os campos necessários para a navegação .
{web/winclude/wi-navega.i}
Include que controla a navegação . Chama os metodos corretos para a
navegação .
{web/winclude/wi-header.i}
Include que contem algumas regras para a navegação e controle de
chamadas de programas Filhos.
{web/winclude/wi-metpost.i}
Include que contem as chamadas para os metodos internos do Webspeed para
o Metodo POST
{web/winclude/wi-metget.i}
Include que contem as chamadas para os metodos internos do Webspeed para
o Metodo GET
CAPÍTULO 2
Templates para WEB
Estilo Cadastro Complexo
Definição
Se todos os campos não ficarem visíveis na área de trabalho, é necessário a
criação de folders. Assim, as informações ficarão reunidas, facilitando o
preenchimento dos dados.
15
16
Como construir o Cadastro Complexo
Selecionar os campos

selecione os campos e insira as variáveis que serão utilizados no Cadastro
Simples;

faça os ajustes necessários nos atributos dos campos;

ajuste a ordem dos campos;

utilizar o botão Folders para criar os folders necessários.
Informar Parâmetros

escolher o estilo Cadastro Complexo;

selecionar os Botões que serão utilizados;

preencher o nome do programa. (para programas web: wprograma);

preencher o nome do programa de Vá para. Informando o Método, Altura
e Largura;

preencher o nome do programa de Pesquisa. Informando o Campo, Altura
e Largura;

preencher o nome dos folders. Basta selecionar alguma opção, que será
aberta uma tela para que o nome seja alterado.
Gerar o programa

utilizar a opção de geração de programa;
Alterações necessárias após a geração

se o programa que acabou de ser gerado não faz nenhuma referência a
outras tabelas, então está pronto o Cadastro Complexo;

se o programa utiliza campos de outras tabelas (chaves estrangeiras), então
veja a técnica de ‘Como construir ZOOM’;
CAPÍTULO 2
Templates para WEB

17
se houver alguma regra de navegação (classificação diferente, por
exemplo), então deverá ser customizada a query do BO que o programa
utiliza.
Especificação Técnica – Cadastro Complexo
O inicio do HTML é o mesmo que no cadastro simples. Incluindo os dois elementos
do formulários : hid_chave e hid_oper.
O arquivo .w é exatamente igual ao de consulta/cadastro simples. A única
diferença é o arquivo HTML , que está com um formato diferente . (Uma tentativa de
simular o Client X Server) .
Segue o HTML que deve ser repetido para cada Folder . As alterações serão
explicadas abaixo .
<div align="center"><center>
Definir o nome do folder . Neste exemplo é folder1
<a name="folder1"></a>
<table align="center"border="0" cellpadding="0" cellspacing="3" width="90%"
class="tableForm">
<tr>
<td colspan="3" class="barratitulo"><!--BXLS-->Template de Cadastro
Complexo<!--EXLS--> </td>
</tr>
O Título do Programa deverá aparecer em todos os folders .
<tr>
<td class="linhaForm" nowrap><div align="center"><center>
<table align="center" border="1" cellpadding="0" cellspacing="1"
width="100%"
class="selectedFolder">
<tr>
<td class="linhaForm" nowrap align="center" width="100%">
<!--BXLS-->Principal<!--EXLS-->
</td>
O Folder selecionado não deverá conter o Link para ele mesmo .
18
</tr>
</table>
</center></div>
</td>
<td class="unselectedFolder" nowrap align="center" >
<a href="#folder2"><!--BXLS-->Secundário<!--EXLS--></a>
</td>
<td class="unselectedFolder" nowrap align="center" >
<a href="#folder3"><!--BXLS-->Terceiro<!--EXLS--></a>
</td>
</tr>
</table>
</center></div>
<div align="center"><center>
<table align="center" border="1" cellpadding="0" cellspacing="1" width="90%"
class="tableForm"
height="300">
<tr>
<td valign="top" class="linhaForm" nowrap align="center" colspan="5"
width="100%"><br>
<table align="center" border="0" cellpadding="0" cellspacing="1">
<tr>
<th align="right" class="linhaForm" nowrap><!--BXLS-->Código<!--EXLS->:</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="5" maxlength="5" name="w_cust_num">
</td>
Sempre deve ser definido <th> contendo o Label e uma <td> contendo um
elemento de formulário
</tr>
<tr>
<th align="right" class="linhaForm" nowrap><!--BXLS-->Nome<!--EXLS->:</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="40" maxlength="40" name="w_name">
</td>
</tr>
</table>
<p><br></p>
</td>
</tr>
</table>
</center></div>
CAPÍTULO 2
Templates para WEB
<p><br><br><br><br></p>
Estes <br> repetidos várias vezes deverão ser ajustados pelo
programador. Para que o folder fique corretamente ajustado na tela .
Lembrando que o padrão para o desenvolvimento é 800 x 600 .
19
20
Estilo Pai x Filho
Características
Para construção do estilo Pai x Filho, são necessários gerar 2 programas.
Consulta Pai e Filho (<nome>.w, <nome>.htm)

a consulta Pai e Filho gerada é sempre Simples;

siga os mesmos passos do estilo Consulta Simples;

selecione o estilo Consulta Pai ;

utilizar opção de geração do programa.
Quando o programador selecionar a Consulta Pai , o SWG gera 2 arquivos:

HTML - por exemplo: wap0005a.htm;

W - por exemplo: wap0005a.w;

Editar o arquivo .w e incluir os campos do Filho.
CAPÍTULO 2
Templates para WEB
21
Especificação Técnica – Consulta PAI
Arquivo HTML
O HTML do Consulta PAI não deve existir as TAGs de finalização
(</body> e </html> do HTML . Pois a consulta Pai irá chamar o consulta
Filho e este finalizará o HTML com uma include de finalização .
Existe um pequeno BUG no Webspeed e o arquivo HTML deve
conter duas linhas em branco no final do documento .
ATENÇÃO :
Existe um formulario para a consulta filho e outro formulário para a
consulta Pai . Sempre um (1) formulário é submetido de vez . E sempre com o
Botão de Submit que estiver em cada Formulário . Não é possível submeter 2
formulários HTML de uma só vez . Por isto não deve ser retirado a TAG
</form> do consulta filho .
<body topmargin="0" leftmargin="0" onload="inicializa()">
<script language="JavaScript">
Definir quais os Botões a Consulta Pai irá conter . Se houver os botões de
cadastro Pai , Modificar e Copiar , este será aberto em uma nova janela .
(Verificar Cadastro PAI) . O significado de cada letra está descrito no
Item Cadastro e Consulta Simples .
function inicializa() {
parent.panel("NGSACMDLHE","WCONPAI 2.00.00.000");
}
</script>
<form method="post">
<input type="hidden" name="hid_chave">
<input type="hidden" name="hid_oper">
<p><br></p>
<div align="center"><center>
<table align="center" border="0" cellpadding="0" cellspacing="3"
width="90%" class="tableForm">
<tr>
<td class="barratitulo">
22
<!--BXLS--> Template de Consulta PAI x FILHO <!--EXLS-->
</td>
</tr>
<tr>
<td class="linhaForm" nowrap align="center">
<div align="center"><center>
<table align="center" border="0" cellpadding="0" cellspacing="1">
<tr>
<th align="right" class="linhaForm" nowrap>
<!--BXLS-->Código <!--EXLS-->:
</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="5" maxlength="5" name="w_cod">
</td>
</tr>
<tr>
<th align="right" class="linhaForm" nowrap>
<!--BXLS-->Nome <!--EXLS-->:</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="30" maxlength="30"
name="w_nome">
</td>
</tr>
</table>
</center></div>
</td>
</tr>
</table>
</form>
</center></div>
Não esquecer de deixar 2 linhas em branco no final do documento HTML.
CAPÍTULO 2
Templates para WEB
Arquivo .W
Definitions
&GLOBAL-DEFINE ttTable1
tt-tabela
Definir o nome da tabela temporária .
Exemplo :
&GLOBAL-DEFINE ttTable1
tt-customer
&GLOBAL-DEFINE hDBOTable1 boXX999
Definir o nome da BO que será utilizada .
Exemplo :
&GLOBAL-DEFINE hDBOTable1 bosp001
&GLOBAL-DEFINE DBOTable1 tabela
Definir o nome da Tabela que a DBO irá utilizar .
Exemplo :
&GLOBAL-DEFINE DBOTable1 customer
&GLOBAL-DEFINE TableName tabela
Definir o nome da Tabela .
Exemplo :
&GLOBAL-DEFINE TableName customer
&GLOBAL-DEFINE PROGZO diretorio/wzoom.p
Definir o diretório e nome do programa de Zoom .
Exemplo :
&GLOBAL-DEFINE PROGZO adzoom/wz01ad001.p
&GLOBAL-DEFINE TAMZOOM "999" "999"
Definir Largura e Altura que o programa de Zoom irá utilizar .
Exemplo :
23
24
&GLOBAL-DEFINE TAMZOOM "500" "350"
&GLOBAL-DEFINE PROGGO diretorio/wgoto.w
Definir o Diretório e nome do programa de Vá Para (GoTo) .
Exemplo :
&GLOBAL-DEFINE PROGGO adgo/wg01ad012.w
&GLOBAL-DEFINE TAMGO "999" "999"
Definir Largura e Altura que o Programa de Vá Para (Goto) irá utilizar.
Exemplo:
&GLOBAL-DEFINE TAMGO "300" "250"
&GLOBAL-DEFINE THISNAME diretorio/thisprogram.w
Definir o nome deste programa .
Exemplo :
&GLOBAL-DEFINE THISNAME app/wap001.w
&GLOBAL-DEFINE CADFATHER diretorio/cadpai.w
Definir o nome do programa de Cadastro PAI .
Exemplo :
&GLOBAL-DEFINE CADFATHER app/wapp002.w
&GLOBAL-DEFINE CADFAWID 999
Definir a Largura que o programa de Cadastro PAI irá utilizar .
Exemplo :
&GLOBAL-DEFINE CADFAWID 600
&GLOBAL-DEFINE CADFAHEI 999
Definir a Altura que o programa de Cadastro PAI irá utilizar .
Exemplo:
&GLOBAL-DEFINE CADFAHEI 160
CAPÍTULO 2
Templates para WEB
25
&GLOBAL-DEFINE CADSON diretorio/cadfilho.w
Definir o nome do programa de Cadastro Filho .
Exemplo :
&GLOBAL-DEFINE CADSON app/wap0003.w
Procedure displayFields

Fazer a associação entre a tabela temporária e as variáveis de tela.
FIND FIRST {&ttTable1} NO-LOCK NO-ERROR.
DO WITH FRAME {&FRAME-NAME}:
ASSIGN w_cust_num:screen-value = string({&ttTable1}.cust-num)
w_name:screen-value = {&ttTable1}.name
hid_chave:screen-value = string({&ttTable1}.rRowid)
.
END.
Procedure process-web-request :



Executar a DBO.
Abrir a Query .
Executar a consulta Filho (Sempre será passado para o consulta Filho
a Tabela do PAI . Isto evita excutar a DBO do PAI novamente .)
RUN outputHeader.
RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.
RUN openQueryStatic in {&hDBOTable1} (input "Main":u).
{web/winclude/wi-getpai.i}
RUN displayError .
delete procedure {&hDBOTable1}.
RUN web/app /wap0004.p (input table {&ttTable1}) .
26
Includes utilizadas no Consulta PAI
{dbo\boXX999.i {&ttTable1}}
Include que define o nome da tabela temporária na Interface .
{method\dbotterr.i}
Includes Utilizadas para a integração da Interface com a DBO .
{web/winclude/wi-error.i}
Verifica se houveram erros na temp-table de erros e se houver gera o
código Javascript necessário para montar a tela de erro .
{web/winclude/wi-enafied.i}
Habilita e Desabilita os campos necessários para a navegação .
{web/winclude/wi-navega.i}
Include que controla a navegação . Chama os metodos corretos para a
navegação .
{web/winclude/wi-header.i}
Include que contem algumas regras para a navegação e controle de
chamadas de programas Filhos.
{web/winclude/wi-getpai.i}
Include que contem as chamadas para os metodos internos do Webspeed para
o Metodo GET .
Especificação Técnica – Consulta Filho
O Programa de Consulta Filho é um CGI-WRAPER .
Definitions :
&GLOBAL-DEFINE THISNAME diretorio/confilho.p
Definir o diretório e nome deste programa .
Exemplo:
CAPÍTULO 2
Templates para WEB
27
&GLOBAL-DEFINE THISNAME ricardo/wconson.p
&GLOBAL-DEFINE FATHERNAME conpai.w
Definir o nome do Programa PAI . (Somente o Nome)
Exemplo :
&GLOBAL-DEFINE FATHERNAME wconpai.w
&GLOBAL-DEFINE ttTableFather tt-tabela
Definir o nome da tabela temporária PAI .
Exemplo:
&GLOBAL-DEFINE ttTableFather tt-customer
&GLOBAL-DEFINE TableName tabela
Definir o nome da tabela PAI .
Exemplo:
&GLOBAL-DEFINE TableName customer
&GLOBAL-DEFINE ttTableSon tt-tabela-filho
Definir o nome da tabela temporária do Filho .
Exemplo:
&GLOBAL-DEFINE ttTableSon tt-order
&GLOBAL-DEFINE TableName tabela-filho
Definir o nome da Tabela do Filho .
Exemplo:
&GLOBAL-DEFINE TableName Order
&GLOBAL-DEFINE hDBOSon
boXX999
Definir o nome da DBO do Filho .
Exemplo:
&GLOBAL-DEFINE hDBOSon
bosp005
&GLOBAL-DEFINE sonNAME
cadfilho.w
28
Definir o nome do Programa de Cadastro Filho .
Exemplo:
&GLOBAL-DEFINE sonNAME
wcadsonc.w
&GLOBAL-DEFINE sonWIDTH
999
Definir a largura que o programa de Cadastro filho ocupará .
Exemplo:
&GLOBAL-DEFINE sonWIDTH
500
&GLOBAL-DEFINE sonHEIGHT
999
Definir a altura que o programa de Cadastro filho ocupará .
Exemplo:
&GLOBAL-DEFINE sonHEIGHT 215
&GLOBAL-DEFINE SONBUTTONS ADD,MOD,DEL
Definir os botões para Incluir , Modificar e Eliminar registros filhos.
O preprocessador deve ser definido apenas com os botões desejados.
Exemplo:
1) &GLOBAL-DEFINE SONBUTTONS ADD,MOD,DEL
2) &GLOBAL-DEFINE SONBUTTONS ADD,DEL
Procedure addCol :



Definir quais os campos que serão apresentados na Consulta Filho .
Utilizar os métodos da API de BROWSE .
Se o programa de Consulta chamar : Inclusão , Modificação e Exclusão,
deve-se definir um elemento de Radio chamado xradio .
CAPÍTULO 2
Templates para WEB
Exemplo :
RUN addInput in h-brwapi ("xradio" , "R" , "" , "center" , ?) .
RUN addField in h-brwapi ("Cust-Num", "I", "Customer", "center", ?).
RUN addField in h-brwapi ("Order-num", "I", "Order", "center", ?).
RUN addField in h-brwapi ("Order-Date", "D" , "Data", "center", ?).
Procedure addNav :


Definir se vai existir Navegação no Browse .
Definir qual o tamanho da Borda .
RUN setNavigation in h-brwapi (true).
RUN setBorder in h-brwapi (2).
Procedure generateHeaderSon :

Se houver mais botões além dos Default(Incluir , Modificar e Excluir) ,
deve utilizar a include abaixo .
def var auxFunction as char no-undo .
assign auxFunction = "marcar()" .
{web/winclude/wi-sonbut.i "Marcar" "btn_Marcar" auxFunction}
A função javascript marcar() deve ser declarada na output-header , depois da
include wi-header.i .
Os botões gerados são do tipo button , e este não submetem o formulário do
filho . Para submeter o formulário do filho , deve-se utilizar uma função
javascript :
function SubmeterSon() {
29
30
document.form[1].submit() ;
}
Deve-se prestar atenção para o número do formulário , que sempre será o
segundo . ( No JavaScript o primeiro número de um Array é sempre 0 (ZERO)
)
Definir o Título do Filho .
assign titleSon = "Relação Customer X Order" .
Procedure process-web-request :
Executar a DBO Filho .
RUN dbo/bosp005.p PERSISTENT SET {&hDBOSon}.
find first {&ttTableFather} no-lock no-error .
Executar a SetConstraint correspondente a restrição que será feita .
RUN setConstraintCust-Num in {&hDBOSon} (input {&ttTableFather}.CustNum) .
Abrir a Query
RUN openQueryStatic in {&hDBOSon} (input "Cust-Num":u).
Definir o Número de Linhas do Browser .
{web/winclude/wi-sonnav.i &nrlinha=5}
Esta include instancia a API de Browser, por isso, é necessário que o
desenvolvedor elimine o handle (h-brwapi) desta API no final do
programa.
CAPÍTULO 2
Templates para WEB
31
Includes utilizadas no Consulta Filho
{dbo\boXX999.i tt-tabela}
Include que define o nome da tabela temporária na Interface . No
programa de Consulta Filho é necessário declarar duas vezes . A temptable da Pai e a Temp-table do Filho .
{method\dbotterr.i}
Includes Utilizadas para a integração da Interface com a DBO .
{web/winclude/wi-header.i}
Include que contem algumas regras para a navegação e controle de
chamadas de programas Filhos.
{web/winclude/wi-sonhei.i}
Gera as tags iniciais de tabela e formulário para a geração do codigo do
filho .
{web/winclude/wi-sonbdef.i}
Gera os botões (default) para inclusão , modificação e exclusão de
registros .
{web/winclude/wi-sonbut.i}
Gera botões customizados . Onde deve-se definir o nome do botão e a
chamada javascript (É aconselhado utilizar uma função Javascript.)
{web/winclude/wi-sonhef.i}
Geras as tags finais para os botões .
{web/winclude/wi-sontitle.i}
Gera o título para o programa filho .
{web/winclude/wi-sonnav.i}
Posiciona na DBO no registro desejado . Por exemplo : Navegação e na
exclusão de registros.
{web/winclude/wi-endson.i}
Gera os códigos finais para o HTML e deleta a handle da procedure de
API.
32
Cadastro PAI (Simples/Complexo) (<nome>.htm, <nome>.w)

independente de que se for um Cadastro Simples ou Complexo,
basta seguir os mesmos passos de construção do Cadastro Simples
ou Complexo;

selecionar o estilo Cadastro PAI Simples ou Cadastro PAI
Complexo;

utilizar opção de geração do programa.
Especificação Técnica – Cadastro PAI SIMPLES/COMPLEXO
Arquivo HTML
O diferencial dos HTML para os outros cadastro ,é que no Cadastro
Pai existe um botão de Submit e outro para limpar o formulário (Restaurar
para os valores originais.)
Segue um exemplo para o Cadastro Pai simples :
<html>
<head>
<title>Template Cadastro do Pai Simples</title>
<link rel="StyleSheet" type="text/css" href="/ems20web/padrao.css">
<meta http-equiv="Cache-Control" content="No-Cache">
<meta http-equiv="Pragma"
content="No-Cache">
<meta http-equiv="Expires"
content="0">
</head>
<body topmargin="0" leftmargin="0">
<form method="post">
<input type="hidden" name="hid_chave" value="?">
<input type="hidden" name="hid_oper" value="?">
<div align="center"><center>
CAPÍTULO 2
Templates para WEB
<table align="center" border="0" cellpadding="0" cellspacing="1"
width="100%" class="tableForm">
<tr>
<td class="linhaForm" nowrap align="center"><br>
<table align="center" border="0" cellpadding="0" cellspacing="1">
<tr>
<th align="right" class="linhaForm" nowrap>
<!--BXLS-->Código <!--EXLS-->:
</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="5" maxlength="5" name="w_cod">
</td>
</tr>
</table>
<br>
</td>
<tr>
<td class="linhaForm" nowrap colspan="2" align="center">
<input type="submit" name="ok" value="
OK ">
<input type="button" name="cancel" value="Cancelar"
onclick="self.close()">
Os dois botões devem ser elementos de formulários . Não devem
ser utilizadas as imagens de OK e Cancel do Menu .
<p><br></p>
</td>
</tr>
</table>
</center></div>
</form></body></html>
Segue um exemplo para o Cadastro Pai Complexo :
<div align="center"><center>
Definir o nome do folder . Neste exemplo é folder1
<a name="folder1"></a>
<table align="center"border="0" cellpadding="0" cellspacing="3" width="90%"
class="tableForm">
<tr>
33
34
<td colspan="3" class="barratitulo"><!--BXLS-->Template de Cadastro
Complexo<!--EXLS--> </td>
</tr>
O Título do Programa deverá aparecer em todos os folders .
<tr>
<td class="linhaForm" nowrap><div align="center"><center>
<table align="center" border="1" cellpadding="0" cellspacing="1"
width="100%"
class="selectedFolder">
<tr>
<td class="linhaForm" nowrap align="center" width="100%">
<!--BXLS-->Principal<!--EXLS-->
</td>
O Folder selecionado não deverá conter o Link para ele mesmo .
</tr>
</table>
</center></div>
</td>
<td class="unselectedFolder" nowrap align="center" >
<a href="#folder2"><!--BXLS-->Secundário<!--EXLS--></a>
</td>
<td class="unselectedFolder" nowrap align="center" >
<a href="#folder3"><!--BXLS-->Terceiro<!--EXLS--></a>
</td>
</tr>
</table>
</center></div>
<div align="center"><center>
<table align="center" border="1" cellpadding="0" cellspacing="1" width="90%"
class="tableForm"
height="300">
<tr>
<td valign="top" class="linhaForm" nowrap align="center" colspan="5"
width="100%"><br>
<table align="center" border="0" cellpadding="0" cellspacing="1">
<tr>
<th align="right" class="linhaForm" nowrap><!--BXLS-->Código<!--EXLS->:</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="5" maxlength="5" name="w_cust_num">
</td>
Sempre deve ser definido <th> contendo o Label e uma <td> contendo um
elemento de formulário
CAPÍTULO 2
Templates para WEB
35
</tr>
<tr>
<th align="right" class="linhaForm" nowrap><!--BXLS-->Nome<!--EXLS->:</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="40" maxlength="40" name="w_name">
</td>
</tr>
<tr>
<td class="linhaForm" nowrap align="center" width="100%">
<center>
<input type="submit" name="ok" value="
OK ">
<input type="button" name="cancel" value="Cancelar"
onclick="self.close()">
</center>
</td>
</tr>
</table>
...
Os botões devem ficar sempre o último Folder . Nâo faz sentido
colocar em cada Folder os Botões de OK e Cancelar em cada Folder , se
todos os dados devem ser cadastrados . Assim obriga o usuário a passar
em todos os folders .
Arquivo .W
Definitions :
&GLOBAL-DEFINE ttTable1
tt-tabela
Definir o nome da tabela temporária .
Exemplo :
&GLOBAL-DEFINE ttTable1
tt-customer
36
&GLOBAL-DEFINE hDBOTable1 boXX999
Definir o nome da DBO .
Exemplo :
&GLOBAL-DEFINE hDBOTable1 bosp001
&GLOBAL-DEFINE DBOTable1 tabela
Definir o nome da tabela .
Exemplo :
&GLOBAL-DEFINE DBOTable1 customer
&GLOBAL-DEFINE TableName tabela
Definir o nome da Tabela que será utilizada na DBO .
Exemplo :
&GLOBAL-DEFINE TableName customer
&GLOBAL-DEFINE THISNAME diretorio/wcadpai.w
Definir o diretório e nome deste programa .
Exemplo :
&GLOBAL-DEFINE THISNAME app/wap0006.w
&GLOBAL-DEFINE NFACON diretorio/wconpai.w
Definir o diretório e nome do programa de consulta pai .
Exemplo :
&GLOBAL-DEFINE NFACON ricardo/wconpai.w
Procedure assignFields :



Definir quais os campos que serão validados com wi-datatype.i .
Verificar no Capítulo de Validações o funcionamento da wi-datatype.i
Fazer a associação entre as variáveis de tela (HTML) com a tabela
temporária .
if request_method = "POST" then DO WITH FRAME {&FRAME-NAME} :
CAPÍTULO 2
Templates para WEB
create {&ttTable1} .
ASSIGN {&ttTable1}.cust-num = int(w_cod:screen-value)
{&ttTable1}.name = w_nome:screen-value
{&ttTable1}.address = w_end:screen-value
{&ttTable1}.city = w_cid:screen-value
{&ttTable1}.state = w_est:screen-value
{&ttTable1}.sales-rep = w_sal:screen-value
.
{web/winclude/wi-assign.i}
end.
Procedure displayFields

Fazer a associação entre a tabela temporária e as variáveis de tela.
FIND FIRST {&ttTable1} NO-LOCK NO-ERROR.
DO WITH FRAME {&FRAME-NAME}:
ASSIGN w_cod:screen-value = string({&ttTable1}.cust-num)
w_nome:screen-value = {&ttTable1}.name
w_end:screen-value = {&ttTable1}.address
w_cid:screen-value = {&ttTable1}.city
w_est:screen-value = {&ttTable1}.state
w_sal:screen-value = {&ttTable1}.sales-rep
hid_chave:screen-value = string({&ttTable1}.rRowid)
.
{web/winclude/wi-disp.i}
END.
Procedure process-web-request :
37
38


Executar a DBO persistente .
Abrir a Query (Se houver no programa , antes abrir a SetConstraint) .
RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.
RUN openQueryStatic in {&hDBOTable1} (input "Main":u).
Consulta Filho (<nome>d.w, <nome>d.htm)

seguir os mesmos passos do estilo Cadastro Simples/Complexo;

selecionar o Estilho Cadastro FILHO Simples ou Cadastro FILHO
Complexo;

utilizar opção de geração do Programa.
Especificação Técnica – Cadastro Filho SIMPLES/COMPLEXO
Para construir o HTML para Cadastro Filho deve-se seguir o padrão
Cadastro Pai Simples (Especificação Técnica – Cadastro Pai
Simples/Complexo) .
Estilo Consulta Simples / Estilo Consulta Complexa
Para a construção deste estilo, seguir os mesmos passos dos Estilos Cadastro
Simples/Complexa. O template, internamente, é muito semelhante. A única
diferença da Consulta para o Cadastro são os parâmetros da função JavaScript
inicializa (). Que se encontra, sempre, no HTML:
<bodytopmargin=”0”leftmargin=”0”onload=”inicializa()” >
CAPÍTULO 2
Templates para WEB
Os parâmetros do Cadastro são:
function inicializa() {parent.panel(“NGSACMDUROHE”,”wap0005
2.00.00.000”);}
E os parâmetros da Consulta são:
function inicializa(){parent.panel(“NGSROHE”,”wap00051
2.00.00.000”);}
O significado de cada letra é:
N - Botões de Navegação
G - Go to
S - Search
A - Add
C - Copy
M - Modify
D - Delete
U - Undo
L – Consulta Relacionada
R - Reset (Formulário)
O - OK (Função de Submit)
H - Home
E - Exit
39
40
Estilo Vá Para
Seleção:

selecionar os Campos;

ajustar os Campos/Variáveis.
Parâmetros:

selecionar Estilo Vá Para;

escolher o Método da BO (para fazer a busca);

utilizar a opção para gerar o programa.
CAPÍTULO 2
Templates para WEB
Especificação Técnica – Vá Para
Arquivo HTML
O início (cabeçalho) do HTML é exatamente igual ao HTML de
Consulta.

Definir na TAG <title> o título do Programa.
<table align="center" border="0" cellpadding="0"
cellspacing="1" width="90%">
<tr>
<td class="linhaForm" nowrap align="center">
<p align="center"><br></p>
<div align="center"><center>
<table align="center" border="0" cellpadding="0"
cellspacing="1">

Definir quais são os campos chaves que farão a busca.
<tr>
<th align="right" class="linhaForm" nowrap>
<!--BXLS-->Código<!--EXLS-->:</th>
<td class="linhaForm" align="left" nowrap>
<input type="text" size="5" maxlength="5"
name="w_cod">
</td>
</tr>

Não esquecer de deixar uma linha da tabela em branco .
<tr>
<td class="linhaForm" nowrap>&nbsp;</td>
<td class="linhaForm" nowrap>&nbsp;</td>
41
42
</tr>
<tr>

Depois da linha da tabela em branco , definir os botões de
Submit e Reset .
<td class="linhaForm" nowrap align="center" colspan="2">
<input type="submit" name="button" value=" Ok
">&nbsp;
<input type="button" name="button" value=" Cancel "
onclick="self.close()">
</td>
</tr>
</table>
</center></div><p><br></p>
</td>
</tr>
</table>
</center></div>
<p>&nbsp;</p>
</form></body></html>.
Arquivo .W
Definitions
&GLOBAL-DEFINE ttTable1
tt-tabela
Definir o nome da tabela .
Por Exemplo :
&GLOBAL-DEFINE ttTable1
tt-customer
&GLOBAL-DEFINE hDBOTable1 boaa000
Definir o nome da BO que será utilizada .
Por Exemplo :
&GLOBAL-DEFINE hDBOTable1 bosp001
CAPÍTULO 2
Templates para WEB
43
&GLOBAL-DEFINE DBOTable1 tabela
Definir o nome da tabela que a BO utilizará .
Por Exemplo :
&GLOBAL-DEFINE DBOTable1
customer
&GLOBAL-DEFINE TableName
tabela
Definir o nome da tabela que o programa utilizará .
Por Exemplo :
&GLOBAL-DEFINE TableName
customer
Procedure displayFields
Definir o nome variável de tela que será atribuida a ela mesmo . Assim , quando
o programa entrar no método POST não irá perder o valor que o usuário digitou
no campo .
Exemplo :
IF request_method = "post" then do WITH FRAME {&FRAME-NAME} :
assign w_cod:screen-value = get-value("w_cod") .
end.
else do :
RUN SUPER .
end.
Procedure displayFields

Executar a BO em Persistente .

Abrir a Query.

Resgatar o valor da variável (pesquisa) HTML .

Executar a Procedure goToKey passando como parâmetro o valor da
variável HTML .
def var cod_num as integer no-undo .
def var wRowid as rowid no-undo .
44
def var c-nome-prog-requis as char no-undo .
assign c-nome-prog-requis = get-value("prog").
RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.
RUN openQueryStatic in {&hDBOTable1} (input "Main":u).
assign cod_num = int(get-value("w_cod")) .
RUN goToKey in {&hDBOTable1} (input cod_num) .
{web/winclude/wi-retgoto.i}
delete procedure {&hDBOTable1}.
CAPÍTULO 2
Templates para WEB
Estilo Pesquisa / ZOOM
Seleção:
Como construir um Programa de Zoom/Pesquisa utilizando o template
wmazoom.p.
Passos :

Copie do diretório wmasters (x:\ems20por\web\wmasters) o arquivo
wmazoom.p e renomeie .

A seguir altere nas seguinte procedures :
Definitions
45
46
-
Utilizar a include da BO para configurar o nome da tabela temporária .
Utilizar a include da Tabela de Error
{xx/bo/boXX999.i tt-tabela}
{include/boerrtab.i}
- Definir os nome da HANDLE
def var h-boXX999 as handle no-undo.
- Definir as variaveis de Faixa
def var ini_var as char no-undo .
def var fim_var as char no-undo .
- Definir a Variável que Guarda o número da Query a ser executada. (Isto se
o seu programa de Zoom/Pesquisa tiver várias Ordenações )
def var ordena as char no-undo .
PROCEDURE process-web-request
-
Se o seu programa tiver Faixas de Pesquisa , Várias Ordenações , deverá ser
executado a procedure setVariablesRange
run setVariablesRange.
-
Executar a BO .
run XXbo/boXX999.p persistent set h-boad018.
-
Definir qual a setConstraint a ser utilizada
Por Exemplo : run setConstraint1 in h-boad018 (input ini_nome , input
fim_nome) .
-
Dependendo a Ordenaçao a ser utilizada ,
definir qual a openQuery que deverá ser utilizada.
Por Exemplo :
if ordena = "1" then
run openQuery in h-boad018 (4).
if ordena = "2" then
run openQuery in h-boad018 (2) .
CAPÍTULO 2
Templates para WEB
47
run openquery in h-boXX999 (1).
-Definir o nome da handle da BO utilizada
-Deninir o Número de Linhas do Browse
{web/winclude/wi-inibrz.i &bohandle="h-boXX999" &nrlinha=10}
-
Para adicionar uma coluna com campo , execute o método da API de BROWSEaddField . Por Exemplo :
run addField in h-brwapi ("cod-banco", "I", "Banco", "right", ?).
run addField in h-brwapi ("campo", "I", "Label", "right", ?).
-
Para adicionar um link para o Retorno das Variáveis deve-se :
Definir o nome do campo utilizado
Definir o tipo
Definir o Label
Definir o alinhamento
Por exemplo :
{web/app/wi-rtnbrz.i &nome-campo="nome-banco" &tipo="C" &label="Nome"
&align="right"}
{web/winclude/wi-rtnbrz.i &nome-campo="campo" &tipo="C" &label="Label"
&align="right"}
-
Executar o método addField para adicionar outras colunas
48
-
Definir o nome do programa de ZOOM/PESQUISA
Obs.: Não deve ser colocado APPURL . O WEB SERVER ASSUME O
CAMINHO .
Por exemplo :
{web/winclude/wi-likbrz.i &nomeprog="wg01ad001.p"}
{web/winclude/wi-likbrz.i &nomeprog="wg99XX999.p"}
run setNavigation in h-brwapi (true).
run setBorder in h-brwapi (2).
Run output-header.
{&OUT}
"<HTML>":U SKIP
"<HEAD>":U SKIP
"<TITLE> {&FILE-NAME} </TITLE>":U SKIP
'<link rel="stylesheet" href="/ems20web/padrao.css">'
.
-Definir o número de Campos utilizados no Browser .
Por Exemplo :
{web/app/wi-jscbrz.i &num_campos_browse=3}
{web/app/wi-jscbrz.i &num_campos_browse=10}
-
Na TAG FORM , deve ser colocado o nome do programa de zoom .
Por exemplo :
'<form method="post" action="wg01ad001.p?funcao=' get-value("funcao")
'&prog_requis=' get-value("prog_requis") '&retorno=' get-value("retorno") '">'
{&out}
"</HEAD>":U SKIP
"<BODY>":U SKIP
'<form method="post" action="wg99XX999.p?funcao=' get-value("funcao")
'&prog_requis=' get-value("prog_requis") '&retorno=' get-value("retorno") '">' .
-
O Método generateRange deve ser executado se o seu programa conter faixa ,
multipla ordenação e botão para parâmetro.
run generateRange.
CAPÍTULO 2
Templates para WEB
run generateBrowse in h-brwapi.
{&out} return-value.
{&OUT}
'</form>'
"</BODY>":U SKIP
"</HTML>":U SKIP
.
delete procedure h-brwapi.
delete procedure h-boad018.
PROCEDURE retornaJavaScript :
-
Esta Procedure é executada pelo método addFunction da Api de Browse .
define input parameter r-rowid as rowid no-undo.
define output parameter c-char as char no-undo.
-
Executar o getCurrent e encontrar o primeiro registro da Temp-Table
Por exemplo :
RUN getCurrent in h-boad018 (output table tt-banco).
find first tt-banco where tt-banco.r-rowid = r-rowid no-lock no-error.
RUN getCurrent in h-boXX999 (output table tt-tabela).
find first tt-tabela where tt-tabela.r-rowid = r-rowid no-lock no-error.
-
Definir o número de Campos no Browser nas variáveis Extent
Por Exemplo :
define variable aux-nome as char extent 3 init "".
define variable aux-valor as char extent 3 init "".
define variable aux-campo as char extent 3 init "".
define variable aux-nome as char extent 10 init "".
define variable aux-valor as char extent 10 init "".
define variable aux-campo as char extent 10 init "".
-
Definir o nome da variável e o valor de cada campo
Por Exemplo :
assign aux-nome[1] = "tt-banco.cod-banco"
aux-valor[1] = string(tt-banco.cod-banco)
49
50
aux-nome[2]
aux-valor[2]
aux-nome[3]
aux-valor[3]
= "tt-banco.nome-banco"
= tt-banco.nome-banco
= "tt-banco.ag-padrao"
= tt-banco.ag-padrao .
assign aux-nome[99] = "tt-tabela.campo"
aux-valor[99] = string(tt-tabela.campo)
.
{web/app/wi-shlbrz.i}
-
Definir qual o campo que será mostrado no Link
Por exemplo :
assign c-char = beginLink + tt-banco.nome-banco + endLink.
assign c-char = beginLink + tt-tabela.campo + endLink.
END PROCEDURE.
PROCEDURE generateRange :
Esta procedure Gera o HTML para a Faixa , Ordenação e para Botões de Parâmetro
Segue abaixo uma lógica default para mostrar uma faixa e ordenação .
Obs.: Na inclusão de Novas faixas , o programador deve inserir a lógica
para mostrar as outras faixas.
-
Deve ser definido as variável chamadas LabelN e que vai conter as Labels das
faixas , Labels dos Radio e Labels do Botão
Por Exemplo :
def var label1 as char no-undo.
assign label1 = "Banco Inicial".
.
PROCEDURE setVariablesRange :
-
Segue uma lógica default para gravar no Contexto de Sessão um campo de
ordenação e de dois Campos de Faixa . 1 Inicial e ou Campo Final .
def var h-prog
as handle no-undo.
CAPÍTULO 2
Templates para WEB
51
def var c-token
as char no-undo.
assign c-token = get-cookie("SessionContextToken":u).
run web/wutp/wu-sessao.p persistent set h-prog.
run setToken in h-prog (c-token).
if request_method <> "POST" then do :
- Verificar se existe Contexto de sessao gravado .
- Se nao existir colocar valores iniciais
- Se existir colocar os valores que estao no contexto de sessao
run getContext in h-prog ("ini_nome":u , output ini_nome) .
run getContext in h-prog ("fim_nome":u , output fim_nome) .
run getContext in h-prog ("ordena":u , output ordena).
if ini_nome = "" then
assign ini_nome = "" .
if fim_nome = "" then
assign fim_nome = "ZZZZZZZZZZZ".
if ordena="" then
assign ordena = "1".
end.
else do:
assign ini_nome = get-value("ini_nome")
fim_nome = get-value("fim_nome")
ordena = get-value("ordena") .
run setContext in h-prog ("ini_nome":u, ini_nome ) .
run setContext in h-prog ("fim_nome":u, fim_nome ) .
run setContext in h-prog ("ordena":u, ordena).
end.
delete procedure h-prog.
ZOOM
O Zoom utiliza o mesmo template de pesquisa. (Seguir os mesmos passos para
a geração do programa). O que diferencia é que o programa de Zoom utiliza a
função JavaScript abreZoom().
Exemplo:
52
...
<input type=”text”size=”5” name=”w_gb_codigo”>
<a
href=”javascript:abreZoom(‘web/<modulo>zoom/<nomezoom>.p’,400,40
0,’tt-grupo-bem.gb-codigo,w_gb_codigo,tt-grupobem.descrcao,w_c_desc_gb’)”>
<img src=”/ems20web/wimages/ii-zoom.gif” align=”absmiddle”
border=”0” width=”23” height=”23”></a>
<input type=”text” size=”37” name=”w_c_desc_gb”>
...
Atenção :
Nas chamadas dos programas de zoom/pesquisa , é passado
como parâmetro uma variável chamada primeira e o valor é
sempre yes . Assim , é possível fazer um teste e saber que
aquele programa está sendo executado pela primeira vez .
Isto é o usuário clicou nos botões de zoom e pesquisa .
Por exemplo :
If get-value(“primeira”) = “yes” then do:
ValorInicial = “AAAAA”
ValorFinal
= “ZZZZZ”
End.
Else do:
/* Recupera do contexto de sessão */
End.
Este procedimento é necessário , pois toda
usuário especificar uma faixa e selecionar
fechar o Zoom/Pesquisa . E na mesma sessão
reabrir o programa os valores devem ser os
os valores que ele colocou na faixa .
a vez que o
um campo ou
este usuário
iniciais e não
Estilo Relatório
Os programas de relatório na WEB não serão executados de modo on-line, e
sim em batch. O programador, após entrar com os parâmetros e seleções,
deverá agendar a execução do relatório via RPW, este que após realizado
poderá ser consultado e visualizado via seu monitor.
CAPÍTULO 2
Templates para WEB
53
Para criar um programa de relatório na WEB, deve-se seguir os seguintes
passos:
1. Copiar o programa temprel.w e temprel.htm para o diretório, onde ficará o
novo programa.
2. Renomeie estes arquivos para o nome do programa.
3. Mude na seguinte linha, o nome do arquivo .htm

&Scoped-define WEB-FILE wmasters/temprel.htm
4. Alterar via um editor de HTML os folders seleção e parâmetros de acordo
com a especificação do programa, podendo ser criados novos folders caso
necessário.
5. Abrir o programa no Workshop para que ele faça o mapeamento dos
campos.
6. Alterar a definição da temp-table “tt_param”, na sessão “Definitions”, para
ficar de acordo com a temp-table utilizada no programa RP.
7. Associar os campos da temp-table tt_param aos campos de tela, na sessão
pi-executar.
8. Alterar o valor do campo tta_cod_modul_dtsul_corren da temp-table
tt_param_segur para o módulo a qual este programa pertence.
9. Alterar o valor do campo tta_cod_prog_dtsul da temp-table tt_ped_exec
para o nome do programa original no EMS 2.0.
10. Alterar o valor do campo tta_cod_prog_dtsul_rp da temp-table
tt_ped_exec para o nome do programa RP a ser executado pelo RPW.
11. Alterar o valor do campo tta_cod_dwb_file da temp-table
tt_ped_exec_param para o nome do programa original no EMS 2.0.
12. (EMS 2.02) Alterar o nome do programa nas procedures internas
uspfLoadParameters e uspfSaveParameters
Para maiores informações sobre estas tabelas temporárias, consulte a
documentação da api btb912zb.p.
55
CAPÍTULO 3
Como usar uma BO
Para usarmos uma BO devemos:
1. Declarar a variável que irá conter o handle da BO.
2. Instanciar a BO, ou seja, rodar a BO deixando-a disponível na memória.
3. Chamar os métodos.
3.1. A abertura da query pode ser feita através da chamada do método
openQuery passando como parâmetro o número da query que deve ser
aberta. É importante atentarmos para o fato de que é necessário rodar
o método setConstraint correspondente, ou seja, ao abrirmos a query 2
devemos rodar o método setConstraint2 anteriormente.
3.2. Se não for aberta uma query a BO usará o comando find para realizar
pesquisas nos métodos padrões, usa-se esta característica em especial
para o método findRowid onde neste caso há ganhos de performance.
4. Eliminar a instância da BO.
Exemplo:
def var w-cd-banco as integer no-undo.
def var h-boad018 as handle no-undo. // passo 1
def var h-DataObject as handle no-undo.
RUN adbo/boad018.p persistent set h-boad018. // passo 2
RUN findRowid in h-boad018(input r_chave). // passo 3
RUN getIntField ind h-boad018(input “cod-banco”, output wcd-banco).
delete procedure h-boad018.
RUN adbo/boad002.p persistent set h-DataObject.
56
RUN setConstraint2 in h-DataObject(input w-cd-banco). //
item 3.1
RUN openQuery in h-DataObject(2). // item 3.1
Observação:
Os retornos de erro da BO são realizados via tt-bo-erro que não pode ser
customizada pelos desenvolvedores.
57
CAPÍTULO 4
Contexto de Sessão
Descrição
O contexto de sessão (CS), tem por objetivo fornecer ao desenvolvedor WEB,
um mecanismo para guardar valores para uso posterior nos programas. Seria o
equivalente a variáveis globais no ambiente Cliente/Servidor.
Alguns destes valores podem ser utilizados: usuário corrente, idioma do
usuário, rowid de registros correntes, etc.
Através do CS, o programador vai poder trocar informações entre dois
programas, já que as informações vão ficar disponíveis para outros programas.
O uso do CS deve ser exclusivamente na parte de interface. Os BO´s não
devem acessar a API de contexto de sessão. O motivo é que o CS usa
mecanismos que são específicos da interface WEB (cookie) que não estão
disponíveis na parte do BO.
Métodos

método setContext para indicar que este quando o valor passado como
parâmetro para ser setado não existir na tabela de contexto este será
criado;

método getTransacao quando não encontra o registro que o usuário tenta
recuperar retorna branco. Para verificar se o registro está em branco na
base de dados ou não existe pode-se usar o método getContextStatus que
irá retornar false quando a informação não existir.
Funcionamento
O contexto de sessão se baseia no fato de que cada usuário conectado vai ter
um token que identifica a sessão do mesmo. Este token identifica os valores do
contexto da sessão do usuário.
58
Para usar o contexto de sessão, deve ser usado o programa WU-SESSION.P. A
seguir estão descritos os processos disponíveis.
Gerando o token da sessão
O token da sessão é gerado pelo programa de login (web/btp/wbtb910.w).
Normalmente, o programador não vai gerar novos tokens. O que o
programador precisa é buscar o token da sessão, quando precisar salvar ou
recuperar valores.
O programa de login gera o token para a sessão e o deixa disponível em um
cookie (‘SessionContextToken). Para obter o valor deste token use a função
get-cookie, conforme demonstrado a seguir.
Obtendo o token da sessão
Para obter o token gerado pelo programa de login, use a função get-cookie e
salve numa variável do tipo char. Depois o programador usará este token para
salvar e recuperar valores.
def var c-token
as char no-undo.
assign c-token = get-cookie(“SessionContextToken”:u).
Armazenando um valor para uso futuro
De posse do token da sessão, o programador poderá guardar valores usando a
função createNewContext da api de contexto (wu-sessao.p). Por exemplo, o
programador quer guardar a empresa e idioma do usuário corrente.
def var h-prog
def var c-token
as handle no-undo.
as char no-undo.
assign c-token = get-cookie(“SessionContextToken”:u).
run web/wutp/wu-sessao.p persistent set h-prog.
run setToken in h-prog (c-token).
run createNewContext in h-prog (“meuprog-empresa”:u, “1”).
run createNewContext in h-prog (“meuprog-idioma”:u,
“portugues”:u ).
delete procedure h-prog.
O desenvolvedor define os nomes de variáveis (no exemplo:
meuprog-empresa, meuprog-idioma) para os valores de contexto que desejar
guardar. O padrão para este nome de variável é o nome do programa, o
caracter “-“ e uma sequência de caracteres para identificar a variável. É
importante usar o nome do programa como parte do nome da variável para
Observação
CAPÍTULO 4
Contexto de Sessão
59
garantir que programas com nomes de variáveis idênticos não acabem
recuperando contextos trocados.
Recuperando um valor armazenado
Para obter um valor armazenado previamente use a função getContext da API.
def
def
Def
Def
var
var
var
var
h-prog
c-token
c-emp
c-idioma
as
as
as
as
handle no-undo.
char no-undo.
char no-undo.
char no-undo.
Assign c-token = get-cookie(“SessionContextToken”:U).
run web/wutp/wu-sessao.p persistent set h-prog.
Run set Token (c-token) in h-prog.
run getContext in h-prog (‘meuprog-empresa’:U, output cemp).
run getContext in h-prog (‘meuprog-idioma’:U, ouput cidioma).
Delete procedure h-prog.
Observações:

os valores para createNewContext e getContext são do tipo character. O
programador precisa fazer as conversões necessárias quando trabalhar com
variáveis inteiro, decimal, date, etc.;

os nomes de variáveis são definidos pelo desenvolvedor dentro do padrão
estabelecido. É importante apenas colocar após o nome da variável o
identificador: U para evitar a tradução destes nomes;

o login deixa disponível alguns valores padrões para a sessão. Verificar no
include “web/winclude/wivglob.i”;

se não for executado o login, não haverá token definido para a sessão e o
contexto de sessão não funcionará;

sempre que usar strings e for possível use a propriedade :u para as
informações;

quando executamos o método createNewContext ele cria um novo
registro, caso o registro já exista e o programador deseje alterá-lo, basta
usar o método setContext que recebe dois input parameter que são
respectivamente o nome a ser alterado e o novo valor.
61
CAPÍTULO 5
Contexto de Transação
Descrição
O contexto de transação (CT), tem por objetivo fornecer ao desenvolvedor
WEB, um mecanismo para guardar grandes quantidades de valores para uso
posterior nos programas. Seria o equivalente a passar temp-tables como
parâmetros de um programa para outro em programas que trabalham por
etapas como wizards no ambiente Cliente/Servidor. Esta solução foi criada
para que pudéssemos permitir para Web Browsers manterem conjuntos
grandes de informações temporárias em processos que exijam várias etapas
para serem executados. Precisamos de um mecanismo que permita o nosso
programa CGI (.w) receba dados de um web-browser e realize algum processo
sobre estes dados guardando-os para uso futuro e possa devolver uma resposta
ficando no aguardo por uma confirmação do usuário ou outro conjunto de
dados. No momento em que esta confirmação for feita, os dados que foram
guardados de forma temporária são transferidos para as devidas tabelas do
produto. Exemplo:

desmembramento de bens (usa um wizard e pede um conjunto de dados
que só são gravados no banco de dados do produto quando todo o processo
está completo, ou seja, o usuário usa vários formulários HTML e só
confirma a gravação no último deles);

entra de lote e capa de lote, onde a capa de lote não pode existir sem os
itens do lote.
Normalmente, usado para guardar valores de temp-tables entre etapas de um
processo interativo.
O uso do CT deve ser exclusivamente na parte de interface. Os BO´s não
devem acessar a API de contexto de transação. O motivo é que o CT usa
62
mecanismos que são específicos. O acesso a tabela de CT deve ser feito
exclusivamente pela API wu-transacao.
Métodos

o método setTransacao para indicar que este quando o valor passado como
parâmetro para ser setado não existir na tabela de transação este será
criado;

o método getTransacao quando não encontra o registro que o usuário tenta
recuperar retorna branco. Para verificar se o registro está em branco na
base de dados ou não existe pode-se usar o método getTransacaoStatus
que irá retornar false quando a informação não existir.
Funcionamento
Para possibilitar o processo de controle de transação e manter informações
persistentes, mesmo após o .w ter encerrado e devolvido dados para o cliente
(Web Browser) optou-se por manter do lado server uma tabela que mantém as
informações temporariamente.
Como as informações referentes a transação estão localizadas em tabelas do
banco de dados o programa .w precisa instanciar a API wu-contexttrn.p para
poder acessar os valores, evitamos desta forma que haja embutido no.w
acessos ao banco. Para que a API possa gravar informações de contexto é
necessário definir um TOKEN que irá indicar a transação e a qual tabela a
transação se refere. Observando que um token (transação) pode ser usado para
várias tabelas. O token da transação deve ser gravado no Contexto de Sessão.
Guardando uma transação para uso futuro
O programa .w que irá precisar que a transação seja persistente deve
armazenar no contexto um token que identifique a transação.
Quando o cliente vai usar ou criar dados de transação ele deve antes de mais
nada definir o token da transação chamando o método setToken e logo em
seguida definir a tabela/processo setNomTabela que irá ser usado.
Devemos observar no entanto que se o cliente .w ainda não possuir um token
para tratamento de transação ele deve requisitar um fazendo uma chamada a
getToken. Gravação de novas informações é feita através de chamadas ao
método createNewTransacao que recebe como parâmetro o campo a ser
gravado, um indicador de seqüência e um valor, notamos que o campo
seqüência é extremamente útil quando gravamos campos extent ou quando
CAPÍTULO 5
Contexto de Transação
63
estamos gravando relacionamentos de uma tabela, por exemplo pedido e itens
do pedido, onde cada item do pedido possuiria sua própria seqüência.
Usando uma transação
O processo de busca a partir de um .w é extremamente simples, sendo
constituído apenas pelas tarefas de:
1. O .w recuperar o token.
2. É instanciada a API de transação.
3. O método setToken da API é chamado recebendo o token que foi
recuperado.
4. A tabela deve ser setada.
O método getTransacao da API é chamado.
Exemplo:
Gravando a transação
RUN settoken IN h-transacao (input v-token).
RUN setNomtabela IN h-transacao (input “meuprog-bem”).
RUN createNewTransacao IN h-transacao (input “bm-codigo”,
input i-seq, input (W_bm_codigo: screen-value)).
RUN createNewTransacao IN h-transacao (input “bm-indice”,
input i-seq, input (w_bm_indice:screen-value)).
RUN createNewTransacao IN h-transacao (input “descricao”,
input i-seq, input (w_descricao:screen-value)).
RUN createNewTransacao IN h-transacao (input “gb-codigo”,
input i-seq, input (w_gb_codigo:screen-value)).
RUN createNewTransacao IN h-transacao (input “di-codigo”,
input i-seq, input (w_di_codigo:screen-value)).
RUN createNewTransacao IN h-transacao (input “sc-codigo”,
input i-seq, input (w_sc_codigo:screen-value)).
Recuperando a transação
RUN settoken IN h-transacao (input v-token).
RUN setNomtabela In h-transacao (input “meuprog-bem”).
64
DO i-cont-ini = 2 TO i-contador:
create tt-bem.
RUN gettransacao IN h-transacao (input “bm-codigo”,
i-cont-ini, c-retorno).
assign tt-bem.bm-codigo = dec(c-retorno).
RUN gettransacao IN h-transacao (input “bm-indice”,
i-cont-ini, c-retorno).
assign tt-bem.bm-indice = dec(c-retorno).
end.
delete procedure h-transacao.
Recuperando o número da última seqüência
Quando o programa por alguma razão precisar que seja retornardo o número
da última seqüência usada, ele deve fazer isto usando o procedimento de
contexto procedendo conforme especificado a seguir:
1. Criar o primeiro registro no contexto com o nome “lastSequence”.
2. Gravar neste registro o número 1 (um) indicando que um valor já foi
usado.
3. Para cada novo registro criado no contexto incrementar em um o valor de
“lastSequence”.
Sempre que o programador precisar saber qual foi a última seqüência usada ele
pode recuperar “lastSequence”.
65
CAPÍTULO 6
Perfil do Usuário
Descrição
A função de perfil do usuário, permite determinar se o usuário conectado ao
produto é interno ou externo. Em caso de usuários externos, podemos ainda
verificar se este é Cliente, Representante ou Fornecedor, e temos condições de
saber o seu número de cadastro dentro das tabelas do produto. Caso seja
necessário incluir mais um tipo é necessário que seja aberta FO para ADF.
Funcionamento
Para possibilitar o processo de definição do perfil do usuário (interno /
externo) foi desenvolvido um programa cliente servidor para cadastro do perfil
do usuário, este programa é executado a partir do programa de cadastro do
usuário (sec000aa.w). O usuário pode ser indicado como sendo do tipo
“Nenhum, Cliente, Fornecedor, Representante”, estes itens correspondem aos
valores 1, 2, 3, 4 que, estão definidos no include uninc/i01un178.i que pode ser
usado conforme técnicas de desenvolvimento cliente servidor.
Uso do perfil em programas WEB
Para usarmos o perfil nos programas WEB temos disponível no include wivglob as variáveis:

v_ind_perfil_usuario - variavel char que contém um número informando o
número do perfil do usuário;

v_cod_ext_perfil_usuario - contém o código que relaciona o usuário com a
entidade que ele representa.
Se o v_ind_perfil_usuario contém 2, o usuário é um cliente e o código deste na
tabela de cliente está gravado na variável (v_cod_ext_perfil_usuario).
66
Incluindo novos tipos no perfil
Novos tipos podem ser incluídos alterando-se o include uninc/i01un178.i esta
alteração deve ser feita pelo ADF, ou seja, é necessário abrir FO para o grupo
ADF.
Informações Gerais
Para verificar os valores já disponíveis e a que número eles estão associados
pode-se verificar o conteúdo do include uninc/i01un178.i.
Onde usar
Deve ser usado na interface e nunca nas BO´s que devem receber esta
informação como um parâmetro e processá-la conforme necessário,
normalmente, definindo restrições de navegação ou de operações que alterem
o conteúdo da base de dados.
Exemplo
Um exemplo de uso do perfil de usuários é a consulta de pedidos. Dentro da
empresa um usuário pode consultar todos os pedidos, mas um representante
(usuário externo), somente pode ver os pedidos que pertencem a ele. Neste
caso deveremos ter a seguinte situação:

programa de interface apenas identifica se o usuário externo ou interno
(através das informações do perfil de usuário). Se for externo deve
identificar qual é o representante;

BO de consulta pedidos deve estar preparado para navegar em todos
registros de pedidos (quando for usuário interno) ou navegar apenas numa
faixa de pedidos (quando for o representante). O BO deve receber de
parâmetro o código do representante para então fazer a seleção e abrir a
query específica.
67
CAPÍTULO 7
Consultas Relacionadas
Definição
Esta técnica descreve os procedimento para que os programas sempre
mantenham contexto nos registros acessados. Por exemplo: ao consultar uma
nota-fiscal, o usuário poderá ter necessidade de acessar a consulta de clientes.
Ao chamar a consulta relacionada, o programa de consulta de clientes já deve
se posicionar naquele registro de cliente da nota-fiscal que o usuário estava
consultando. Para tanto deve ser aplicada esta técnica descrita aqui.
Descrição
Esta técnica deve ser usada em conjunto com a técnica de Contexto de Sessão.
Basicamente, teremos o ‘Programa Origem’ que define o contexto do registro
(rowid do registro corrente) e o ‘Programa Destino’ que, ao ser executado
procura um contexto de registro (rowid) e se posiciona neste registro. Um
programa deverá implementar estes dois comportamentos (origem e destino).
Considerações
Gerais

não há uma dependência direta entre estes dois programas, os dois
funcionam de forma independente. Ou seja, o programa de consulta de
clientes, independentemente de que o chamou, sempre procura o rowid do
cliente para posicionar-se nele;

o programa origem sempre grava no contexto de sessão, o rowid da tabela
principal do programa e outras que forem necessárias. Por exemplo: o
programa de consulta nota-fiscal grava no contexto de sessão o rowid da
nota-fiscal e do cliente (principal entidade ligada a nota-fiscal);

o programa destino sempre procura no contexto de sessão o rowid de sua
tabela principal e posiciona-se no mesmo. Se algum programa
anteriormente gravou um contexto de sessão o mesmo estará sendo usado
neste momento;

o padrão para o nome da variável de contexto de sessão contendo o rowid
da tabela é:
68
rg-<tabela>
69
CAPÍTULO 8
Uso de páginas de código
Descrição
Os sistemas da Datasul são desenvolvidos usando a página de códigos ibm850
para fluxos de saída (-cpstream), e também para os caracteres escritos nos
códigos fontes. Optou-se por este padrão por ser a página default do Progress
nas versões anteriores a 8 e a utilizada pelos ambientes em modo caracter. O
padrão adotado pelos navegadores da Web é página iso8859-1, para manter a
compatibilidade com os demais sistemas da Datasul a versão Web deverá estar
com o parâmetro –cpstream ibm850.
A solução encontrada foi a otimização do arquivo web-disp.p do Webspeed,
configurando a saída web para converter a página de códigos para iso8859-1.
OUTPUT {&WEBSTREAM} TO "WEB":U CONVERT TARGET "iso8859-1":U.
Funcionamento
Para perfeito funcionamento da exibição de caracteres acentuados, deve-se
atentar as seguintes regras:

literais em HTML, devem estar em ibm850, verificar via editor do
Progress se esta correto, pois o FrontPage utiliza iso8859-1 ou UTF-8;

todas as literais dentro de fontes, devem estar em ibm850.
Observação : Problemas com código de Página no Combo-box
70
Na web a saída é iso8859-1 e os programas e includes estão em IBM-850.
Quando selecionar algum valor no combo e enviar para o servidor poderá
ocorrer algum erro . Em resumo , quando os valores forem jogados para a
WEB deverá ser convertido para iso8859-1 e quando forem dados enviados ao
servidor deverá ser convertido para IBM-850. Os dados que estão na base de
dados estão no formato IBM-850. Para que não ocorra o erro , é necessário
utilizar o codepage-convert .
Segue o código de exemplo :
procedure display-fields:
...
w_ind_tipo_desconto_01 = codepage-convert(string({diinc/i01di272.i 04 ttparam-bonif.ind-tipo-desconto[01]}),"ibm850","iso8859-1")
...
procedure assign-fields:
...
tt-param-bonif.ind-tipo-desconto[01] = lookup(codepage-convert(getvalue("w_ind_tipo_desconto_01"),session:charset,"ibm850"),{diinc/i01di272.i
03})
...
BUG NO IE 5 :
Quando for feito um get-value de um combo-box , exemplo abaixo , e
aparecer um conjunto de caracteres , em vez de aparecer o ç ou qualquer
caracter especial , a solução é migrar para o IE 5.01 .
Por Exemplo :
{&out} '<script> alert("Teste : ' string(codepage-convert(getvalue("w_cb_tipo_nota"),session:charset,"ibm850")) '")</script>'.
Resultado : Diferen&#8225o de Pre&#8225o (Diferença de Preço)
CAPÍTULO 9
Customização de arquivos WebSpeed
71
CAPÍTULO 9
Customização de arquivos WebSpeed
Descrição
Com a utilização dos templates Web, surgiu a necessidade da criação e
alteração de utilitários customizados no webspeed.
Funcionamento
ARQUIVO
LOCALIZAÇÃO
TECNOLOGIA
CARACTERÍSTICAS
tagmap.dat
raiz
Webspeed
Alterado para incluir as referências as
tag´s criadas pela Datasul (literal, label,
titulo).
web-disp.p
web/objects
Webspeed
Alterado para suportar a conversão entre
as páginas de código imb850 para
iso8859-1
webedit.p
web/support
Webspeed
Alterado para suportar a opção de
desabilitação do campo de acordo com a
especificação da versão 4.0 do HTML.
webinput.p
web/support
Webspeed
Alterado para suportar a opção de
desabilitação do campo de acordo com a
versão 4.0 do HTML
weblist.p
web/support
Webspeed
Alterado para suportar a opção de
desabilitação do campo de acordo com a
versão 4.0 do HTML.
webradio.p
web/support
Webspeed
Alterado para suportar a opção de
desabilitação do campo de acordo com a
versão 4.0 do HTML.
webtog.p
web/support
Webspeed
Alterado para suportar a opção de
desabilitação do campo de acordo com a
versão 4.0 do HTML.
weblabel.p
web/support
Datasul
Criado para suportar tradução de label´s
72
de campos através da tag <!--Label -->
que utiliza o utilitário ut-liter.
webliter.p
web/support
Datasul
Criado para suportar tradução de literais
através da tag <!--Literal -->que utiliza o
utilitário ut-liter.
webtitul.p
web/support
Datasul
Criado para recuperar o título cadastrado
no sistema de menus através da tag <!-Titulo -->.
webtitu2.p
web/support
Datasul
Chamado pelo programa webtitul.p
73
CAPÍTULO 10
Utilitários
WU-GRAF
Definição:
A API de Gráficos tem como função gerar gráficos para o ambiente WEB.
Para isto, ela utiliza um componente de terceiros KavaChart
(http://www.ve.com/kavachart/) da Visual Engineering Inc.. Este componente
foi construído na forma de um applet Java (programa Java que é executado por
navegadores Java-enabled) que de acordo com os parâmetros recebidos gera o
gráfico desejado.
Funcionamento:
1. Instancia-se a api em modo persistente.
Ex.: run web/wutp/wu-graf.p persistent set h-graf.
2. Cria-se as seqüências necessárias.
Ex.: run addSequence in h-graf(1, "seq1").
3. Adiciona-se os valores na quantidade necessária.
Ex.: run addValue in h-graf(1, 10.0).
4. Adiciona-se as labels.
Ex.: run addLabel in h-graf(1, "Label 1").
5. Adiciona-se parâmetros desejáveis (opcional).
Ex.: run addParam in h-graf("titleString", "Teste de Gráfico").
6. Executa-se a geração e exibe-se o gráfico.
7. Elimina-se a instância da API.
74
Métodos Internos:




addSequence (integer seqüência, char descrição): adiciona uma nova
seqüência de valores;

seqüência: número ordinal da seqüência;

descrição: descrição a ser apresentada no gráfico.
addValue(integer seqüência, decimal valor): adiciona um valor a uma
seqüência existente;

seqüência: número de seqüência, na qual, será acrescentado o valor;

valor: valor a ser acrescentado;
addLabel(integer coluna, char label): adiciona uma label para a
coluna/valor;

coluna: numero seqüência1 da coluna;

label: nome da label da coluna correspondente;
addParam(char param, char valor): adiciona um parâmetro qualquer ao
Applet KavaChart;

param: nome do parâmetro a ser passado;

valor: valor a ser setado no parâmetro;

deleteAll(): limpa todos os dados do gráfico;

generate(char tipo, integer width, integer height);

tipo: tipo do gráfico (bar, column, hiLoBar, indBar, stackBar,
stackColumn, area, labelLine, disLine, pie, polar. (Obs.: este
parâmetro é case sensitivo.)

width: largura utilizada pelo applet;

height: altura utilizada pelo applet;

return-value: possui a tag preparada para a geração do gráfico;
Exemplo:
run web/wutp/wu-graf.p persistent set h-graf.
RUN output-header.
{&OUT}
"<HTML>":U SKIP
"<HEAD>":U SKIP
"<TITLE> Teste de Graficos </TITLE>":U SKIP
CAPÍTULO 10
Utilitários
75
"</HEAD>":U SKIP
"<BODY>":U SKIP
.
/* cria as seqüências */
run addSequence in h-graf (1, "seq1").
run addSequence in h-graf (2, "seq2").
/* adiciona os valores
run addValue in
run addValue in
run addValue in
run addValue in
run addValue in
run addValue in
run addValue in
run addValue in
run addValue in
run addValue in
*/
h-graf
h-graf
h-graf
h-graf
h-graf
h-graf
h-graf
h-graf
h-graf
h-graf
(1,
(1,
(1,
(1,
(1,
(2,
(2,
(2,
(2,
(2,
10.0).
7.0).
2.0).
15.0).
10.0).
11.0).
2.0).
6.0).
2.0).
12.0).
/* adiciona as labels */
run addLabel in h-graf
run addLabel in h-graf
run addLabel in h-graf
run addLabel in h-graf
run addLabel in h-graf
(1,
(2,
(3,
(4,
(5,
"11").
"12").
"13").
"14").
"15").
/* adiciona parâmetros
run addParam in
run addParam in
Grafico").
run addParam in
run addParam in
Roman,20,2").
run addParam in
run addParam in
*/
h-graf ("3D", "").
h-graf ("titleString", "Teste de
h-graf ("legendlly", "0").
h-graf ("titleFont", "Times New
h-graf ("xAxisOptions", "gridOn").
h-graf ("yaxisOptions", "gridOn").
/* gera a tag e apresenta a saída */
run generate in h-graf ("labelLine", 600, 400).
{&out} return-value.
{&out} "<br><br>".
{&OUT}
"</BODY>":U SKIP
"</HTML>":U SKIP
delete procedure h-graf.
Saída:
76
Applet KavaChart:
Principais parâmetros:
Parâmetro
Tipo
Efeito
titleString
String
Título do gráfico
titleFont
font
nome, tamanho e estilo do fonte (default TimesRoman, plain, 12 pt)
titleColor
color
cor do texto na legenda (default black)
legendOn
anything
torna a legenda visível
legendOff
anything
torna a legenda invisível (default)
legendColor
color
seta a cor de fundo da legenda
legendVertical
anything
ícones da legenda em lista vertical (default)
legendHorizontal
anything
ícones da legenda em lista horizontal
legendLabelFont
font
nome, tamanho e estilo da legenda (default TimesRoman, plain, 12 pt)
legendLabelColor
color
cor de texto na legenda (default black)
legendllX
double
posição X do canto inferior esquerdo da legenda (default 0.2)
legendllY
double
posição Y do canto inferior esquerdo da legenda (default 0.2)
iconWidth
double
largura do ícone da legenda (default 0.07)
iconHeight
double
altura do íconde da legenda (default 0.05)
iconGap
double
espaço entre o ícone e a próxima entrada da legenda (default 0.01)
CAPÍTULO 10
Utilitários
77
plotAreaTop
double
topo da área plotável
plotAreaBottom
double
base da área plotável
plotAreaRight
double
lado direito da área plotável
plotAreaLeft
double
lado esquerdo da área plotável
plotAreaColor
color
cor de fundo da área plotável (default white)
backgroundColor
color
cor de fundo do gráfico (default white)
3D
anything
liga o efeito 3D no gráfico
2D
anything
liga o efeito 2D no gráfico (default)
xDepth
integer
número de pixels na direção X para efeitos 3D (default 15)
yDepth
integer
número de pixels na direção Y para efeitos 3D (default 15)
dwellLabelsOn
false
desabilita labels no popup (default habilitado)
dwellUseLabelString true
Usa labels de dados no popup (default off)
dwellUseXValue
false
Usa valores X no popup (default on)
dwellUseYValue
false
Usa valores Y no popup (default on)
dwellXString
String
A string que contém o caracter "#", que será substituída pelo ponto X
(default: "X:#")
dwellYString
String
A string que contém o caracter "#", que será substituída pelo valor Y
(default: "Y:#")
dwellLabelPrecision
integer
Número máximo de dígitos significantes para exibir número não
inteiros. (default 2)
dwellLabelFormat
0,1,2
Tipo de formato numérico para as labels popup (0 - nenhum, 1 vírgula, 2 - formato europeu, default 1)
78
CAPÍTULO 11
Tratamento de Erros
A tt-bo-erro deve ser usado para passar toda e qualquer informação referente a
ocorrência de erros dentro de BOs ela possui como campos:

i-sequen  seqüência em que o erro ocorreu;

cd-erro  código do erro;

mensagem  mensagem associada ao código;

parâmetro  parâmetros que devem ser substituídos na mensagem (este
campo esta em branco quando a mensagem não possui parâmetros).
A criação de erros com parâmetro pode ser feita conforme o exemplo a seguir:
Exemplo (na BO):
{utp/ut-table.i mgadm {&TABLE-NAME} 1}
run utp/ut-msgs.p( input “msg”,
input 146,
input return-value).
create tt-bo-erro.
assign tt-bo-erro.i-sequen = i-seq-erro
tt-bo-erro.cd-erro = 146
tt-bo-erro.mensagem = return-value.
tt-bo-erro.parametro = rowObject.nome-banco.
Para passar mais de 1 parâmetro utilize assim;
tt-bo-erro.parametro = repres.cod-repres + “~~” +
regiao.cod-regiao + “~~” + string(regiao.val-minimo)).
79
CAPÍTULO 12
Validações de Campos na WEB
Em geral, as validações de entrada de dados devem ser feitas no método
'validateFields' da BO. Desta forma, estas validações podem ser aproveitadas
pelo 'validateCreate' e 'validateUpdate' da BO, e também por outros programas
de interface. Observamos que as chamadas das validações devem ser feitas na
local-assign-fields da interface.
A seguir são relacionados os procedimentos para tratar as validações:
Validações de valores obrigatórios
Validações do tipo: campo não por ser zero ou espaços, campo precisa ser
informado devem estar no validateFields do BO, pois são validações
independentes de interface, são regras de negócio.
Validações de campos mandatórios
Estas validações (campo <> ?) devem estar no validateFields nos DBO´s.
Também, são regras de negócio.
Validações de Faixa de Dados
Por exemplo: Campo deve estar entre 1 e 10, campo deve ser "A", "B" ou "C",
também devem estar no validateFields do BO. Em alguns casos implica na
leitura de tabelas do banco de dados.
80
Validações de Integridade Referencial
Validações do tipo can-find, ou seja, o campo deve estar em outra tabela,
devem ser feitas no validateFields dos DBO´s, por motivo claro da
necessidade de leitura de registros.
Validações de Tipo de Dado (wi-datatype.i)
Esta validação deve ser feita diretamente no programa da WEB, pois outras
interfaces (GUI, por exemplo) já fazem esta validação automaticamente. Isto
pode ser feito com o uso do ASSIGN NO-ERROR conforme exemplo abaixo:
assign i-val = integer(x:screen-value) no-error.
if error-status:error then
/* aconteceu algum erro na conversão do tipo de dado */
Isto evita mensagens de erro do Progress referente a tipo de dado inválido (por
exemplo: letras em campos inteiros e decimais, datas inválidas, estouro de
formato).
Para fazer este tipo de validação foi criado o include "wi-datatype.i".
Os tipos de Dados que serão validados são Inteiro, Data, Decimal e Character.
Para isto, deve-se utilizar a include wi-datatype.i. As Validações devem ser
feitas na local-assign-fields.
No wi-datatype.i também são feitas as validações de formato e tamanho do
campo. Se acontecer algum erro este é retornado na tt-bo-erro e ao campo
valido será atribuído o valor "?".
Se não houver erro o campo destino receberá o valor informado.
A seguir um código que demonstra o uso do wi-datatype.i.
Na Definitions:
def var i-seq-erro as integer no-undo.
PROCEDURE local-assign-fields :
IF REQUEST_METHOD="POST":U THEN DO:
DO TRANSACTION NO ERROR UNDO, LEAVE WITH FRAME {&FRAME-NAME}:
create tt-banco.
/* É preciso definir qual é a variável destino, o tipo de dado e
a Origem (variável HTML)
{web/winclude/wi-datatype.i &dst="temp-table.campo"
&type="integer" &org="w_variavel:screen-value"}
*/
CAPÍTULO 12
Validações de Campos na WEB
81
{web/winclude/wi-datatype.i &dst="tt-banco.cod-banco"
&type="integer" &org="w_cod_banco:screen-value"}
{web/winclude/wi-datatype.i &dst="tt-banco.data-1" &type="date"
&org="w_data_1:screen-value"}
{web/winclude/wi-datatype.i &dst="tt-banco.dec-2"
&type="decimal" &org="w_dec_2:screen-value"}
assign
tt-banco.char-1 = w_char_1:screen-value
tt-banco.char-2 = w_char_2:screen-value
/** Fim do Assign **/
/* Se houver algum assign com dados incompatíveis, será criado
registros na tt-bo-erro */
find first tt-bo-erro no-error.
if not avail tt-bo-erro then
case c-param:
when "add" or when "cop" then do:
run validateCreate in h-boad018 (input table ttbanco, output table tt-bo-erro, output r-chave).
end.
when "mod" then do:
run validateUpdate in h-boad018 (input table ttbanco, input r-chave, output table tt-bo-erro).
end.
end case.
find first tt-bo-erro
no-lock no-error.
if avail tt-bo-erro then do:
{web/winclude/wi-erapi.i "tt-bo-erro"}
assign hid_oper = c-param
hid_chave:screen-value = string(tt-banco.r-rowid).
RUN dispatch IN THIS-PROCEDURE ('enable-fields':U).
end.
else do:
RUN findRowid in h-boad018 (input r-chave).
RUN getCurrent in h-boad018 (output table ttbanco).
end.
END./* DO TRANSACTION */
END.
ELSE DO:
END.
/*RUN dispatch IN THIS-PROCEDURE ( INPUT 'assign-fields':U )
*/.
END PROCEDURE.
Observação:
É utilizado a validação (wi-datatype.i) em caracter. O maxlenght é usado
somente em caracter, pois os outros tipos a include consegue gerar o erro. E
com o Caracter, a include apenas "trunca" a string.
82
Em programa de Vá Para , o SWG só gera variáveis do tipo caracter
(Validações) . Por exemplo: c-teste (caracter) . Quando for outro tipo de dado
deverá ser declarada a variável . Seguindo este padrão : Dec-test – decimal
,Dat-test – DATA, Int-test – Inteiros
Atenção : As validações devem ser feitas numa mesma procedure. Pois as
variaveis internas da include não são globais. E depois de executado a
primeira vez , a include não define as variáveis. É aconselhado colocar todas
as validações na assign-local-fields.
CAPÍTULO 13
API de BROWSE – wu-browse.p
83
CAPÍTULO 13
API de BROWSE – wu-browse.p
Definição:
A API de Browse tem como função gerar tabelas no formato browse para o
ambiente WEB.
Funcionamento:
8. Instancia-se a api em modo persistente.
Ex.: run web/wutp/wu-browse.p persistent set h-browse.
9. Instancia-se a BO em modo persistente.
Ex.: run adbo/boad018.p persistent set h-boad018.
10. Informa-se a api qual a BO que irá fornecer os dados.
Ex.: run setDataset in h-browse (h-boad018).
11. Adiciona-se os campos a serem apresentados.
Ex.: run addField in h-browse ("nome-banco", "C", "Nome", "left", ?).
12. Configura-se a bo, posiciona-se o registro e define-se a query.
13. Executa-se a geração e exibe-se o browse.
Ex.: run generateBrowse in h-browse.
14. Elimina-se a instância da API.
Métodos Internos:
 addEditableField (char chField, char chType, char chTitle, char chAlin, int
iTam) – insere um campo cujo valor pode ser editado.
 chField – nome do campo
 chType – tipo do campo (C – char, E – decimal, I – integer, D – date,
L – logical)
 chTitle – título da coluna
84
 chAlin – alinhamento do campo (Right, Left, Center)
 iTam – tamanho do campo de entrada a ser gerado
 addField (char chField, char chType, char chTitle, char chAlin, char
chLink) – insere um campo a ser apresentado
 chField – nome do campo
 chType – tipo do campo (C – char, E – decimal, I – integer, D – date,
L – logical)
 chTitle – título da coluna
 chAlin – alinhamento do campo (Right, Left, Center)
 chLink – link a ser gerado no campo. Utilizar a string &1 no local
onde será substituido pelo rowid do registro corrente.
 addFunction (handle hProg, char chFunction, char chTitle, char chAlin) –
insere uma chamada à uma procedure interna cuja assinatura é (input
rowid, output saida) e o resultado do parâmetro saida é inserido na tabela.
 hProg – handle do programa que possui a procedure interna
 chFunction – nome da procedure interna a ser executada
 chTitle – título da coluna
 chAlin – alinhamento do campo (Right, Left, Center)
 addFunctionTT (handle hProg, char chFunction, char chTitle, char chAlin,
table TEMP-TABLE)
 hProg – handle do programa que possui a procedure interna
 chFunction – nome da procedure interna a ser executada
 chTitle – título da coluna
 chAlin – alinhamento do campo (Right, Left, Center)
 Temp-Table – Tabela com os campos que vão ser trabalhados . (Segue
exemplo abaixo.
Exemplo :
Definir Temp-Table com os campos que serão utilizados (Campos chaves
da tabela temporária) .
Definitions :
CAPÍTULO 13
API de BROWSE – wu-browse.p
85
def temp-table tt-nome-campos field
field tipocampo as char .
def var contador
nomecampo as char
as integer no-undo initial 1 .
Na Process-web-request :
run addFunction
in h-brwapi
(this-procedure, "geraRow":U, "", "right":U).
create tt-nome-campos .
assign tt-nome-campos.nomecampo = "numero-ordem"
tt-nome-campos.tipocampo = "I" .
create tt-nome-campos.
assign tt-nome-campos.nomecampo = "it-codigo"
tt-nome-campos.tipocampo
= "I" .
create tt-nome-campos.
assign tt-nome-campos.nomecampo = "seq-cotac"
tt-nome-campos.tipocampo = "I" .
create tt-nome-campos.
assign tt-nome-campos.nomecampo = "un"
tt-nome-campos.tipocampo = "C" .
run addFunctionTT
in h-brwapi
(this-procedure , "geraCheck" , "" , "center", input table
tt-nome-campos ) .
...
PROCEDURE geraCheck:
86
define input parameter c-char2 as char no-undo.
define output parameter c-char as char no-undo.
assign c-char = '<input type="checkbox" name="cbchave' +
string(contador) + '" value="' + string(c-char2) + '">' .
assign contador = contador + 1 .
END PROCEDURE.
PROCEDURE geraRow:
define input parameter r-rowid as row no-undo.
define output parameter c-char as char no-undo.
assign c-char = '<input type="hidden" name="row' + string(contador) +
'" value="' + string(r-rowid) + '">' .
END PROCEDURE.
 addInput (char chField, char chType, char chTitle, char chAlin, int iTam)
– insere um campo editável para fins de digitação.
 chField – nome do campo, será concatenado com o rowid exeto no
radio
 chType – tipo do campo (T – text, C – checkbox, R – radio)
 chTitle – título da coluna
 chAlin – alinhamento do campo (Right, Left, Center)
 iTam – tamanho do campo de entrada a ser gerado
 generateBrowse – gera o browse e retorna-o via return-value.
 setBorder (int iBorder) – seta a espessura das bordas do browse. Default: 1
 iBorder – espessura da borda
 setDataset (handle hBO) – seta o handle da bo que será a fonte de dados.
 hBO – handle da bo instanciada
CAPÍTULO 13
API de BROWSE – wu-browse.p
87
 setForm (logical lOp) – define se a api irá gerar um form ou não. Default:
false
 lOp – true ou false se deseja form
 setLines (int iLines) – define a quantidade de linhas geradas, 0 – gera
todas as linhas. Default: 10
 iLines – número de linhas geradas
 setLinkNavigation (char chLink) – define o link a ser utilizado caso haja
navegação
 chLink – link para a navegação
 setNavigation (logical lOp) – define se a api irá gerar os botões de
navegação. Default: false
 lOp – true ou false se deseja navegação
Exemplo:
run adbo/boad018.p persistent set h-boad018.
run web/brwapi/brwapi.p persistent set h-brwapi.
run setDataset in h-brwapi (h-boad018).
run findFirst in h-boad018.
run addField in h-brwapi ("cod-banco", "I", "Banco", "right",
"prog2?param=mod").
run addEditableField in h-brwapi ("cod-febraban", "I", "Febraban",
"right", 2).
run addEditableField in h-brwapi ("nome-abrev", "C", "Abrev",
"left", 10).
run addField in h-brwapi ("nome-banco", "C", "Nome", "left", ?).
run addInput in h-brwapi ("t", "T", "Entrada", "left", 5).
run addInput in h-brwapi ("c", "C", "Quais?", "center", ?).
run addInput in h-brwapi ("r", "R", "Qual?", "center", ?).
run addFunction in h-brwapi (this-procedure, "valorMethod",
"Calculado", "center").
run setNavigation in h-brwapi (true).
88
run setLinkNavigation in h-brwapi ("teste.p?x=x").
run setBorder in h-brwapi (2).
RUN output-header.
{&OUT}
"<HTML>":U SKIP
"<HEAD>":U SKIP
"<TITLE> {&FILE-NAME} </TITLE>":U SKIP
'<link rel="stylesheet" href="/ems20web/padrao.css">'
"</HEAD>":U SKIP
"<BODY>":U SKIP
'<form><input type="submit">'
.
run generateBrowse in h-brwapi.
{&out} return-value.
{&OUT}
'</form>'
"</BODY>":U SKIP
"</HTML>":U SKIP
.
Saída:
Banco
0
1
2
3
Febraban
Abrev
Nome
Banco de
Teste
Banco do
Brasil
Banco de
Teste
Banco da
Gente
Entrada
Quais?
Qual?
teste0x0006584
5
teste0x0012ac0
1
teste0x0010948
9
teste0x0018ac6
3
Calcula
do
CAPÍTULO 13
API de BROWSE – wu-browse.p
Banco do
Nordeste
Teste Banco
Adriana
Teste do
Ricardo
4
5
6
7
LCS Banks
Banco
General
Motors
1010101010
1010101
8
9
89
teste0x00013b2
3
teste0x00013b2
4
teste0x0013ccc
3
teste0x00013c0
1
teste0x00132f0
0
teste0x00084e8
5
Exemplo de Recuperação de Variáveis no BROWSE . (SEM O USO DE
JAVASCRIPT). Continuando o exemplo do AddFuntionTT .
No Método POST :
def var conta2 as integer no-undo.
def var conta as integer no-undo .
def var aux-row as char no-undo .
def var aux-un as char no-undo .
assign conta2 = integer(get-value("contador")) .
do conta = 1 to conta2 :
if get-value("cbchave" + string(conta)) <> "" then do :
aux-row = get-value("row" + string(conta)) .
aux-un = get-value("un" + aux-row) .
{&out} "<big><big>" get-value("cbchave" + string(conta))
"</big></big>" .
{&out} ",<big><big>" aux-un "</big></big>" .
aux-un = get-value("preco-fornec" + aux-row) .
{&out} ",<big><big>" aux-un "</big></big><br>" .
end.
90
end.
CAPÍTULO 14
Preferências do Usuário – wu-uspf.p
91
CAPÍTULO 14
Preferências do Usuário – wu-uspf.p
Definição:
A definição de preferências do usuário consiste em salvar os valores das
opções que o usuário utilizou em determinado programa (normalmente
relatórios). Assim o usuário pode retornar a este mesmo programa e
recuperar estas informações sem precisar digitar tudo novamente (Folders
de Seleção, Parâmetros, Classificação, Digitação, etc. Disponível a partir
do EMS 2.02.
Utilização:
1. Inserir os botões de Salva, Carrega e Elimina as preferências do
usuário no HTML:
parent.panel("NGSACMDUROLHEPWX","WCADSIMP 2.00.00.000");
2. Inserir os campos uspf_pref e uspf_defualt no HTML:
<form method="post"><center>
<INPUT TYPE="HIDDEN" NAME="uspf_pref" VALUE="">
<INPUT TYPE="HIDDEN" NAME="uspf_default" VALUE="">
3. Definir variáveis utilizadas pelas preferências do usuário:
define variable i-pref as integer
define variable c-defa as character
define variable l-defa as logical
no-undo.
no-undo.
no-undo.
4. No início da WEB-REQUEST, incluir a seguinte linha de comando:
run outputHeader.
run output-javascript.
{web/ winclude/wi-rpini.i}
{web/winclude/wi-jscrp.i '' '' '' '' '' '' {&THISNAME}}
assign c-pref = get-value("uspfseq":U).
92
5. No método POST, depois da inputFields e da assignFields, incluir a
seguinte lógica:
assign c-pref = get-value("uspf_pref":U).
IF c-pref <> "" THEN DO:
assign c-defa = get-value("uspf_default":U).
if c-defa = "true":U then assign l-defa = true.
run uspfSaveParameters.
assign ab_unmap.uspf_pref = ""
ab_unmap.uspf_default = "".
END.
ELSE DO:
/* Lógica padrão do método POST */
END.
6. Na WEB-REQUEST, antes da enableFields e da outputFields, incluir,
caso não exista, a seguinte lógica:
IF REQUEST_METHOD = "POST":U OR c-pref = "" THEN DO:
RUN displayFields.
END.
7. No método GET, após a displayFields, incluir a seguinte lógica:
RUN displayFields.
if c-pref <> "" then run uspfLoadParameters (false).
else run uspfLoadParameters (true).
8. Criar uma procedure interna com o nome de uspfLoadParameters com
o seguinte código:
{web/winclude/wi-uspfl.i <nome do programa>}
Ex.:
{web/winclude/wi-uspfl.i cd0101}
9. Criar uma procedure interna com o nome de uspfSaveParameters com
o seguinte código:
{web/winclude/wi-uspfs.i <nome do programa>}
Ex.:
{web/winclude/wi-uspfs.i cd0101}
É possível definir que também o conteúdo de um programa de
digitação seja salvo e recuperado a partir das preferências de usuário. Esta
CAPÍTULO 14
Preferências do Usuário – wu-uspf.p
93
implementação consiste em definir alguns pré-processadores. Existem hoje
duas tecnologias para construir programas que se comportem como BOs de
temp-table que são usados nos programas de digitação: Transbo e Virtual
DBO. Parte do procedimento que descreve como fazer para salvar a digitação
nas preferências do usuário se aplica apenas quando se usa Virtual DBO. Os
passos genéricos são os seguintes:
a) Definir no programa que implementa a técnica de preferência o préprocessador RECUPERADIGITACAO: A este pré-processador deve
estar associado o nome da temp-table de comunicação com o
programa que implementa a BO de tabela temporária (Transbo ou
Virtual DBO). É possível indicar a própria temp-table que já está
sendo usada no programa para recuperar a digitação ( geralmente ttdigita ), porém, para garantir que esta operação não vá interferir na
lógica do programa, pode-se definir uma outra temp-table igual a já
existente e indicar esta outra no pré-processador.
Ex:
DEFINE TEMP-TABLE tt-digita
/* Temp-table de comunicação */
FIELD it-codigo
as CHARACTER
FIELD nrVias
as INTEGER
FIELD r-Rowid
as ROWID.
DEF TEMP-TABLE tt-digita-rec LIKE tt-digita.
&SCOPED-DEFINE RECUPERADIGITACAO
tt-digita-rec
/* Usa outra tabela. Não interfere na lógica do programa */
ou
DEFINE TEMP-TABLE tt-digita
/* Temp-table de comunicação */
FIELD it-codigo
as CHARACTER
FIELD nrVias
as INTEGER
FIELD r-Rowid
as ROWID.
&SCOPED-DEFINE RECUPERADIGITACAO
tt-digita
/* Usa a mesma tabela. Pode interferir na lógica do programa */
b) Definir o pré-processador TABELADIGITACAO com um nome
para a tabela da BO de temp-table: Este pré-processador somente
precisa ser definido se não for utilizado o nome padrão para esta
temp-table que é tt-digita. Caso tenha sido usado um outro nome, aí
sim é necessário definir este pré-processador com este nome.
Ex:
run setTableName
in h-handleboTT ("tt-digita":U).
/* Usado nome padrão. Não precisa do pré-processador.
ou
&SCOPED-DEFINE TABELADIGITACAO
tt-mydigita
run setTableName
in h-handleboTT ("tt-mydigita":U).
*/
94
/* Não usado nome padrão. Pré-processador é necessário. */
Caso se esteja utilizando Virtual DBO no programa de digitação, além
dos passos acima, os seguintes itens também devem ser observados:

Definir o pré-processador DIGITACAOVDBO: A definição deste
pré-processador indica que o programa de digitação trabalha com
a tecnologia de Virtual DBO. Se ele não for definido, se assumirá
que a tecnologia utilizada foi Transbo.
Ex:
&SCOPED-DEFINE DIGITACAOVDBO

Definir os pré-processadores DIGITACAOVDBOINDTIPO,
DIGITACAOVDBOINDCOMP
e
DIGITACAOVDBOINDHAND: Estes pré-processadores servem
para indicar como foi definido o comportamento da Virtual DBO
com relação a índices no programa de digitação. Em
DIGITACAOVDBOINDTIPO deve ser indicado o tipo de índice,
em DIGITACAOVDBOINDCOMP o complemento e em
DIGITACAOVDBOINDHAND o handle ou o valor nulo (?).
Estes pré-processadores apenas precisam ser definidos se no
programa de digitação se usou o comando setIndexType.
Ex:
run setIndexType in h-data (input 1,input "nrVias",input ?).
&SCOPED-DEFINE DIGITACAOVDBOINDTIPO 1
&SCOPED-DEFINE DIGITACAOVDBOINDCOMP "nrVias"
&SCOPED-DEFINE DIGITACAOVDBOINDHAND ?

Definir o pré-processador DIGITACAOVDBOORDEM: Este préprocessador deve ser definido se no programa de digitação foi
informada uma ordem para a recuperação dos registros. Seu valor
deve ser o mesmo utilizado no método setQuerySort.
Ex:
run setQuerySort in h-data (input 2).
&SCOPED-DEFINE DIGITACAOVDBOORDEM 2
A documentação sobre o uso de Virtual DBO pode ser encontrda em
X:\ferramentas\ddk2000\Manual\ManualUsoDBO.doc
CAPÍTULO X...
Considerações Gerais
CAPÍTULO X...
Considerações Gerais
Includes do EMS 2 GUI
Sempre que possível usar includes do EMS 2 GUI no produto Web, isto é,
extremamente recomendável por gerar reaproveitamento, como pode haver
casos onde seja necessário verificar dentro do include se o produto rodando
está na sua versão Web ou não deve-se usar a função Proversion do Progress
conforme a seguir:
if INDEX(proversion, "WebSpeed") = 0 then
/* comandos gui */
else
/* comandos para web */
Como esta decisão é tomada em tempo de execução, o usuário deve atentar
para que dentro do bloco de lógica não existam comandos específicos do
WebSpeed.
Label dos Campos no HTML´s
O label dos campos deve estar sempre no formato:
LABEL:<ESPAÇO>CAMPO
95
96
Controles para a não utilização de cache
Para que os programas não utilizem o cache do browser, o que pode acarretar
inconsistência dos dados, deve ser verificado se nos .HTML, existem as
seguintes TAGS entre o <HEAD> e o </HEAD>:
<meta http-equiv="Cache-Control" content="No-Cache">
<meta http-equiv="Pragma"
content="No-Cache">
<meta http-equiv="Expires"
content="0">
Inclusão recursiva
Para implementar a inclusão recursiva nos programas WEB (somente para as
novas templates) deve-se incluir o seguinte pré-processador:
&GLOBAL-DEFINE RECURSIVE_ADD YES
Fechamento de janelas de inclusão de pai
Para que os programas que utilizam a template de cadastro de pai simples ou
complexo, fechem corretamente após a inclusão, deve-se atentar para os
seguintes pré-requisitos:

Deve conter o pré-processador &ttTableFather;

Deve conter o pré-processador &NFACON;

Não deve conter o pré-propcessador &CADSON.
Validações em Geral
As validações em HTML se resumem a tipo de dado, tamanho de campo,
formato de data. Ou seja, validações simples que não dependam de regras de
negócio.
CAPÍTULO X...
Considerações Gerais
97
Validação de Inicial e Final
Estas validações devem seguir o mesmo padrão do ambiente cliente/servidor
que não valida isto. Caso o usuário informe o inicial maior que o final, o
desenvolvedor pode fazer esta validação na BO e retornar o erro, ou
simplesmente não fazer nada (é claro que, a faixa não vai encontrar registros).
Desta forma não é preciso fazer o controle na interface que fica mais simples.
Validações em Relatórios
Após solicitar os dados e antes de gerar o pedido RPW, se houver necessidade
deve-se fazer validações. Estas validações devem ser feitas no programa
Progress. Se forem validações específicas da tabela deve-se usar o BO.
A regra geral é não gravar erros no pedido de execução do RPW.
Lembrando que o recurso muito comum nos relatórios GUI de habilitar e
desabilitar campos na interface não deve ser usado, ou seja, devemos deixar
tudo habilitado e fazer a validação depois.
Desenvolvimento Específico/Customizações
Para o desenvolvimento de aplicações específicas e/ou customizações (AEC)
na WEB, deve-se procurar observar algumas regras para isto:

deve-se colocar as tabelas AEC em um banco de dados separado ao
produto EMS;

os programas do AEC devem ser criados em diretório separado do
produto;

programas que referenciam somente tabelas AEC devem ficar no diretório
específico da customização;

programas que existem no EMS e são necessários para a AEC, mas que
ainda não foram convertidos para WEB, devem ser convertidos e devem
ficar como parte do produto EMS. O motivo é que estes programas
98
deverão ser convertidos futuramente para WEB. Fica a cargo das equipes
de desenvolvimento definir qual das duas equipes (EMS ou AEC) deve
fazer esta conversão;

novos programas necessários para AEC que referenciam tabelas do
produto EMS devem ser criados e devem ficar no diretório do AEC, já que
os mesmos não serão utilizados no EMS.
Como fazer links para detalhe do registro

os links devem ser criados logo abaixo do Título do Programa;

a sintaxe do link é a seguinte:<a
href=”javascript:funcaoJavaScript()”>Nome do Detalhe</a>
A função JavaScript abrirá uma outra página com o detalhe do registro.
Exemplo:
function funcaoJavaScript () {
window.open(“wcr0703b.p?chave=” + document.forms[0]
CAPÍTULO X...
Considerações Gerais
99
.elements[0].value, “NomedaFrame”,
“top=0,left=0,width=500,height=450,scrollbars=no,toolbar=no,loca
tion=no, directories=no,status=no,resizable=yes”);
Como habilitar/desabilitar campos nos HTML´s
Não deve ser habilitado e desabilitado campos 'on line'. Ou todo HTML está
habilitado ou está desabilitado. O objetivo disto é facilitar a programação.
Utilizar a área do label do radio-set e check-box para click do mouse
Sintaxe
Para Radio-Sets:
<label for=”valor1”><input type=”radio” name=”campo”
value=”valor” id=”valor1”>
Descrição </label>
Para CheckBox:
<label for=”valor1”><input type=”checkbox” name=”campo”
value=”valor” id=”valor1”>
Descrição </label>
Exemplo:
<html>
<body topmargin=”0” leftmargin=”0”>
<form method=”post”>
<center>
<label for=”opcao1”><input type=”radio” name=”campo0”
value=”1” id=”opcao1”> Valor1</label>
<label for=”opcao2”><input type=”radio” name=”campo0”
value=”2” id=”opcao2”> Valor2</label>
<br>
<label for=”opcao3”><input type=”checkbox” name=”campo1”
value=”ON” id=”opcao3”> CheckBox </label>
<label for=”opcao4”><input type=”checkbox” name=”campo2”
value”ON” id=”opcao4”> CheckBox </label>
</center>
100
</form>
</body>
</html>
Botão de zoom para tabela estrangeira
O botão de zoom padrão deve ter a imagem wimages/ii-zoom.gif.
Como selecionar um Texto via JavaScript
Onde utilizar
Um exemplo clássico da utilização de seleção é a cópia de um registro.
Quando um registro é copiado, geralmente, é modificado algum valor. E para
facilitar ao usuário, deve-se implementar a seleção. Assim, o usuário não
precisa selecionar o texto e pressionar a tecla DEL. O texto já vem selecionado
e assim o usuário ganha mais agilidade no preenchimento do formulário.
Como utilizar
Basta utilizar a função select(). Exemplo:
document.forms[0].nome.select().
Para maiores detalhes, observe o exemplo a seguir:
CAPÍTULO X...
Considerações Gerais
101
Exemplo em HTML:
<html>
<script>
function ChamaFunção() {
document.form[0].elements[0].select();
}
</script>
<body>
<form>
<input type=”text” name=”ricardo” value=”Seleção de Texto”
size=”20”>
<input type=”button” name=”acao” value=”Teste”
onClick=”javascript:ChamaFuncao()”>
</form>
</body>
</html>
102
Como definir nomes das FRAMES(Janelas):
A definição de uma regra para nomes de frames é necessária para que não
ocorra erros de JavaScript no IE (Internet Explorer). Por exemplo: Se um
usuário abrir uma consulta Pai X Filho e abre a tela de cadastro Pai e por
algum motivo, ele clica no menu principal (deixando a janela do cadastro
aberta). O usuário entra em outro programa Pai X Filho e clica no cadastro do
Pai. Acontecerá um erro de JavaScript no IE, pois o IE não consegue mudar o
tamanho da janela (pois, os nomes das Janelas são iguais). A solução para este
problema é criar frames com nomes diferentes.
Consulta Pai X Filho filho
Função ChamaInclusao - Nome do programa + i
Por exemplo: wap0005i
Função ChamaModificação - Nome do programa + m
Por exemplo: wap0005m
Consulta Pai X Filho pai
Quando o parâmetro for ADD, MOD, COP, a consulta abre outra janela.
É o nome desta janela (Frame) deve ser:
Nome do Programa + p
Por exemplo: wap0005p
Para outros casos deve-se utilizar assim:
Nome do Programa + N
Por exemplo: wap00051
Como mapear variáveis entre o HTML e o programa Progress
manualmente (sem utilizar o Appbuilder)
O primeiro passo, deve-se apagar o <arquivo>.off
Neste exemplo, estaremos acrescentando mais uma Variável (ou Campo) no
programa WebSpeed. O processo para eliminar alguma variável é semelhante
(deve-se trocar acrescentar por eliminar).
CAPÍTULO X...
Considerações Gerais
103
No arquivo HTML - Acrescentar um elemento do formulário.
Exemplo
...
<tr>
<th align=”right” class=”linhaForm” nowrap><!--label
name=”mgadm#banco#cod-banco#1” -->:</th>
<td class=”linhaForm” align=”left” nowrap>
<input type=”text” size=”3” name=”w_cod_banco”>
<!--label name=”mgadm#banco#nome-banco#1” -->
<input type=”text” size=”20” name=”w_nome_banco”>
</td>
</tr>
...
No arquivo .W
Exemplo
...
&Scoped-Define ENABLED-OBJECTS ~
w_cod_banco ~
ww_nome_banco ~
w_nome_banco
...
&Scoped_Define DISPLAYED-OBJECTS ~
w_cod_banco ~
ww_nome_banco ~
w_nome_banco
...
DEFINE VARIABLE w_cod_banco AS CHARACTER FORMAT “X(256)”
VIEW-AS FILL-IN
SIZE 3 BY 1 NO-UNDO.
DEFINE VARIABLE ww_nome_banco AS CHARACTER FORMAT “X(256)”
VIEW-AS FILL-IN
SIZE 20 BY 1 NO-UNDO.
DEFINE VARIABLE w_nome_banco AS CHARACTER FORMAT “X(256)”
VIEW-AS FILL-IN
SIZE 20 BY 1 NO-UNDO.
DEFINE FRAME Web-Frame
104
w_cod_banco SKIP
ww_nome_banco SKIP
w_nome_banco SKIP
WITH NO-LABELS.
PROCEDURE htm-offsets:
...
RUN htm-associate IN THIS-PROCEDURE
(“w_cod_banco”:U,”w_cod_banco”:U,w_cod_banco:HANDLE
IN FRAME{&FRAME-NAME}).
RUN htm-associate IN THIS-PROCEDURE
(“mgadm#banco#nomebanco#1”:U,”ww_nome_banco”:U,ww_nome_banco:HANDLE IN FRAME
{&FRAME-NAME}).
RUN htm-associate IN THIS-PROCEDURE
(“w_nome_banco”:U,”w_nome_banco”:U,
w_nome_banco:HANDLE IN FRAME{&FRAME-NAME}).
...
End Procedure.
Note na Procedure htm-offsets que o nome do campo (literal) deve ser sempre
associada com um ‘w’ a mais. No nosso exemplo, estamos mapeando o nome
do banco. Então, o nome da variável associada a literal deve ser
ww_nome_banco.
Atenção
Literais, Títulos e Labels de Banco (<!--label name=”mgadm#banco#nomebanco#1” -->,<!--literal name=”Teste_de_literal#*” e <!-titulo name=”ap0000”-->) também, são mapeados. O não mapeamento
destas literais e Títulos aplicarão em erro de off.
Blocos de Assign e funções do Webspeed
Os "blocos de assign", utilizados para ganharmos performance, estão
apresentando problemas quando neles se econtram comandos "get-value" e
"get-cookie". Resumindo, cada "get-" deve ter seu único "assign", ex:
assing c-rep = repres:screen-value
c-cli = emitente.cod-emitente
c-nome = emitente.nome-abrev.
CAPÍTULO X...
Considerações Gerais
105
assing c-emp = get-value("c-empresa-ramo").
assing c-user = get-cookie("ck-usuario").
O exemplo acima representa o modo correto para programação dos assign,
caso contrário pode ocorrer o seguinte erro:
Compiling xxx0010e.w...
Attempt to reference an user defined function 'get-value' in an
ASSIGN
type statement after an assignment to key field
'tt-cotacao-item-cex.cod-emitente-desp'. (7955)
** Could not understand line 667. (196)
Lembramos o uso de cookie não faz parte da nossa metodologia de
desenvolvimento. Favor ler sobre a técnica de manutenção de contexto.
Como faço para retornar o nome do Banco, se a minha tabela é de Conta
corrente e só tenho o Código do Banco?
(para programas de Zoom, Pesquisa, Filho)
Definitions
/*
Criar função para retornar um String e passando como parâmetro o
código do Banco.
/*
&global-define conteudo2 fn-nome-banco(string(tt-cta-corrente.codbanco))
-------FUNCTION fn-nome-banco RETURNS CHARACTER (INPUT p-cod-banco AS CHAR):
RUN adbo/boad018.p PERSISTENT SET h-boad018.
RUN FindNomeBanco in h-boad018(input p-cod-banco, output w-cnome-banco).
DELETE PROCEDURE h-boad018.
RETURN (w-c-nome-banco).
END FUNCTION.
Programa de filho chamando um outro programa de Pai x Filho
106
O único problema de um programa Filho chamar um outro programa
Pai x Filho é se o programa 1 passar um ROWID ou até mesmo algumas
chaves . Pois não é possível fazer isto através da passagem de parâmetros .
http://localhost/scripts/cgiip.exe/WService=ems20web/web/men/wrun.w?prog
ram=web/XXp/wXX000.w?rowid=0x032445 (Isto Não é Válido)
Infelizmente não é possivel utilizar o exemplo acima . Pois a passagem
de parâmetro na WEB não é recursivo . O Browser entende tudo como um
único parâmetro .
Para isto , é necessário criar um terceiro programa . A estrutura de navegação
ficaria assim :
WXXFilho.w -> wXXgrava.p -> OutroPaixFilho.w .
O programa Filho deverá chamar um programa que irá gravar no
contexto as chaves e depois de feito chamará o outro programa de Pai x Filho .
Quando a nomeclatura do programa , deverá ser adicionado um sufixo
. Este sufixo deverá ser uma letra .
Segue exemplo do Programa que Grava o Contexto (Poderá ser utilizado este
código para fazer o programa. Lembrando apenas que o Programador deverá
fazer os ajustes necessário para a criação do contexto e declarar o nome do
programa que será chamado ) :
&ANALYZE-SUSPEND _VERSION-NUMBER WDT_v2r1 Web-Object
&ANALYZE-RESUME
&ANALYZE-SUSPEND _CODE-BLOCK _CUSTOM Definitions
/*-----------------------------------------------------------------Author
:
Created :
---------------------------------------------------------------------*/
def var h-prog
def var c-token
as handle.
as char no-undo.
&ANALYZE-RESUME
&ANALYZE-SUSPEND _PREPROCESSOR-BLOCK
&Scoped-define PROCEDURE-TYPE Web-Object
&ANALYZE-RESUME
CAPÍTULO X...
Considerações Gerais
107
&ANALYZE-SUSPEND _PROCEDURE-SETTINGS
&ANALYZE-RESUME _END-PROCEDURE-SETTINGS
&ANALYZE-SUSPEND _INCLUDED-LIBRARIES
{src/web/method/wrap-cgi.i}
&ANALYZE-RESUME _END-INCLUDED-LIBRARIES
&ANALYZE-SUSPEND _CODE-BLOCK _CUSTOM "Main Code Block"
ON CLOSE OF THIS-PROCEDURE
RUN dispatch ('destroy':U).
RUN process-web-request.
IF NOT THIS-PROCEDURE:PERSISTENT THEN RUN dispatch ('destroy':U).
&ANALYZE-RESUME
&ANALYZE-SUSPEND _CODE-BLOCK _PROCEDURE output-header
PROCEDURE output-header :
output-content-type ("text/html":U).
END PROCEDURE.
&ANALYZE-RESUME
&ANALYZE-SUSPEND _CODE-BLOCK _PROCEDURE process-web-request
PROCEDURE process-web-request :
{web/winclude/wi-vglob.i}
RUN output-header.
def var h-prog
def var c-token
as handle no-undo.
as char no-undo.
assign c-token = get-cookie("SessionContextToken":u).
run web/wutp/wu-sessao.p persistent set h-prog.
run setToken in h-prog (c-token).
108
run createNewContext in h-prog ("empresa":u, get-value("empresa")
) .
run createNewContext in h-prog ("idioma":u, get-value("idioma")
).
delete procedure h-prog.
assign irpara="wXX000.w" .
{&out}
'<HTML>':u SKIP
'<body>':u Skip
'<big><center>':u skip
'Salvando Contexto ...'
'</center></big>':u skip
'</body>':u skip
.
{&out}
'<script language=javascript>':u skip
' ~{':u skip
' window.open("' + appurl + '/web/wrun.w?program=' irpara ',
"prgWindow","top=0,left=0,width=" + lar + ",height=" + alt +
",scrollbars=no,toolbar=no,location=no,directories=no,status=no,resizabl
e=no")~; ':u skip
'
~}':u
skip
'</script>':u skip
'</HTML>':U SKIP
{&end}
END PROCEDURE.
&ANALYZE-RESUME
CAPÍTULO X...
Considerações Gerais
109
Selecionar , Inverter e Desmarcar CHECKBOX via JavaScript
O exemplo abaixo é um documento HTML com código Javascript ,
feito para marcar , inverter e desmarcar qualquer checkbox do formulário
selecionado .
Inserir no seu programa a função javascript (Em Azul) . Esta
função é genérica .
A chamada da função JavaScript (Geralmente utiliza-se botões)
encontra-se neste exemplo nos botões (Em Vermelho) .
Analisando a função seleciona(formulário, opção) .
* Formulário (Valor Inteiro) – Corresponde ao número do
formulário que deve ser utilizado . Lembre-se : No
JavaScript o valor 0 (zero) significa o primeiro
formulário
* Opção (Valor Inteiro)
Opção = 1 – Seleciona Todos
Opção = 2 – Desmarca Todos
Opção = 3 – Inverte
<html>
<head>Exemplo - Selecionar CHECKBOX </head>
<script language="JavaScript">
function seleciona(formulario,numero)
{
for (var i=0;i<document.forms[formulario].elements.length;i++) {
var e = document.forms[formulario].elements[i];
if (numero == 1) {
e.checked = true ;
}
if (numero == 2) {
e.checked = false ;
}
if (numero == 3) {
e.checked = !e.checked;
}
}
}
110
</script>
<body>
<form>
<input type="button" name="todos"
value="Todos">
onClick="seleciona(0,1)"
<input type="button" name="nenhum"
value="Nenhum">
onClick="seleciona(0,2)"
<input type="button" name="inverte" onClick="seleciona(0,3)"
value="Inverte">
<br><br>
<input type="checkbox" name="item1"> 1. Item
<br>
<input type="checkbox" name="item2"> 2. Item
<br>
<input type="checkbox" name="item3"> 3. Item
<br>
<input type="checkbox" name="item4"> 4. Item
<br>
<input type="checkbox" name="item5"> 5. Item
<br>
<input type="checkbox" name="item6"> 6. Item
<br>
<input type="checkbox" name="item7"> 7. Item
<br>
<input type="checkbox" name="item8"> 8. Item
<br>
<br>
</form>
</body>
</html>
Como trazer em relatórios o servidor default do usuário
Programas de relatório construídos com uma template mais antiga não
trazem automaticamente no campo Servidor de Execução o servidor default
para o usuário corrente. Para implementar esta funcionalidade basta seguir
estes passos:

Definir um handle para a BO unbo/boun135.p se ele ainda não estiver sido
definido;

Definir uma variável char que receberá o código do servidor de execução
padrão do usuário;
CAPÍTULO X...
Exemplo:
Considerações Gerais
111

Definir uma varável char que receberá a descrição do servidor de execução
padrão do usuário se esta informação for desejada;

Rodar a BO unbo/boun135.p persistentemente se isto ainda não estiver
sido feito;

Rodar dentro da procedure display-fields o método getServidUsuarDefault
na BO unbo/boun135.p e testar o retorno.

Se o rotorno for igual a OK, rodar o método getCharField na BO passando
como parâmetro o valor “cod_servid_exec” e a variável que irá conter o
código do servidor de execução padrão do usuário. Em seguida, associar
ao campo de tela Servidor de Execução o valor que a variável recebeu no
método anterior.

Sendo o retorno de getServidUsuarDefault igual OK, caso se deseje
também a descrição do servidor, rodar o método getCharField na BO
passando como parâmetro o valor “des_servid_exec” e a variável que irá
conter a descrição do servidor de execução padrão do usuário. Em seguida,
associar ao campo de tela relativo a descrição do servidor de execução o
valor que a variável recebeu no método anterior.

Caso tenha-se incluído uma instância da BO unbo/boun135.p, removê-la.
def var h-boun135 as handle no-undo.
def var c-cod-servid-exec
def var c-desc-servid-exec
as char no-undo.
as char no-undo.
RUN unbo/boun135.p persistent set h-boun135.
RUN getServidUsuarDefault IN h-boun135.
if return-value = "OK" then do:
RUN getCharField IN h-boun135
("cod_servid_exec":U, output c-cod-servid-exec).
assign w_cod_servid_exec:screen-value
in frame {&frame-name} = c-cod-servid-exec.
RUN getCharField IN h-boun135
("des_servid_exec":U, output c-desc-servid-exec).
assign w_desc_servid_exec:screen-value
in frame {&frame-name} = c-desc-servid-exec.
end.
112
DELETE PROCEDURE h-boun135.
Como acrescentar um botão “Implantar” no Zoom
O Botão “Implantar” não existe por padrão nos programas Web. Isso
se deve principalmente ao fato de que não existem programas de cadastros
correspondentes para Web. Quando necessário o uso deste botão, os seguintes
passos devem ser seguidos:

Alterar a procedure “process-web-request”, colocando a geração do botão
“Implantar”. O botão deverá executar o programa de manutenção
correspondente, em uma janela separada. O código deve estar logo depois
da chamada a procedure “generateBrowse”. Deve ser parecido com o
listado abaixo:
RUN generateBrowse IN h-brwapi.
{&OUT} return-value.
/* Início da codificação do botão Implantar */
{&OUT}
'<table align="center">':U SKIP
' <tr>':U SKIP
'
<td align="center">':U SKIP
'
<input type="button" name="implanta" value="Implantar"
OnClick="javascript:window.open(~'':U
HostURL + AppURL +
'/web/men/wrun.w?program=web/wCustomer01.w~', ~'_blank~')">':U
SKIP
'
</td>':U SKIP
' </tr>':U SKIP
'</tabble>':U SKIP
'</form>':U SKIP
'</body>':U SKIP
'</html>':U SKIP
.
/* Fim da codificação do botão “Implantar” */
delete procedure h-brwapi.
CAPÍTULO X...
Considerações Gerais
113
Utilizando Help na WEB
Nos programas Web não se faz necessário definir qualquer
código para fazer a exibição de help. A tarefa de exibir o help nos
programas Web é realizada pela include wi-jscrp.i,que já faz parte do
padrão de todos os templates.

Documentos relacionados