Flickr Images

Pages

Banner 468

sexta-feira, 7 de outubro de 2011

Validar formato de CPF e CNPJ em Lista

9 comentários
 
Olá para todos!!!
Bom vamos para mais um problema que tive que resolver e achei uma solução agradável:

Problema:

Em uma determinada lista do Sharepoint precisava validar se um campo o formato do CPF ou do CPNJ estavam corretos. Lembrando:
CPF: xxx.xxx.xxx-xx
CPNJ: xx.xxx.xxx/xxxx-xx

Observação:
Apenas validar se o formato está correto, não valido os dígitos verificadores.
Bom vamos lá, estrutura da lista:
Bom vamos agora nas definições da coluna CPF/CNPJ:
Observe que o tamanho máximo do campo é 18 caracteres. Feito isso agora vamos na opção de validação de coluna e colocamos a seguinte fórmula:
=OR(AND(MID([CNPJ/CPF];3;1)=".";MID([CNPJ/CPF];7;1)=".";MID([CNPJ/CPF];11;1)="/";MID([CNPJ/CPF];16;1)="-";LEN([CNPJ/CPF])=18);AND(MID([CNPJ/CPF];4;1)=".";MID([CNPJ/CPF];8;1)=".";MID([CNPJ/CPF];12;1)="-";LEN([CNPJ/CPF])=14))
Como ficou:
E agora vamos ao teste, lembrando que o cpf é falso!
Observe que quando esta mal formatado ele dispara o erro de formato inválido. Bom é isso qualquer coisa postem ai. Abraços!!!
Readmore...
quinta-feira, 29 de setembro de 2011

Filtro Usuário Corrente em Campo Texto

0 comentários
 
Olá para todos mais uma vez!!!! Após um tempo sem postagem resolvi falar um pouco sobre um problema que tive. Baseado nesse problema vou criar uma situação semelhante para poder exibir a funcionalidade.
Cenário:
Temos uma lista que tem o cadastro de projetos e seus responsáveis. O problema ocorre porque essa lista é alimentada por um outro sistema e o campo que guarda responsável é do tipo texto e não Pessoa ou Grupo, como deveria ser. Precisamos criar uma visão que filtre quais são os projetos que o usuário corrente é responsável.
Vamos lá, a estrutura da lista:
Alguns dados de exemplo:
Bom agora vamos ao que interessa: Abrimos o site com o Sharepoint designer a acessamos a lista de Projetos:
Na tela que irá aparecer selecione, na direita Views e o botão New e, em seguida, damos o nome da view de Meus Projetos e marcamos a opção de ser a view padrão:
Na página que é exibida role a barra de rolagem até encontrar a query da view:
Altere essa query da seguinte forma:
Salve essa view e acesse a lista pelo browse.


Visão todos os itens:


Observe que é a view Todos os itens e que está sendo exibido todos os itens. Observe também o usuário corrente. Agora selecionamos a view que criamos no sharepoint designer e observe o resultado:

Meus Projetos:
Pronto! Problema resolvido! Qualquer dúvida postem ai!
Readmore...
domingo, 21 de agosto de 2011

70-573: Microsoft SharePoint 2010, Application Development

0 comentários
 
A todos boa noite!!!!
Após muito estudo passei na prova 70-573 Sharepoint Application Development.
Já li em alguns outros blogs algumas informações sobre a prova. Como existem várias e várias questões vou falar um pouco só sobre a minha:
Caiu o que é novo no Sharepoint 2010 e como utilizar bem o Visual Studio. Nesse último item a ajuda do @rojao333 foi muito útil pois ele adora ver o que tem de novo em cada versão do VS.
Outra coisa que me chamou a atenção foi a parte de Client Object Model e interfaces. WCF para quem ainda não começou a estudar é melhor correr atrás do prejuízo...
Caíram umas 2 questões mais "bobinhas" estilo a prova 70-571, creio que somente para ninguém zerar a prova.
Outra coisa que gostei muito foi que, apesar de ser uma prova para desenvolvedores, agora são expostos alguns cenários que são resolvidos apenas usando conceitos e boas práticas. Dessa forma acho que a prova fica uma coisa mais real.
Agora um lado bem chato: O curso 10175 que deveria ser o preparatório não achei que prepara muito bem não... tem que buscar fontes em muitos outros locais.
Bom agora alguns sites que usei de referência:

