terça-feira, 21 de maio de 2013

CSV 'Facinho'!

CSV é um mecanismo tão antigo para gerar um padrão estruturado de informações, que seria um desperdício perder tempo com ele, se o mesmo não fosse tão útil.  Muita gente prefere trabalhar
gerando arquivos XLS, mas o CSV tem também suas qualidades, porque? Todo programa do tipo planilha eletrônica que se preze lê esse tipo de arquivo (Google Drive Spreadsheet, Microsoft Excel, OpenOffice, ...), portanto, pode representar um excelente mecanismo de compatibilidade de sistemas.

Genexus, por outro lado não possui nativamente tratamento para esse tipo de arquivo, mas não fique triste nem nervoso, é possível com mínimo esforço gerar documentos nesse formato.  Para isso você somente precisa de uma procedure.

Para facilitar ainda mais optamos por gerar o arquivo como se fosse um relatório, ou seja, deixar para o Genexus criar o arquivo no disco e também facilitar a geração das linhas da nossa ‘planilha’. Para fazer isso você deve na aba Layout incluir uma variável do tipo character, que em nosso caso denominamos de &linha.



Assim, para gerar CSV, precisamos concatenar os textos com um caracter separador, que pode ser, por exemplo, o ponto-e-vírgula.  Uma forma de fazer isso com grande facilidade é utilizando a função Format.  Considere que para cada %n temos uma coluna na nossa ‘planilha’.

 for each
  &linha = Format('%1;%2;%3;%4',
   ClienteNome,
   CidadeNome,
   PaisId.ToString(),
   PaisNome
  )
  print Item
 endfor


Incluímos na string varias colunas separadas por um caracter que inclusive pode ser variável, basta por sua imaginação para funcionar, que dá pra fazer muita coisa com esse código simples.

Para o relatório Genexus, precisamos definir algumas propriedades:

Main program=true
Call protocol=internal


E a regra output_file('teste.csv', 'txt'), na aba Rules.

Ao executar o procedimento, temos como resultado, um arquivo chamado teste.csv, com o seguinte conteúdo, que pode ser aberto no Excel, por exemplo, com o seguinte formato.
 


Interessante e muito simples! Ou melhor, facinho, facinho...


Bibliografia

sábado, 18 de maio de 2013

Shrinking

Que palavrinha interessante essa hein! acho ela o máximo, posso até dizer que ao entendê-la respirei aliviado. Deixa eu te contar a historinha.

Meu note com duas partições de 250Gb cada estava com a C: no berro, com apenas 360Mb de memória, ou seja, praticamente travada, nada funcionava direito, lentidão total. Começei uma investigação nas pastas e descobri na pasta DATA do SQL Server um arquivo com 101Gb!! Acredite, era o LDF de uma base de dados de teste. Não pergunte porque ficou desse tamanho, mas esse arquivo maluco representava quase 50% do disco todo.  Quem inventou esse tal de LOG que não tem limites para crescer, parece tiririca.

Então surgiu o tal de Shrink, que não é parente do Shrek, e que resolveu a parada.

USE teste_sql;
GO
DBCC SHRINKFILE (teste_sql_log, 7);
GO


O primeiro comando apresentou o tamanho do arquivo mas não o limpou. Veja que estava dando 130Gb.


Para limpar mesmo executei esse commando ai.

