Programmation d’applications Office avec Visual C#

Ken Getz
MCW Technologies, LLC
Traduit par Bernard Opic, MVP

Septembre 2005

Concerne :
Microsoft Visual Basic 2005
Microsoft Visual Basic for Applications
Microsoft Visual C# 2005
Microsoft Visual Studio 2005
Microsoft Visual Studio 2005 Tools for the Microsoft Office System
Microsoft Office Excel 2003
Microsoft Office Word 2003

Résumé : Découvrez les problèmes dont les développeurs C# doivent être conscients lors de l’utilisation de Visual Studio 2005 Tools for Office pour créer des applications Word et Excel, y compris comment utiliser des méthodes et propriétés VBA. Consultez des exemples afin de comparer le code Visual Basic et le code C#. (17 pages imprimées)

Remarque : Cet article est une version préliminaire de la documentation et pourra faire l'objet de modifications dans les versions futures. Les versions bêta de Microsoft Visual Studio 2005 Tools for the Microsoft Office System sont incluses dans les versions bêta de Microsoft Visual Studio 2005.

Consultez l'article en anglais 

Sur cette page

Introduction Introduction
Transmission de paramètres à Word Transmission de paramètres à Word
Gestion de paramètres facultatifs avec Excel Gestion de paramètres facultatifs avec Excel
Gestion de paramètres facultatifs avec Word Gestion de paramètres facultatifs avec Word
Gestion de propriétés paramétrées avec Excel Gestion de propriétés paramétrées avec Excel
Utilisation de méthodes d’accès dans Word Utilisation de méthodes d’accès dans Word
Liaison tardive dans Word Liaison tardive dans Word
Conclusion Conclusion
Ressources complémentaires Ressources complémentaires
À propos de l’auteur À propos de l’auteur

Introduction

Microsoft Visual Studio 2005 Tools for the Microsoft Office System (Visual Studio 2005 Tools for Office) vous permet de créer des applications riches basées sur Microsoft Office 2003 dans Microsoft Visual Studio 2005, en utilisant la puissance de Microsoft Office Word 2003 et de Microsoft Office Excel 2003. Vous pouvez tirer parti de toutes les fonctionnalités offertes par les modèles d’objet Word et Excel à partir de Microsoft Visual Basic 2005 ou Microsoft Visual C#. Biens que les développeurs Visual Basic puissent utiliser facilement les objets exposés par les modèles d’objet, les développeurs C# peuvent être confrontés à des défis. En raison de l’historique et de la conception originale des modèles d’objet Office, les membres de leurs objets ont été créés dans le but d’être appelés par du code Microsoft Visual Basic for Applications (VBA). Par conséquent, les diverses propriétés et méthodes tirent parti des fonctionnalités offertes par VBA, mais qui ne correspondent pas aux fonctionnalités C#. Ce document étudie les problèmes impliqués dans l’utilisation de méthodes et propriétés VBA pour Word et Excel, et contient des exemples qui comparent le code Visual Basic et le code Visual C# correspondant.

Lors de l’utilisation de Visual Studio 2005 Tools for Office, les développeurs C# doivent être conscients de problèmes que les développeurs VBA ou Visual Basic n’ont pas besoin d’envisager. En particulier, la liste suivante décrit les problèmes étudiés en détail dans ce document :

  • Passage de paramètres. Par défaut, VBA s’attend au passage des paramètres par référence. Par défaut, Visual Basic et C# transmettent tous deux les paramètres par valeur. VBA et Visual Basic sont flous sur cette distinction et l’assembly interop primaire d’Excel accepte les paramètres passés par valeur, même s’il a reçu à l’origine toutes les valeurs du code VBA par référence. L’assembly interop primaire de Word n’est pas aussi accomodant ; ses paramètres (à quelques exceptions près) doivent être transmis par référence. Visual Basic peut gérer cela sans travail supplémentaire, contrairement à C#.

  • Paramètres facultatifs. VBA et Visual Basic prennent en charge les paramètres facultatifs sur d’autres appels de méthode, contrairement à C#. De nombreuses méthodes Office autorisent 20, 30 ou plus de paramètres facultatifs ; par conséquent, les développeurs C# doivent écrire plus de code que les développeurs Visual Basic pour obtenir le même effet.

  • Propriétés paramétrées. VBA et Visual Basic prennent en charge les propriétés qui acceptent des paramètres, jouant ainsi le rôle de fonctions en lecture seule. Dans la mesure où C# ne permet pas cela, vous devez utiliser des méthodes d’accès pour définir et extraire les valeurs des propriétés qui acceptent des paramètres. Les mêmes problèmes s’appliquent à Word lors de l’utilisation de méthodes qui acceptent des paramètres Variant.

  • Liaison tardive. VBA peut déterminer les propriétés des objets lors de l’exécution, permettant ainsi la liaison tardive entre le code et les objets proprement dits. Word tire parti de ce comportement dans sa classe Dialogue. Visual Basic peut uniquement gérer la liaison tardive avec sa directive Option Strict Off. Les développeurs C# et les développeurs Visual Basic qui utilisent Option Strict On ne peuvent pas tirer parti d’une liaison tardive et doivent utiliser des moyens alternatifs d’interagir par programmation avec la classe Dialog de Word.

