jCanistrum
www.mvirtual.com.br/jcanistrum
Meu primeiro site ASP
O Cenário
Um cadastro de empresas na área Gráfica onde cada Empresa é cadastrada em uma área de atuação.
O Sistema admite 3 tipos de Usuário : Admin, Usuário e Anônimo.
O Admin gerencia o sistema.
Usuários são os representantes das empresas cadastradas.
Anônimos são as pessoas que visitam o site apenas para pesquisar sobre as empresas.
Só Admin pode inserir/alterar/excluir empresas. O Usuário só pode alterar alguns dados da sua própria empresa. O Anônimo pode apenas listar as empresas.
O nosso controle de acesso será muito simples para o nosso objetivo.
Se o usuário que quiser se logar for o Admin terá que entrar com a senha gravada em um arquivo de constantes. Se for outro usuário será uma empresa cadastrada cujo login é o email da própria empresa e a senha a que foi cadastrada durante o registro. Aos anônimos óbviamente nada será pedido.
Os casos de uso são extremamente simples
UC1 ListarEmpresa
Ator: Usuário Anônimo
1. Ator Acesso o site
2. Sistema Exibe lista de Areas das Empresas Cadastradas
3. Ator seleciona Area
4. Sistema Exibe Empresas da Area
5. Caso de Uso Encerrado
UC2 Manter Empresa
Ator : Empresa
1. Ator acessa formulario de login e informa email e senha
2. Sistema verifica se email/senha existem e correspondem e exibe dados para edição ( endereço, telefone, email secundário e descrição ) [A1]
3. Ator altera as informações que deseja e seleciona alterar.
4. Sistema exibe dados alterados e pede confirmação
5. Ator confirma
6. Sistema exibe dados alterados
7. Ator seleciona Sair
8. Caso de Uso encerrado
[A1] email/senha não conferem
1. Sistema mensagem de erro. ( “Email/Senha não conferem” ) e exibe link para retorno a tela de login.
2. Ator seleciona o link
3. Sistema retoma ao passo 1 do fluxo principal deste caso de uso.
Com o apoio do STARUML (http://staruml.sourceforge.net/en/) vamos aprofundar a nossa Análise.
O diagrama de casos de uso

O diagrama de classes

Os diagrama de sequência


As Tabelas são apenas 2
Empresa ( EmpresaID, AreaID , nome, endereco, bairro, cidade, estado, .... )
Area ( AreaID, Area )
As tabelas no MS Access



E vamos tentar fazer isso no nosso site em ASP
Como nem todos tem XP e quase sempre se enrolam com a instalação do IIS vamos usar o BabyServer, uma aplicação Free que roda ASP direitinho.
Baixem daqui.
http://www.pablosoftwaresolutions.com/html/baby_web_server.html
Ele não exige instalação, unzipou rodou,
ideal para carregar no pen drive, levar para a faculdade ou para o trabalho enquanto estudam.

Basta clicar 2x para ele executar e depois em “settings” informem o diretório aonde irão ser instaladas as suas páginas .asp e caso voce já tenha algum outro servidor usando a porta 80, altere para 81, ou outro número até que o servidor não dê mais mensagens de erro.

Nada além.
Para saber o que são Active Server Pages, veja algum dos links abaixo:
http://pt.wikipedia.org/wiki/ASP
http://www.linhadecodigo.com.br/Artigo.aspx?id=598
Mas fundamentalmente um servidor ASP implementa uma série de serviços que nos permitem através de uma linguagem de programação de Scripts como o VBSCRIPT acessar dados em banco de dados e produzir páginas que respondam de forma dinâmica as entradas dos usuário e a eventos do sistema.
Então o ato de desenvolver em ASP implica em conhecer que RECURSOS e SERVIÇOS que um servidor ASP dispõe e aprender uma outra linguagem de programação no caso nosso o VBScript.
O VBScript é uma linguagem extremamente simples e ágil derivada do antigo BASIC, não é orientada a objetos ( ainda que seja possível algumas implementações)
Mas essencialmente com ela podemos solicitar dados a um servidor dados via o ASP e percorrer a série de registros de uma consulta usando comandos simples como o FOR e o WHILE.
Para saber mais sobre VBScript alguns links:
http://www.supertrafego.com/ms_funcoes_asp.asp
Eu prefiro do DEVGURU para está em inglês
Onde há uma divisão entre COMANDOS, FUNÇÕES e CONSTANTES que voce pode usar na linguagem alem de objetos do servidor ASP.
http://www.devguru.com/technologies/vbscript/14154.asp
http://www.devguru.com/technologies/asp/index.asp
O importante é ficar claro que existe um interpretador de comandos VBSCRIPT dentro de uma servidor ASP, mas os objetos ASP são outra coisa de certa forma independente que podemos contar para produzir as nossas aplicações dinâmicas.
Principais vantagens do ASP ?
Tecnologia barata e rápida para sistemas pequenos, muita gente sabe usar, muita documentação.
Principal desvantagem
Difícil manutenção, os códigos de HTML ficam embebidos no meio da comandos de VBScript e Objetos ASP, as camadas de exibição, negócio e dados se interpenetram tornando o sistema vulnerável, com alto acoplamento e baixo encapsulamente. Não que não seja possível possível produzir aplicativos 2 ou 3 camadas com ASP, mas exige uma arquitetura bem projetada desde o início.
O que não será o nosso caso agora .... -)
Outra questão importante. Aonde editar ASP ? VisualStudio é um deles, DreamWeaver é outro e existem diversos editores free, mas você pode editar até mesmo com o simples NotePad.
Um excelente free e que ilumina e identa o código é NotePad++,