USE teste_sql;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE teste_sql
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (teste_sql_log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE teste_sql
SET RECOVERY FULL;
GO


E o resultado foi esse, uma redução significativa no arquivo de LOG, que no final ficou com 1028Kb.


Brincadeiras a parte, o tal Shrink de fato salvou meu dia, ou o meu HD. Mas pensando bem, nada como manter a grama aparadinha e sem pragas não é?

fonte: http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx


--------------------------------------------------------------------------------
Ps1: Antes de encerrar, caso apareça algum erro do SQL não encontrar o tal LDF, então pode executar os seguintes comandos que o nome da criatura aparece!

USE teste_sql;
SELECT NAME FROM SYSFILES

Ps2: Outra coisa, como contribuição à formação caipira dos nossos queridos amigos urbanos, uma explicação sobre a imagem desse post, trata-se da tiririca!
(pior que eu achava que Tiritica era Deputado!, ou pior, que Deputado era como tiririca, rs)

terça-feira, 14 de maio de 2013

Sincronismo com GxServer

Um pequeno detalhe que incomoda os que trabalham com GxServer e Genexus, é o sincronismo com o servidor quando ocorre a remoção de certo objeto e a inclusão de outro totalmente diferente, mas com o mesmo nome do objeto apagado, essa situação exige um pouco de atenção do desenvolvedor, caso contrário pode haver uma perda significativa de tempo para resolvê-la.

Primeiro a situação

Estaremos fazendo aqui um passo-a-passo da situação para que você entenda o problema, e nas próximas ocasiões, evite que a mesma ocorra e atrapalhe a vida dos demais desenvolvedores do projeto.

A causa do incomodo é que os objetos possuem um número do tipo GUID que é randômico e designado automaticamente pelo Gx para cada novo objeto criado, como, por exemplo, na Imagem abaixo e seu GUID associado (f5a88c30-db5b-012e-3dd2-1231380f2e23), que nesse exemplo se encontra perfeitamente sincronizada entre o GxServer e as máquinas dos Desenvolvedores 1 e 2.



O GxServer utiliza o nome da imagem e também o GUID para controlar eventuais modificações nos objetos.

1) Remoção do objeto

O problema ocorre quando a imagem é removida por certo Desenvolvedor, (o Desenv 2, no nosso exemplo) e que em seguida publica o ajuste no GxServer, com o commit. Se o Desenv1 não realizar o update do seu projeto, a imagem antiga ficará em sua kb e poderá ocorrer o erro.



2) Criação de outra imagem com o mesmo nome

Antes que o Desenvolvedor 1 realize o update de sua kb, o Desenvolvedor 2, apressadinho, criou um novo objeto e chamou-o com o mesmo nome do anterior removido (Imagem) e novamente subiu ao servidor, com o commit.  O GeneXus criou um novo GUID para esse novo objeto, e o que temos é o nome do antigo, mas com identificadores diferentes.


3) Tentativa frustrada de atualização

 Para completar a tragédia o Desenvolvedor 1, um dia acordou de seu sono profundo, e resolveu atualizar sua kb com o gxServer. O que aconteceu?  Erro!


Ao tentar sincronizar a sua kb, o Desenvolvedor 1 recebe uma mensagem de erro no objeto Imagem devido a diferença de GUID de sua maquina e a do GxServer, uma vez que são elementos completamente distintos.  Quem causou a situação, o Desenvolvedor 2, encontra-se tranquilo e nem percebe a tragédia, acho que até eu ouvi ele dizer 'aqui na minha máguina não tem problema, tá tudo certo!'


Agora a correção

Para que essa situação possa ser corrigida é necessário que o Desenvolvedor 2, (causador da lambança), saia de sua zona de conforto e suba uma correção para o GxServer renomeando a Imagem para qualquer outro nome, como Imagem1, por exemplo.

Essa situação ilustra bem a necessidade de comunicação e treinamento da equipe de desenvolvimento, principalmente nos termos de conduta do projeto, e talvez o primeiro item a ser registrado nesse termo seria:

Apagar um objeto e criar outro com o mesmo nome... Melhor não.



quinta-feira, 9 de maio de 2013

Efeito Click em Botão

Uma interface Web ganha contornos profissionais quando nos preocupamos com pequenos 'detalhes', e detalhes não faltam nas interfaces construídas com HTML 5, CSS3, e as novas tendências tecnológicas. As interfaces web estão ficando mais precisas, interessantes e claro mais atraentes para os usuários, quer por questões puramente estéticas, apelos de marketing ou mesmo para melhorar a usabilidade. Sendo assim, convém um pequeno esforço para tornar nossos programas mais atrativos.

No caso de 'usabilidade', por exemplo, o efeito de uma imagem que simula um botão pressionado gera uma sensação mais positiva no usuário, pois dá a impressão que a operação foi de fato solicitada, e ajuda no desempenho da aplicação, pois faz com que o mesmo evite pressionar várias vezes uma imagem estática, já que ela não responde imediatamente. Então para resumir, podemos dizer que não é frescura, detalhes como esses melhoram a vida das pessoas.