Pour exposer la fonctionnalité de modèle d’objet Office pour les développeurs Visual Basic et C#, Microsoft a créé un ensemble d’assemblys interop primaires. Visual Studio 2005 Tools for Office utilise des assemblys interop primaires individuels pour Word et Excel, et chacun présente ses propres comportements distincts pour les développers Visual Basic et C#. La suite de cet article étudie chacun de ces problèmes, en illustrant la façon dont les assemblys interop primaires de Word et Excel gèrent chaque cas, avec des exemples de code qui illustrent la façon dont les développeurs C# peuvent gérer chacune des situations décrites ici.

Transmission de paramètres à Word

Les objets fournis par le modèle d’objet de Word attendent le passage des paramètres par référence. Bien que cela ne pose pas de problème pour les développeurs Visual Basic, en tant que développeur C#, vous devez faire particulièrement attention lors du passage des paramètres aux méthodes Word. Chaque méthode fournie par Word s’attend à ce que chacune de ses méthodes soit passée via le mot-clé ref, et vous pouvez uniquement passer les valeurs lvalue (c'est-à-dire les éléments qui apparaissent à gauche d’une affectation) par référence. Vous ne pouvez pas passer de valeurs littérales aux méthodes Word à partir de code C#.

À titre d’exemple, la procédure suivante crée une nouvelle fenêtre à partir d’une fenêtre existante, puis elle affiche les deux fenêtres sous forme de mosaïque. Le fragment de code suivant illustre les versions Visual Basic et C# du code.

' Visual Basic
Friend Sub CreateNewWindowAndTile()
	' Create a new window from the active document.
	Dim wnd As Word.Window = _
		Application.ActiveWindow.NewWindow
	' Tile the two windows.
	Application.Windows.Arrange( _
		Word.WdArrangeStyle.wdTiled)
End Sub

// C#
public void CreateNewWindowAndTile() 
{
	// Create a new window from the active document.
	Word.Window wnd =  Application.ActiveWindow.NewWindow();
	
	// Tile the two windows.
	Object value = Word.WdArrangeStyle.wdTiled;
	Application.Windows.Arrange(ref value);
}

Dans cet exemple, le code crée une variable Objet et lui affecte une valeur. Le code transmet ensuite cette variable, via le mot-clé ref, à la méthode Arrange. Vous devez appeler chaque méthode de cette façon dans Word ; chaque paramètre doit être transmis avec le mot-clé ref et doit transmettre une variable contenant la valeur réelle.

Remarque : Les développeurs C# qui ciblent Excel n’ont pas besoin d’actions particulières. L’assembly interop primaire d’Excel a été créé de sorte que les valeurs littérales passées par valeur aux divers membres soient gérées correctement.

Gestion de paramètres facultatifs avec Excel

Comme dans les autres langages prenant en charge les paramètres facultatifs, les paramètres facultatifs dans VBA doivent apparaître à la fin de la liste d’appel d’une méthode et, une fois un paramètre marqué comme facultatif, les autres paramètres doivent également être facultatifs. De nombreuses méthodes fournies par Excel acceptent des paramètres facultatifs ; les développeurs Visual Basic peuvent ignorer ces paramètres pour accepter leurs valeurs par défaut .

