domingo, 5 de maio de 2013

Genexus ExcelDocument - Gerando Planilhas

Em alguns momentos quando projetamos aplicações, verificamos a necessidade de gerar relatórios em planilhas do excel. Seja para os usuários da aplicação ou então, para a transferência de dados e integração entre sistemas.

A entrega de relatórios em planilhas gera um grande valor aos clientes. Através delas, os usuários poderão gerar filtros, fórmulas, inserir, alterar e excluir as informações presentes no relatório.

Neste post irei demonstrar como podemos gerar planilhas através de funções no Genexus. Procurarei utilizar algumas as funções que este tipo de variável nos permite, desde a utilização de Templates à inserção de conteúdos com a fonte desejada.

Além de gerar planilhas, o Genexus nos permite realizar a leitura destas, realizando desta forma, a função contrária à comentada neste tópico. Neste caso, um outro software geraria uma planilha e através da nossa aplicação poderíamos internalizar estes registros.

Vamos iniciar, o objetivo traçado neste tópico é disponibilizar ao usuário uma planilha que contenha a lista de clientes cadastrados em um sistema. Nesta lista estarão inclusos os campos: nome, data de nascimento, idade, sexo e o endereço completo de cada um. Para facilitar a visualização dos dados, iremos gerar esta planilha com base em um arquivo template previamente criado. Este arquivo já irá conter o layout desejado e fórmulas condicionais. Ao fim, a planilha irá ficar semelhante a esta abaixo:

Genexus Excel Document

Criando o template de utilização

O que é um template?

Templates são modelos, design, padrões pré-definidos porém sem conteúdo. Um template é utilizado para dar uma certa estrutura à sua planilha. A própria Microsoft dispõem de inúmeros templates para serem utilizados, você pode ver cada um deles clicando aqui.

A primeira etapa é criar um template ao qual a planilha irá se basear. Para isso, crie primeiramente dentro da pasta "web" da sua base de conhecimento, a pasta "Template". Sendo assim o caminho ficará: "...\web\Template\".  

Agora, execute o Excel, crie o template que desejar, e salve-o com a extensão .XLT (Modelo do Excel 97-2003) dentro da pasta criada anteriormente. O meu template ficou da seguinte forma:

Genexus Excel Document

Criando o Efeito Zebrado - Formatação Condicional

A segunda etapa é a criação de formatações condicionais no nosso template. Para isso utilizaremos a seguinte lógica, as linhas pares terão o fundo cinza quando não forem vazias, já as linhas impares terão o fundo branco quando não forem vazias.

Portanto, abra o template criado, clique em "Formatação Condicional" e em "Nova Regra". Agora clique em  "Usar uma fórmula para determinar quais células devem ser formatadas".

Para as linhas pares:
Fórmula: =SE(MOD(LIN();2)=0;$C6<>"")
Visualização: Preenchimento cinza, borda inferior;
Aplica-se a =$B$6:$L$1000 (linhas e colunas onde estarão os dados)

Para as linhas impares:
Fórmula: =SE(MOD(LIN();2)=1;$C6<>"")
Visualização: Preenchimento branco, borda inferior;
Aplica-se a =$B$6:$L$1000 (linhas e colunas onde estarão os dados)

Ao fim, eis o resultado:

Genexus Excel Document

Gerando Planilhas através do Genexus

Por fim, iremos criar uma procedure e utilizar as funções apropriadas para a criação da nossa planilha. Nesta procedure não receberei parâmetros, irei facilitar para a demonstração deste exemplo. Então em "Source" defini da seguinte forma:

Considerações
- não utilizei a função "Clear()" pois como o  template contem textos, eles iriam ser excluídos. Logo, para não abrir uma planilha já criada defina o nome com base na data, hora, usuário de geração.
- o endereço de geração da planilha é o endereço onde a aplicação esta hospedada. Para disponibilizar ao cliente por meio de uma interface, você deverá utilizar a função "Link(endereço da planilha)".

//=====Define que as Colunas não irão se auto ajustar=====
&ExcelDocument.AutoFit = 0

//=====Define a utilização do template=====
&ExcelDocument.Template = '..\web\Template\RelatorioClientes.xlt'

//=====Define o endereço e nome do arquivo a ser criado (aberto)=====
&Source = 'C:\Temp\ListaClientes_'+&Today.ToString().Trim()+'.xls'
&Source = StrReplace(&Source,'/','_')

//=====Abrir Arquivo=====
&ExcelDocument.Open(&Source)

