Поиск значения констант MS Office Interop вместо жесткого их кодирования - PullRequest
7 голосов
/ 25 ноября 2010

Используя PowerShell, достаточно легко создать, скажем, экземпляр класса приложения Excel и начать манипулировать им:

$app = New-Object -ComObject "Excel.Application"

Однако, если мне нужно использовать константы, такие как xlDoubleQuote или xlDelimited -кажется, что я вынужден жестко их кодировать.Я действительно хотел бы иметь возможность сделать что-то вроде:

$constants = New-Object -ComObject "Excel.Constants"
$constants.xlDoubleQuote

и посмотреть, что он вернет значение 1. К сожалению, я не могу создать экземпляр перечисления, и там не кажетсячтобы можно было ссылаться на нее, как если бы вы использовали обычную библиотеку классов .NET:

[Excel.Constants]::xlDoubleQuote

Есть ли способ динамического импорта этого перечисления в PowerShell?Может через управляемые библиотеки, а не через COM?

Ответы [ 5 ]

9 голосов
/ 25 ноября 2010

Используйте основную сборку взаимодействия для Excel. Если у вас установлен Office, они должны быть в GAC. Используйте вот так:

Add-Type -AssemblyName Microsoft.Office.Interop.Excel
[int][Microsoft.Office.Interop.Excel.Constants]::xlDoubleQuote
4 голосов
/ 25 ноября 2010

Кит уже дал вам ответ, вот еще один вариант. Вы можете использовать завершение табуляции в объекте $ xlConstants, чтобы получить константы:

$xl = New-Object -ComObject Excel.Application
$constants = $xl.gettype().assembly.getexportedtypes() | where-object {$_.IsEnum -and $_.name -eq 'constants'}

$pso = new-object psobject
[enum]::getNames($constants) | foreach { $pso | Add-Member -MemberType NoteProperty $_ ($constants::$_) }
$xlConstants = $pso
1 голос
/ 21 июля 2011

Кит и Шей дали отличные ответы, однако обратите внимание на это:

При использовании Excel 2003 или Excel 2007 на компьютере должны быть установлены основные сборки взаимодействия Office (PIA).Есть распространяемые версии, доступные от Microsoft.См. Эту публикацию на stackoverflow.com для получения дополнительной информации:

Разные ссылки Interop на двух разных компьютерах не работают

0 голосов
/ 24 марта 2019

Чтобы объединить технику из Полезный ответ Кейта Хилла с идеей завершения табуляции из Ответ Шей Леви :

# Instantiate Excel, which implicitly loads the interop
# assembly that contains the [enum] type of interest.
# Assign to $null, if you're not planning on using the object further.
$xl = New-Object -ComObject Excel.Application

# Store the [enum] type of interest in a variable for easier access.
$xlConstants = [Microsoft.Office.Interop.Excel.Constants]

Примечание. Чтобы найти полное имя типа Constants, можно использовать завершение табуляции: после выполнения New-Object -ComObject Excel.Application введите [constants<tab> (не вводите закрывающий ]), которое должно расшириться до [Microsoft.Office.Interop.Excel.Constants; если тип из пространства имен отличается от , отличного от Microsoft.Office.Interop.Excel, нажмите клавишу табуляции, пока не будет найден нужный тип.

Теперь вы можете:

  • Доступ к отдельным значениям перечисления в виде статических членов типа, хранящихся в $xlConstants, с помощью оператора ::, который также работает с завершением табуляции; e.g.:

    $xlConstants::xl3d<tab>  # -> expands to $xlConstants::xl3DBar
    
  • Получить базовое число определенного значения, приведя к [int] или открыв свойство .Value__:

    [int] $xlConstants::xl3DBar    # -> -4099
    
    $xlConstants::xl3DBar.Value__  # ditto
    
  • Перечислить все символические имена:

    [enum]::GetNames($xlConstants)
    
  • Также покажите числа, лежащие в основе символических имен:

    PS> [enum]::GetNames($xlConstants) |
        Select @{ n='Name'; e={$_} }, @{ n='Number'; e={ $xlConstants::$_.Value__ } }
    
    Name            Number
    ----            ------
    xlAbove              0
    xlFirst              0
    xlDirect             1
    # ...
    
0 голосов
/ 20 ноября 2018

Используя 32-разрядную версию Visio 2016, я обнаружил, что попытка использовать подход Кейта Хилла вызвала сообщение об ошибке: «Add-Type: Невозможно добавить тип. Не удалось найти сборку« Microsoft.Office.Interop.Visio »» Подход Шей Леви потребовал немного больше изменений для работы с Visio. Вот что мне удалось получить:

$visioApp = New-Object -ComObject Visio.Application 
$visioConstants = @{}

$visioEnums = $visioApp.gettype().assembly.getexportedtypes() | where-object {$_.IsEnum } #-and $_.name -eq 'constants'}

The answers of Keith Hill and Shay Levy are best, however, I found that Visio 
$visioEnums |%{
    $enumname = $_
    [enum]::getNames($enumname) | foreach {
        $val = invoke-expression "[$($enumname)]::$($_).value__"
        $visConstants.$_ = $val
    }
}
$visioApp.Quit()

echo $visConstants.visTopEdge 

К сожалению, на выполнение теста у меня уходит около 12 секунд.

...