baixem daqui :
http://notepad-plus.sourceforge.net/br/site.htm
Muito bom mesmo.
Vamos agora tentar implementar os nossos caso de uso, começando por ListarEmpresas
Precisamos de um ListaAreas aonde ao clicar no nome de uma determinada área recuperemos a lista de empresas.
ListaAreas.asp
Observem com carinho, muito carinho mesmo os COMENTÀRIOS ao logo do código, eles tornam o programa auto-explicativo.
Comentários são as linhas que se iniciam ou que contenham a aspas simples ‘ . Da aspa simples em diante até o final da linha não é um comando é comentário e o interpretador ignora.
<HTML>
<HEAD>
<TITLE>graficas</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<%
'aqui começa ASP
'cria objeto ASP de conexão
Set objConn = server.createobject("ADODB.Connection")
'cria string de conexão específica para um determinado banco de dados
strConn = "DBQ=" & server.mappath("graficasonline.mdb") & ";Driver={Microsoft Access Driver (*.mdb)}"
'conecta ao banco de dados
objConn.open strConn,3,3
'cria o recordset para executar uma consulta e retornar com os dados obtidos
Set rs= Server.CreateObject("ADODB.Recordset")
' texto do comando sql a ser executado
sql = "SELECT AreaID, Area FROM Areas ORDER BY Area"
' executa a consulta
rs.Open empresas, strConn, 3, 3
'enquanto houver registros
do while not rs.eof
' imprime no navegador
response.write rs("area") & "<br>"
' procura o próximo
rs.movenext
loop
'importante .. fechar conexao e destruir objetos
set rs= nothing
objConn.close
set objConn = nothing
%>
</BODY>
</HTML>
Quando executamos o script no BabyWebServer, voilá a nossa lista de áreas.

O nosso problema, ou melhor nosso código começa a ficar mais sujo a medida que precisamos usar comandos da linguagem HTML para criar os links, impor o formato de uma tabela ou inserir figuras por exemplo.
Vou fazer isso em vários etapas correndo o risco de ser cansativo, mas acho melhor.
Vou começar colocando uma imagem no topo da página que será o nosso cabeçalho, em HTML imagens são incluídas com o TAG IMG
Vejam a pequena modificação apenas no início do arquivo

E o efeito no site