//=====Definir a primeira linha de trabalho=====
&Linha = 6

//=====Percorre Lista de Clientes Cadastrados=====
for each ClienteCod

//=====Código do Cliente; 2ª Coluna; Negrito=====
&ExcelDocument.Cells(&Linha,2).Bold = true
&ExcelDocument.Cells(&Linha,2).Number = ClienteCod

//=====Nome do Cliente; 3ª Coluna=====
&ExcelDocument.Cells(&Linha,3).Text = ClienteNome

//=====Data de Nascimento; 4ª Coluna=====
&ExcelDocument.Cells(&Linha,4).Date = ClienteNascimento

//=====Idade; 5ª Coluna; Italico=====
&ExcelDocument.Cells(&Linha,5).Italic = true
&ExcelDocument.Cells(&Linha,5).Number = Age(ClienteNascimento)

//====Sexo; 6ª Coluna; Negrito; Masculino = Azul; Feminino = Vermelho====
&ExcelDocument.Cells(&Linha,6).Bold = true
if ClienteSexo = Sexo.Masculino
&ExcelDocument.Cells(&Linha,6).Color = 5
else
&ExcelDocument.Cells(&Linha,6).Color = 3
endif
&ExcelDocument.Cells(&Linha,6).Text = ClienteSexo.EnumerationDescription()

//=====Endereço; 7ª Coluna=====
&ExcelDocument.Cells(&Linha,7).Text = ClienteEndereco

//=====Número; 8ª Coluna=====
&ExcelDocument.Cells(&Linha,8).Text = ClienteNumero

//=====Complemento; 9ª Coluna=====
&ExcelDocument.Cells(&Linha,9).Text = ClienteComplemento

//=====CEP; 10ª Coluna=====
&ExcelDocument.Cells(&Linha,10).Text = ClienteCEP

//=====Cidade; 11ª Coluna=====
&ExcelDocument.Cells(&Linha,11).Text = ClienteCidade

//=====Estado; 12ª Coluna=====
&ExcelDocument.Cells(&Linha,12).Text = ClienteEstado

//=====Passa para a próxima linha=====
&Linha += 1
endfor

//=====Renomeia Aba (máximo de 31 caracteres)=====
&NomeAba = 'Emissao em '+&Today.ToString().Trim()
&NomeAba = StrReplace(&NomeAba,'/','-')
&ExcelDocument.RenameSheet(&NomeAba)

//=====Salva alterações realizadas=====
&ExcelDocument.Save()

//=====Fecha Arquivo=====
&ExcelDocument.Close()

//=====Mostra Arquivo Gerado=====
&ExcelDocument.Show()

segunda-feira, 22 de abril de 2013

Testando a sua aplicação em diferentes dispositivos e browsers

Durante o desenvolvimento de aplicações, é fundamental visualizarmos em diferentes dispositivos e variáveis de browsers, o resultado obtido.

Hoje em dia, ao escolhermos um browser favorito temos diversas opções disponíveis para download. Antigamente éramos "obrigados" a trabalhar com o Internet Explorer, não havia outras possibilidades, porém esta pouca opção dava uma grande segurança aos web designers. 

Ao criar um design para um software, tínhamos a certeza que este design iria se comportar adequadamente em qualquer ambiente. Hoje, porém, um usuário pode além de escolher o browser a ser trabalhado, determinar a resolução de tela mais adequada para o dispositivo de acesso.

Além de computadores, nossos usuários podem querer acessar as aplicações através de smartphones, tablets, netbooks, notebook, desktops e Smart TV. Cada dispositivo possui uma configuração e uma linguagem, e é ai que nosso design vai pro saco.

Foi em virtude destes problemas que surgiu um novo conceito de design, o Design Responsivo. A principal característica do design responsivo é se adaptar adequadamente ao dispositivo de acesso. 

Hoje não irei entrar em mais detalhes a respeito deste conceito, porém irei dar duas dicas de como podemos testar nossas aplicações em diferentes dispositivos e browsers, sem precisar instalar e realizar isto na mão..

A primeira dica é o site ScreenFly, este site permite testarmos a aplicação gratuitamente em diferentes resoluções de tela (1024x600; 1024x768;etc), modelos de smartphones (RAZR, Galaxy, Iphone), tablets (Google; Kindle; Apple), Televisões e é claro notebooks, netbooks e desktops.


