为什么Range.BorderAround向控制台发出“ True”?

时间:2019-04-12 21:28:15

标签: excel powershell output

使用BorderAround会向控制台发出“ True”消息。

$range = $sum_wksht.Range('B{0}:G{0}' -f ($crow))
$range.BorderAround(1, -4138)

这可以通过使用以下方法之一来解决。

$wasted = $range.BorderAround(1, -4138)
[void]$range.BorderAround(1, -4138)

为什么需要这个?我没有正确创建范围吗?有更好的解决方法吗?

1 个答案:

答案 0 :(得分:1)

  

为什么需要这个?

这是必需的,因为BorderAround method具有返回值,并且在PowerShell中, 输出(返回)数据的任何命令或表达式... strong>是 隐式输出到其(成功)输出流 ,默认情况下流到 host 通常是运行PowerShell会话的控制台窗口(终端)。

也就是说,数据显示在控制台/终端中,除非它们是:

  • 已捕获($var = ...
  • 通过管道发送以进行进一步处理(... | ...;最后一个管道段的命令本身可能会或可能不会产生输出)
  • 已重定向(... >

或其任何组合。

也就是说:

$range.BorderAround(1, -4138)

(更高效)是以下简称:

Write-Output $range.BorderAround(1, -4138)

(很少需要明确使用Write-Output。)

由于您不希望该输出,因此必须抑制 ,为此您有几种选择:

  • $null = ...

  • [void] (...)

  • ... > $null

  • ... | Out-Null

$null = ...可能是最佳的总体选择,因为:

  • 传达了压制预先的意图
    • [void] = (...)也可以这样做,但是出于语法原因,通常需要您将其余语句放在(...)中;例如,[void] 1 + 2不能正常工作,只有[void] (1 + 2)
  • 它在 command 输出(例如$null = Get-AdUser ...)和 expression 输出(例如$null = $range.BorderAround(1, -4138))上都表现良好。

相反,避免使用... | Out-Null ,因为它通常要慢得多(PowerShell Core 中的表达式输出除外)。

但是,如果您需要使全部 output streams 保持沉默-不仅是成功输出,还包括错误,详细输出,...-您必须使用*> $null


PowerShell为什么会隐式产生输出?

  • 作为 shell PowerShell的输出行为基于 ,就像在cmd.exe这样的传统shell中一样或Bash。 (虽然传统的shell具有 2 输出流-stdout和stderr-PowerShell具有 6 ,以便提供更复杂的功能-请参见about_Redirection。)

    • cmdlet,脚本或函数可以根据需要多次写入输出流,并且通常立即可用显示这些输出,但尤其是对于潜在的使用者,它启用管道提供的流式传输,一对一处理

    • 这与传统的编程语言相反,传统的编程语言的输出行为基于返回值,通常通过return关键字提供,从而使输出变得平凡流控制(退出范围并返回给调用方)的数据(返回值)。

      • 一个常见的陷阱是期望PowerShell的return语句执行相同的操作,但事实并非如此:return <val>只是<val>; return的语法糖,即{{ 1}},然后无条件地将控制权返回给调用方;值得注意的是,<val>的使用不会排除同一范围内早期语句的输出。
  • 与传统的shell不同, PowerShell不需要要求显式写入输出流命令即可产生输出

    • 尽管PowerShell确实与return相对应,即Write-Output,但很少需要使用它。

      • 在极少数echo有用的情况下,是防止使用Write-Output对输出进行枚举,或者使用common parameter -NoEnumerate来同时输出两个数据并将其捕获到变量中(由于cmdlet和高级函数/脚本本身支持-OutVariable,因此通常仅对表达式才需要)。
    • 隐式输出行为

      • 通常是祝福

        • 用于交互式实验-只需键入任何语句-特别是包括-OutVariable[IO.Path]::GetExtension('foo.txt')之类的表达式-并查看其输出(类似于REPL的行为)。
        • 用于编写不需要说明隐含行为的简洁代码(请参见下面的示例)。
      • 有时可能是陷阱

        • 面向习惯传统编程语言语义的用户。

        • 由于您可能不希望产生输出的陈述(例如您的情况)会导致输出流的意外污染;一个更典型的示例是[math]::Pow(2, 32)类的.Add()方法意外产生输出。

示例:

[System.Collections.ArrayList]

上面的结果如下:

# Define a function that takes an array of integers and
# outputs their hex representation (e.g., '0xa' for decimal 10)
function Get-HexNumber {
  param([int[]] $numbers)      
  foreach ($i in $numbers) {
    # Format the integer at hand 
    # *and implicitly output it*.
    '0x{0}' -f $i.ToString('x')
  }
}

# Call the function with integers 0 to 16 and loop over the
# results, sleeping 1 second between numbers.
Get-HexNumber (0..16) | ForEach-Object { "[$_]"; Start-Sleep 1 }

这演示了行为的流方面:[0x0] # 1-second pause [0x1] # 1-second pause [0x2] ... [0x10] cmdlet调用正在生成时可以使用Get-HexNumber cmdlet调用,而不是 after < / em> ForEach-Object已退出。