Antigamente precisávamos recorrer a várias imagens, javascript, html, e mais um montão de coisas para provocar tal efeito, nos dias atuais basta duas classes CSS e uma imagem projetada para esta finalidade e pronto. Um conceito interessante é  apresentado no site do Kyle Schaeffer (Pure CSS Image Hover) que tomamos a liberdade de utilizar para resolver nosso problema, e também site do  Dmitry Fadeyev (Pressed Button State With CSS), que nos ensina o conceito de uma imagem 'active', ou seja, pressionada.

Portanto, apesar de parecer tão complicado, apresentamos uma estratégia simples para gerar esse efeito em GeneXus, não é a única, entenda apenas como um ponto de partida neste processo de aprendizagem.

Design do Botão


Pra começo de conversa precisamos de uma imagem diferenciada para realizar esta operação, que é composta por duas imagens distintas e em sequencia, na mesma imagem.  Primeiro na sequencia incluimos a imagem que gera o efeito pressionado e em seguida a que deve ser apresentada como normal.

A imagem a seguir representa um botão do tipo Filtrar com as duas representações: clicada primeiro e normal em seguida.


As dimensões são importantes e deve representar uma proporcionalidade, e observe que utilizamos uma sombra para melhorar o aspecto do efeito de pressionamento da imagem. Na primeria imagem a sombra aparece internamente e na representação da imagem normal externamente ao botão.

Efeito Click em TextBlock


O conceito do pressionamento definido pelo Kyle Schaeffer é feito mediante uma classe CSS, que trazendo para o Genexus, poderia ser embutida em um controle Textblock, como apresentado a seguir.

Event Start
    Textblock1.Caption = '<style>'
    Textblock1.Caption += '.myButtonLink {'
    Textblock1.Caption += ' display: block;'
    Textblock1.Caption += ' width: 32px;'
    Textblock1.Caption += ' height: 32px;'
    Textblock1.Caption += " background: url('"+filter.Link()+"') bottom;"
    Textblock1.Caption += ' text-indent: -99999px;'
    Textblock1.Caption += '}'
    Textblock1.Caption += '.myButtonLink:active{'
    Textblock1.Caption += ' background-position: 0 0;'
    Textblock1.Caption += '}'
    Textblock1.Caption += '</style>'
    Textblock1.Caption += '<a class="myButtonLink" href="#LinkURL">Leaf</a>'
EndEvent

 
Observe que a incorporação no código fonte da interface da classe CSS pode ser realizada em um controle Textblock, isso caso a propriedade Format deste controle for determinada como HTML.

Finalmente, para conectar uma imagem ao botão, utilizamos o modelo de importa-la primeiramente ao Genexus (Image - New Image - filter.png) e em seguida a utilização de sua referência, filter.link().


Textblock1.Caption += " background: url('"+filter.link()+"') bottom;"

Para definirmos o Click na imagem programamos um link para conectar a um objeto Genexus ou URL.
 
Textblock1.Caption += '<a class="myButtonLink" href="#LinkURL">Leaf</a>'
 
Onde #LinkURL everá ser substituído pelo link desejado, algo do tipo:
 
Textblock1.Caption += '<a class="myButtonLink" href="'+ objetoGx.Link() +'">Leaf</a>'
 

CSS Externo


Outra possibilidade, para minimizar o efeito da programação direta do estilo, é incorporar a classe em um arquivo CSS externo, incluindo o mesmo através

form.HeaderRawHTML = '<link rel="stylesheet" type="text/css" href="botao/botao.css" >'

Desta forma simplificariamos o evento Start com.

Event Start
 form.HeaderRawHTML = '<link rel="stylesheet" type="text/css" href="botao/botao.css" >'
 Textblock1.Caption += '<a class="myButtonLink" href="#LinkURL">Leaf</a>'

EndEvent

Bastando programar no arquivo botaopressionado.css o texto a seguir.

.myButtonLink {
 display: block;
 width: 32px;
 height: 32px;
 background: url('filter.png') bottom;
 text-indent: -99999px;
}
.myButtonLink:active{
 background-position: 0 0;
}


Conclusão

Esse recurso é muito interessante e simples, mas esse formato tem sua limitação, pois ficaria mais complicado para chamar um evento em um objeto Gx, por exemplo.  É possível realizar isso, mas deixemos esse tema para uma próxima postagem.

Portanto, feliz usabilidade para seus sistemas.