A segunda dica é sobre o BrowserShots, neste site é necessário realizar uma conta informando nome, email e senha. Através do BrowserShots podemos escolher uma URL, e definir as opções de browser e sistema operacional a ser testada esta URL. São mais de 130 opções de browsers, desde o Internet Explorer 5.0 à última versão do Google Chrome, e 4 opções de sistemas operacionais, desde o clássico Windows ao próprio MAC. O resultado pode demorar até 2 minutos, mas isto dependerá as opções definidas.


quinta-feira, 4 de abril de 2013

Genexus - Gerando Botões em CSS

Neste tópico irei fugir um pouco sobre exemplos, lógicas e funções do Genexus. Irei falar de algo simples, mas que insere um "plus" a mais em nossas aplicações. 

Querendo ou não, quando focamos no layout das aplicações geradas, passamos por muitos sufocos. Isso, porque geralmente trabalhamos com tabelas e mais tabelas, criando e recriando classes no nosso tema e aplicando às células, linhas, text blocks, enfim a tudo que aparece em uma web panel...

Vou compartilhar algo que testei a pouco, a geração de estilos em css para aplicar a todos os botões que desejarmos. Estes códigos permitem diferenciar a "cara" dos botões em 3 diferentes momentos, default, mouse over e em cliques, e isso tudo sem utilizar imagem alguma!

Gerando o estilo css

O gerador de css que iremos utilizar é o site www.cssbuttongenerator.com. Neste, podemos configurar as cores, nome da classe, fonte, tamanho desta, sombras, bordas, praticamente cada detalhe do botão.

Genexus Botão

Bom, não irei dar um passo a passo sobre cada elemento das propriedades, mas é muito simples. Ao irem alterando-as já há como detectar cada uma aplicada ao botão.

Após definirmos o nosso estilo, é só clicarmos sobre o botão gerado que o código css irá aparecer logo abaixo.

Como exemplo irei criar três tipos diferentes de botões, um Azul (classAzul), Vermelho (classVermelho) e por último um Amarelo (classAmarelo).

Cada uma destas classes eu irei salvar em um arquivo chamado "botoesCss.css", e este arquivo estará presente dentro da pasta web da aplicação.

Porém, ao copiar cada uma destas classes para o arquivo, não serão necessárias a primeira e a última tag.

1ª Tag (eliminar): <style type="text/css">
Última Tag (eliminar): </style>

Aplicando ao Genexus

Agora, já com os nossos estilos copiados para o arquivo, iremos aplicar a uma web panel qualquer.

Primeiro, precisamos adicionar ao <header> da página o link do nosso arquivo css, para isso dentro do evento start digitaremos:

Event Start
Form.HeaderRawHTML = '<link href="botaoCss.css" rel="stylesheet" type="text/css" />'
EndEvent

Agora irei incluir três botões na web panel, e na propriedade "class" de cada um destes, irei informar (digitar, não há como selecionar) o nome das classes criadas. Veja um exemplo para a classe do botão Azul (classAzul):

Genexus Botao CSS

Por fim o resultado será igual ao abaixo:

Genexus Botao CSS


segunda-feira, 25 de março de 2013

Genexus - Capturar Blob File Name

Quando trabalhamos com arquivos do tipo Blob (Binay large object), nos deparamos com situações onde devemos armazenar, em atributos ou variáveis, o nome e a extensão original do arquivo informado.

Trabalhando com Atributos

Ao trabalharmos com atributos isso pode ser realizado de uma forma bem simples. Por exemplo, em uma transação teremos 3 variáveis:
  1. File - blob;
  2. FileName - varchar(40);
  3. FileType - varchar(5);
Para gravarmos o nome e a extensão original do arquivo selecionado pelo usuário, devemos definir nas propriedades do atributo File (blob) as seguintes características:

Genexus Blob

Trabalhando com Variáveis

Um dos problemas em se trabalhar com variáveis do tipo Blob, é a falta de uma função para capturarmos o nome original do arquivo.

Por exemplo, quando o usuário da nossa aplicação deseja enviar algum arquivo via FTP ou Email, somos obrigados a gravar este arquivo em uma tabela para dessa forma, obtermos o nome original deste. Caso essa gravação não seja realizada, o arquivo enviado pelo usuário, automaticamente, é aberto na pasta "Temp media directory", que por padrão é a pasta "PublicTempStorage", e, recebe um nome aleatório.

Neste post irei demonstrar como podemos obter o nome original deste arquivo através da biblioteca Jquery.