Legal não ? e saiu barato.
Agora vou incluir um recurso dos mais utilizados em sites ASP, usar tabelas para ter mais controle sobre o visual das páginas.
Em tempo já cito que um controle de qualidade profissional sobre o estilo e a aparências de páginas web é obtido com o uso de CSS, cascading styles sheets, pesquisem o assunto é de muito valia.
Mas vamos aqui percorrendo essa caminho mais tortuoso mas ainda muito usado, sem contar que desenvolvedores web irão ainda esbarrar por muitos e muitos anos com sistemas legados em ASP e na hora de migrar ou acoplar com sistemas existentes um bom contato com as técnicas das “antigas” vai ser de grande utilidade.
Tabelas em HTML são criadas com o TAG <table> </table>
Cada linda da tabela é um ROW <tr> </tr>
E as colunas são células criadas com o TAC <td> </td>
Assim uma tabela com 3 linhas e 3 colunas seria criada como
<table>
<tr> <td> </td> <td> </td> <td> </td> </tr>
<tr> <td> </td> <td> </td> <td> </td> </tr>
<tr> <td> </td> <td> </td> <td> </td> </tr>
</table>
Ao tentar usar esses tags em nosso site asp temos 2 grandes opções, interromper as partes asp usando <% e %> e colocando o HTML fora dessas regiões ou usando o comando response.write para escrever todos os tags na página. A segunda opção da uma melhor sensação de estarmo num único ambiente mas dá muito mais trabalho, a primeira produz um código mais confuso mas facilita a edição das tags em programas como o DreamWeaver e é a preferida em ambientes aonde é necessária a integração entre webdesigners e webdevelopers e é nessa direção que eu vou.
<HTML>
<HEAD>
<TITLE>graficas</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<table border=1 align="center">
<tr><td>
<img src="images/graficaonline_01.gif">
</td>
</tr>
<%
'aqui começa ASP
'cria objeto ASP de conexão
Set objConn = server.createobject("ADODB.Connection")
'cria string de conexão específica para um determinado banco de dados
strConn = "DBQ=" & server.mappath("graficasonline.mdb") & ";Driver={Microsoft Access Driver (*.mdb)}"
'conecta ao banco de dados
objConn.open strConn,3,3
'cria o recordset para executar uma consulta e retornar com os dados obtidos
Set rs= Server.CreateObject("ADODB.Recordset")
' texto do comando sql a ser executado
sql = "SELECT AreaID, Area FROM Area ORDER BY Area"
' executa a consulta
rs.Open sql, strConn, 3, 3
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<%= rs("area") %>
</td>
</tr>
<%
' procura o próximo
rs.movenext
loop
%>
</table>
<%
'importante .. fechar conexao e destruir objetos
set rs= nothing
objConn.close
set objConn = nothing
%>
</BODY>
</HTML>
Que ao executar produz

Detalhes a observar :
Agora para finalizar vamos incluir o link sobre o nome da área de modo que ao clicar sobre ele sejamos levados a listar as empresas daquela área.
E já adianto que vai ser uma misturada de comandos -)
Para fazer um link precisamos usar o TAG <A> </A>
Que tem o seguinte formato
<A HREF=” ENDERECO DO LINK ” > NOME QUE APARECE PARA SER CLICADO </A>
O que será exibido na página é : NOME QUE APARECE PARA SER CLICADO mas o link para onde iremos estará definido em ” ENDERECO DO LINK ”
No nosso caso o que queremos é que seja mostrado o nome da ÁREA mas que ao clicar sejamos levados a página LISTAEMPRESAS.asp
O nosso comando deve então ficar algo como
<A HREF=”ListaEmpresas.asp” >Agência de Publicidade</A>
Entrentanto o nosso sitema é dinâmico e nome das áreas são trazidas do banco pelo recordeser de no rs, no comando rs(“Area”)
Melhorando um pouco mais
<A HREF=”ListaEmpresas.asp” > <%= rs(“Area”) %> </A>
Mas isso ainda não é o suficiente pois a página ListaEmpresas.asp terá que listar apenas as empresas que sejam da mesma área que rs(“Area”), mas aonde está armazenado o ID da área ? em rs(“AreaID“) que foi carregado junto da área via o SQL :
sql = "SELECT AreaID, Area FROM Areas ORDER BY Area"
Então precisamos arrumar um mode de passer para a rotina ListaEmpresas.asp o AreaID da Área que for clicada. Faremos isso através de um recurso do HTML, a querystring. A querystring é um parâmetro que podemos acrescentar ao nosso endereço, a nossa URL. Veja o exemplo
www.meusite.com.br/listaEmpresa.asp?area=15
tudo o que vem depois da interrogação faz parte da querystring, estamos passando a variavel area cujo valor é 15, depois verermos iremos recuperar esse valor
Então o nosso comando completo deverá ser
<A HREF='ListaEmpresas.asp?area=<%= rs("areaID") %>' > <%= rs("Area") %> </A>
Feio? Não, feio sou eu, é horroroso -), mas é assim mesmo, não adianta reclamar.
IMPORTANTE >>>> Observem que tivemos usar ASPAS SIMPLES no HREF para não misturar com as ASPAS DUPLAS do rs (“”) .
Criei uma listaAreas2.asp
<HTML>
<HEAD>
<TITLE>graficas</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<table border=1 align="center">
<tr><td>
<img src="images/graficaonline_01.gif">
</td>
</tr>
<%
'aqui começa ASP
'cria objeto ASP de conexão
Set objConn = server.createobject("ADODB.Connection")
'cria string de conexão específica para um determinado banco de dados
strConn = "DBQ=" & server.mappath("graficasonline.mdb") & ";Driver={Microsoft Access Driver (*.mdb)}"
'conecta ao banco de dados
objConn.open strConn,3,3
'cria o recordset para executar uma consulta e retornar com os dados obtidos
Set rs= Server.CreateObject("ADODB.Recordset")
' texto do comando sql a ser executado
sql = "SELECT AreaID, Area FROM Area ORDER BY Area"
' executa a consulta
rs.Open sql, strConn, 3, 3
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<A HREF='ListaEmpresas.asp?area=<%= rs("areaID") %>' > <%= rs("Area") %> </A>
</td>
</tr>
<%
' procura o próximo
rs.movenext
loop
%>
</table>
<%
'importante .. fechar conexao e destruir objetos
set rs= nothing
objConn.close
set objConn = nothing
%>
</BODY>
</HTML>
O efeito é