Par exemple, la méthode Workbooks.Add vous permet de spécifier un paramètre facultatif indiquant le modèle à utiliser. Vous pouvez spécifier le nom d’un fichier de modèle ou un membre des constantes XlWBATemplate qui indique le type de feuille que le classeur doit contenir, ou vous pouvez ne fournir aucune valeur (en créant un classeur avec des feuilles vides). Si vous choisissez de ne fournir aucune valeur (en acceptant ainsi le comportement par défaut), vous pouvez écrire du code tel que le suivant.

' Visual Basic
Dim wb As Excel.Workbook = Application.Workbooks.Add()

Un code similaire en C# n’est en revanche pas compilé, en raison du paramètre manquant. Pour résoudre le problème, transmettez le champ System.Type.Missing pour le paramètre facultatif. Si vous créez un projet en utilisant Visual Studio 2005 Tools for Office, vous pouvez tirer parti de la variable prédéfinie nommée missing, laquelle contient la valeur System.Type.Missing, afin de vous éviter la saisie.

// C#
Excel.Workbook wb = Application.Workbooks.Add(System.Type.Missing);
// or
Excel.Workbook wb = Application.Workbooks.Add(missing);

System.Type.Missing est utile pour les développeurs Visual Basic lors de l’utilisation de la réflexion pour créer de manière dynamique des appels de méthodes acceptant des paramètres facultatifs. Il indique que vous souhaitez utiliser la valeur par défaut pour le paramètre spécifié. Vous pouvez bien sûr lire la documentation Excel, trouver vous-même la valeur par défaut et la transmettre explicitement.

Si la méthode Excel nécessite plusieurs paramètres facultatifs, vous pouvez vous apercevoir que l’écriture de code en C# nécessite plus d’efforts que l’écriture du code Visual Basic correspondant. Par exemple, les fragments suivants comparent le code dans Visual Basic et dans C#. La méthode Workbooks.Open vous permet de spécifier plusieurs paramètres facultatifs, indiquant le comportement du classeur que vous ouvrez.

' Visual Basic
Dim wb As Excel.Workbook = _
	Application.Workbooks.Open("C:\YourPath\YourWorkbook.xls")
	
// C#
Excel.Workbook wb = Application.Workbooks.Open( 
	"C:\YourPath\YourWorkbook.xls", 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing);

Vous pouvez uniquement transmettre la valeur System.Type.Missing pour les paramètres qui acceptent des types de référence. Pour les paramètres de type de valeur, vous devez déterminer la valeur par défaut réelle et la transmettre à la place. La méthode Range.Sort, par exemple, accepte un grand nombre de valeurs énumérées en tant que paramètres. En tant que types de valeurs, ces paramètres nécessitent que vous spécifiiez exactement la valeur à transmettre.

' Visual Basic
' rng is a variable of type Excel.Range.
rng.Sort(rng, _
	Orientation:=Excel.XlSortOrientation.xlSortColumns)

// C#
// rng is a variable of type Excel.Range.
rng.Sort(rng, Excel.XlSortOrder.xlAscending, 
	missing, missing, Excel.XlSortOrder.xlAscending, 
	missing, Excel.XlSortOrder.xlAscending, 
	Excel.XlYesNoGuess.xlNo, missing,missing, 
	Excel.XlSortOrientation.xlSortColumns, 
	Excel.XlSortMethod.xlPinYin, 
	Excel.XlSortDataOption.xlSortNormal, 
	Excel.XlSortDataOption.xlSortNormal, 
	Excel.XlSortDataOption.xlSortNormal);

Vous vous demandez peut-être pourquoi C# ne prend pas en charge les paramètres facultatifs. À l’inverse, C# et Visual Basic prennent tous deux en charge la surcharge de méthode, qui vous permet de créer plusieurs « versions » d’une même procédure, en transmettant différents jeux de paramètres. La restriction principale sur les méthodes surchargées est que la signature de paramètre de chaque méthode individuelle doit être différente ; le compilateur doit pouvoir déterminer quelle version de la procédure vous appelez, uniquement en fonction des paramètres avec lesquels vous l’appelez. Cette fonctionnalité est plus puissante et plus flexible que la prise en charge des paramètres facultatifs par VBA.

