msdn01_capa.JPG

Clique aqui para ler todos os artigos desta edição

 

Office 2003

Traga a Superioridade do Visual Studio .NET para as Soluções de Negócios Criadas com o Microsoft Office

por Ken Getz e Brian A. Randell

 

Resumo

O Microsoft Visual Studio Tools for Microsoft Office System é uma nova tecnologia que traz os recursos avançados do Visual Studio .NET e do .NET Framework para os aplicativos criados no Microsoft Word 2003 e no Excel 2003. Agora você pode usar o Visual Basic .NET e o C# para escrever soluções de código gerenciado (managed code), as quais são executadas juntamente com o Word 2003 ou Excel 2003, aproveitando assim as vantagens dos ricos modelos de objetos que eles expõem. Com isso, você usufrui os benefícios do ambiente gerenciado (como, por exemplo, a segurança de acesso ao código) que permite executar um aplicativo baseado em .NET totalmente compilado.

 

O Microsoft® Office fornece um ambiente rico para a criação de aplicativos comerciais. Com os modelos de objeto baseados em COM revelados pelos aplicativos do Office, você pode usar código VBA (Visual Basic® for Applications), Automação COM autônoma e suplementos COM para criar aplicativos não gerenciados para o Office.

Você pode executar o código VBA diretamente no próprio aplicativo do Office. Esse código é executado ao mesmo tempo, e os bits compilados e de código são geralmente armazenados com o documento (todos os aplicativos do Office, exceto o Outlook®, armazenam códigos dentro do documento). Lembre-se de que o código VBA armazenado é compilado para p-code, não para o código nativo, o que causa uma leve queda no seu desempenho, embora a execução simultânea ative as chamadas de método otimizadas para os objetos Office.

Você também pode escrever aplicativos em Visual Basic ou em outras linguagens aceitas pelo COM que interajam com as interfaces expostas publicamente fornecidas pelos aplicativos Office. Em geral, esses aplicativos são executados de forma independente e necessitam de chamadas através da camada proxy/stub do COM. Os aplicativos de automação são freqüentemente compilados para código nativo e, por esse motivo, são executados com mais rapidez do que o código VBA. No entanto, esse benefício é prejudicado pelo fato de haver uma redução de desempenho, causada pelos métodos de chamada entre os aplicativos.
A começar pelo Office 2000, os aplicativos do Office procuram por componentes de suplementos registrados que implementem a interface IDTExtensibility2 e carregam esses suplementos durante a inicialização ou on- demand, dependendo de como o suplemento foi configurado. Com o Visual Basic e outras linguagens compatíveis com VBA e COM, você pode criar aplicativos que implementem essa interface (é possível criar suplementos COM até mesmo com Office Developer e VBA). Esse nível de flexibilidade possibilita uma boa conciliação, permitindo que aplicativos totalmente integrados sejam executados simultaneamente. Essa técnica requer o registro dos componentes, a fim de que os aplicativos do Office sejam notificados da existência do suplemento. Você pode criar um único aplicativo de suplemento COM que seja carregado dentro de vários aplicativos do Office, e o próprio suplemento COM fornecerá um conjunto de ferramentas entre os documentos (o que significa que seu comportamento não será alterado de forma inerente de um documento para outro).

Haverá situações em que você se encontrará no mundo do código gerenciado (managed code) e nas quais preferirá interagir com o Office em um mundo seguro, livre do lixo dos códigos. Felizmente, devido aos milagres da interoperabilidade do COM e do RCW (runtime-callable wrapper) do ambiente CLR (common language runtime), você ainda pode fazer chamadas independentes para métodos de um aplicativo do Office e, com um pouco de trabalho, criar suplementos COM usando o código gerenciado. O VBA, entretanto, permanece não gerenciado e provavelmente permanecerá assim por um bom tempo. Escrever um código baseado no Framework que utilize automação para controlar aplicativos do Office é indicado quando você pretende criar seu próprio aplicativo front-end; os usuários precisarão iniciar o seu aplicativo, o que poderá carregar então o Word ou outro aplicativo (seja visível ou não). Se você precisar criar uma solução que possa ser executada em vários hosts Office e que não seja baseada em documento, pode criar um suplemento COM usando o código gerenciado (managed code).

É possível que nenhum desses modelos atenda às suas necessidades. Por exemplo, talvez seus usuários estejam acostumados a carregar um documento do Word e ter automaticamente o aplicativo de gerenciamento de documentos em execução, ou a abrir uma planilha do Excel e executar análises estatísticas no conteúdo da pasta de trabalho. Ou,Ou talvez você queira usar o código gerenciado para responder aos eventos de aplicativo do Office. Ou ainda: talvez você queira ser capaz de usar o código em C# ou o Visual Basic .NET para reagir a um clique de menu ou botão ocorrido dentro de um aplicativo Word. Por fim, é possível que você queira exibir um Windows® Form criado no Visual Studio® .NET em resposta a uma solicitação de entrada em uma planilha do Excel. Para atender a esses requisitos, a Microsoft lançou o Visual Studio Tools for Microsoft Office, um suplemento do Visual Studio .NET 2003 que lhe permite criar aplicativos gerenciados, orientados a documento, que são executados juntamente com o Word 2003 ou com o Excel 2003.