Em uma Web Panel, adicionei à tela, duas variáveis e um botão. As variáveis definidas foram:
  1. &Blob - blob;
  2. &FileName - Varchar(40)
Agora precisamos programar a função em Jquery que irá executar esta captura do nome original. Para isso, utilizei a função "blur". Esta função é justamente o oposto da função "focus", ou seja, quando a variável blob perder o foco, o procedimento irá se executar. Vejamos:

Event Start
//=====Adiciona a biblioteca Jquery=====
Form.JScriptSrc.Add('http://code.jquery.com/jquery-latest.js">')

//=====Inicio do Script=====
Form.HeaderRawHTML = '<script type="text/javascript">'
Form.HeaderRawHTML += '$(document).ready(function(){'

//=====Quando a variável Blob perder o foco, executa=====
Form.HeaderRawHTML += '$("#vBLOB").blur(function(){'
Form.HeaderRawHTML += 'var nome = $("#vBLOB").val();'
Form.HeaderRawHTML += 'nome = nome.match(/[-_\w]+[.][\w]+$/i)[0];'

//=====Define o valor da variavel File name=====
Form.HeaderRawHTML += '$("#vFILENAME").val(nome);'
Form.HeaderRawHTML += '});'
Form.HeaderRawHTML += '});'
Form.HeaderRawHTML += '</script>'
EndEvent

Mais uma ótima utilização de Jquery, qualquer dúvida o email genexus@outlook.com é ótimo para receber qualquer coisa. Abraço.

segunda-feira, 18 de março de 2013

Genexus FTP - Envio e Recebimento de Arquivos

Nesta matéria irei demonstrar como podemos realizar o envio e o recebimento de arquivos via FTP através de funções do Genexus.

Para atingir este objetivo, vou utilizar, primeiramente para o envio de arquivos, um objeto web panel, onde irei adicionar uma variável blob, capaz de "guardar" um arquivo e, a partir de um botão, realizar o envio deste arquivo para um servidor FTP previamente configurado em uma transação de parâmetros da aplicação.

Após, irei demonstrar como realizar o recebimento deste arquivo salvo no servidor FTP. Com isso podemos até trabalhar com este arquivo, ou então gravá-lo em uma tabela da aplicação.

Funções FTP

O Genexus possui funções FTP pouco conhecidas, ou difundidas... Estas funções não se encontram na biblioteca de funções do software (Menu Insert Function), e mesmo quando digitamos estas funções, ao buscar a tecla de atalho (CTRL + Espaço) elas não são mostradas!

O Genexus disponibiliza 7 funções FTP ao total, estas funções nos permitem desde programar uma conexão a um servidor, quanto excluir arquivos presentes neste servidor. 

Uma função que o genexus não disponibiliza, mas que seria muito importante, é algum método de listar todos os arquivos e pastas presentes no servidor FTP. Para isso devemos utilizar a linguagem ambiente .NET ou Java, mas isso veremos em um outro tópico.

Ao longo dos exemplos irei utilizar e explicar todas estas funções.

Conectando a um Servidor FTP

Bom, para começarmos, primeiro necessitamos de um servidor FTP. Para demonstrar irei imaginar um servidor ftp, seu usuário e senha, isso pois não consegui achar um servidor público que permita realizar o dowload e o upload de arquivos.

As variáveis utilizadas poderão ser recebidas como parâmetros nos objetos.

Vamos então realizar a conexão:

//=====Definindo valores das variáveis=====
&Host = 'ftp.genexus.com'
&Usuario = 'Admin'
&Senha = '123456'

//=====Conexão com o Servidor (Host)=====
Call("GxFtpCon", &Host, &Usuario, &Senha)

//=====Verifica se a conexão foi realizado com sucesso=====
Call("GxFtpError", &Retorno)

//===== Retorno 1 - erro ao conectar=====
if &Retorno = 1
//=====Captura mensagem de erro e exibe na tela=====
Call("GxFtpStat",&Mensagem)
msg('Erro: '+&Mensagem)
else
//=====Retorno 0 - conectado com sucesso=====
msg('Conectado com sucesso')
endif

//=====Realiza Logoff do Servidor FTP=====
Call("GxFtpDis")

Enviando Arquivos a um Servidor FTP

Após realizarmos a conexão a um servidor, a partir de funções do Genexus teremos uma possibilidade de 3 ações a serem tomadas: o envio de arquivos, o recebimento e a exclusão destes.