http://msdn.microsoft.com/en-us/library/ee557253.aspx
http://msdn.microsoft.com/en-us/library/ee556427.aspx
http://fabiangehrke.com.br/
http://larahvidotti.wordpress.com/
http://blogs.msdn.com/b/alexschulz/
http://rodrigoromano.net

Abraços a todos!!!


Readmore...
terça-feira, 2 de agosto de 2011

Monitorar Mudanças de Propriedades

0 comentários
 
Olá para todos!!!!!
Essa semana, que começou ontem, tive a necessidade de monitorar quando uma determinada propriedade de minha classe teve seu valor alterado. Dei uma pesquisada por ai até que cheguei na interface INotifyPropertyChagend. Ela basicamente cria um evento que será disparado quando a propriedade for alterada.
Para demonstrar o uso dessa interface criei um exemplo bem bobo. Nesse caso tenho uma classe com o nome de Aluno com as propriedades: Nome, AnoNascimento, Horario que é um enum do tipo Turno. Vamos ao código?

Primeiro vou criar um projeto do tipo console application. Em seguida adicionar uma classe com o nome de Aluno.

Não esqueça de adicionar using System.ComponentModel.

Agora informamos que a classe Aluno implementa a interface INotifyPropertyChaged. Observe que a interface gerou o seguinte evento:




Agora criamos o metodo Notify, que será responsável por invocar o evento criado.


Vamos agora na propriedade que queremos monitorar, no caso a propriedade turno. Nela chamamos o método Notify quando a propriedade receber um novo valor. Observe:


Apenas para o exemplo falei que o set é um tipo privado, logo poderemos alterar o valor da propriedade Horario somente pela própria classe aluno.

Por fim criamos um método que apenas irá alterar o valor da propriedade Horario.


Feito isso vamos a classe Program do nosso projeto. Dentro do método main vou criar um objeto da classe Aluno e preencher algumas propriedades. Em seguida adicionar o evento ProperyChanged.


No método gerado vamos exibir os novos valores da propriedade Horario da variável aluno:

Agora todas as classes:



   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.ComponentModel;
   6:   
   7:  namespace TrabalhandoComPropriedades
   8:  {
   9:      public class Aluno : INotifyPropertyChanged
  10:      {
  11:          public enum Turno
  12:          {
  13:              Manha,
  14:              Tarde,
  15:              Noite
  16:          }
  17:   
  18:          #region INotifyPropertyChanged Members
  19:   
  20:          public event PropertyChangedEventHandler PropertyChanged;
  21:   
  22:          #endregion
  23:   
  24:          public string Nome
  25:          {
  26:              get;
  27:              set;
  28:          }
  29:   
  30:          public int AnoNascimento
  31:          {
  32:              get;
  33:              set;
  34:          }
  35:   
  36:          private Turno _horario = Turno.Manha;
  37:          public Turno Horario
  38:          {
  39:              get
  40:              {
  41:                  return _horario;
  42:              }
  43:              private set
  44:              {
  45:                  _horario = value;
  46:                  Notify("Horario");
  47:              }
  48:          }
  49:   
  50:          private void Notify(string property)
  51:          {
  52:              if (PropertyChanged != null)
  53:              {
  54:                  PropertyChanged.Invoke(this, new PropertyChangedEventArgs(property));
  55:              }
  56:          }
  57:   
  58:          internal void ProcessarTurnos()
  59:          {
  60:              this.Horario = Turno.Tarde;
  61:              System.Threading.Thread.Sleep(1000);
  62:              this.Horario = Turno.Noite;
  63:          }
  64:      }
  65:  }





   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.ComponentModel;
   6:   
   7:  namespace TrabalhandoComPropriedades
   8:  {
   9:      class Program
  10:      {
  11:          static void Main(string[] args)
  12:          {
  13:              Aluno aluno = new Aluno();
  14:              aluno.Nome = "Pedro Marques";
  15:              aluno.AnoNascimento = 1984;
  16:              aluno.PropertyChanged += new PropertyChangedEventHandler(aluno_PropertyChanged);
  17:              aluno.ProcessarTurnos();
  18:              Console.ReadKey();
  19:          }
  20:   
  21:          static void aluno_PropertyChanged(object sender, PropertyChangedEventArgs e)
  22:          {
  23:              Console.WriteLine("Propriedade {0} alterada para {1}", e.PropertyName, ((Aluno)sender).Horario.ToString());
  24:          }
  25:      }
  26:  }

