segunda-feira, 18 de fevereiro de 2008

Algumas funções úteis em JavaScript

Algumas funções em Javascript que na verdade são atalhos para sintaxe de VB.

Pra quem ainda não está acostumado com linguagens derivadas do C, acaba sendo útil.

//Retorna uma quantidade específica de caracteres de uma string, contando da esquerda para a direita.
function Left(str, n){
if
(n <= 0)
{
return "";
}
else if (n > String(str).length)
{

return str;
}
else
{

return String(str).substring(0,n);
}
}

//Retorna uma quantidade específica de caracteres de uma string, contando da direita para a esquerda.
function Right(str, n){
if (n <= 0)

{
return "";
}
else if (n > String(str).length)
{
return str;

}
else

{
var iLen = String(str).length;
return String(str).substring(iLen, iLen - n);
}
}

//Remove os espaços no ínicio e no fim da string.
//Ex.: Trim(" Alisson "); retorna "Alisson".
function Trim(str)
{
return str.replace(/^\s+\s+$/g,"");
}


façam bom proveito :)

quarta-feira, 13 de fevereiro de 2008

Formatar Data com o Microsoft SQL Server

Já vi muita gente dizer que mexer com data é chato em qualquer linguagem de programação. Concordo com as pessoas que ouvi dizer isso. O legal é que com o tempo você vai se acostumando e logo a tarefa chata de lidar com formatação se torna algo comum. Seja pela experiência prática ou por macetes que a gente aprende.

O que vou descrever nesse post é um macete muito útil pra formatação de datas no SQL Server, já que este não dispõe de uma função nativa onde possamos formatar uma data sem ter que ficar decorando parâmetros númericos de conversão.

Se eu precisar usar converter uma data pro formato "YYYYMMDD", precisamos fazer o seguinte:

SELECT CONVERT(CHAR(8), GETDATE(), 112)

Não seria muito mais intuitivo se pudessemos fazer assim? :

SELECT CONVERT(VARCHAR, GETDATE(), 'YYYYMMDD')

É. Mas não funciona assim.

Com isso, descrobri uma UDF (user defined function) que facilita nossa vida.

A função é a seguinte:

CREATE FUNCTION dbo.FormatDateTime
(
@dt DATETIME,
@format VARCHAR(16)
)
RETURNS VARCHAR(64)
AS
BEGIN
DECLARE @dtVC VARCHAR(64)
SELECT @dtVC = CASE @format

WHEN 'LONGDATE' THEN

DATENAME(dw, @dt)
+ ',' + SPACE(1) + DATENAME(m, @dt)
+ SPACE(1) + CAST(DAY(@dt) AS VARCHAR(2))
+ ',' + SPACE(1) + CAST(YEAR(@dt) AS CHAR(4))

WHEN 'LONGDATEANDTIME' THEN

DATENAME(dw, @dt)
+ ',' + SPACE(1) + DATENAME(m, @dt)
+ SPACE(1) + CAST(DAY(@dt) AS VARCHAR(2))
+ ',' + SPACE(1) + CAST(YEAR(@dt) AS CHAR(4))
+ SPACE(1) + RIGHT(CONVERT(CHAR(20),
@dt - CONVERT(DATETIME, CONVERT(CHAR(8),
@dt, 112)), 22), 11)

WHEN 'SHORTDATE' THEN

LEFT(CONVERT(CHAR(19), @dt, 0), 11)

WHEN 'SHORTDATEANDTIME' THEN

REPLACE(REPLACE(CONVERT(CHAR(19), @dt, 0),
'AM', ' AM'), 'PM', ' PM')

WHEN 'UNIXTIMESTAMP' THEN

CAST(DATEDIFF(SECOND, '19700101', @dt)
AS VARCHAR(64))

WHEN 'YYYYMMDD' THEN

CONVERT(CHAR(8), @dt, 112)

WHEN 'YYYY-MM-DD' THEN

CONVERT(CHAR(10), @dt, 23)

WHEN 'YYMMDD' THEN

CONVERT(VARCHAR(8), @dt, 12)

WHEN 'YY-MM-DD' THEN

STUFF(STUFF(CONVERT(VARCHAR(8), @dt, 12),
5, 0, '-'), 3, 0, '-')

WHEN 'MMDDYY' THEN

REPLACE(CONVERT(CHAR(8), @dt, 10), '-', SPACE(0))

WHEN 'MM-DD-YY' THEN