Vantagens

O Visual Studio Tools para Office oferece muitas vantagens. Você pode usar todos os recursos do Visual Studio .NET para criar aplicativos baseados no Office. Pode também usar o código Visual Basic .NET ou C# para criar seus aplicativos. Essas duas linguagens são mais avançadas que a VBA. É possível aproveitar todos os recursos do .NET Framework - de leitores XML a ADO.NET e Web Services – de dentro dos aplicativos do Office.

Além disso, você pode tirar proveito da segurança de acesso ao código incorporada no CLR. Diferentemente das macros do VBA, as soluções gerenciadas que utilizam o Visual Studio Tools for Office simplesmente não serão executadas, a não ser que sejam explicitamente confiáveis. As configurações padrão usadas pelo carregador do Visual Studio Tools for Office não permitem a execução de nenhuma montagem (assembly), o que protege os usuários contra vírus e outros códigos maliciosos. Antes que os usuários possam carregar um documento com extensões de código gerenciado, o administrador deverá explicitamente conceder confiança total a uma montagem (assembly) ou local. O Visual Studio Tools for Office permite que você tire proveito do desenvolvimento no-touch. Os usuários podem receber automaticamente atualizações para o aplicativo sem precisarem intervir no componente.


Primeiros Passos

Para começar, vamos examinar a instalação e, em seguida, orientá-lo durante o processo de criação de um aplicativo Excel simples, usando o código C# ou Visual Basic .NET, que recuperará os dados e os colocará em um gráfico.

A instalação do Visual Studio Tools for Office adiciona um conjunto de modelos de projeto ao Visual Studio .NET 2003, permitindo que você crie documentos do Word, projetos de modelo ou planilhas do Excel usando o código C# e o Visual Basic .NET para reagir aos eventos e automatizar os produtos. Uma vez instalado o Visual Studio .NET 2003, seguido do Microsoft Office 2003 e, por fim, do Visual Studio Tools for Microsoft Office System (nessa ordem), você estará pronto para criar aplicativos que aproveitem as vantagens das PIAs (Primary Interop Assemblies) do Microsoft Office 2003 armazenadas no GAC (Global Assembly Cache). Você será capaz de criar projetos em Word ou Excel no Visual Studio .NET que utilizem código C# ou Visual Basic .NET para automatizar o Office durante a execução. (Não, você não entendeu errado — por enquanto, o Visual Studio Tools for Office só permite que você crie projetos em Word e Excel no Visual Studio .NET. Com o tempo, você provavelmente verá suporte estendido para outros produtos do Office).

Para dar início ao aplicativo de exemplo, você precisa criar um projeto Excel no Visual Studio .NET. Primeiro, verifique se você instalou o Visual Studio .NET 2003, o Office 2003 e o Visual Studio Tools for Office. Ao instalar o Office 2003, é fundamental que você execute uma instalação completa ou que selecione individualmente o suporte .NET para cada um dos produtos do Office, a fim de que as PIAs apropriadas sejam instaladas no GAC. É mais fácil instalar o Office completo, mas você também pode instalar individualmente as PIAs do Word, Excel, Microsoft Forms e Microsoft Graph.

Em seguida, no Visual Studio .NET, use o item de menu File | New | Project para selecionar o tipo de projeto e de modelo. Primeiro, selecione Microsoft Office 2003 Projects. Selecione Visual Basic Projects ou C# Projects e, em seguida, selecione Excel Workbook como tipo de modelo. Digite um nome de projeto e, quando terminar, clique em OK.

Por fim, a segunda página do Microsoft Office Project Wizard lhe permite escolher se deseja usar um documento existente ou criar um novo documento. Você também pode usar o link Security Settings nesta página e ignorar a sugestão padrão oferecida pelo assistente para configurar a segurança de acesso necessária ao seu projeto. Por enquanto, selecione a opção Create New Document e escolha uma localização conveniente para o projeto. Para completar as etapas do assistente e criar o novo projeto, clique em Finish. (Não altere agora as configurações de segurança padrão. Espere até estar familiarizado com a segurança de acesso ao código e com as configurações usadas pelo Visual Studio Tools for Office. Alterar as configurações de segurança neste ponto pode impossibilitá-lo de executar ou depurar seus aplicativos.)
Uma vez criado esse projeto, você perceberá que a janela Solution Explorer contém referências ao aplicativo do Office, juntamente com um arquivo que contém uma classe denominada OfficeCodeBehind que permite que você vincule manipuladores de evento aos eventos dos documentos.