E o resultado:

Readmore...
quinta-feira, 21 de julho de 2011

CRUD Listas Sharepoint

0 comentários
 

Apenas para mostrar como fazer um CRUD na lista do sharepoint que criamos no post Criação de Listas Programaticamente. Para isso utilizei novamente um console aplication referenciando a dll Microsoft.Sharepoint.dll

Vamos ao código:


   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using Microsoft.SharePoint;
   6:   
   7:  namespace Sharepoint.Crud
   8:  {
   9:      class Program
  10:      {
  11:          static void Main(string[] args)
  12:          {
  13:              using (SPSite oSite = new SPSite("http://intranet.contoso.com/"))
  14:              {
  15:                  using (SPWeb oWeb = oSite.OpenWeb())
  16:                  {
  17:                      bool allowUnsafeUpdates = oWeb.AllowUnsafeUpdates;
  18:                      oWeb.AllowUnsafeUpdates = true;
  19:                      try
  20:                      {
  21:                          SPList oList = oWeb.Lists.TryGetList("Ramais Empresa");
  22:                          if (oList != null)
  23:                          {
  24:                              //Adiciona um novo item e pega o id gerado
  25:                              int id = AdicionarRamal(oList, "João Carlos", "Administativo", "Filial - São Paulo", "Somente pode ser encontrado após as <b>18:00</b>.");
  26:   
  27:                              //Atualiza o Ramal
  28:                              AtualizarRamal(oList, id, "Maria Antônia", "Administrativo", "Filial - Rio de Janeiro", "");
  29:   
  30:                              //Envia o item criado para a lixeira
  31:                              RemoverRamal(oList, id, false);
  32:   
  33:                              //Adiciona um novo item
  34:                              id = AdicionarRamal(oList, "Joaquina Ferreira", "Financeiro", "Filial - São Paulo", "Trabalho apenas nas quartas e sextas.");
  35:   
  36:                              //Remove o item permanentemente
  37:                              RemoverRamal(oList, id, true);
  38:                          }
  39:                      }
  40:                      finally
  41:                      {
  42:                          oWeb.AllowUnsafeUpdates = allowUnsafeUpdates;
  43:                      }
  44:                  }
  45:              }
  46:          }
  47:   
  48:          private static void RemoverRamal(SPList oList, int id, bool excluirPermanentemente)
  49:          {
  50:              try
  51:              {
  52:                  SPListItem oListItem = oList.GetItemById(id);
  53:                  if (excluirPermanentemente)
  54:                  {
  55:                      //Exclui o item permanentemente
  56:                      oListItem.Delete();
  57:                  }
  58:                  else
  59:                  {
  60:                      //Envia o item para a lixeira do site
  61:                      oListItem.Recycle();
  62:                  }
  63:              }
  64:              catch
  65:              {
  66:                  throw new Exception("Item inexistente!");
  67:              }
  68:          }
  69:   
  70:          private static void AtualizarRamal(SPList oList, int id, string nome, string setor, string unidade, string observacao)
  71:          {
  72:              try
  73:              {
  74:                  SPListItem oListItem = oList.GetItemById(id);
  75:                  oListItem[SPBuiltInFieldId.Title] = nome;
  76:                  oListItem["Setor"] = setor;
  77:                  oListItem["Unidade"] = unidade;
  78:                  oListItem["Observacao"] = observacao;
  79:                  oListItem.Update();
  80:              }
  81:              catch
  82:              {
  83:                  throw new Exception("Item inexistente!");
  84:              }
  85:          }
  86:   
  87:          private static int AdicionarRamal(SPList oList, string nome, string setor, string unidade, string observacao)
  88:          {
  89:              SPListItem oListItem = oList.AddItem();
  90:              oListItem[SPBuiltInFieldId.Title] = nome;
  91:              oListItem["Setor"] = setor;
  92:              oListItem["Unidade"] = unidade;
  93:              oListItem["Observacao"] = observacao;
  94:              oListItem.Update();
  95:              return oListItem.ID;
  96:          }
  97:      }
  98:  }

