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")

sábado, 2 de março de 2013

Configuração de Servidores - Erro no envio de emails

Configuração Servidor
Uma das dificuldades de se trabalhar com aplicações web, são as configurações dos servidores, seja de produção ou homologação.

Quando iniciamos com o Genexus, temos um desafio inicial, que é correta configuração do ambiente, tanto para compilar aplicações em Java quando em .Net. Após esta configuração inicial, do ambiente de desenvolvimento, temos um outro desafio: A configuração dos servidores de produção e homologação. 

Esta tarefa se torna árdua em virtude das "N" combinações possíveis de ambiente. Podemos trabalhar com SQL Server 2005 em um servidor Windows Server 2003, 32 bits, ou talvez com Postgresql em um sistemos operacional Windows Server 2008 64 bits. Além destas possíveis combinações, temos as diferentes versões  do Genexus. Tudo isso combinado, se torna um pesadelo para qualquer profissional da TI.

Bom pessoal, vou compartilhar um erro que enfrentei nesta última semana. Estou trabalhando em um projeto na versão do Genexus Upgrade 2, ao publicar o sistema em um ambiente Windows Server 2008 64 bits, enfrentei uma dificuldade nos envios de email pela aplicação.

Independente da configuração do firewall, ele podia inclusive estar desligado, e das portas configuradas através da programação da procedure, eu sempre recebia a mesma mensagem:

"An error occurs while communicating with the remote host."

Esta mensagem aparecia logo na hora de realizar o login junto ao host. Cheguei inclusive, a dar privilégios totais de segurança para o usuário IIS, isso, para verificar se era alguma configuração do servidor. Porém, mesmo assim, nada disso trouxe um efeito positivo.

Após algumas pesquisas e pesquisas, encontrei um post de um usuário, isso em 2010, onde este, afirma ter encontrado um bug ao realizar envios  de emails em um servidor Windows 7 64 bits, este usuário estava programando na versão Upgrads 2 do genexus, a mesma que a minha.

Segundo a artech, este bug foi corrigido na versão Upgrade 7, logo, as outras versões devem apresentar o mesmo problema.
E qual a solução proposta?

Encontrei no blog Genexando, uma rotina de envio de email em CSharp, a ser implementada no genexus. Esta programação contorna o problema, porém restringe a aplicação para um único gerador, caso deseja compliar em Java, deverá criar a mesma rotina em Java.

Vamos lá pra o código. Criei um objeto Procedure no Genexus, e em Source programe:
//=====Variáveis utilizadas - poderão ser recebidas como parâmetros=====

//=====Host de conexão - Varchar(40)=====
&SMTPHost = 'smtp.gmail.com.br'

//=====Usuário e senha de conexão -Varchar(40)=====
&SMTPUserName = 'Usuario'
&SMTPEmailPassword = 'senha'

//=====Enviar o email para... - Varchar(40)=====
&EMailTo = 'edu_ferroni@hotmail.com'

//=====Assunto - Varchar(40) e Mensagem - LongVarchar=====
&EMailSubject = 'Assunto'
&EMailMessage = 'Mensagem'

//=====Código nativo CSharp=====
csharp try
csharp {
csharp System.Net.Mail.MailMessage mM = new System.Net.Mail.MailMessage();

csharp mM.From = new System.Net.Mail.MailAddress([!&SMTPUserName!]);
csharp mM.To.Add([!&EMailTo!]);
csharp mM.Subject = [!&EMailSubject!];
csharp mM.Body = [!&EMailMessage!];
csharp mM.IsBodyHtml = true;
csharp mM.Priority = System.Net.Mail.MailPriority.High;

//=====Porta de conexão utilizada: 587=====
csharp System.Net.Mail.SmtpClient sC = new System.Net.Mail.SmtpClient([!&SMTPHost!], 587);
csharp string strId;
csharp string strPassword;
csharp strId = [!&SMTPUserName!];
csharp strPassword = [!&SMTPEmailPassword!];
csharp sC.Credentials = new System.Net.NetworkCredential(strId, strPassword);
csharp sC.Send(mM);

//=====Verifica status: 1 = envio com sucesso; 0 = erro ao enviar=====
csharp [!&statusEnvio!] = 1;
csharp }
csharp catch (System.Exception ex)
csharp {
csharp [!&statusEnvio!] = 0;
csharp }

Agradeço ao Genexando pelo código, me ajudou bastante, e espero que ajude a quem mais precisar.

Com o tempo irei postar mais sobre este assunto, configuração de ambientes. Irá inclusive, me ajudar a documentar os processos que venho passando.

Grande abraço.

segunda-feira, 25 de fevereiro de 2013

Teste seu conhecimento #2 (lógica de programação)