Visual Basic prend en charge les paramètres facultatifs, car Visual Basic et VBA incluent cette fonctionnalité depuis plusieurs versions. En revanche, pour le code que vous écrivez aujourd’hui, il est préférable d’utiliser la surcharge plutôt que les paramètres facultatifs. Pour obtenir le meilleur code possible, les concepteurs de C# ont utilisé la surcharge plutôt que la prise en charge des paramètres facultatifs. Pour le codage général, vous ne remarquerez probablement jamais que cette fonctionnalité est absente de C#. L’absence des paramètres facultatifs dans C# est perceptible uniquement lorsque vous programmez par rapport à des modèles d’objets (tels que ceux fournis par Office), dans lesquels de nombreux membres tirent parti des paramètres facultatifs et qui utilisent un grand nombre de ces paramètres.

Dans certains cas, vous pouvez trouver utile de créer des méthodes wrapper autour des méthodes intégrées. Par exemple, la classe Excel WorksheetFunction expose un grand nombre de fonctions, destinées à l’origine à une utilisation dans des feuilles de calcul, qui prennent en charge les fonctions statistiques, financières et autres types de fonctions liées aux feuilles de calcul. La plupart des méthodes de la classe WorksheetFunction acceptent 30 paramètres, avec un ou deux paramètres obligatoires. L’appel de ces méthodes à partir de C# est complexe, comme vous pouvez le voir dans l’exemple suivant, qui appelle la méthode WorksheetFunction.Min sur un objet Range Excel spécifié.

' Visual Basic
MessageBox.Show(Application.WorksheetFunction.Min(rng))
MessageBox.Show(Application.WorksheetFunction.Max(rng))

// C#
MessageBox.Show(Application.WorksheetFunction.Min(rng, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing).ToString());
MessageBox.Show(Application.WorksheetFunction.Max(rng, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing, missing, missing, missing, 
	missing).ToString());

Pour les cas tels que celui-ci, vous pouvez envisager de créer une méthode wrapper pouvant appeler la méthode existante, ce qui vous évite d’avoir à compter tous les paramètres facultatifs et à en effectuer le suivi.

// C#
private delegate double WorksheetFunctionDelegate(
	object value1, object value2, object value3,
	object value4, object value5, object value6,
	object value7, object value8, object value9,
	object value10, object value11, object value12,
	object value13, object value14, object value15,
	object value16, object value17, object value18,
	object value19, object value20, object value21,
	object value22, object value23, object value24,
	object value25, object value26, object value27,
	object value28, object value29, object value30);

private double CallWorksheetFunction(
	WorksheetFunctionDelegate func,
	Object value,
	params object[] values)
	{
	// All the values except the first one.
	object[] overflowParameters = new object[29];
	
    values.CopyTo(overflowParameters, 0);
    for (int i = values.Length;  i ? overflowParameters.Length;  i++)
    {
		overflowParameters[i] = missing;
	}
	
	return func (
		value,
		overflowParameters[0], overflowParameters[1], 
		overflowParameters[2], overflowParameters[3], 
		overflowParameters[4], overflowParameters[5],
		overflowParameters[6], overflowParameters[7], 
		overflowParameters[8], overflowParameters[9], 
		overflowParameters[10], overflowParameters[11],
		overflowParameters[12], overflowParameters[13], 
		overflowParameters[14], overflowParameters[15], 
		overflowParameters[16], overflowParameters[17],
		overflowParameters[18], overflowParameters[19], 
		overflowParameters[20], overflowParameters[21], 
		overflowParameters[22], overflowParameters[23],
		overflowParameters[24], overflowParameters[25], 
		overflowParameters[26], overflowParameters[27], 
		overflowParameters[28]);
}

Ensuite, pour appeler une fonction de feuille de calcul qui accepte un paramètre obligatoire unique, vous pouvez écrire du code tel que celui-ci.

WorksheetFunctionDelegate func = 
new WorksheetFunctionDelegate(
	Application.WorksheetFunction.Min);
	
MessageBox.Show( 
	CallWorksheetFunction(func, rng, missing).ToString());

