【问题标题】:How to handle multi-type variables in Powershell?如何在 Powershell 中处理多类型变量?
【发布时间】:2015-05-31 09:02:16
【问题描述】:

我有一个 Powershell 脚本,它通过一个可以是 String 或 Int32 类型的变量来运行 Excel VLookUp 函数。当我将 $Value 变量声明为 String 或 Int32 时,脚本运行良好,但我该如何处理 $Value 变量可以是 Int32 或 String 形式的事实(例如:$Value = 155 (uint32) 或$Value = 90:9123 80:8989(字符串))。有任何想法吗?

$files2MX1005 = Get-ChildItem C:\source -Recurse

$Excel = New-Object -ComObject excel.application
[reflection.assembly]::LoadWithPartialName( "Microsoft.Office.Interop.Excel" )
$Excel.visible = $false
$Excel.DisplayAlerts=$False

foreach($fileMX1005 in $files2MX1005) {

    $Workbook = $Excel.Workbooks.open($fileMX1005.FullName) 
    $workbook2 = $Excel.Workbooks.open("C:\Lookup_Table.xlsx")
    $range4 = $workbook2.ActiveSheet.Range("A2:E10")
    $range = $Workbook.ActiveSheet.Range("A1:FZ1").EntireColumn 
    $range2 = $Workbook.ActiveSheet.Range("A1:A39").EntireRow 
    $range.Delete()
    $range2.Delete()
    $Workbook.SaveAs("C:\StrippedHeader.csv")

    $Values = @(Get-Content C:\StrippedHeader.csv -Raw) -split '\s+' | Where-Object {$_ -like '*:*' -or '0.*'} 

    for ($i = 0; $i -lt $Values.length; $i++) {
    if ($Values[$i] -lt 1) { [float]$Values[$i] *= 1440 }
    }                

    "UniqueActiveFaults" |Out-File C:\IdealOutput.csv
    $Values | Sort-Object -Unique | Out-File CIdealOutput.csv  

    $Values2 = @(Get-Content C:\IdealOutput.csv) 


    $OutputLookUp2 = @()
    foreach ($Value in $Values2){
        $OutputLookUp2 += "$Value $($Excel.WorksheetFunction.VLookup([int32]$Value,$range4,3,$true))`r`n"          
}

Idealoutput.csv 的示例:

0.451564 (INT32)

0.84645 (INT32)

90:4585 90:7878(字符串)

BA:4545 BA:2525(字符串)

0.6587 (INT32)

查找的输出理想地是:

650 (0.451564 * 1440) = X

90:4585 = 是的

BA:2525 = Z

等...每个代码。

今天……我明白了

650

90:4585 = 是的

BA:2525 = Z

650 的查找输出不成功,因为查找未将其作为字符串读取。

【问题讨论】:

  • 实际问题是什么?您说无论$Value[string] 还是[int32],都运行相同的代码,那么您是否有实际理由需要区分类型是什么?或者这只是学术性的?或者您是否试图避免使用不是字符串或 int32 的东西运行 VLookup?或者如果可能的话,您想将字符串转换为整数的问题是什么?
  • 问题是当 $Value 同时包含字符串和 int32 时。脚本无法同时处理两者。它处理字符串或整数,其余部分给我一个错误,因为 $Value 设置为仅处理一种类型的数据。
  • @CarlosSousa,那么你需要展示这个问题。 PowerShell 可以很好地在另一个字符串中扩展包含字符串和数字的数组。目前还不清楚问题是什么。创建一个代码示例,手动定义一个通常会从 VLookup 返回的数组,以便我们自己测试代码。
  • @briantist,请查看我上面原始帖子的更新。感谢您的帮助。
  • 这种情况$_ -like '*:*' -or '0.*' 总是$true。如果 excel 文件包含 0.451564,你想如何找到 650 的内容?

标签: powershell vlookup


【解决方案1】:

您不应将值转换为[string],而不是[int],以便它们保留其原始类型。此外,您不应将中间结果导出并重新导入到文件中,因为您将它们转换为[string]

$Workbook.SaveAs("C:\StrippedHeader.csv")

$OutputLookUp2 = @(
    -split (Get-Content C:\StrippedHeader.csv -Raw) |
    ForEach-Object {
        switch -Wildcard ($_){
            *:* {$_}
            0.* {[int]([double]$_*1440)}
        }
    } |
    Sort-Object {$_ -is [string]},{$_} -Unique |
    ForEach-Object {
        "$_ $($Excel.WorksheetFunction.VLookup($_,$range4,3,$true))`r`n"
    }
)

【讨论】:

    【解决方案2】:

    你可以测试看看它是否会转换为 [int32]。

    if ($Value -as [int32] -is [int32])
      {'Value is integer'}
    
     else { 'Value is string' }
    

    然后为该类型运行适当的代码。

    【讨论】:

    • 我明白你的意思,这是一个选项,但我不希望这样做,因为字符串或整数的代码都是相同的。有没有更有效的方法来做到这一点?还是按照您的建议进行测试不会影响脚本的性能?
    • 我刚刚测试过,运行该测试需要 0.2 毫秒。我认为这不会影响您的表现。
    • 谢谢 - 现在我知道这是一个选项,为了保持我的脚本简短和有条理,我仍然想知道是否有更简单的方法来处理这个问题,所以我会等待为进一步的 cmets。不过谢谢!
    • 然后总是施放它,不要做检查:"BlahBlah $([int32]$Value) blah" 或更恰当的"Blah $([String]$Value) blah"
    • @briantist,很抱歉我没有明白这一点。我是 Powershell 的新手。请您再详细解释一下好吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2022-01-08
    • 1970-01-01
    • 2019-09-21
    • 2020-04-24
    相关资源
    最近更新 更多