Algumas observações:

Linha 17:

oWeb.AllowUnsafeUpdates: Esse AllowUnsafeUpdates permite atualizações não seguras no banco de dados. Para atualizações via código devemos setar essa propriedade para true, o que ocorre na linha 18.

Linha 56 e 61:

Na linha 56 o item é enviado para a lixeira do site através do método Recycle(). Já se utilizarmos o método Delete() o item é excluído permanentemente.

Linha 89:

O Objeto SPList agora possui o método AddItem(). Esse método não existia nas versões anteriores então era necessário fazer da seguinte forma: SPList.Items.Add();
E os resultados:

Cadastro do primeiro item:

Atualização do item:

Item enviado para a lixeira do site:

Cadastro de um novo item:


Bom então é isso, até a próxima e qualquer dúvida postem ai!
Readmore...
terça-feira, 19 de julho de 2011

Criação de Listas Programaticamente

1 comentários
 
Olá para todos!!! Uma das necessidades que ocorre durante o desenvolvimento de alguma feature é a utilização de listas customizadas. Para não deixar a criação dessas listas para o usuário gosto de criar as listas que preciso programaticamente. O visual studio 2010 tem um tipo de projeto especial para a criação de listas, mas não irei trabalhar com esse tipo de projeto neste exemplo. Aqui vamos criar uma lista via código mesmo. O objetivo é demonstrar que é realmente fácil criar uma lista via código. Então vamos lá:
Para esse projeto criei um console application. Adicionei a referência da Dll Microsoft.SharePoint.dll. Como sabemos o Sharepoint 2010 trabalha na plataforma 64 bits logo temos que alterar nossa aplicação para que também rode em 64 bits. Acesse as propriedades do projeto e altere a seguinte configuração:

Feito isso salve e vamos a codificação:


   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using Microsoft.SharePoint;
   6:   
   7:  namespace Sharepoint.CriacaoListas
   8:  {
   9:      class Program
  10:      {
  11:          static void Main(string[] args)
  12:          {
  13:              using (SPSite oSite = new SPSite("http://intranet.contoso.com/"))
  14:              {
  15:                  using (SPWeb oWeb = oSite.OpenWeb())
  16:                  {
  17:                      string nomeLista = "Ramais Empresa";
  18:                      SPList oList = oWeb.Lists.TryGetList(nomeLista);
  19:                      if (oList == null)
  20:                      {
  21:                          CriaListaRamaisEmpresa(oWeb);
  22:                      }                    
  23:                  }
  24:              }
  25:          }
  26:   
  27:          private static void CriaListaRamaisEmpresa(SPWeb oWeb)
  28:          {
  29:              //Seguindo as boas práticas colocamos a lista sem espaços ou caracteres especiais.
  30:              Guid idLista = oWeb.Lists.Add("Ramais_Empresa", "Lista com os ramais da empresa", SPListTemplateType.GenericList);
  31:              SPList oList = oWeb.Lists[idLista];
  32:              
  33:              //Colocando o nome amigável para o usuário
  34:              oList.Title = "Ramais Empresa";
  35:   
  36:              //Informo que não quero que a lista apareça na barra de inicio rápido do site.
  37:              oList.OnQuickLaunch = false;
  38:              
  39:              //Atualizo a lista
  40:              oList.Update();
  41:              
  42:              //Atualizando o campo titulo
  43:              SPField oField = oList.Fields[SPBuiltInFieldId.Title];
  44:              oField.Title = "Funcionário";
  45:              oField.Update();
  46:              
  47:              //Adiciono os campos a lista
  48:              //Campo setor do tipo escolha e obrigatório.
  49:              oList.Fields.Add("Setor", SPFieldType.Choice, true);
  50:              SPFieldChoice oChoiceField = (SPFieldChoice)oList.Fields["Setor"];
  51:              oChoiceField.Choices.Add("Financeiro");
  52:              oChoiceField.Choices.Add("Administrativo");
  53:              oChoiceField.Choices.Add("TI");
  54:              oChoiceField.Choices.Add("Recursos Humanos");
  55:              oChoiceField.Description = "Informe o setor do funcionário.";
  56:              oChoiceField.Update();
  57:   
  58:              //Campo unidade
  59:              oList.Fields.Add("Unidade", SPFieldType.Choice, true);
  60:              oChoiceField = (SPFieldChoice)oList.Fields["Unidade"];
  61:              oChoiceField.Choices.Add("Matriz - Belo Horizonte");
  62:              oChoiceField.Choices.Add("Filial - São Paulo");
  63:              oChoiceField.Choices.Add("Filial - Rio de Janeiro");
  64:              oChoiceField.DefaultValue = "Matriz - Belo Horizonte";
  65:              oChoiceField.Description = "Informe qual a unidade do funcionário.";
  66:              oChoiceField.Update();
  67:   
  68:              //Campo Observação
  69:              oList.Fields.Add("Observacao", SPFieldType.Note, false);
  70:              SPFieldMultiLineText oMultilineField = (SPFieldMultiLineText)oList.Fields["Observacao"];
  71:              
  72:              oMultilineField.Title = "Observação";
  73:              
  74:              //Informo que o campo deve aceitar tags Html.
  75:              oMultilineField.RichText = true;
  76:              
  77:              //Informo que ele apenas pode utilizar algumas tags html simples como negrito, itálico e alinhamento.
  78:              oMultilineField.RichTextMode = SPRichTextMode.Compatible;
  79:              oMultilineField.Update();
  80:   
  81:              //Atualiza a view default para exibir os novos campos criados.
  82:              SPView oView = oList.DefaultView;
  83:              oView.ViewFields.Add("Setor");
  84:              oView.ViewFields.Add("Unidade");
  85:              oView.ViewFields.Add("Observacao");
  86:              oView.Update();
  87:          }
  88:      }
  89:  }


