代码之家  ›  专栏  ›  技术社区  ›  Goyuix

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

  •  7
  • Goyuix  · 技术社区  · 14 年前

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

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

    但是,如果我需要使用象xldoublequeote或xldelimited这样的常量,我似乎不得不硬编码它们。我真的希望能够做一些事情,比如:

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

    并确保它将返回值1。不幸的是,我无法创建枚举的实例,而且似乎没有一种方法可以像引用普通的.NET类库那样引用它:

    [Excel.Constants]::xlDoubleQuote
    

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

    5 回复  |  直到 14 年前
        1
  •  4
  •   Shay Levy    14 年前

    基思已经给了你答案,这是另一个选择。您可以在$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
    
        2
  •  9
  •   Keith Hill    14 年前

    使用Excel主互操作程序集。如果您安装了Office,这些应该在GAC中。使用如下:

    Add-Type -AssemblyName Microsoft.Office.Interop.Excel
    [int][Microsoft.Office.Interop.Excel.Constants]::xlDoubleQuote
    
        3
  •  1
  •   Community CDub    7 年前

    然而,基思和谢伊给出了完美的答案,请注意:

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

    Different Interop references on two different computers doesn't work

        4
  •  0
  •   Justin    6 年前

    使用Visio2016 32位,我发现尝试使用Keith Hill的方法会导致错误消息:“添加类型:无法添加类型”。找不到程序集“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秒。

        5
  •  0
  •   mklement0    6 年前

    结合技术 Keith Hill's helpful answer 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]
    

    注意:要查找 Constants 类型,可以使用制表符完成:运行后 New-Object -ComObject Excel.Application 类型 [constants<tab> (不要键入结束语 ] )应该扩展到 [Microsoft.Office.Interop.Excel.Constants ;如果来自命名空间的类型 其他 Microsoft.Office.Interop.Excel 显示,按Tab键直到找到所需类型。

    现在你可以:

    • 将单个枚举值作为存储在 $xlConstants ,通过 :: 操作员,也可以完成选项卡;例如:

      $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
      # ...