Observem o que é exibido quando o mouse passa sobre o link.
Se clicarem, ocorrerá um erro, já que não fizemos o ListaEmpresas.asp ainda.
Com o todo o nosso know-how adquirido nos execícios anteriores ListaEmpresas.asp vai ser bem fácil de fazer é praticamente a mesma coisa com exceção de :
1. Temos que saber como recuperar o valor da área passado pelo link no ListaArea.asp
2. E temos que nos virar para usar esse valor no meio do SELECT que irá recuperar as empresas que são dessa área.
Para capturar o valor passado usaremos um objeto do ASP chamado REQUEST, especificamente o método Querystring desse objeto e formato é
Request.QueryString(“area”)
De forma prudente e para gerar menos chamadas ao objeto vamos logo desde o início armarzanar esse valor passado numa variavel que escolhi chamar areaid assim :
Areaid = Request.QueryString(“area”)
Se e ListaEmpresa foi chamado no formato
www.meusite.com.br/listaEmpresa.asp?area=15
então é certo que em AreaID estará o valor 15,
como então recuperamos todas as empresas da área = 15 ?
basta construir um SQL com uma clásula WHERE que inclua esse valor passado pela querystring
Aqui está a primeira versão de ListaEmpresa.asp, estou retirand o cabeçalho inicial para tentar enquadrar o central é um única página.
<table border=1 align="center">
<tr><td>
<img src="images/graficaonline_01.gif">
</td>
</tr>
<%
' recupera o valor da areaID
Areaid = Cint(Request.QueryString("area"))
'cria objeto ASP de conexão
Set objConn = server.createobject("ADODB.Connection")
'cria string de conexão específica para um determinado banco de dados
strConn = "DBQ=" & server.mappath("graficasonline.mdb") & ";Driver={Microsoft Access Driver (*.mdb)}"
'conecta ao banco de dados
objConn.open strConn,3,3
'cria o recordset para executar uma consulta e retornar com os dados obtidos
Set rs= Server.CreateObject("ADODB.Recordset")
' texto do comando sql a ser executado
sql = "SELECT EmpresaID, Empresa,Estado FROM Empresa WHERE AreaID = " &_
AreaId & " ORDER BY Empresa"
' executa a consulta
rs.Open sql, strConn, 3, 3
'testa se foi ao final do arquivo sem encontrar nada e para
if ( rs.eof ) then
%>
<tr>
<td>
Não existem empresas cadastradas nesse área! <p>
<a href="ListaAreas2.asp">retornar</a>
</td>
</tr>
</table>
<%
response.end
end if
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<%= rs("EmpresaID") %> <%= rs("empresa") %> <%= rs("estado") %> </A>
</td>
</tr>
<%
' procura o próximo
rs.movenext
loop
%>
</table>
<%
'importante .. fechar conexao e destruir objetos
set rs= nothing
objConn.close
set objConn = nothing
%>
O mais importante aqui é
sql = "SELECT EmpresaID, Empresa,Estado FROM Empresa WHERE AreaID = " & _
AreaId & " ORDER BY Empresa"
E nessa linha duas coisas a destacar, primeiro o símbolo “_” no final da linha, ele está lá para indicar que o comando que começa numa linha vai continuar na próxima.
Segundo o fato de que sql é uma string e uma string que é “concatenada” ou seja ela é união de 3 partes que se juntam para forma uma única string, a primeira parte é
"SELECT EmpresaID, Empresa,Estado FROM Empresa WHERE AreaID = "
Que é somada ao valor vindo de AreaID
Que por fim se soma a string " ORDER BY Empresa"
O símbolo que garante essa concatenação é o “&”.
Então supondo que na hora que você clica na página ListaArea em um link cujo AreaId = 15
Esse string sql se tornará
SELECT EmpresaID, Empresa,Estado FROM Empresa WHERE AreaID = 15 ORDER BY Empresa;

