查找 MS Office Interop 常量的值而不是对其进行硬编码

发布于 2024-10-04 11:16:04 字数 498 浏览 0 评论 0原文

使用 PowerShell,创建 Excel Application 类的实例并开始操作它是很容易的:

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

但是,如果我需要使用 xlDoubleQuote 或 xlDelimited 等常量 - 似乎我被迫对它们进行硬编码。我真的希望能够做类似的事情:

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

并看到它会返回 1 的值。不幸的是我无法创建枚举的实例,并且似乎没有办法像你一样引用它普通的 .NET 类库:

[Excel.Constants]::xlDoubleQuote

是否有某种方法可以将该枚举动态导入到 PowerShell 中?也许通过托管库而不是 COM?

Using PowerShell, it is easy enough to create, say, an instance of the Excel Application class and start manipulating it:

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

However, if I need to use the constants like xlDoubleQuote or xlDelimited - it seems like I am forced to hard code them. I would really like to be able to do something like:

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

And see that it would return the value of 1. Unfortunately I can't create an instance of an enumeration, and there doesn't seem to be a way to reference it like you would a normal .NET class library:

[Excel.Constants]::xlDoubleQuote

Is there some way to dynamically import that enumeration into PowerShell? Maybe through the managed libraries rather than COM?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

人间不值得 2024-10-11 11:16:04

使用 Excel 的主互操作程序集。如果您安装了 Office,它们应该位于 GAC 中。像这样使用:

Add-Type -AssemblyName Microsoft.Office.Interop.Excel
[int][Microsoft.Office.Interop.Excel.Constants]::xlDoubleQuote

Use the primary interop assembly for Excel. If you have Office installed these should be in the GAC. Use like so:

Add-Type -AssemblyName Microsoft.Office.Interop.Excel
[int][Microsoft.Office.Interop.Excel.Constants]::xlDoubleQuote
罪歌 2024-10-11 11:16:04

基思已经给了你答案,这是另一个选择。您可以在 $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

Keith already gave you the answer, here's another option. You can use tab completion on the $xlConstants object to get the constants:

$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
魂归处 2024-10-11 11:16:04

Keith 和 Shay 给出了完美的答案,但是请注意这一点:

使用 Excel 2003 或 Excel 2007 时,应在计算机上安装 Office 主互操作程序集 (PIA)。 Microsoft 提供了可再发行版本。有关详细信息,请参阅此处的 stackoverflow.com 帖子:

不同的互操作参考在两台不同的计算机上不起作用

Keith and Shay gave perfect answers, however, note this:

When using Excel 2003 or Excel 2007, the Office Primary Interop Assemblies (PIAs) should be installed on the machine. There are redistributable versions available from Microsoft. See this stackoverflow.com posting here for more info:

Different Interop references on two different computers doesn't work

零崎曲识 2024-10-11 11:16:04

使用 Visio 2016 32 位,我发现尝试使用 Keith Hill 的方法会导致错误消息:“Add-Type:无法添加类型。找不到程序集 'Microsoft.Office.Interop.Visio'。” Shay Levy 的方法需要进行更多修改才能与 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 秒。

Using Visio 2016 32-bit, I found that attempting to use Keith Hill's approach resulted in error message: "Add-Type : Cannot add type. The assembly 'Microsoft.Office.Interop.Visio' could not be found." Shay Levy's approach required a bit more modification to work with Visio. Here is what I was able to get working:

$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 

Disappointingly, it takes around 12 seconds to execute when I tested.

神回复 2024-10-11 11:16:04

Keith Hill 的有用答案中的技术与 Shay Levy 的回答

# 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(不要输入结束符 ]),它应扩展为 [ Microsoft.Office.Interop.Excel.Constants;如果出现除 Microsoft.Office.Interop.Excel 之外的命名空间中的类型,请按 Tab 键,直到找到所需的类型。

现在您可以:

  • 通过 :: 运算符以存储在 $xlConstants 中的类型的静态成员的形式访问各个枚举值,该运算符也适用于制表符补全;例如:

    $xlConstants::xl3d; #->扩展为 $xlConstants::xl3DBar
    
  • 通过转换为[int]或访问.Value__属性来获取特定值的基础数字:

    [int] $xlConstants::xl3DBar # -> -4099
    
    $xlConstants::xl3DBar.Value__ # 同上
    
  • 枚举所有符号名称:

    [enum]::GetNames($xlConstants)
    
  • 还显示符号名称背后的数字:

    <前><代码>PS> [枚举]::GetNames($xlConstants) |
    选择@{n='姓名'; e={$_} }, @{ n='数字'; e={ $xlConstants::$_.Value__ } }

    姓名 号码
    ---- ------
    xl0以上
    xl第0个
    xl直接1
    # ...

To combine the technique from Keith Hill's helpful answer with the tab-completion idea from Shay Levy's answer:

# 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]

Note: To find the full name of the Constants type, you can use tab completion: after having run New-Object -ComObject Excel.Application, type [constants<tab> (don't type the closing ]), which should expand to [Microsoft.Office.Interop.Excel.Constants; if a type from a namespace other than Microsoft.Office.Interop.Excel shows up, press the tab key until the desired type is found.

Now you can:

  • Access the individual enumeration values as static members of the type stored in $xlConstants, via the :: operator, which also works with tab completion; e.g.:

    $xlConstants::xl3d<tab>  # -> expands to $xlConstants::xl3DBar
    
  • Get a specific value's underlying number by either casting to [int] or accessing the .Value__ property:

    [int] $xlConstants::xl3DBar    # -> -4099
    
    $xlConstants::xl3DBar.Value__  # ditto
    
  • Enumerate all symbolic names:

    [enum]::GetNames($xlConstants)
    
  • Also show the numbers underlying the symbolic names:

    PS> [enum]::GetNames($xlConstants) |
        Select @{ n='Name'; e={$_} }, @{ n='Number'; e={ $xlConstants::$_.Value__ } }
    
    Name            Number
    ----            ------
    xlAbove              0
    xlFirst              0
    xlDirect             1
    # ...
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文