Vous pouvez développer cette fonctionnalité afin de prendre en charge plusieurs paramètres obligatoires, et vous pouvez également tirer parti du mot-clé C# params.

Astuce : Les exemples inclus dans la documentation de Visual Studio 2005 Tools for Office comprennent des méthodes d’aide pour certains membres couramment utilisés. Dans les exemples, recherchez les régions ou classes dont le titre contient le mot « helper ». Vous pouvez utiliser ces méthodes au début de votre ensemble de méthodes afin de faciliter l’appel des méthodes fournies par Word et Excel.

Gestion de paramètres facultatifs avec Word

L’utilisation de paramètres facultatifs dans Word nécessite de tenir compte des mêmes problèmes que dans le cas d’Excel. Vous pouvez écrire du code tel que le fragment suivant, lequel compare l’ouverture d’un document Word en Visual Basic avec le même code en C#.

' Visual Basic
Application.Documents.Open("C:\Test\MyNewDocument.doc")

// C#
Object filename = @"C:\Test\MyNewDocument.doc";

Application.Documents.Open(ref filename, 
	ref missing, ref missing, ref missing, 
	ref missing, ref missing, ref missing, 
	ref missing, ref missing, ref missing, 
	ref missing, ref missing, ref missing, 
	ref missing, ref missing, ref missing);

En général, l’appel de méthodes Word à partir de code C# est plus complexe que l’appel de méthodes Excel similaires, car vous devez passer la plupart des paramètres par référence. Vous pouvez trouver utile, si vous devez fréquemment appeler des méthodes de cette façon, de tirer parti de la variable missing créée par les modèles de projet Visual Studio 2005 Tools for Office.

Vous devez souvent faire référence à des plages dans Word. Dans Visual Basic, le fait de spécifier la propriété Range sans aucun paramètre renvoie la plage entière ; vous n’avez pas besoin de spécifier les valeurs de début et de fin si vous souhaitez travailler avec tout le contenu du document. Cela n’est bien sûr pas vrai pour les développeurs C#, car en C# vous devez toujours passer les valeurs pour tous les paramètres facultatifs. En C#, vous pouvez passer System.Type.Missing pour tous les paramètres facultatifs afin d’utiliser les valeurs par défaut, comme dans le fragment de code suivant.

' Visual Basic
Dim rng As Word.Range = ThisDocument.Range()
rng.Select()

// C#
Word.Range rng = ThisDocument.Range(ref missing, ref missing);
rng.Select();

Gestion de propriétés paramétrées avec Excel

De nombreuses propriétés d’Excel vous permettent de transmettre des paramètres, indiquant l’instance spécifique de la propriété avec laquelle vous souhaitez interagir. Par exemple, vous pouvez spécifier un objet Range en transmettant une plage nommée en tant que chaîne. Vous pouvez également spécifier une plage en transmettant le nom de la cellule supérieure gauche et le nom de la cellule inférieure droite. Vous devez spécifier au moins un paramètre (plage nommée), mais vous pouvez en spécifier deux (les noms des deux cellules). Dans chaque cas, la propriété renvoie un objet Excel.Range correspondant à la plage spécifiée.

En Visual Basic, vous pouvez écrire du code tel que le suivant afin de spécifier et d’extraire une référence à un objet Range.

' Visual Basic
Dim rng1 As Excel.Range = Application.Range("TotalSales")
' or
Application.Range("A1", "B2").Font.Bold = True

C# n’autorise pas ce type de référence de propriété ; en C#, les références de propriété peuvent 
uniquement comporter des paramètres si le paramètre spécifie un index. Pour contourner cette 
limitation, l’assembly interop primaire d’Excel fournit des méthodes get/set d’accès pour 
chaque propriété paramétrée. Par exemple, pour extraire une référence à un objet Excel Range en C#, 
vous pouvez réécrire le code précédent, comme dans l’exemple suivant.

// C#
Excel.Range rng1 = 
	Application.get_Range("TotalSales", missing);
// or
Application.get_Range("A1", "B2").Font.Bold = true;

Notez que vous devez transmettre deux paramètres à la méthode get_Range, car la propriété Application.Range dans Excel nécessite un paramètre avec un deuxième paramètre facultatif.