Na parte superior do arquivo de código (ThisDocument ou ThisWorkbook, com a extensão de arquivo apropriada à linguagem selecionada), você encontrará Imports ou instruções de uso que simplificam a digitação de referências aos objetos dentro do modelo de objeto do host:

 

' Visual Basic .NET

Imports Excel = Microsoft.Office.Interop.Excel

 

// C#

using Excel = Microsoft.Office.Interop.Excel;

 

Em seguida, você encontrará um atributo que descreve a classe:

' Visual Basic .NET

' Office integration attribute. Identifies the startup class

' for the document. Do not modify.

System.ComponentModel.DescriptionAttribute( _

   "OfficeStartupClass, Version=1.0, _

   Class=ChartDemo.OfficeCodeBehind")>

 

// C#

// Office integration attribute. Identifies the startup class

// for the document. Do not modify.

[assembly:System.ComponentModel.DescriptionAttribute(

  "OfficeStartupClass, Version=1.0,

  Class=ChartDemo.OfficeCodeBehind")]

 

Embora o comentário incluído indique que você não deve modificar esse atributo, existem situações em que isso será necessário. Por exemplo, se modificar o nome da classe ou o namespace, você precisará atualizar manualmente esse atributo para que ele corresponda às alterações. O carregador do Visual Studio Tools for Office usa esse atributo para determinar o nome da classe que ele deverá carregar à medida que os usuários abrirem o documento host — você obterá mais informações sobre esse assunto posteriormente neste artigo.

 

Em seguida, você encontrará declarações para variáveis que correspondem aos objetos do documento principal e do aplicativo (ThisWorkbook e ThisApplication para Excel, e ThisDocument e ThisApplication para Word), conforme mostrado na Listagem 1.

 

Listagem 1 Declarações

Visual Basic .NET

Friend WithEvents ThisWorkbook As Excel.Workbook

Friend WithEvents ThisApplication As Excel.Application

 

C#

internal Excel.Application ThisApplication

{

  get { return thisApplication;}

}

 

internal Excel.Workbook ThisWorkbook

{

  get { return thisWorkbook;}

}

 

private Excel.Application thisApplication = null;

private Excel.Workbook thisWorkbook = null;

 

Além disso, as classes contêm manipuladores de evento para eventos básicos (Workbook.Open e Workbook.BeforeClose no Excel, Document.Open e Document.Close no Word), conforme mostrado na Listagem 2.

 

Listagem 2 Event Handlers

Visual Basic .NET

Private Sub ThisWorkbook_Open() Handles ThisWorkbook.Open

 

End Sub

 

Private Sub ThisWorkbook_BeforeClose(ByRef Cancel As Boolean) _

    Handles ThisWorkbook.BeforeClose

    Cancel = False

End Sub

 

C#

private Excel.WorkbookEvents_OpenEventHandler openEvent;

private Excel.WorkbookEvents_BeforeCloseEventHandler

    beforeCloseEvent;

 

protected void ThisWorkbook_Open()

{

 

}

 

protected void ThisWorkbook_BeforeClose(ref bool Cancel)

{

    Cancel = false;

}

 

Existem mais coisas acontecendo e, se expandir a região Generated do código de inicialização em sua classe, você encontrará alguns outros procedimentos, que discutiremos mais tarde neste artigo. Por enquanto, role para baixo na classe e localize o procedimento ThisWorkbook_Open. Adicione o código de modo que o procedimento se pareça com os exemplos na Listagem 3. Observe as diferenças entre o código Visual Basic .NET e o C#. Por exemplo, no Visual Basic .NET, você pode chamar a propriedade Application.Range simplesmente passando um único parâmetro. A propriedade Application.Range foi definida para aceitar dois parâmetros opcionais, mas o C# não oferece suporte a propriedades com parâmetros nem a parâmetros opcionais. Desse modo, ao criar a PIA para o Excel, a equipe adicionou o método get_Range, um dentre os vários métodos accessor que possibilitam aos desenvolvedores de C# trabalhar com o modelo de objeto do Excel. O mesmo problema ocorre com a propriedade Range.Value, que aceita apenas um parâmetro. No C#, você deve usar a propriedade Value2, que não aceita nenhum parâmetro. No Visual Basic, você também pode usar Value2, mas não há nenhuma vantagem em fazer isso.

 

Listagem 3 Configuração das propriedades

Visual Basic .NET

Private Sub ThisWorkbook_Open() Handles ThisWorkbook.Open

  Dim rng As Excel.Range = ThisApplication.Range("A1")

  rng.Value = DateTime.Now.ToString()

  rng.Font.Name = "Verdana"

  rng.Font.Size = 16

End Sub

 

C#

protected void ThisWorkbook_Open()

{

  Excel.Range rng = ThisApplication.get_Range("A1", Type.Missing);

  rng.Value2 = DateTime.Now.ToString();

  rng.Font.Name = "Verdana";

  rng.Font.Size = 16;

}

 

Selecione Debug | Start para executar o aplicativo. O Visual Studio .NET compila e executa o aplicativo, que carrega o Excel. Se você seguiu com atenção as etapas, verá uma planilha com o texto formatado corretamente na célula A1. Quando terminar de admirar seu trabalho, feche o Excel e retorne ao modo de design.

Para ver o que você fez, salve seu projeto, feche o Visual Studio .NET e use o Windows Explorer para ir até a pasta que contém seu projeto e o arquivo da pasta de trabalho do Excel. Clique duas vezes no arquivo XLS para carregar o Excel e verifique se o texto apropriado aparece na planilha. Carregue novamente o Visual Studio .NET e seu projeto de exemplo para prosseguir com a empreitada.

Por mais trivial que pareça, você conseguiu dar cabo de uma tarefa que, se tentasse fazer por conta própria, poderia lhe deixar em apuros: escreveu um código gerenciado (managed code) que reage a um evento do Excel por meio da interação com o modelo de objeto do Excel a partir de um código C# ou Visual Basic .NET.

Investigando as Instalações do Código

Quando você criou seu projeto, especificou a localização do documento do Word ou do Excel que desejava associar ao projeto. Quando o Visual Studio .NET criou o projeto, ele definiu várias propriedades associadas a ele, como AssemblyLinkLocation e OfficeDocument (veja a Figura 1). A propriedade AssemblyLinkLocation indica onde o documento do Office espera encontrar o arquivo de montagem (assembly) necessário para executar seu código, e a propriedade OfficeDocument indica onde a solução Visual Studio .NET pode encontrar o documento correspondente do Office.


image001.gif
Figura 1 Propriedades do Projeto


Além disso, a criação do projeto configura alguns recursos de depuração. Iniciar o projeto a partir do Visual Studio .NET carrega o Excel ou o Word juntamente com seu documento do Office e executa o seu código conforme necessário. Para que o Visual Studio seja capaz de depurar seu aplicativo, ele precisa saber qual aplicativo carregar. Quando você cria seu projeto, o Visual Studio .NET recupera a localização do aplicativo Office apropriado e armazena essa localização juntamente com os parâmetros necessários de linha de comando. Se observar a Figura 2, você verá as páginas de propriedades do projeto, mostrando tanto a localização do aplicativo como os argumentos da linha de comando.


image002.gif
Figura 2 Definição de Propriedades de Localização

 

Depois que você iniciou a sessão de depuração (ou simplesmente carregou o documento do Office a partir do Windows Explorer), como o documento saberá qual montagem (assembly) deverá carregar e qual código executar? Sem que você soubesse, o Visual Studio .NET inseriu duas propriedades personalizadas no documento que você especificou quando criou o projeto. Com o seu documento carregado no Excel, você pode selecionar File | Properties para exibir a caixa de diálogo mostrada na Figura 3. Na guia Custom, você verá duas propriedades, denominadas _AssemblyName0 e _AssemblyLocation0. Essas propriedades contêm o caminho e o nome de arquivo da montagem (assembly) selecionada. Por padrão, a montagem estará localizada em uma pasta com o mesmo nome do projeto, acrescido de "_bin".Por exemplo, se o nome de seu projeto é ChartDemo, a localização padrão para a montagem será a pasta ChartDemo_bin.

image003.gif
Figura 3 Caixa de Diálogo ChartDemo

 

Nitidamente, há um fragmento de código que faz com que o Excel ou o Word carregue e execute a montagem especificada nas propriedades do documento personalizado. No momento em que carregar o documento, se o Excel (ou o Word) encontrar essas propriedades especiais do documento, ele acionará a DLL do carregador não gerenciado do Visual Studio Tools for Office (OTKLOADR.DLL), que por sua vez carregará e vinculará sua montagem gerenciada. Depois que o aplicativo Office host tiver carregado a montagem que você criou, como ele saberá qual código deverá executar? É aqui que o atributo da montagem anteriormente analisado entra na história — esse atributo descreve o nome amplamente qualificado da classe que contém o seu código Visual Basic .NET ou C#.

Uma vez carregada a montagem apropriada, a DLL OTKLOADR passa o procedimento em sua classe (denominado _Startup) para o CLR, a fim de que ele seja executado. Você não cria esse procedimento — ele é criado pelo modelo de projeto, que o coloca na região Generated do código de inicialização. Embora você possa modificar o procedimento, não é recomendável que o faça. O carregador também passa ao método _Startup uma referência ao aplicativo (um objeto Word ou Excel Application) e uma referência ao documento propriamente dito (uma instância de Excel.Workbook ou de Word.Document). O método _Startup copia essas informações nas variáveis locais e vincula as manipulações de evento necessárias, conforme mostrado na Listagem 4.

 

Listagem 4 Método _Startup

Visual Basic .NET

' Required procedure. Do not modify.

Public Sub _Startup(ByVal application As Object, _

 ByVal workbook As Object)

  ThisApplication = CType(application, Excel.Application)

  ThisWorkbook = CType(workbook, Excel.Workbook)

End Sub

 

C#

// Required procedure. Do not modify.

public void _Startup(object application, object workbook)

{

  this.thisApplication = application as Excel.Application;

  this.thisWorkbook = workbook as Excel.Workbook;

 

  openEvent =

    new Excel.WorkbookEvents_OpenEventHandler(ThisWorkbook_Open);

  thisWorkbook.Open += openEvent;

     

  beforeCloseEvent =

    new Excel.WorkbookEvents_BeforeCloseEventHandler(

    ThisWorkbook_BeforeClose);

  thisWorkbook.BeforeClose += beforeCloseEvent;

}

 

A região também contém um procedimento public denominado _Shutdown, que é chamado automaticamente pelo carregador quando o aplicativo fecha o documento, conforme mostrado na Listagem 5.

 

Listagem 5 Método Shutdown<0}

' Visual Basic .NET

' Required procedure. Do not modify.

Public Sub _Shutdown()

  ThisApplication = Nothing

  ThisWorkbook = Nothing

End Sub

 

// C#

// Required procedure. Do not modify.

public void _Shutdown()

{

  thisApplication = null;

  thisWorkbook = null;

}

 

Daí em diante, sua montagem usa os mecanismos de marshaling (empacotamento) do evento COM padrão para responder aos eventos acionados pelos objetos Word e Excel. Observe que não há uma interação definida entre os manipuladores de evento VBA e os manipuladores de eventos gerenciados. Se o seu documento do Word ou Excel contiver um código VBA que manipule um evento, a inclusão de um código em Visual Basic .NET ou C# que manipule o mesmo evento funcionará a contento, mas você não poderá ter certeza da ordem em que os manipuladores de evento serão executados. Certifique-se de que seus aplicativos não dependam de uma ordem específica.

É claro, um dos principais benefícios de se usar o código gerenciado consiste no suporte à segurança de acesso ao código, e o código que você escreve em sua montagem tira proveito das políticas de segurança do usuário. Apesar de o Visual Studio .NET ter criado uma política de segurança apropriada para sua montagem quando você criou o projeto (concedendo amplos direitos), isso não será o caso quando você implementar sua solução. Você tem muitas opções ao distribuir as soluções criadas com o Visual Studio Tools for Office. Por exemplo, pode distribuir tanto o documento do Office como a montagem para o computador cliente. Ou, pode distribuir o documento do Office para o computador local e hospedar a montagem em um local compartilhado. Ou ainda: pode distribuir o documento do Office e a montagem para o local compartilhado.
Cada uma dessas opções possui suas vantagens e desvantagens, tais como capacidade de atualizar o documento e/ou a montagem quando estes estiverem hospedados em um local compartilhado. Em todos os casos, ao distribuir soluções criadas por meio do Visual Studio Tools for Office, você precisará levar em conta os requisitos de segurança de acesso ao código e reservar um tempo na sua agenda de distribuição (implementação) para configurar e testar vários cenários de segurança.


Completando a Demonstração

Para recuperar os dados do SQL Server™, adicioná-los a uma planilha e formatá-los em um gráfico, siga as sete etapas apresentadas abaixo:

 

1.       Execute o projeto. No Excel, clique com o botão direito na barra de menus principal e selecione a barra de ferramentas Control Toolbox.

2.       A partir dessa barra de ferramentas, selecione e arraste um controle CommandButton na planilha, cobrindo as células A3 a A4.

3.       Na Control Toolbox, selecione o botão Properties. Na janela Properties, defina a propriedade Name do controle CommandButton como cmdChart, e sua propriedade Caption como Create Chart.

4.       No Control Toolbox, desmarque a caixa de seleção da ferramenta Design Mode, colocando o controle no modo de execução. Feche a janela Control Toolbox. Quando tiver terminado, a planilha deverá se parecer com a Figura 4.


image004.gif
Figure 4 CommandButton

 

5.       Feche o Excel, salvando as alterações em sua pasta de trabalho.

6.       De volta ao Visual Studio .NET, role até a parte superior do arquivo atual e adicione a instrução apropriada, conforme mostrado na Listagem 6.

 

Listagem 6 Lista de Imports/using <0}

' Visual Basic .NET

Imports System.Data

Imports System.Data.SqlClient

 

// C#

using System.Data

using System.Data.SqlClient;

 

7.       No restante da classe atual, adicione o procedimento mostrado na Listagem 7. Em seguida, modifique o valor da variável connectionInfo para que reflita o local e as configurações de segurança da sua instalação do SQL Server.

 

Listagem 7 Código completo <0}