CONVERT(CHAR(8), @dt, 10)

WHEN 'MM/DD/YY' THEN

CONVERT(CHAR(8), @dt, 1)

WHEN 'MM/DD/YYYY' THEN

CONVERT(CHAR(10), @dt, 101)

WHEN 'DDMMYY' THEN

REPLACE(CONVERT(CHAR(8), @dt, 3), '/', SPACE(0))

WHEN 'DD-MM-YY' THEN

REPLACE(CONVERT(CHAR(8), @dt, 3), '/', '-')

WHEN 'DD/MM/YY' THEN

CONVERT(CHAR(8), @dt, 3)

WHEN 'DD/MM/YYYY' THEN

CONVERT(CHAR(10), @dt, 103)

WHEN 'HH:MM:SS 24' THEN

CONVERT(CHAR(8), @dt, 8)

WHEN 'HH:MM 24' THEN

LEFT(CONVERT(VARCHAR(8), @dt, 8), 5)

WHEN 'HH:MM:SS 12' THEN

LTRIM(RIGHT(CONVERT(VARCHAR(20), @dt, 22), 11))

WHEN 'HH:MM 12' THEN

LTRIM(SUBSTRING(CONVERT(
VARCHAR(20), @dt, 22), 10, 5)
+ RIGHT(CONVERT(VARCHAR(20), @dt, 22), 3))

ELSE

'Invalid format specified'

END
RETURN @dtVC
END
GO

Basta executar o código acima no console do seu SQL. Se você utiliza SQL 7 ou inferior, não tem problema, crie uma StoredProcedure e devolva o resultado num parâmetro de Output.

Para testar a função e todas as suas possibilidades, utilize o seguinte:

DECLARE @now DATETIME
SET @now = GETDATE()

PRINT dbo.FormatDateTime(@now, 'LONGDATE')
PRINT dbo.FormatDateTime(@now, 'LONGDATEANDTIME')
PRINT dbo.FormatDateTime(@now, 'SHORTDATE')
PRINT dbo.FormatDateTime(@now, 'SHORTDATEANDTIME')
PRINT dbo.FormatDateTime(@now, 'UNIXTIMESTAMP')
PRINT dbo.FormatDateTime(@now, 'YYYYMMDD')
PRINT dbo.FormatDateTime(@now, 'YYYY-MM-DD')
PRINT dbo.FormatDateTime(@now, 'YYMMDD')
PRINT dbo.FormatDateTime(@now, 'YY-MM-DD')
PRINT dbo.FormatDateTime(@now, 'MMDDYY')
PRINT dbo.FormatDateTime(@now, 'MM-DD-YY')
PRINT dbo.FormatDateTime(@now, 'MM/DD/YY')
PRINT dbo.FormatDateTime(@now, 'MM/DD/YYYY')
PRINT dbo.FormatDateTime(@now, 'DDMMYY')
PRINT dbo.FormatDateTime(@now, 'DD-MM-YY')
PRINT dbo.FormatDateTime(@now, 'DD/MM/YY')
PRINT dbo.FormatDateTime(@now, 'DD/MM/YYYY')
PRINT dbo.FormatDateTime(@now, 'HH:MM:SS 24')
PRINT dbo.FormatDateTime(@now, 'HH:MM 24')
PRINT dbo.FormatDateTime(@now, 'HH:MM:SS 12')
PRINT dbo.FormatDateTime(@now, 'HH:MM 12')

Pronto. Agora ficou até parecendo VB. Se lembram do FormatDateTime? :)

Minha sugestão é que vocês guardem num cantinho ai essa função pra que sempre que forem inicar um projeto novo, a tenham de fácil acesso, pois ela é bastante útil e poupa um bucado de tempo quando o assunto é formatar data no SQL Server.

Grande abraço.

Referência: www.aspfaq.com

segunda-feira, 11 de fevereiro de 2008

Iniciar e Parar serviços com .NET


Eu costumo dizer que fazer coisas com o .NET framework é igual ao neston. Existem
mil maneiras de fazer. Invente uma.


O que vou descrever é uma das várias maneira que a gente pode fazer para se gerenciar
serviços com o .NET. São várias as situações onde é necessário inicar ou parar um
serviço de acordo com a necessidade de uma aplicação. Seja para economizar recursos
do servidor ou seja para atender a determinada regra de fluxo. Então vamos lá: O
exemplo que irei dar, manipula o serviço do FireBird
SQL
.