Les mêmes problèmes s’appliquent à la propriété Offset d’un objet Range ; cette propriété paramétrée vous permet d’extraire une plage d’un nombre spécifié de lignes et/ou de colonnes à partir du coin supérieur gauche de la plage. Les fragments suivants illustrent l’extraction de la propriété en Visual Basic et C#.

' Visual Basic
Private Sub ListRecentFiles()
	Dim i As Integer
	Dim rng As Excel.Range = DirectCast( _
		Application.Range("RecentFiles"). _
		Cells(1, 1), Excel.Range)
	For i = 1 To Application.RecentFiles.Count
		rng.Offset(i - 1, 0).Formula = _
		  Application.RecentFiles(i).Name
	Next
End Sub

// C#
private void ListRecentFiles()
{
	Excel.Range rng = (Excel.Range)Application.
		get_Range("RecentFiles", missing).Cells[1, 1];
	
	for (int i = 1; i ?= Application.RecentFiles.Count; i++)
	{
		rng.get_Offset(i - 1, 0).Formula = 
			Application.RecentFiles[i].Name;
	} 
}

Astuce : La propriété Range.Cells ressemble à une propriété paramétrée, mais elle n’en est pas une. La propriété Cells renvoie un tableau et vous indexez le tableau en transmettant des valeurs pour les numéros de ligne et de colonne.

Si vous souhaitez utiliser les diverses boîtes de dialogue de gestion des fichiers offertes par Excel, vous devez de nouveau utiliser la méthode d’accès get_FileDialog. Étant donné que la propriété Application.FileDialog comporte un paramètre, elle n’est pas directement disponible dans C#. Pour éviter cette limitation, vous pouvez appeler get_FileDialog, comme dans le fragment de code suivant.

' Visual Basic
With Application.FileDialog( _
	Office.MsoFileDialogType.msoFileDialogFolderPicker)
	If .Show ?? 0 Then
		Application.Range("FolderPickerResults"). _
			Formula = .SelectedItems.Item(1)
	End If
End With

// C#
dlg = Application.get_FileDialog(
	Office.MsoFileDialogType.msoFileDialogFolderPicker);
if (dlg.Show() != 0)
{
	Application.get_Range("FolderPickerResults", missing).
		Formula = dlg.SelectedItems.Item(1);
}

La propriété Excel Range.Value nécessite également un traitement spécial. Cette propriété accepte un paramètre, mais C# ne peut pas accepter de paramètres lors de la définition ou de l’extraction des valeurs de propriétés. Dans ce cas, vous devez utiliser la propriété Value2, une variante de la propriété d’origine qui n’attend pas de paramètre. Par exemple, les fragments de code suivants illustrent des codes équivalents en Visual Basic et en C#.

' Visual Basic
Dim rng As Excel.Range = Application.Range("A1")
rng.Value = "Some Value"

// C#
Excel.Range rng = Application.get_Range("A1", missing);
rng.Value2 = "Some Value";

Cet article a illustré des exemples de l’utilisation des propriétés Range, Offset, Value et FileDialog ; il en existe beaucoup d’autres. Si vous ne pouvez pas extraire ou définir directement la valeur d’une propriété, déterminez si la propriété attend un paramètre et, si tel est le cas, recherchez les méthodes d’accès correspondantes, ou une propriété alternative.

Utilisation de méthodes d’accès dans Word

Bien que Word n’utilise généralement pas de propriétés paramétrées (comme le fait Excel), il existe toujours des cas dans lesquels vous programmez Word et devez utiliser les méthodes d’accès get_ et set_. Word gère ces méthodes différemment d’Excel ; en revanche, dans ce cas, les méthodes d’accès sont masquées. Vous ne les trouvez pas dans la liste des méthodes disponibles lorsque vous tapez, ni dans la fenêtre Explorateur d’objets. Vous devez savoir qu’elles se trouvent là, et les utiliser.

Par exemple, la propriété Style dans Word renvoie et accepte une valeur Variant, et plutôt que de convertir cette valeur en type Object pour une utilisation en C#, vous devez appeler les méthodes get_Style et set_Style afin d’éviter ce problème. Vous pouvez écrire du code tel que le suivant afin de définir le style d’un paragraphe particulier.