Creio que o código esta bem comentado mas mesmo assim vamos a alguns pontos:

Linhas 13 e 15:

É uma ótima prática utilizar o using em objetos SPSite e SPWeb pois eles utilizam muita memoria do servidor. Logo quanto mais rápido vocês liberarem esses objetos da memoria melhor. Em um outro post falo mais sobre a importância de dar o dispose nesses objetos.

Linha 18:

Uma coisa muito boa do sharepoint 2010: agora o objeto SPListCollection possui um método TryGetList. Nas versões Wss 3.0 e MOSS 2007 isso não existia. Para contornar esse problema nas versões antigas criavamos alguns extension methods (Novidade a partir do framework 3.0).

Linha 69:

O campo “Observação” é criado sem caracteres especiais e logo na linha 72 é atualizado para o nome correto. Nas imagens abaixo poderemos ver o motivo.
E o resultado desse código:


A lista "Ramais Empresa" criada já se encontra no site. Observe que como setamos a propriedade OnQuickLaunch da lista para false ela não aparece na barra de inicio rápido do site.


Como podemos ver no detalhe da url o campo tem o InternalName como "Observacao" enquanto o DisplayName é "Observação". Mais uma boa prática aplicada.


Observe que a url da lista ficou como Ramais_Empresa sem os caracteres especiais que tanto incomodam.


O Cadastro de novos itens com os campos dropdown.


Item já cadastrado.


Ainda podemos melhorar esse código fazendo os campos de "Setor" e "Unidade" buscarem de outras listas.
Bom é isso qualquer dúvida basta postar!!!
Readmore...
segunda-feira, 18 de julho de 2011

Hierarquia Sharepoint

2 comentários
 
Olá para todos!!!
Hoje vou falar um pouco da hierarquia do Sharepoint.



Como podemos verificar na image o Sharepoint possui uma hierarquia entre os objetos. A partir dessa hierarquia conseguimos identificar em qual nível estamos e como fazemos para acessar um outro item da hierarquia.

Algumas explicações:

SPFarm:
É o primeiro nível da hierarquia do sharepoint. Ele representa o farm do sharepoint. O objeto SPFarm não pode ser instanciado, ele é um objeto estático. Para acessar o SPFarm em código devemos utilizar o seguinte código:
SPFarm currentFarm = SPFarm.Local;

