Excel 为什么Range.BorderAbround会发出;“真的”;到控制台?

Excel 为什么Range.BorderAbround会发出;“真的”;到控制台?,excel,powershell,output,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) 为什么需要这样做?我是否没有正确创建范围?有更好的解决办法吗 为什么需要这样做 它是必需的,因

使用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)
为什么需要这样做?我是否没有正确创建范围?有更好的解决办法吗

为什么需要这样做

它是必需的,因为有一个返回值,并且在PowerShell中,输出(返回)数据的任何命令或表达式
..
都是隐式输出到(成功)输出流,默认情况下输出到主机,主机通常是控制台窗口(终端)在其中运行PowerShell会话

即,数据显示在控制台/终端中,除非:

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

即:

$range.BorderAround(1, -4138)
是(更有效的)以下简称:

Write-Output $range.BorderAround(1, -4138)
(很少需要显式使用。)

由于您不需要该输出,因此必须抑制该输出,为此您有几个选项:

  • $null=…

  • [void](…)

  • …>$空

  • …|输出空值

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

  • 它传达了预先压制的意图

    • 虽然
      [void]=(…)
      也会这样做,但出于语法原因,它通常要求您在
      (…)
      中包含一个表达式;e、 例如,
      [void]1+2
      不能按预期工作,只有
      [void](1+2)
      ;同样,命令必须始终包含在
      (…)
      [void]New Item test.txt
      不起作用,只有
      [void](New Item test.txt)
      起作用
  • 它在命令输出(例如,
    $null=Get AdUser…
    )和表达式输出(例如,
    $null=$range.BorderAround(1,-4138)
    )中都表现良好

相反,避免
。|Out Null
,因为它通常要慢得多(在PowerShell(Core)6+[1]中的无副作用表达式输出的边缘情况除外)

但是,如果您需要使所有的静音,不仅是成功输出,还有错误、详细输出,…-您必须使用
*>$null


为什么PowerShell隐式生成输出?
  • 作为一个shell,PowerShell的输出行为基于流,与传统shell(如
    cmd.exe
    或Bash)一样。(虽然传统Shell有2个输出流—stdout和stderr—但PowerShell有6个,以便提供更复杂的功能—请参阅。)

    • cmdlet、脚本或函数可以根据需要随时写入输出流,此类输出通常可立即显示,但也可供潜在消费者使用,从而启用管道提供的逐个流式处理

    • 这与传统编程语言不同,传统编程语言的输出行为基于返回值,通常通过
      return
      关键字提供,该关键字将输出数据(返回值)与流控制(退出范围并返回给调用者)合并

      • 一个常见的陷阱是期望PowerShell的
        return
        语句的行为相同,但事实并非如此:
        return
        只是
        的语法糖;返回
        ,即隐式输出,然后无条件地将控制权返回给调用方;值得注意的是,使用
        return
        并不排除从同一范围内的早期语句生成输出
  • 与传统Shell不同,PowerShell不需要显式写入输出流命令来生成输出:

    • 虽然PowerShell确实与echo有对应的功能,也就是说,很少需要使用它

      • 在极少数情况下,
        写入输出
        是有用的,其中包括防止使用
        -NoEnumerate
        枚举输出上的集合,或使用
        -OutVariable
        同时输出数据并将其捕获到变量中(这通常仅适用于表达式,因为cmdlet和高级函数/脚本本身支持
        -OutVariable
    • 隐式输出行为

      • 通常是一种祝福

        • 对于交互式实验-只需键入任何语句-特别是包括表达式,如
          [IO.Path]::GetExtension('foo.txt')
          [math]::Pow(2,32)
          -并查看其输出(类似于一个函数的行为)
        • 用于编写不需要详细说明隐含行为的简明代码(请参见下面的示例)
      • 有时可能是一个陷阱:

        • 对于习惯于传统编程语言语义的用户

        • 由于不希望产生输出的语句可能会意外污染输出流,例如在您的案例中;更典型的示例是
          [System.Collections.ArrayList]
          类的
          .Add()
          方法意外产生输出

例如:

# 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秒停顿
[0x1]
#1秒停顿
[0x2]
...
[0x10]
这演示了行为的流方面:
Get HexNumber
的输出在生成时可用于
ForEach对象
cmdlet调用,而不是在退出
Get HexNumber
之后


[1] 战俘