' Visual Basic
Dim rng As Word.Range = _
	ThisDocument.Paragraphs(1).Range
rng.Style = "Normal Indent"

// C#
Word.Range rng = ThisDocument.Paragraphs[1].Range;
Object style = "Normal Indent";
rng.set_Style(ref style);

Comme avec les autres méthodes dans Word, vous devez transmettre le nom du style (ou l’objet Style) par référence, ce qui nécessite l’utilisation d’une variable contenant la valeur souhaitée. Vous pouvez utiliser du code similaire pour extraire la propriété Style d’une plage, en appelant la méthode get_Style.

La méthode Item dans Word constitue un défi similaire. Plutôt que de vous autoriser à transmettre un paramètre Variant à la méthode, l’assembly interop primaire de Word expose une méthode get_Item qui accepte un paramètre Object par référence. Si vous souhaitez enregistrer un document particulier dans la collection Documents actuelle, vous pouvez écrire du code tel que le suivant.

' Visual Basic
Application.Documents("MyNewDocument.doc").Save()

// C#
Object file = "MyNewDocument.doc";
Application.Documents.get_Item(ref file).Save();

La règle est simple : pour toute méthode qui accepte un paramètre Variant, ou toute propriété paramétrée, vous devez partir du principe qu’une méthode d’accès (ou une paire de méthodes) est disponible.

Liaison tardive dans Word

Étant donné que le modèle de programmation de Word a eu une longue carrière, certaines de ses techniques ne sont pas adaptées à un monde fortement typé et orienté objet. La classe Dialog en est un exemple. Cette classe offre un ensemble de base de propriétés et de méthodes, ainsi qu’un tableau contenant toutes les boîtes de dialogue disponibles que vous voyez dans l’interface utilisateur de Word. Vous pouvez afficher n'importe quelle boîte de dialogue, ou simplement utiliser les diverses propriétés exposées par les boîtes de dialogue afin d’affecter le comportement de Word. Par exemple, utilisez la boîte de dialogue Mise en page pour configurer la largeur et la hauteur des pages du document en cours.

Le problème est que le modèle d’objet Word ne contient pas réellement d’informations sur chaque boîte de dialogue spécifique. Il existe de nombreuses propriétés associées aux boîtes de dialogue, et plutôt que de coder en dur les propriétés dans la bibliothèque de types (et maintenant l’assembly interop primaire) de Word, le modèle d’objet crée les propriétés « à la volée » lors du chargement de chaque boîte de dialogue. Chaque contrôle de chaque boîte de dialogue comporte une propriété correspondante et vous pouvez définir ou extraire la valeur de chaque contrôle par programmation. En VBA, cela ne posait pas de problème. Bien que vous n’obteniez pas de conseils Microsoft IntelliSense pour vous aider à taper le code, vous pouvez faire référence à n'importe laquelle des diverses propriétés ; votre code est quand même compilé.

En Visual Basic (avec Option Strict activé) ou en C#, cela n’est pas vrai. Dans les langages fortement typés, vous ne pouvez pas attendre du compilateur qu’il ignore les propriétés disponibles jusqu’à l’exécution si vous prévoyez d’utiliser la syntaxe Object.Property standard lorsque vous écrivez le code. Par exemple, le code suivant fonctionne en Visual Basic avec Option Strict Off, mais le code C# correspondant n’est pas compilé.

' Visual Basic with Option Strict Off
Dim dlg As Word.Dialog
dlg = Application.Dialogs( _
	Word.WdWordDialog.wdDialogFilePageSetup)
dlg.PageWidth = 3.3
dlg.PageHeight = 6

// C# (This does not compile.)
dlg = Application.Dialogs
	[Word.WdWordDialog.wdDialogFilePageSetup];

dlg.PageWidth = 3.3;
dlg.PageHeight = 6;