Genexus Desafio Lógica
Bom esse novo desafio não tem história por trás, apenas pesquisei e encontrei em um site sobre lógica e desafios matemáticos, hehehe.

Vamos lá, desafio vocês a encontrarem o menor código possível para resolver o seguinte problema:

Se nós listarmos todos os números naturais menores que 10 que são múltiplos de 3 e 5, teremos: 3; 5; 6 e 9. Somando estes múltiplus naturais o resultado será 23!

Encontre a soma de todos os números naturais múltiplos de 3 e 5 menores que 1000! Sem pega ratão.. haha

Existe apenas um resultado certo, o desafio maior é realizar este procedimento com o menor código possível!

Gostaria muito de receber o resultado encontrado e o código utilizado para chegar a este número. Obrigado. :D

domingo, 17 de fevereiro de 2013

Genexus e Google Analytics

Genexus Google Analytics
Google Analytics é uma ferramente poderosa e gratuita que possibilita conhecer como os usuários de sua aplicação se comportam. A partir de estatísticas em tempo real e em períodos determinados, podemos saber entre muitas outras coisas, a quantidade de visitantes únicos por dia, quais páginas eles mais acessam, em qual horário e quanto tempo eles permaneceram na aplicação.

Para desfrutar desta API (Application Programming Interface) é necessário possuir uma conta no Google, qualquer conta, como Gmail, YouTube e Orkut, acessar o site da ferramente e clicar
sobre o botão "Criar Conta". Seguindo o passo a passo da criação você irá informar seu nome, a url da aplicação, país, entre outras coisas.

Após a sua conta ser criada, o Google irá fornecer um código javascript de monitoramento, é necessário incluir este código na Master Page da sua aplicação. Este código contém uma Id única, cada aplicação adicionada ao Analytics terá a sua própria Id, e é desta forma que o Google irá reconhecer a sua aplicação.

Este código poderá ser encontrado através do menu "Administrador" no canto superior direito do site, opção "Informações de acompanhamento", segunda aba apresentada.

Genexus Google Analytics
código que estamos procurando

Inserção de código na aplicação Genexus

Para adicionar o código, em projeto web crie um novo arquivo de extensão ".js" (analytics.js) dentro da pasta "web" do seu projeto, e, abra-o com o bloco de notas, ou qualquer editor que text que desejar.

Inclua o código fornecido pelo Google:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-99999999-9']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

Agora, no objeto Master Page, inclua o código abaixo no evento Start:

Form.JScriptSrc.Add('analytics.js')

Após a publicação deste objeto Master Page em ambiente de Produção, já poderemos monitorar as estatísticas da aplicação. Por exemplo a quantidade de visitas x quantidade de páginas acessadas por visita nos últimos 30 dias:

Genexus Google Analytics


segunda-feira, 4 de fevereiro de 2013

Genexus - Grid Design

Genexus Grid Design
O Design aplicado ao Genexus

Quando trabalhamos em um projeto, a parte gráfica deste, seu design, imagens e estilos, é sempre a última tarefa a ser realizada. Isso, quando não aplicamos o design default disponível a partir da ferramenta Genexus.

Para nós analistas, o design pode parecer algo supérfluo, que não alterará em nada as aplicações. Porém para muitos usuários é algo essencial, a aplicação pode estar perfeita porém se o usuário não se interessar pelo seu design, a sua expectativa com relação ao sistema não terá sido alcançada.

Temos de ser racionais, e considerar que todas estas visões estão corretas. Não podemos transformar a parte gráfica das aplicações no principal processo de desenvolvimento, mas também, devemos considerar que a parte estética pode aumentar em muito a interação de nossas aplicação junto ao usuário final.

Hoje irei tratar de uma configuração simples, como transformar o design padrão dos grids em um grid igual ao da figura do topo do post, muito semelhante à biblioteca gxui. Acredito que a partir deste post podemos avançar para outros mais avançados, como, utilizar consideravelmente a biblioteca jquery em nossa MasterPage.

Configuração do Grid a partir do Tema

Primeiramente, iremos abrir o nosso tema padrão do projeto, a partir da pasta "Customization" - "Themes" (figura 2). Após aberto, precisamos criar uma nova classe do objeto "Grid". Para isso, clicamos com o botão direito sobre o objeto "Grid" e clicamos em "Add Class" (figura 3).

Genexus Folder View
figura 2 - Folder View
Genexus Tema
figura 3 - Adicionar Classe

OK, agora vamos começar a configurar suas propriedades gráficas. Abaixo irei listar cada propriedade, seu valor de configuração, e uma descrição explicativa:

PropriedadeValorDescrição
NameGridBlog(nome da classe)
Background Repeatrepeat-x(determina se a imagem de fundo irá se repetir horizontalmente, verticalmente)
Margin1pt 1pt 1pt 1pt(margem externa: acima, a direita, abaixo, a esquerda)
Padding1pt 5pt 1pt 5pt(margem interna: acima, a direita, abaixo, a esquerda)
Background ColorTransparent(cor de fundo do grid)
Background ImagemGridBackground(imagem de fundo do grid, disponível abaixo do post)
Border Color#1a67b8 #1a67b8 #1a67b8 #1a67b8(cores das bordas: acima, a direita, abaixo, a esquerda)
Border Stylesolid (estilo da borda, linha solida)
Border Width1px(largura da borda)
Line Back Colortransparent(cor das linhas impares)
Line Back Color EvenGainsboro (cor das linhas pares)
Line Font Stylenormal(estilo de fonte normal)
Line Font Size11px(tamanho da fonte das linhas)
Line Font FamilyArial (fonte das linhas)
Title Back Colortransparent (cor de fundo dos títulos das colunas)
Title Font Stylenormal(estilo de fonte normal)
Title Font Weightbold (peso da fonte dos títulos das colunas)
Title Font Size12px(tamanho da fonte dos títulos das colunas)
Title Font FamilyArial (fonte dos títulos das colunas)
Title Fore ColorBlack (cor dos títulos das colunas)
Custom CSS Propertiespadding-top:2pt;(margem interna aplicada ao topo)

Imagens Utilizadas

Neste exemplo estamos utilizando apenas 4 imagens. Imagens de ação (alteração, exclusão e visualização) e a principal e referenciada na propriedade da classe, a imagem de fundo do grid (degrade do topo). São elas:

alteração
alteração
Exclusão
Exclusão
Visualização
Visualização
Imagem GridBackground
Imagem GridBackground
Estas imagens são de escolha do desenvolvedor, indico um ótimo site de ícones. Muito bom para encontrar as imagens adequadas para a sua aplicação, o site é http://findicons.com/.

Definição de classe

Por fim, é necessário definir esta classe criada em nossos grids apresentados. Para isto, no objeto trabalhado (transação ou web panel), clique sobre o grid de modo a apresentar as suas propriedades à direita. No item "Appearance - Class", selecione o nome da classe criada, GridBlog, conforme a figura abaixo:

Genexus Grid Propriedades

quinta-feira, 17 de janeiro de 2013

Teste seu conhecimento #1 (lógica de programação)

Desafio
Nos primórdios de 2007, quando estava começando a entrar no mundo da TI, em meio a tantos currículos enviados fui convidado para fazer uma entrevista em uma empresa que desenvolvia softwares em php. Nessa primeira entrevista, todos os candidatos ficavam na mesma sala e recebiam cada um, uma folha contendo 5 questões de lógica de programação e conhecimentos da linguagem (métodos, funções, etc). 

Dentre estas questões, teve uma que dificilmente vou esquecer, era uma pergunta simples mas que fugia do cotidiano. Lanço um desafio para aqueles que desejarem participar e ver em quantos comandos são capazes de resolves. Mas sem colar... hahaha

A Missão

A proposta deste desafio é:

Dada duas variáveis A e B, sendo A = 3 e B = 5, escreva um código, sem utilizar uma terceira variável, capaz de trocar o valor entre elas. Ao fim, as variáveis deverão ser iguais a: A = 5 e B = 3......

Ah sim! Daqui a UM mês irei divulgar o resultado, então há tempo de sobra.

Gostaria muito de receber sua contribuição. Obrigado. :D

terça-feira, 15 de janeiro de 2013

Genexus - Envio de Email com Anexo

Essa matéria se propõem a analisar o método de envio de email com anexo adicionado, seja através de um caminho fixo do servidor, ou então a partir de uma variável blob. Esta variável, poderá por exemplo, vir de um atributo blob presente em alguma transação.

Trata-se de uma continuidade as tantas postagens a respeito deste assunto nos blogs da comunidade Genexus. Antes de continuar, sugiro uma leitura do post Genexus Mail, do excelente blog Genexando.
Para realizar este exemplo de envio de email, utilizarei 3 objetos Genexus: uma transação contendo os parâmetros de conexão com o host; uma web panel contendo três variáveis; e uma procedure.

Criação da Transação de Parâmetros

Geralmente quando iniciamos um projeto a transação de parâmetros estará presente na especificação do analista. É nesta transação que os dados de configurações do sistema serão registrados, e dentre estes registros possuímos os dados de conexão com o host smtp, responsável pelo envio de email através da aplicação.

Logo, nossa transação terá a seguinte estrutura:

Genexus Transação
Criação da Web Panel

Esta Web Panel criada não é essencial para o nosso exemplo, é apenas para demonstrar que poderemos passar o conteúdo deste email como parâmetro através de variáveis presentes em tela.

Então, apenas como exemplificação disto, adicionei na Form deste objeto três variáveis, além de outra que irei utilizar nos Eventos:
  1. (form) Assunto: VarChar(120);
  2. (form) Anexo: Blob;
  3. (form) TextoHTML: LongVarChar(2M);
  4. (eventos) SourceAnexo: VarChar(400);
Dessa forma, o usuário poderá determinar o Assunto e o Conteúdo da mensagem de email, além de anexar um documento. Ao clicar sobre o botão, o seguinte evento de usuário será executado:
Event Enter
//=====Captura o endereço gerado do documento anexado=====
&SourceAnexo = &Anexo.ToString()

//=====Chama Procedure de Envio de Email=====
EnviaEmail.Call(&Assunto,&TextoHTML,&SourceAnexo)
EndEvent
Criação da Procedure de Envio de Email

Por fim, precisamos programar a procedure que realizará o envio do email. Como este objeto não irá realizar gravação no banco de dados, podemos configurar a sua propriedade commit on exit, como "no".

Nesta procedure iremos receber os seguintes parâmetros (Rules):
parm(in:&Assunto,in:&TextoHTML,in:&SourceAnexo);
Estas variáveis recebidas possuem o mesmo DataType determinado na Web Panel anteriormente especificada.

Agora só nos falta programar os eventos, estes serão:
//=====Captura Dados de Conexão da Transação Parametros=====
for each
defined by ParametroId
//=====Host SMTP exemplo: smtp.live.com(outlook.com);
        //smtp.gmail.com(gmail.com)=====
&SMTPSession.Host = ParametroServidorSMTP.Trim()

//=====Autenticação: 1 (requer usuário e senha)=====
&SMTPSession.Authentication = ParametroAuthentication

//=====Dados de Login: Usuário e Senha=====
&SMTPSession.UserName = ParametroUserName.Trim()
&SMTPSession.Password = ParametroPassword.Trim()

//=====Remetente: Email e Nome=====
&SMTPSession.Sender.Address = ParametroSenderAdress.Trim()
&SMTPSession.Sender.Name = ParametroSenderName.Trim()
endfor

//=====Efetua o Login=====
&SMTPSession.Login()

//=====Verifica se ocorreu algum erro=====
if &SMTPSession.ErrCode <> 0
msg(&SMTPSession.ErrDescription)
else
//=====Insere o texto da mensagem=====
&MailMessage.HTMLText = &TextoHTML

//=====Insere o assunto da mensagem=====
&MailMessage.Subject = &Assunto

//=====Adiciona 1º Destinatário de email=====
&MailRecipient.Address = 'cicrano@hotmail.com'
&MailRecipient.Name = 'Cicrano'
&MailMessage.To.Add(&MailRecipient)

//=====Adiciona 2º Destinatário de email=====
&MailRecipient.Address = 'beltrano@outlook.com'
&MailRecipient.Name = 'Beltrano'
&MailMessage.To.Add(&MailRecipient)

//=====Adiciona email como Copia=====
&MailRecipient.Address = 'fulano@gmail.com'
&MailRecipient.Name = 'Fulano'
&MailMessage.CC.Add(&MailRecipient)

//=====Adiciona email como Copia Oculta=====
&MailRecipient.Address = 'genexus@outlook.com'
&MailRecipient.Name = 'Genexus'
&MailMessage.BCC.Add(&MailRecipient)

//=====Adiciona Anexo a partir de um caminho do servidor=====
&MailMessage.Attachments.Add('C:\Temp\VendaDiaria_20121217.csv')

//=====Adiciona Anexo a partir de uma variável Blob=====
if not &SourceAnexo.IsEmpty()
&MailMessage.Attachments.Add(&SourceAnexo)
endif

//=====Envia Email=====
&SMTPSession.Send(&MailMessage)

//=====Verifica se ocorreu erro=====
if &SMTPSession.ErrCode <> 0
msg(&SMTPSession.ErrDescription)
else
msg('Email enviado com sucesso!')
endif
endif
Observações

Duas observações a respeito deste código, o nome das variáveis são iguais aos seus tipos de dados. Por padrão a porta utilizada para o envio de email é a 25, normalmente utilizada pelos servidores SMTP. Caso seja necessário alterar esta porta, será preciso incluir o seguinte código antes de realizar o Login:
&SMTPSession.Port = 465

Pessoal, qualquer dúvida, incremento ou correção enviem através dos comentários ou pelo email genexus@outlook.com. Abraço.