Antes de prosseguirmos tornando o nosso código cada vez mais completo, complexo e real quero tentar reduzir o efeito “macarrônico” de misturar lógica e apresentação numa mesma página com o uso de FUNCTIONS e SUBROTINAS.
Usando SUBROTINAS e FUNÇÕES é possível obter um código mais fácil de manter e de estruturar o nossos algoritmos.
Primeiro, vamos abordar a questão de usar tabelas para organizar o nosso visual, sabemos que precisamos ter uma TAG de abertura <TABLE> e uma de fechamento </TABLE> e que entre elas fica a nossa apresentação. Sabemos que queremos ter uma cabeçalho interessante que se repete em todas páginas de nosso site e se ficarmos usando
<tr><td>
<img src="images/graficaonline_01.gif">
</td>
</tr>
Imagina o trabalho que teremos se depois de estarmos com 50 páginas prontas resolvermos mudar o nome da figura, ou nome diretório, ou ambos. O Dreamweaver resolve isso facilmente, no caso mudança de nome, mas as modificações pode ser bem mais complexas do que simplesmente mudar o nome da figura, você pode quere por exemplo acrescetar uma linha ao cabeçalho e nela colocar um menu horizontal, e agora ? em 50 páginas, dói né ?
Em pretendo resolver usando subrotinas e include. Com a subrotina eu do mais clareza ao meu código com o include eu permito que as minhas subrotinas ou trechos de códigos possam ser incluidos nas 50 páginas, basta então alterar o include que todas as páginas se alteram automáticamente.
Mas nessas páginas de LISTAR algo no que elas se resumem ?
a) conectar ao banco de dados
b) executar um sql e recuperar um recordset
c) imprimir um cabeçaho da página
d) imprimir todas as linhas do recordset dentro de linhas de tabela
e) e eventualmente imprimir um rodapé ( o que não fizemos até agora )
Vamos tentar agora gerar uma nova ListaEmpresa.asp segundo esse modelo
Será a nossa ListaEmpresa2.asp
<% 'ListaEmpresa2.asp
' recupera lista de empresas que pertencem a uma área
' codEmpresa, Empresa, Estado
'
'o nosso programa se resume a uma série de chamadas a sub-rotinas aonde a lógica do queremos
' fazer fica muito mais evidente
' Para podermos citar as variáveis entre sub-rotina devemo declará-las com o comando DIM
Dim objConn, rs
' recupera o valor da areaID
Areaid = Cint(Request.QueryString("area"))
recuperaDados()
exibeCabecalho()
listaDados()
exibeRodape()
encerraConexao()
'
'* SUB-ROTINAS ***********************************************************
'
Sub recuperaDados()
'cria objeto ASP de conexão
Set objConn = server.createobject("ADODB.Connection")
'cria string de conexão específica para um determinado banco de dados
strConn = "DBQ=" & server.mappath("graficasonline.mdb") & ";Driver={Microsoft Access Driver (*.mdb)}"
'conecta ao banco de dados
objConn.open strConn,3,3
'cria o recordset para executar uma consulta e retornar com os dados obtidos
Set rs= Server.CreateObject("ADODB.Recordset")
' texto do comando sql a ser executado
sql = "SELECT EmpresaID, Empresa,Estado FROM Empresa WHERE AreaID = " &_
AreaId & " ORDER BY Empresa"
' executa a consulta
rs.Open sql, strConn, 3, 3
End Sub
Sub listaDados()
'testa se foi ao final do arquivo sem encontrar nada e para
if ( rs.eof ) then
%>
<tr>
<td>
Não existem empresas cadastradas nesse área! <p>
<a href="ListaAreas2.asp">retornar</a>
</td>
</tr>
<%
else ' existem registros logo vamos listá-los
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<%= rs("EmpresaID") %> <%= rs("empresa") %> <%= rs("estado") %> </A>
</td>
</tr>
<%
' procura o próximo
rs.movenext
loop
end if
End Sub
Sub encerraConexao()
'importante .. fechar conexao e destruir objetos
set rs= nothing
objConn.close
set objConn = nothing
End Sub
Sub exibeCabecalho
%>
<HTML>
<HEAD>
<TITLE>graficas</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<table border=1 align="center">
<tr><td>
<img src="images/graficaonline_01.gif">
</td>
</tr>
<%
End Sub
Sub exibeRodape
%>
</TABLE>
</BODY>
</HTML>
<%
End Sub
%>
Ficou faltando um botão de retorno para a tela anterior e aqui podemos usar um pouco de JavaScript para indicar ao navegador como fazer isso, basta criar um link com o seguinte formato :
<a href=’Javascript:history.go(-1)’>retornar </a>
Vou colocar isso na subrotina de rodapé, acrescento uma nova linha a tabela e coloco o comando lá :
Sub exibeRodape
%>
<tr>
<td>
<a href=’Javascript:history.go(-1)’>retornar </a>
</td>
</tr>
</TABLE>
</BODY>
</HTML>
<%
End Sub
Vejam que funciona

