2009-12-01 8 views
3

J'étudie Boo et je pensais que ce serait un exercice utile pour essayer de convertir quelques VB Scripts vénérables qui automatisent Excel (2007, dans ce cas). Beaucoup de choses semblent se traduire très facilement, mais j'ai énormément de difficulté à sélectionner des plages. Chaque fois que j'essaie de les obtenir ou de les définir, un membre TargetInvocationException est introuvable.Boo - Excel Automation, problèmes de sélection des gammes

est ici un (coupé vers le bas) exemple, j'ai couru dans booish:

def CreateInstance(progid): 
    type = System.Type.GetTypeFromProgID(progid)  
    return type() 

xl as duck = CreateInstance("Excel.Application") 
xl.Visible = true 
xl.Workbooks.Add 

sht as duck = xl.ActiveSheet 
#Next line throws exception 
rng as duck = sht.Range("A1") 

Certaines choses fonctionnent bien, comme définissant la propriété Nom de la feuille et ainsi de suite, mais comment puis-je travailler avec des gammes ? Y a-t-il des méthodes spéciales que VB cache que je devrais appeler, et si oui, comment pourrais-je les trouver?

Cheers,

Lenny.

Répondre

3

La plage est en fait une propriété, et c'est une propriété quelque peu spéciale en ce qu'elle fonctionne comme un indexeur, ce qui signifie qu'elle a une sémantique de type tableau ou dictionnaire. Dans la plupart des langues, cela signifie que vous auriez accès à sht.Range["A1"]. C'est le sucre syntaxique, et vraiment c'est accessible comme tout autre méthode, à savoir:

sht.get_Range("A1",System.Reflection.Missing.Method) 

je tenté d'utiliser Boo, Ruby et IronRuby répéter votre code, utilisant à la fois le style de sucre syntaxique et l'appel de méthode explicite. Dans IronRuby, je peux le faire fonctionner parfaitement, mais seulement dans l'interpréteur 32 bits. En Ruby régulière, qui est une application 32 bits sur ma configuration, cela a aussi bien fonctionné. Dans l'interpréteur 64 bits, la propriété Range n'a jamais été résolue correctement. Cela m'a amené à penser que Boo Interactive Shell fonctionnait en mode 64 bits et que l'interopérabilité échouait à cause de cela. Malheureusement, les mêmes problèmes se sont reproduits après avoir réglé mes binaires Boo locaux en mode 32 bits en utilisant CORFLAGS.exe, donc je ne pense pas que ce soit le vrai problème.

Ce qui n'a, cependant, était d'importer explicitement Excel Dotnet Interop Library, ainsi que les services Interop espaces de noms, comme ceci:

import Microsoft.Office.Interop.Excel 
import System.Runtime.InteropServices 

xl_type=typeof(Application).GetCustomAttributes(typeof(CoClassAttribute),true)[0].CoClass 
xl=xl_type() 
xl.Visible=true 
xl.Workbooks.Add 

Puis:

xl.Range["A1","A2"].Value=12 
xl.Range["A1",System.Type.Missing].Value="Alpha" 
(xl.ActiveSheet as Worksheet).Range["A1","A2"].Value2='Whatever' 

Tous ces travaux , mais ils exigent essentiellement que vous abandonniez le "Scriptiness" auquel vous êtes habitué par une liaison tardive (ce que fait votre frappe de canard). Une différence par rapport à VB/VBScript qui est vrai pour la plupart des langues (autre que C# 4.0) est que, généralement, les paramètres optionnels ne sont pas gérés de façon transparente, vous devez donc regarder l'API plus attentivement lorsque vous traitez méthodes qui prennent en charge les paramètres facultatifs (en les remplaçant par System.Type.Missing ou l'équivalent System.Reflection). Vous le trouverez dans les documents interop Excel, bien que vous puissiez probablement utiliser la réflexion pour identifier les paramètres marqués comme facultatifs si vous trouvez cela plus facile que de le rechercher. Parce que Ruby a une solution raisonnable pour la liaison tardive de ces objets, je soupçonne qu'il existe une fonctionnalité manquante (ou un bug) dans les scénarios d'interopérabilité COM dans Boo.

Edité pour ajouter: Sam Ng writes about indexed property support in C# 4.0; Les problèmes décrits dans son message s'appliquent probablement à Boo.

+0

Merci d'avoir fait tant d'efforts - je vais enquêter un peu plus! –

Questions connexes