Boo - Excel Automation, проблемы с выбором диапазонов - PullRequest
3 голосов
/ 02 декабря 2009

Я изучаю Boo и подумал, что было бы полезно попробовать конвертировать пару почтенных VB-скриптов, которые автоматизируют Excel (в данном случае 2007). Многие вещи, кажется, переводятся очень легко, однако у меня возникают огромные проблемы с выбором диапазонов - всякий раз, когда я пытаюсь получить или установить их, я получаю член TargetInvocationException, который не найден.

Вот (урезанный) пример, который я использовал в 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")

Некоторые вещи работают нормально, например, настройка свойства Name листа и т. Д., Но как мне работать с диапазонами? Существуют ли какие-то специальные методы, которые VB скрывает, и которые мне нужно вызывать, и если да, то как мне их найти?

Приветствия

Ленни.

1 Ответ

3 голосов
/ 03 декабря 2009

Диапазон на самом деле является свойством, и это несколько особенное свойство, поскольку он работает как индексатор, что означает, что он имеет семантику, подобную массиву или словарю. На большинстве языков это означает, что вы получите доступ к sht.Range["A1"]. Это синтаксический сахар, и к нему действительно можно получить доступ, как и к любому другому методу, а именно:

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

Я попытался использовать Boo, Ruby и IronRuby для повторения вашего кода, используя стиль синтаксического сахара и явный вызов метода. В IronRuby я могу заставить его работать без нареканий, но только в 32-битном интерпретаторе . В обычном Ruby, который является 32-битным приложением в моей конфигурации, он также работал нормально. В 64-разрядном интерпретаторе свойство Range никогда не разрешалось правильно.

Так что это заставило меня заподозрить, что Boo Interactive Shell работает в 64-битном режиме, и из-за этого происходит сбой взаимодействия. К сожалению, те же проблемы воспроизводились после установки моих локальных двоичных файлов Boo для запуска в 32-разрядном режиме с помощью CORFLAGS.exe, поэтому я не думаю, что это реальная проблема.

Что сработало, так это явный импорт библиотеки взаимодействия Dotnet Excel, а также пространств имен служб Interop, например:

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

Тогда:

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

Все эти работы, но они по сути требуют от вас отказаться от "Писательности", к которой вы привыкли с позднего связывания (что и делает ваша утка).

Одно отличие от VB / VBScript, которое справедливо для большинства языков (кроме C # 4.0), заключается в том, что, как правило, необязательные параметры не обрабатываются прозрачно, поэтому вам придется более внимательно смотреть на API при работе с методами которые поддерживают необязательные параметры (заменяя их System.Type.Missing или эквивалентом System.Reflection). Вы можете найти это в документах по взаимодействию с Excel, хотя, вероятно, вы сможете использовать отражение, чтобы определить параметры, помеченные как необязательные, если вам будет проще, чем искать их.

Поскольку у Ruby есть разумное решение для позднего связывания этих объектов, я подозреваю, что в сценариях взаимодействия COM в Boo отсутствует недостающая функция (или ошибка).

Отредактировано, чтобы добавить: Сэм Нг пишет о поддержке индексированных свойств в C # 4.0 ; проблемы, описанные в его посте, вероятно, относятся и к Бу.

...