Em paralelo para não perder o que já fizemos e ainda incluir as novidades, estou alterando a ListaArea.asp para ListaArea2.asp e fazendo com que a mesma aponte para ListaEmpresa2.asp
Veja que o programa se comporta as mil maravilhas mesmo com as subrotinas.
E o mais legal fiz alteração na APRESENTAÇÃO da página e não mexi na lógica do programa, isso é bom! -)
Já separamos melhor a lógica da página da sua apresentação mas ainda não resolvemos a questão de termos 50 páginas baseadas num mesmo cabeçalho e rodapé e como alterá-las de uma vez só.
O que vamos fazer ?
Vamos salvar a rotina de cabeçalho e de rodapé em um arquivo em separado e vamos acrescentar esse arquivo em tempo de execução através da diretiva INCLUDE.
Primeiro crio um arquivo SUBROTINAS.asp e coloco lá as rotinas que quero sem esquecer de retirar as rotinas do arquivo original.
O Arquivo de Subrotinas
<%
' Arquivo de subrotinas a ser incluído em rotinas do sistema
Sub exibeCabecalho
%>
<HTML>
<HEAD>
<TITLE>graficas</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<table border=1 align="center">
<tr><td>
<img src="images/graficaonline_01.gif">
</td>
</tr>
<%
End Sub
Sub exibeRodape
%>
<tr>
<td>
<a href='Javascript:history.go(-1)'>Retornar </a>
</td>
</tr>
</TABLE>
</BODY>
</HTML>
<%
End Sub
%>
E o listaEmpresa2.asp sem as mesmas mas com o comando include logo no início do arquivo
<!--#include file="subrotinas.asp" -->
<% 'ListaEmpresa2.asp
' recupera lista de empresas que pertencem a uma área
' codEmpresa, Empresa, Estado
'
'o nosso programa se resume a uma série de chamadas a sub-rotinas aonde a lógica do queremos
' fazer fica muito mais evidente
' Para podermos citar as variáveis entre sub-rotina devemo declará-las com o comando DIM
Dim objConn, rs
' recupera o valor da areaID
Areaid = Cint(Request.QueryString("area"))
recuperaDados()
exibeCabecalho()
listaDados()
exibeRodape()
encerraConexao()
'
'* SUB-ROTINAS ***********************************************************
'
Sub recuperaDados()
'cria objeto ASP de conexão
Set objConn = server.createobject("ADODB.Connection")
'cria string de conexão específica para um determinado banco de dados
strConn = "DBQ=" & server.mappath("graficasonline.mdb") & ";Driver={Microsoft Access Driver (*.mdb)}"
'conecta ao banco de dados
objConn.open strConn,3,3
'cria o recordset para executar uma consulta e retornar com os dados obtidos
Set rs= Server.CreateObject("ADODB.Recordset")
' texto do comando sql a ser executado
sql = "SELECT EmpresaID, Empresa,Estado FROM Empresa WHERE AreaID = " &_
AreaId & " ORDER BY Empresa"
' executa a consulta
rs.Open sql, strConn, 3, 3
End Sub
Sub listaDados()
'testa se foi ao final do arquivo sem encontrar nada e para
if ( rs.eof ) then
%>
<tr>
<td>
Não existem empresas cadastradas nesse área! <p>
<a href="ListaAreas2.asp">retornar</a>
</td>
</tr>
<%
else ' existem registros logo vamos listá-los
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<%= rs("EmpresaID") %> <%= rs("empresa") %> <%= rs("estado") %> </A>
</td>
</tr>
<%
' procura o próximo
rs.movenext
loop
end if
End Sub
Sub encerraConexao()
'importante .. fechar conexao e destruir objetos
set rs= nothing
objConn.close
set objConn = nothing
End Sub
%>
Agora sim eu consegui um relativamente grau de independência, se todas as minhas rotinas forem estruturadas assim, basta que editemos o cabeçalho e o rodapé que todas mudarão de acordo.
Claro que isso é uma meia verdade, pois se alterarmos a estrutura de apresentação da página para não se apoiar mais em TABELAS, as rotinas de exibir resultados teriam que ser alteradas tambem. Por isso que um bom planejamento de arquitetura do projeto web é indispensável e pode salvar muito tempo no futuro.
Mas essas não é a única questão que devemos nos preocupar com as nossas rotinas, ROBUSTEZ é outra, serão as nossas rotinas a prova de falhas?, a prova de valores informados incorretamente ?
Até agora tudo está muito correto, mas se houver algum engano ? se a rotina ListaEmpresa for acessada assim ?
www.meusite.com.br/listaEmpresa.asp?area=XYZK
vai acontecer um errro porque esperamos um número e foi passado uma string e se for chamado sem parâmetro algum assim :
www.meusite.com.br/listaEmpresa.asp
o valor de área ficará indefinido e novamemte ListaEmpresa não irá ser executada corretamente e um erro irá acontecer. Lembre-se dos conceitos de Engenharia de Software que ROBUSTEZ é um dos fatores de qualidade de um softeware e está associado a capacidade do mesmo facer face a entrada erradas e não previstas, para previnir isso teremos que testar o valor da área passada e tomar decisões sobre como a nossa rotina irá se comportar, ok ?
Para fins de nosso exemplo eu vou assumir o seguinte :
ListaEmpresa.asp só deverpa ser executada se algum valor númerico de area for passado caso contrário uma mensagem de erro deverá ser exibida, e quais são essas possibildades :
1. O valor de área não foi passado é nulo,
2. O valor de área foi passado mas não é um número inteiro,
3. O valor de área foi passado é um inteiro mas não existe área alguma que corresponda a esse número,
Correto, Sim? Não?
Rotinas robustas devem ser uma meta enquanto desenvolvemos sistemas, não devemos esperar que os dados fornecidos sejam sempre corretos sob pena de assisitir ao nosso sistema falhar de forma vergonhosa. -)
Então como exercício, tentem fazer testes sobre os valores passados na querystring antes da mesma ser usado na string sql.
Exibindo detalhes dos registros
O nosso sistema ASP já consegue lista areas nas quais as empresas se enquadram e listar alguns dados das empresas que pertençam as áreas, o próximo passo e poder exibir em uma página de detalhe os dados em um formato de formulário e que não couberam na listagem ou que por uma questão de projeto não deveriam aparecer no meio da listagem.
A listaEmpresa2.asp produz o resultado abaixo