Il existe deux options pour l’utilisation de ces propriétés. Vous pouvez soit créer un fichier Visual Basic incluant le paramètre Option Strict Off au début et placer votre code dans ce fichier, soit trouver un moyen d’effectuer une liaison tardive. Les développeurs C# et Visual Basic peuvent tirer parti de l’espace de noms System.Reflection, ce qui permet d’exécuter le code afin de déterminer les membres disponibles d’un type spécifié et d’effectuer un type de liaison tardive. Étant donné les informations sur les membres, votre code peut utiliser l’espace de noms System.Reflection afin d’appeler la procédure de définition de propriété, par exemple pour définir la valeur d’une propriété.

Pour gérer les objets avec liaison tardive dans Visual Basic ou C#, vous pouvez ajouter un wrapper simple avec la capacité de l’espace de noms System.Reflection à définir une propriété d’un objet dont les fonctionnalités ne sont pas connues lors de l’exécution.

' Visual Basic
Private Sub InvokeHelper(ByVal dlg As Word.Dialog, _
	ByVal member As String, ByVal dlgValue As Object)
	Dim dlgType As Type = GetType(Word.Dialog)
	dlgType.InvokeMember(member, _
	 BindingFlags.SetProperty Or _
	 BindingFlags.Public Or BindingFlags.Instance, _
	 Nothing, dlg, New Object() {dlgValue})
End Sub

// C#
private void invokeHelper(Word.Dialog dlg, string member, Object dlgValue) 
{ 
	// Assumes a using statement in the file:
	// using System.Reflection;
	Type dlgType = typeof(Word.Dialog); 
	dlgType.InvokeMember(member, 
	BindingFlags.SetProperty | 
	BindingFlags.Public | 
	BindingFlags.Instance, 
	null, dlg, new object[] {dlgValue.ToString()}); 
}

Pour tirer parti de la méthode InvokeHelper, transmettez l’objet Dialog, la propriété à définir et la valeur de la propriété.

' Visual Basic
Public Sub HiddenPageSetupDialog()
	Dim dlg As Word.Dialog
	dlg = Application.Dialogs( _
		Word.WdWordDialog.wdDialogFilePageSetup)

	InvokeHelper(dlg, "PageWidth", 3.3)
	InvokeHelper(dlg, "PageHeight", 6)
	dlg.Execute()
End Sub

// C#
public void HiddenPageSetupDialog()
{
	Word.Dialog dlg;
	dlg = Application.Dialogs[
		Word.WdWordDialog.wdDialogFilePageSetup];
	invokeHelper(dlg, "PageWidth", 3.3);
	invokeHelper(dlg, "PageHeight", 6);
	dlg.Execute();
}

Conclusion

Word et Excel exposent des modèles de programmation riches, mais ces modèles d’objets ont été écrits à l’origine pour être consommés par les clients VBA. Visual Basic, même avec Option Strict On, peut gérer la plupart des exigences des modèles d’objet Office. La consommation de ces modèles d’objet avec C# nécessite plus d’attention. Lors de l’écriture d’applications avec Visual Studio 2005 Tools for Office et C#, rappelez-vous que vous devez souvent faire des concessions pour les différences entre les langages, en examinant les paramètres facultatifs, les propriétés paramétrées, les paramètres Variant et la liaison tardive. Une fois que vous avez compris les types de problème que vous pouvez rencontrer, l’écriture de code C# qui interagit avec Office n’est pas plus difficile que d’écrire du code Visual Basic.

Ressources complémentaires

Visual Studio 2005 Tools pour Office

Centre de développement Office

À propos de l’auteur

Ken Getz est développeur, rédacteur et formateur, agissant en tant que consultant sénior de MCW Technologies, LLC, un fournisseur de solutions Microsoft. Il a co-écrit plusieurs ouvrages techniques pour les développeurs, notamment le best-seller ASP.NET Developer's Jumpstart (Débuts du développeur ASP.NET), la série Access Developer's Handbook (Manuel du développeur Access) et la série VBA Developer's Handbook (Manuel du développeur VBA). Ken a co-écrit les cours AppDev sur C#, ASP.NET, Visual Basic .NET et ADO.NET. Ken est réviseur technique de VB.NET Technical Journal d’Advisor Publications et écrit dans les magazines MSDN Magazine et CoDe. Ken intervient régulièrement sur des expositions, notamment les événements Advisor Media's Advisor Live, FTP's VSLive, DevConnection's VS Connection et ASP Connection, ainsi que Microsoft Tech-Ed.