Vamos começar enviando um arquivo determinado por um usuário da aplicação, através de uma variável blob presente em um objeto web panel.

Para isso, primeiro precisamos desenhar a nossa web panel, de forma bem simples será necessário incluirmos uma variável blob e um botão. Este botão irá chamar a nossa procedure de envio de arquivos, enviando como parâmetro o link do arquivo definido pelo usuário, da seguinte forma:

Event Enter
if &Blob.IsEmpty()
msg('Selecione um arquivo!')
else
ConexaoFTP.Call(&Blob.ToString())
endif
EndEvent

Em nossa procedure, iremos programar o envio do arquivo após a conexão com o servidor FTP. Esta função de envio recebe 3 parâmetros:
  1. Source do arquivo, caminho do arquivo físico, este arquivo deverá estar presente no servidor de hospedagem da aplicação;
  2. Local a ser salvo no servidor FTP. Diretório e nome que será atribuído ao arquivo quando este for enviado ao servidor. Quando apenas o diretório seja informado, o nome permanecerá o mesmo.
  3. Modo de envio, poderá ser ASCII ou Binario. Irei determinar ASCII, mas cada tipo de arquivo possui uma opção ideial. Pesquise para encontrar aquele melhor para o seu caso.
Logo, nossa programação ficará da seguinte forma, em rules:

//=====Caminho físico do arquivo - Varchar(400)=====
parm(in:&SourceArquivo);

Em Source:
&Host = 'ftp.genexus.com'
&Usuario = 'Admin'
&Senha = '123456'
&Diretorio = 'ArquivosEnviados\'

Call("GxFtpCon", &Host, &Usuario, &Senha)
Call("GxFtpError", &Retorno)

if &Retorno = 1
Call("GxFtpStat",&Mensagem)
msg('Erro: '+&Mensagem)
else
msg('Conectado com sucesso')

//=====Realiza o envio de um arquivo para o Servidor=====
// Modo "A" = Ascii "B" = Binario
Call("GxFtpPut", &SourceArquivo, &Diretorio, "A")

//=====Verifica se ocorreu algum erro=====
Call("GxFtpError", &Retorno)
if &Retorno = 1

//=====Captura mensagem de erro e exibe na tela=====
Call("GxFtpStat",&Mensagem)
msg('Erro: '+&Mensagem)
else
msg('Arquivo enviado com sucesso!')
endif
endif

Call("GxFtpDis")

Download e Exclusão de arquivos do Servidor FTP

Bom, por fim vamos visualizar como realizar o download de um arquivo e consequentemente a sua exclusão do servidor FTP.

Assim como a função de Upload, a função de download receberá 3 parâmetros:
  1. Source do arquivo presente no servidor FTP, diretório e nome;
  2. Destino do download, se apenas o diretório for determinado, o arquivo manterá o nome original;
  3. Modo de recebimento, "A" = ASCII, "B" = Binario;

Neste exemplo não precisaremos da nossa web panel, logo, em uma procedure programe os eventos da seguinte forma:

&Host = 'ftp.genexus.com'
&Usuario = 'Admin'
&Senha = '123456'
&SourceArquivo = 'ArquivosEnviados\teste.txt'
&DiretorioDestino = 'C:\Temp\'

Call("GxFtpCon", &Host, &Usuario, &Senha)
Call("GxFtpError", &Retorno)

if &Retorno = 1
Call("GxFtpStat",&Mensagem)
msg('Erro: '+&Mensagem)
else
msg('Conectado com sucesso')

//=====Realiza o download de um arquivo para o Servidor=====
// Modo "A" = Ascii "B" = Binario
Call("GxFtpGet",&SourceArquivo,&DiretorioDestino, "A")

//=====Verifica se ocorreu algum erro=====
Call("GxFtpError", &Retorno)
if &Retorno = 1

//=====Captura mensagem de erro e exibe na tela=====
Call("GxFtpStat",&Mensagem)
msg('Erro: '+&Mensagem)
else
msg('Arquivo recebido com sucesso!')

//=====Realiza a exclusão do arquivo no servidor FTP=====
Call("GxFtpDelete",&SourceArquivo)

//=====Verifica se ocorreu algum erro=====
Call("GxFtpError", &Retorno)
if &Retorno = 1

//=====Captura mensagem de erro e exibe na tela=====
Call("GxFtpStat",&Mensagem)
msg('Erro: '+&Mensagem)
else
msg('Arquivo excluído com sucesso!')
endif
endif
endif

Call("GxFtpDis")