Dentro de um diretório específico (normalmente o diretório da sua aplicação), crie
dois arquivos *.bat. Um para parar e outro para inicializar o seriviço.



No arquivo que pára o serviço, a linha de comando é



NET STOP "FireBird Server - DefaultInstance"



e o arquivo que starta o serviço:



NET START "FireBird Server - DefaultInstance"



Lembrando que você precisa conferir no painel de controle > ferramentas administrativas > serviços se o nome do serviço do firebird que vc instalou é mesmo
"FireBird Server - DefaultInstance".
Pode ser que o nome a instância não seja o nome
"default".



Se achar conveniente, teste os batches diretamente no prompt de comando para verificar
se eles estão corretos.



Com os batches prontos, podemos partir para a implementação do código.



Abaixo temos um exemplo de como fazer a chamada dos arquivos .bat via código .NET.



Basta adequá-lo a sua necessidade.


//Evite deixar esse valor hardcoded.
//Passe-o para um arquivo de configura‡Æo
//(app.settings, web.config, ou uma classe serializada)
const string STARTFILE = @"c:\firebirdstart.bat";
const string STOPFILE = @"c:\firebirdstop.bat";


private void btnIniciar_Click(object sender, EventArgs e)
{
int resultado = this.StartService();
MessageBox.Show(resultado.ToString());
}


private void btnParar_Click(object sender, EventArgs e)
{
int resultado = this.StopService();
MessageBox.Show(resultado.ToString());
}


int StartService()
{
return this.ManageFirebirdService(STARTFILE);
}


int StopService()
{
return ManageFirebirdService(STOPFILE);
}


int ManageFirebirdService(string pBatchFile)
{
Process proc = Process.Start(this.GetProcess(pBatchFile));
if (proc.HasExited)
return proc.ExitCode;
else
return 0;
}


ProcessStartInfo GetProcess(string pFile)
{
ProcessStartInfo psi = new ProcessStartInfo(pFile);
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
return psi;
}


É isso ai!




sexta-feira, 8 de fevereiro de 2008

Recuperando IP da rede com C# ASP .NET

Esse tópico descreve uma dúvida respondida por mim no fórum de ASP .NET da MSDN Brasil

"Bom dia.

Eu tenho um sistema em ASP.NET 2.0 usando o C# onde os representantes passam pedidos pela web.
Existe um módulo onde este representante tem a opção de aceitar a comissão ou não. Nesta ação, além de outras informações, eu preciso pegar também o IP da máquina do representante e gravar no meu banco. Como eu faço isso???"


Vamos lá:

Pra se obter o IP de alguém que está acessando sua aplicação pela Internet , basta apenas recuperar o valor pela seguinte variável de Servidor:

String IP = Request.UserHostAddress;

Porém, se sua necessidade é pegar o IP das máquinas ques estão em uma rede e estão acessando sua aplicação, podemos fazer o seguinte:

using System;
using System.Net;

namespace Rede