SPService:
Representa os serviços que estão rodando no farm. Exemplo: Access Services, Performance Point, Sharepoint Search, etc. O SPService é utilizado para trabalhos administrativos como Backup, configruação de serviços, etc. Para retornar os objetos SPService do farm utilize o código:
SPServiceCollection oServiceCollection = SPFarm.Local.Services;

SPWebApplication:
É a representação do site sharepoint no IIS(internet information Services). Podemos utilizar o SPWebApplication para configurar o tamanho maximo de arquivos, criar uma nova site collection.

SPSite
O SPSite representa o site collection. A classe SPSite suporta construtores, para isso basta passarmos o Guid do site ou a URL:
SPSite oSite = SPContext.Current.Site;
Ou:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    //...
}
O Objeto SPSite possui uma coleção de SPWeb.

SPWeb
Representa um web site do Sharepoint. Nele que estão as listas, biblioteca, etc. O Objeto SPWeb pode ser obtido através do SPSite. Alguns exemplos:
SPWebCollection oWebCollection = SPContext.Current.Site.AllWebs;

Ou podemos buscar o Web Atual;
SPWeb currentWeb = SPContext.Current.Web;

Ou ainda:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    using (SPWeb oWeb = oSite.OpenWeb())
    {
        //...
    }
}
O Objeto SPWeb ainda pode ter mais objetos SPWeb.

SPList:
Nos objetos SPList do site que os dados ficam armazenados, tanto documentos, quanto imagens, páginas, etc. Algo interessante que a versão do sharepoint 2010 server possui uma biblioteca especial apenas para midia.
Para obtermos as listas e/ou bibliotecas do site devemos utilizar o objeto SPWeb. Alguns exemplos:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    using (SPWeb oWeb = oSite.OpenWeb())
    {
        SPListCollection oListCollection = oWeb.Lists;
    }
}

Ou buscando apenas a biblioteca de documentos administrativos:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    using (SPWeb oWeb = oSite.OpenWeb())
    {
        SPList oList = oWeb.Lists["Documentos Administativos"];                    
    }
}

SPListItem e SPFolder
Os objetos SPListItem e SPFolder são os registros das listas(SPLists) do SPWeb. O SPFolder é um item do SPList, contudo o SPFolder pode ter SPListItem “dentro” dele. Mas como o SPFolder também é um SPListItem coloquei eles no mesmo nível. Podemos obter o SPListItem e o SPFolder a partir das listas. Alguns exemplos:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    using (SPWeb oWeb = oSite.OpenWeb())
    {
        SPList oList = oWeb.Lists["Documentos Administativos"];
        SPListItem oItem = oList.GetItemById(1);                    
    }
}
Pegando as pastas da lista:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    using (SPWeb oWeb = oSite.OpenWeb())
    {
        SPList oList = oWeb.Lists["Documentos Administativos"];

        //Observe que as pastas são SPListItem
        SPListItemCollection oFoldersCollection = oList.Folders;
    }
}

SPFile
O Objeto SPFile representa os arquivos estão em listas ou bibliotecas do site. Para podermos acessar um objeto SPFile devemos buscar nos itens(SPListItem) das listas ou passando como parametro para o SPWeb a url do arquivo. Alguns exemplos:
using (SPSite oSite = new SPSite("http://meusite.com.br"))
{
    using (SPWeb oWeb = oSite.OpenWeb())
    {
        SPList oList = oWeb.Lists["Documentos Administrativos"];
        SPListItem oListItem = oList.GetItemById(1);
        SPFile oFile = oListItem.File;
    }
}

Bom então é somente isso por hoje. Até mais a todos e qualquer dúvida, comentário ou crítica postem ai!
Abraços!
Readmore...
quinta-feira, 26 de maio de 2011

O Início

0 comentários
 
A todos um ótimo dia!

Bom resolvi criar esse blog com a idéia de aprender mais. Ouvi uma certa vez que somente aprendemos mais, e melhor, quando resolvemos ensinar algo as pessoas. Pretendo falar um pouco sobre programção, sharepoint, arquitetura de software enfim, essas pequenas coisas que eu gosto e espero que gostem também!
Abraços!!!
Readmore...