Sendo que o primeiro número de cada linha é o ID da Empresa, ora usando o mesmo conceito que empregamos para ir da página de areas para a de empresas podemos ir da de empresas para o detalhe de empresa.
Como já estamos mestres, basta o que ?
Basta criar um link que aponte para um nova página de detalhes da empresa que vou chamar de detalheEmpresa.asp e passar o ID da empresa.
Novamente a fim de não perder os nossos exercícios anteriores vou criar uma nova ListaEmpresa a ListaEmpresa3.asp e é lá que vou colocar esse link, basta alterar uma única linha dentro da subrotina listaDados
Sub listaDados()
'testa se foi ao final do arquivo sem encontrar nada e para
if ( rs.eof ) then
%>
<tr>
<td>
Não existem empresas cadastradas nesse área! <p>
<a href="ListaAreas2.asp">retornar</a>
</td>
</tr>
<%
else ' existem registros logo vamos listá-los
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<a href=’detalheEmpresa.asp?emp=<%= rs("EmpresaID") %>’> <%= rs("empresa") %> </a><%= rs("estado") %>
</td>
</tr>
<%
' procura o próximo
rs.movenext
loop
end if
End Sub
Qual o detalhe a destacar ?
<a href=’detalheEmpresa.asp?emp=<%= rs("EmpresaID") %>’> <%= rs("empresa") %> </a> <%= rs("estado") %>
O link composto de uma referência a rotina detalheEmpresa que ainda vamos fazer, passando um valor chamdo emp que deverá conter o código da empresa exibida.
Veja o efeito na página

