Pergunta Addin para outlook (calendário)

  • terça-feira, 15 de setembro de 2009 14:48
     
      Contém Código
    Olá, pessoal.

    Estou desenvolvendo um addin para o outlook 2003 com o VS 2008 e SQL 2008. Basicamente, esse addin cria um botão que, ao ser clicado, abre uma conexão com o db e puxa as informações para o calendário do outlook, fazendo uma espécie de sincronização de informações.

    O problema é que, caso o compromisso já exista no outlook, o mesmo deve ser deletado para se evitar duplicidade de informações, só que o código que eu desenvolvi não está apagando o item do calendário, ou seja, se eu apertar o botão 5 vezes, aparecerão 5 compromissos marcados no calendário, no mesmo dia e horário. Segue abaixo o código:

    using System;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.Tools.Applications.Runtime;
    using Outlook = Microsoft.Office.Interop.Outlook;
    using Office = Microsoft.Office.Core;
    using System.Data.SqlClient;
    using System.Data;
    
    namespace Teste_Botao_Outlook_DeletaAgenda
    {
        public partial class ThisAddIn
        {
            //declara o objeto Barra de Ferramentas
            Office.CommandBar BarraFerramentas;
    
            //declara o objeto Botão
            Office.CommandBarButton Botao;
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                //verifica se o objeto BarraFerramentas existe
                if (BarraFerramentas == null)
                {
                    //adiciona a barra de comandos ao Active explorer
                    Office.CommandBars BarraComandos = this.Application.ActiveExplorer().CommandBars;
    
                    //adiciona a barra de comandos à barra de ferramentas
                    BarraFerramentas = BarraComandos.Add("Sincronizador", Office.MsoBarPosition.msoBarTop, false, true);
                }
    
                //adiciona o botão à barra de ferramentas customizada
                Office.CommandBarButton Botao1 = (Office.CommandBarButton)BarraFerramentas.Controls.Add(1, missing, missing, missing, missing);
    
                //define o estilo do botão
                Botao1.Style = Office.MsoButtonStyle.msoButtonCaption;
    
                //define o título do botão
                Botao1.Caption = "Sincronizar com a Agenda";
    
                //verifica se o objeto Botao existe
                if (this.Botao == null)
                {
                    //adiciona o handler de evento para o botão na barra de ferramentas
                    this.Botao = Botao1;
                    Botao.Click += new Office._CommandBarButtonEvents_ClickEventHandler(ButtonClick);
                }
            }
    
    
            //define o evento do botão na barra de ferramentas customizada
            private void ButtonClick(Office.CommandBarButton ButtonContrl, ref bool CancelOption)
            {
                    //DataTable instanciado , usado para ler as informações do db
                    DataTable dtTeste = new DataTable();
    
                    //cria e abre a conexão
                    SqlConnection conexao = new SqlConnection();
                    conexao.ConnectionString = @"Data Source=...";
                    conexao.Open();
    
                    //cria e executa o sql query
                    SqlCommand comando = new SqlCommand();
                    comando.CommandText = "SELECT dbo.agenda.* FROM dbo.agenda WHERE (nomefuncionario = N'José da Silva')";
                    comando.Connection = conexao;
                    SqlDataReader drTeste = comando.ExecuteReader();
    
                    //Carrega as informações no DataTable
                    dtTeste.Load(drTeste);
    
                    //enquanto lê o db
                    while (drTeste.Read())
                    {
                        //Usa o objeto MAPIFolderpara pegar a pasta do calendário
                        Outlook.MAPIFolder PastaAgendamento = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
    
                        //acessa os ítens do calendário através do item object do Outlook
                        Outlook.Items ItemAgendamento = PastaAgendamento.Items.Restrict("[MessageClass]='IPM.Appointment'");
    
                        //lê as informações do db uma a uma através do DataTable
                        foreach (System.Data.DataRow DataRowAgendamento in dtTeste.Rows)
                        {
    
                            //checa se o item da agenda existe no Outlook ou não
                            Outlook.AppointmentItem AgendamentoExistente = (Outlook.AppointmentItem)ItemAgendamento.Find("[Subject] = '" + 
    
    DataRowAgendamento["escopovisita"].ToString() + "'");
    
                            //se o item da agenda já existe, então deleta o mesmo
                            if (AgendamentoExistente != null)
                            {
                                AgendamentoExistente.Delete();
                            }
    
                            else
                            {
    
    
                                //objeto do Outlook AppointmentItem para criar um novo agendamento
                                Outlook.AppointmentItem agendamento = 
    
    (Outlook.AppointmentItem)this.Application.CreateItem(Outlook.OlItemType.olAppointmentItem);
    
                                //cria um array com o valor da data, separando o ano, o mês e o dia através da barra
                                string[] data = drTeste["data"].ToString().Split('/');
    
                                //cria um array com o valor da hora inicial, separando as horas e os minutos através dos dois-pontos
                                string[] horainicial = drTeste["horainicial"].ToString().Split(':');
    
                                //cria um array com o valor da hora inicial, separando as horas e os minutos através dos dois-pontos
                                string[] horafinal = drTeste["horafinal"].ToString().Split(':');
    
                                //define o campo Subject
                                agendamento.Subject = drTeste["escopovisita"].ToString();
    
                                //define o campo Location
                                agendamento.Location = drTeste["empresa"].ToString();
    
                                //define a data e a hora inicial
                                agendamento.Start = new DateTime(Convert.ToInt32(data[2]), Convert.ToInt32(data[1]), Convert.ToInt32(data[0]), 
    
    Convert.ToInt32(horainicial[0]), Convert.ToInt32(horainicial[1]), 00);
    
                                //define a data e a hora final
                                agendamento.End = new DateTime(Convert.ToInt32(data[2]), Convert.ToInt32(data[1]), Convert.ToInt32(data[0]), 
    
    Convert.ToInt32(horafinal[0]), Convert.ToInt32(horafinal[1]), 00);
    
                                //define o campo Body
                                agendamento.Body = "Tipo de Agendamento: " + drTeste["tipoagendamento"].ToString();
    
                                //salva o agendamento no outlook
                                ((Outlook.AppointmentItem)agendamento).Save();
                            }
                        }
    
                    //fecha tudo
                    drTeste.Close();
                    drTeste.Dispose();
                    comando.Dispose();
                    conexao.Close();
                    conexao.Dispose();
                }
            }
    
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
            }
    
            #region VSTO generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }
            
            #endregion
        }
    }
    

    Acredito que o erro está dentro do laço foreach, será que alguém pode verificar?

    Grato,

    Marcelo Silveira

Todas as Respostas

  • terça-feira, 12 de janeiro de 2010 15:29
     
     
    Boas!

    Coloca um Watch para o valor de "DataRowAgendamento["escopovisita"].ToString() " e verifica se realmente o que está a passar no valor da Datarow, pois o "ItemAgendamento.Find" parece ser sempre NULL.

    Uma outra questão é que voce está a utilizar chaves longas como "WHERE (nomefuncionario = N'José da Silva'" e esta a pesquisar um Subject, quando devia ir buscar o "GlobalAppointmentID", esse sim é ÚNICO.  Veja aqui http://support.microsoft.com/kb/899919/.

    Mas tente assim e veja se resulta

    string mEscopovisita = DataRowAgendamento.Item["escopovisita"].ToString();
    Outlook.AppointmentItem AgendamentoExistente = (Outlook.AppointmentItem)ItemAgendamento.Find((String.Format("[Subject] = '{0}', mEscopovisita);

    Cpts
    Tito