Visual Basic .NET

Private Sub RetrieveData()

  ' Modify this string for your own situation.

  Dim connectionInfo As String = _

   "Server=.;Database=Northwind;Integrated Security=True"

  Dim commandText As String = "[Ten Most Expensive Products]"

  Dim connection As SqlConnection

  Dim command As SqlCommand

  Dim dataReader As SqlDataReader

  Try

    connection = New SqlConnection(connectionInfo)

    command = New SqlCommand(commandText, connection)

    command.CommandType = CommandType.StoredProcedure

    connection.Open()

    dataReader = command.ExecuteReader(CommandBehavior.CloseConnection)

    Dim rng As Excel.Range = ThisApplication.Range("A5")

    Dim i As Integer

    rng.CurrentRegion.Clear();

    While dataReader.Read

      rng.Offset(i, 0).Value = dataReader(0)

      rng.Offset(i, 1).Value = dataReader(1)

      i += 1

    End While

  Catch ex As Exception

    MessageBox.Show(ex.Message)

  Finally

    If Not dataReader Is Nothing Then

      dataReader.Close()

    End If

    If Not command Is Nothing Then

      command.Dispose()

    End If

    If Not connection Is Nothing Then

      connection.Dispose()

    End If

  End Try

End Sub

 

C#

private void RetrieveData()