{

public class DNSUtility
{
public static int Main (string [] args)
{
String strHostName = String.Empty;

if (args.Length == 0)
{

// Pega o Host name.
strHostName = Dns.GetHostName ();
Console.WriteLine ("Nome da máquina local: " + strHostName);
}
else
{
strHostName = args[0];
}
// Usando o hostname, pega o IP na lista
IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
IPAddress [] addr = ipEntry.AddressList;

for (int i = 0; i <>
{
Console.WriteLine ("IP {0}: {1} ", i, addr[i].ToString ());
}

Console.Read();
return 0;
}
}

}

Link para o post: http://forums.microsoft.com/MSDN-BR/ShowPost.aspx?PostID=2376723&SiteID=21

Outra sugestão: http://www.codeproject.com/KB/IP/ListNetworkComputers.aspx

Abraços

quarta-feira, 6 de fevereiro de 2008

Dynamics CRM 4 Titan for Developers

Participei semana passada de um treinamento sobre o CRM 4.0, ministrado por Joe Hominick (Microsoft Regional Director).

O treinamento e a experiência com o pessoal que participou do treinamento foi muito bacana.

Foram mostradas todas as novidades e melhorias com relação a versão 3.0. E que melhorias.
A mais aclamada pelo pessoal foi o famoso relacionamento N:N. Esqueça as gambiarras ("hackings") e as linker tables que você costumava fazer pra conseguir o relacionamento N:N.
Callouts agora são "plugins". A novidade é que, além de em disco, se pode armazenar a assembly no banco de dados.
Quanto a maneira de se programar os plugins, isso não mudou muito com relação a 3.0. Praticamente a mesma coisa. Exceto por não se usar mais o conceito de eventos (PreCreate, PreUpdate, PreSetState...). As classes SDK são praticamente as mesmos. A diferença é que agora temos serviços específicos para cada tipo de deploy do CRM (on premise - que é o que conhecemos hoje no CRM 3.0, live ou on-demand.). CRMs configurados como On-demand ou Live têm certas restrições com relação a plugins, mas para CRM configurado como On-Premise, o céu é o limite.

É possível criar entidades e atributos de forma programática. Os Workflows de workflow só mativeram o nome. Agora tudo é baseado no Windows Workflow Foundation.

Outra novidade é a escalabilidade. A plataforma (o SDK) pode ser instalada em servidor diferente do servidor de aplicação.

A plataforma é capaz de validar diversas condições pré-configuradas, como duplicidade (tratamento de concorrência) e validação de dados. Tudo podendo ser configurado em ambiente visual, ou seja, através da aplicação.

Outra coisa bacana é o reporting server agora não precisar estar em um domínio de confiança. Muito mais simples de se configurar.

Foram apresentadas também muitas novidades sobre BI com CRM. Conteúdo bastante extenso que pretendo comentar aqui num futuro post.

Houve quem esperasse mais do treinamento. Uma cobertura mais profunda com relação a customizações e desenvolvimento. Eu achei que dentro dos três dias o que foi exposto foi o suficiente. Afinal em três dias não dá pra se explicar com detalhes uma aplicação tão versátil como o Titan.
Quem quiser discutir o assunto, email-me através do alissonsantana@gmail.com

Abraços

Usando StringBuilder para concatenar Strings

- Você tem o hábito de concatenar strings assim?


string _texto = "Alisson ";
_texto += " Rodrigo";
_texto += " de Santana";
_texto += " Blog";
_texto += " Micosoft";
_texto += " Spaces"

Se a resposta é sim, quero apresentar a você um cara chamado StringBuilder. Da "família", digo, Namespace System.Text.

Primeiro quero explicar o por que não usarmos o "shorthand" += para se concatenar strings.

Toda vez que se atribui um valor a uma variável string, um objeto novo é criado na memória. E quando você concatena uma string a esta variável, um novo objeto novamente é criado para armazenar o resultado da concatenação!


Por que? Eu te digo: - o tipo System.String é imutável!!! Você não consegue mudá-lo uma vez atribuído seu valor.


Com isso, pra que o resultado do shorthand "+=" aconteça, o sistema cria um novo objeto para receber o resultado da concatenação.

Você me pergunta: "- E o valor inicial da variável?" Sim. Ele permanece na memória. E orfão, coitado. Ele é um valor inútil que um dia pertenceu a variável e só serviu para ser jogado para o novo objeto que agora armazena a string antiga mais o valor que você pediu pra ser concatenado.

Agora que você sabe como as coisas acontece "behind the scenes" (por baixo dos panos, na versão tupiniquim), imagine o seguinte:

string numeros = string.Empty;

for(int
i = 0; i < 1000; i++)
{
numeros += + i.ToString();
}

Isso geraria um overhead totalmente desnecessário ao sistema. 999 objetos ficariam orfãos e ocupando espaço na memória e somente o último, o de número 1000, seria o utilizado.

E então, como evitar isso? Usando o StringBuilder que lhes apresentei no início do texto.

O código acima, utilizando-se o StringBuilder, ficaria assim:

StringBuilder numeros = new StringBuilder(1000);

for(int i = 0; i<1000; i++)
{
numeros.Append(i.ToString());
}

Dessa forma, cada valor adicionado ao objeto irá ser armazenado num único lugar da memória. Num único endereço, que é o do próprio objeto.

No final da iteração, podemos obter o valor do resultado chamando o método ToString() do StringBuilder. E fazendo isso também não iremos criar uma nova String. Este método retorna uma instância que aponta para a String dentro do objeto.

"Ah. Agora vou usar sempre o StringBuilder ao invés de usar String".

Não. Cada caso é um caso. Não exclua dos seus planos utilizar a concatenação de strings usando "+=".
Recomendo que se use o StringBuilder em casos que necessitem quatro ou mais concatenações.

Referência: http://msdn2.microsoft.com/en-us/library/system.text.stringbuilder.aspx

Por enquanto é só, pessoal.