Melhor não ? Até porque não tinha muito sentido para os nossos clientes ficar vendo o código da empresa, não acrescenta nada de valor nesse nível de uso ao cliente final.
Nesse listagem tem algo que está me incomodando mas que eu vinha evitando alterar, o fato de o estado da empresa aparecer colado ao lado do nome da empresa, eu preferia que estivessem numa única coluna todos alinhados.
A solução para isso é colocar o nome da empresa em uma coluna e o estado em outra, assim :
<tr>
<td>
<!—primeira coluna -->
<a href='detalheEmpresa.asp?emp=<%= rs("EmpresaID") %>'> <%= rs("empresa") %> </a>
</td>
<!—segunda coluna -->
<td>
<%= rs("estado") %>
</td>
</tr>
Eu consigo o que eu queria, vejam :

Mas com um efeito colateral indesejado, o cabeçalho da primeira linha aonde está a figura na cobre as 2 colunas. Para contornar isso temos que usar a TAG COLSPAN=2 na linha do cabeçalho e do rodapé e que agora estão em um arquivo separado.
Vou aproveitar para dar um incrementada no visual, retirando a borda da tabela e especificando fontes e seus tamanhos e ainda linhas separadoras.
Nas subrotinas
<%
' Arquivo de subrotinas a ser incluído em rotinas do sistema
Sub exibeCabecalho
%>
<HTML>
<HEAD>
<TITLE>graficas</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
</HEAD>
<BODY BGCOLOR=#FFFFFF>
<table border=0 align="center">
<tr><td colspan=2>
<img src="images/graficaonline_01.gif">
</td>
</tr>
<tr height=30><td></td></tr>
<%
End Sub
Sub exibeRodape
%>
<tr>
<td colspan=2 height=50>
<font FACE="arial" SIZE="1">
<a href='Javascript:history.go(-1)' class="style1">Retornar</a>
</font>
</td>
</tr>
</TABLE>
</FONT>
</BODY>
</HTML>
<%
End Sub
%>
Em ListaEmpresa3.asp a modificação foi apenas em listaDados
<%
Sub listaDados()
'testa se foi ao final do arquivo sem encontrar nada e para
if ( rs.eof ) then
%>
<tr>
<td>
<font FACE="arial" SIZE="1">
Não existem empresas cadastradas nesse área! <p>
<font>
</td>
</tr>
<%
else ' existem registros logo vamos listá-los
'enquanto houver registros
do while not rs.eof
%>
<tr>
<td>
<font FACE="arial" SIZE="1">
<!-- exibindo um valor do ambiente VBScripp/Asp dentro do HTML -->
<a href='detalheEmpresa.asp?emp=<%= rs("EmpresaID") %>'> <%= rs("empresa") %> </a>
</font>
</td>
<td><font FACE="arial" SIZE="1">
<%= rs("estado") %>
</font>
</td>
</tr>
<tr>
<td bgcolor="#CCCCFF" height="1" colspan=2></td></tr>
<%
' procura o próximo
rs.movenext
loop
end if
End Sub
%>
O efeito é esse, letras menores, mais espaço entre o cabeçalho e a listagem e da listagem para o rodapé.