{

  // Modify this string for your own situation.

  string connectionInfo =

    "Server=.;Database=Northwind;Integrated Security=true";

  string commandText = "[Ten Most Expensive Products]";

  SqlDataReader dataReader = null;

  using (SqlConnection connection =

    new SqlConnection(connectionInfo))

  {

    using (SqlCommand command =

      new SqlCommand(commandText, connection))

    {

      try

      {

        command.CommandType = CommandType.StoredProcedure;

        connection.Open();

        dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);

        Excel.Range rng = ThisApplication.

          get_Range("A5", Type.Missing);

        int i = 0;

        rng.CurrentRegion.Clear();

        while (dataReader.Read())

        {

          rng.get_Offset(i, 0).Value2 = dataReader[0];

          rng.get_Offset(i, 1).Value2 = dataReader[1];

          i += 1;

        }

      }

      catch (Exception ex)

      {

        MessageBox.Show(ex.Message);

      }

      finally

      {

        if (dataReader != null)

        {

          dataReader.Close();

        }

      }

    }

  }

}

 

Além do código ADO.NET padrão, o procedimento RetrieveData limpa todas as células em torno da célula A5 e, em seguida, percorre as linhas retornadas pelo objeto SqlDataReader e insere cada uma das duas colunas nas células da planilha. Observe novamente a diferença entre o código Visual Basic .NET e o C# — a propriedade Offset espera dois parâmetros, e como o código C# não pode lidar com propriedades com parâmetros, a PIA do Excel fornece o método get_Offset que deverá ser usado pelos desenvolvedores de C#.
Sua próxima tarefa será vincular um manipulador de eventos para o controle CommandButton incorporado na planilha. Esse controle é parte do pacote Microsoft Forms — um conjunto de controles baseados em COM usado pela maioria dos produtos do Office. Para facilitar a vinculação de manipuladores de evento aos controles deste pacote, o modelo do projeto Visual Studio .NET inclui duas versões sobrecarregadas de um método FindControl (uma versão aceita apenas o nome do controle, ao passo que a outra aceita o nome do controle e uma referência ao documento, no caso do controle não estar na planilha atual). Você chamará esse método para recuperar a referência a um controle no documento.

A versão final do Visual Studio Tools for Office cuidará dos detalhes posteriores por você. Entretanto, se estiver trabalhando com a versão beta do produto, é possível que você precise executar algumas etapas adicionais para trabalhar com os controles fornecidos no pacote Microsoft Forms. Se você vir uma instrução imports/using que faça referência ao Microsoft Forms no início de seu módulo (indicando que você está trabalhando com uma versão beta ou com uma versão final do produto), ignore esse trecho e vá direto para as etapas que descrevem como adicionar uma variável button. Caso contrário, adicione uma referência à biblioteca COM do Microsoft Forms 2.0 na janela Solution Explorer do Visual Studio .NET. (é possível que você encontre duas referências à biblioteca na lista. Nesse caso, selecione a primeira). Clique em Select e, em seguida, clique em OK para descartar a caixa de diálogo. Role até o início do arquivo de código e adicione a seguinte instrução, dependendo da linguagem selecionada (Visual Basic .NET ou C#):

 

' Visual Basic .NET

Imports MSForms = Microsoft.Vbe.Interop.Forms

 

// C#

using MSForms = Microsoft.Vbe.Interop.Forms;

 

Adicione a declaração a seguir imediatamente após as declarações para as variáveis ThisApplication e ThisWorkbook:

 

' Visual Basic .NET

Private WithEvents button As MSForms.CommandButton

 

// C#

private MSForms.CommandButton button;

 

Em seguida, adicione o seguinte procedimento à classe:

 

' Visual Basic .NET

Private Sub button_Click() Handles button.Click

  RetrieveData()

End Sub

 

// C#

private void button_Click()

{

  RetrieveData();

}

Adicione esse código ao procedimento ThisWorkbook_Open da classe:

' Visual Basic .NET

button = DirectCast(FindControl("cmdChart"), _

    MSForms.CommandButton)

 

// C#

button = (MSForms.CommandButton) FindControl("cmdChart");

button.Click +=new

  MSForms.CommandButtonEvents_ClickEventHandler(button_Click);


Salve e, em seguida, execute o projeto. Verifique se o clique no botão da planilha carrega os dados do SQL Server e os exibe na planilha, conforme mostrado na
Figura 5. Quando terminar, feche o Excel. Se quiser, você pode salvar a pasta de trabalho.


image005.gif
Figura 5 Exibição de dados

 

De volta ao Visual Studio .NET, adicione o procedimento da Listagem 8 à classe, que excluirá o gráfico se este já existir. Como você pode notar ao investigar esse código, muitos métodos no Excel (e no Word) retornam tipos Object, o que significa que você precisará ajustar cuidadosamente os valores de retorno para os tipos corretos. (Você pode evitar esse inconveniente no Visual Basic .NET deixando de usar Option Strict On, mas esse procedimento não é recomendado. Com ele, é muito fácil criar um código que seja compilado mas que não execute corretamente) .

 

Listagem 8 Exclui o gráfico <0}

Visual Basic .NET

Private Sub DeleteExistingChart()

  Try

    Dim ws As Excel.Worksheet = _

     DirectCast(ThisApplication.Worksheets(1), Excel.Worksheet)

    Dim charts As Excel.ChartObjects = _

     DirectCast(ws.ChartObjects, Excel.ChartObjects)

 

    If charts.Count > 0 Then

      DirectCast(charts.Item(1), Excel.ChartObject).Delete()

    End If

  Catch ex As Exception

    MessageBox.Show(ex.Message, ex.Source)

  End Try

End Sub

 

C#

private void DeleteExistingChart()

{

  try

  {

    Excel.Worksheet ws =

      (Excel.Worksheet)ThisApplication.Worksheets[1];

    Excel.ChartObjects charts =

      (Excel.ChartObjects)ws.ChartObjects(Type.Missing);

 

    if (charts.Count > 0)

    {

      ((Excel.ChartObject)charts.Item(1)).Delete();

    }

  }

  catch (Exception ex)

  {

    MessageBox.Show(ex.Message, ex.Source);

  }

}

 

Em seguida, adicione o procedimento da Listagem 9 à classe, o que criará o gráfico. Observe a diferença entre o código C# e o código Visual Basic .NET correspondente. Muitos métodos do Excel aceitam parâmetros opcionais que, conforme mencionado anteriormente, não são aceitos pelo C#. Para contornar essa limitação, o código C# precisa passar o campo Type.Missing para cada parâmetro opcional que represente um tipo de referência. (No caso dos parâmetros opcionais de tipo de valor, o código C# precisa passar o valor padrão real). No método DeleteExistingChart, o método WorkSheet.ChartObjects permite que você especifique um índice do gráfico que deseja recuperar ou nenhum parâmetro para recuperar uma coleção ChartObjects. No C#, para recuperar a coleção inteira, você precisa passar Type.Missing para o parâmetro opcional. A mesma regra é válida quando você chama o método Charts.Add no método CreateChart. De modo geral, para qualquer método que requeira parâmetros de tipo de referência opcionais, os desenvolvedores de C# podem passar Type.Missing. Modifique o manipulador de eventos Click para o comando CommandButton, adicionando uma chamada ao procedimento CreateChart:

 

Listagem 9 Cria o gráfico <0}

Visual Basic .NET

Private Sub CreateChart()

  Try

    DeleteExistingChart()

 

    Dim cht As Excel.Chart = _

     DirectCast(ThisApplication.Charts.Add(), Excel.Chart)

    cht.ChartType = Excel.XlChartType.xl3DBarClustered

    cht.Location(Excel.XlChartLocation.xlLocationAsObject, _

     "Sheet1")

 

    cht = ThisApplication.ActiveChart

    cht.HasLegend = False

    cht.SetSourceData( _

     ThisApplication.Range("A5").CurrentRegion, _

     Excel.XlRowCol.xlColumns)

    DirectCast(cht.ChartGroups(1), Excel.ChartGroup). _

     VaryByCategories = True

 

  Catch ex As Exception

    MessageBox.Show(ex.Message, ex.Source)

  End Try

End Sub

 

C#

private void CreateChart()

{

  try

  {

    DeleteExistingChart();

 

    Excel.Chart cht =      

      (Excel.Chart)ThisApplication.Charts.Add(

      Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    cht.ChartType = Excel.XlChartType.xl3DBarClustered;

    cht.Location(Excel.XlChartLocation.xlLocationAsObject,

      "Sheet1");

 

    cht = ThisApplication.ActiveChart;

    cht.HasLegend = false;

    cht.SetSourceData(ThisApplication.

      get_Range("A5", Type.Missing).CurrentRegion,      

      Excel.XlRowCol.xlColumns);

    ((Excel.ChartGroup)cht.ChartGroups(1)).VaryByCategories = true;

  }

  catch (Exception ex)

  {

    MessageBox.Show(ex.Message, ex.Source);

  }

}


Por fim, salve e execute o projeto, clique no botão e verifique se conseguiu carregar os dados e criar o gráfico. Quando terminar, saia do Excel (se desejar, salve a pasta de trabalho). Se você seguiu cuidadosamente este procedimento, deve ter criado um gráfico que se assemelha ao da Figura 6. Durante o procedimento, você aprendeu a tirar proveito de vários objetos do Excel, bem como a vincular eventos aos controles incorporados nos documentos. Você também conheceu algumas das diferenças de codificação entre o Visual Basic .NET e o C# (relacionadas a objetos do Office). Embora esse exemplo não aproveite os menus e barras de ferramentas disponíveis no Office, você poderá trabalhar com esses itens de forma programática dentro de seu código gerenciado.



image006.gif
Figura 6 Gráfico de Barras

 

É claro, você ainda não viu como a segurança de acesso ao código pode afetar a capacidade de execução de seu projeto. Quando você criou seu projeto, o Visual Studio .NET adicionou uma política de acesso ao código que permitia executar a montagem na localização atual em que ela se encontrasse. Copiá-la para outro local no disco rígido pode fazer com que o código falhe. Para verificar como funciona a segurança de acesso ao código, vá para o Visual Studio .NET e mude a propriedade Assembly Link Location para qualquer outra localização. Agora, crie novamente o aplicativo e execute o projeto. Você verá que, embora o código compile corretamente e que o Visual Studio .NET carregue o Excel junto com a pasta de trabalho, o código não será executado. A Figura 7 mostra o alerta que você receberá. Redefina a propriedade Assembly Link Location e repita as etapas anteriores para verificar se o seu código é executado novamente depois que você redefiniu o nome da pasta.


image007.gif

Figura 7 Mensagem de Alerta

 

A segurança de acesso ao código garante que você que não possa executar sua montagem a partir de um local diferente daqueles para os quais foram concedidas permissões para execução. Por padrão, o Visual Studio .NET configura uma política de acesso ao código que permite executar o código a partir do local em que ele foi desenvolvido. Se você mudar o local, o código não será executado. Uma análise mais abrangente sobre distribuição e opções de segurança (assuntos inexoravelmente interligados) demandaria um artigo completo. Por enquanto, saiba apenas que, para distribuir seus aplicativos para os computadores de outros usuários, você precisará definir uma política de segurança que permita que seu código seja executado. O comportamento é o mesmo, tanto para as montagens (assemblies) criadas por meio do Visual Studio Tools for Office como para montagens baixadas na Internet ou em uma intranet — a montagem (assembly) é descarregada no cache de download do usuário e executada nesse local. As mesmas questões de segurança se aplicam aos dois tipos de montagens.

 

Conclusões

 

O uso do Visual Studio Tools for Office exigirá algum conhecimento dos modelos de objeto do Office, um bom conhecimento a respeito de questões relacionadas à distribuição e segurança do .NET e alguma necessidade comercial. Por fim, os desenvolvedores poderão usufruir todos os avanços do CLR e do .NET Framework sem sair dos aplicativos do Office. Com esses novos aplicativos, os usuários terão a impressão de estar simplesmente executando o Word ou o Excel. As atualizações podem ser executadas automaticamente, sem interferência do usuário, e o código não confiável não poderá ser executado sem o conhecimento de um administrador. Esses são apenas alguns dos recursos que contribuem para a robustez, a segurança e a flexibilidade do Visual Studio Tools for Microsoft Office System.