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

kse8i1jr  于 2022-12-05  发布在  其他
关注(0)|答案(1)|浏览(151)

使用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)

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

2uluyalo

2uluyalo1#

为什么需要这样做?
这是必需的,因为BorderAround method有一个返回值,而且在PowerShell中,任何 * 输出(返回)数据的命令或表达式都是*隐式输出 * 到 (成功)输出流**,默认情况下,输出流将转到 * 主机 *,通常是PowerShell会话运行的 * 控制台窗口 (终端)。
也就是说,数据显示在控制台/终端中,
除非 * 是:

  • 捕获($var = ...
  • 通过流水线发送用于进一步处理(... | ...;最后管线段命令本身可能产生输出,也可能不产生输出)
  • 已重定向(... >

、或其任意组合。
那就是:

$range.BorderAround(1, -4138)

是(更有效的)简写:

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

(很少需要显式使用Write-Output。)
由于您不希望该输出,因此必须 * 抑制 * 它,为此您有以下几种选择:

  • $null = ...
  • [void] (...)
  • ... > $null
  • ... | Out-Null
    $null = ...可能是最佳的整体选择,因为:
  • 它传达了一种意图,即预先抑制
  • 虽然[void] = (...)也能做到这一点,但由于语法原因,它通常要求您将 expression 括在(...)中;例如,[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]。
但是,如果您需要静默 * 所有 * output streams-不仅是 * 成功 * 输出,还有错误、详细输出... -您必须使用*> $null

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

  • 作为 shellPowerShell的输出行为基于 * 流*,与cmd.exe或Bash等传统shell一样。(传统shell有 2 个输出流- stdout和stderr,而PowerShell有 6 个,以便提供更复杂的功能-请参阅about_Redirection。)
    *cmdlet、脚本或函数可以根据需要随时写入输出流,并且此类输出通常可 * 立即 * 用于显示,但也可用于潜在的消费者,这支持 * 管道 * 提供的逐个处理
  • 这与传统的 * 编程语言 * 不同,后者的输出行为基于 * 返回值 *,通常通过return关键字提供,它将输出数据(返回值)与流控制(退出作用域并返回到调用者)合并在一起。
  • 一个常见的陷阱是期望PowerShell的return语句也能起到同样的作用,但实际上并非如此:return <val>仅仅是<val>; return的语法糖,即,<val>的隐式输出之后是控制向调用者的无条件返回;值得注意的是,return的使用 * 不 * 排除从相同作用域中的较早语句生成输出。
  • 与传统shell不同,PowerShell不 * 需要 * 显式的write-to-the-output stream命令来生成输出
  • 虽然PowerShell确实有echo的对应物,即Write-Output,但很少需要使用它。
  • Write-Output在极少数情况下是有用的,其中包括使用-NoEnumerate防止在输出上枚举集合,或者使用common parameter-OutVariable输出数据 * 并 * 将其捕获到变量中(通常只有 * 表达式 * 才需要,因为cmdlet和高级函数/脚本本身支持-OutVariable)。
    *隐式输出行为
    一般是 * 福
  • 对于交互式实验-只需键入任何语句-特别是包括[IO.Path]::GetExtension('foo.txt')[math]::Pow(2, 32)这样的表达式-并查看其输出(类似于REPL的行为)。
  • 用于编写不需要详细说明隐含行为的简洁代码(请参阅下面的示例)。
  • 有时也会成为一个“陷阱”:
  • 对于习惯于传统编程语言的语义的用户来说。
  • 因为可能会意外地污染输出流,而这些输出流来自那些不希望生成输出的语句,例如您的示例;一个更典型的示例是[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-second pause
[0x1]
# 1-second pause
[0x2]
...
[0x10]

这演示了该行为的流方面:Get-HexNumber的输出可用于ForEach-Object cmdlet调用,* 因为它正在产生 而不是 * 在Get-HexNumber退出 * 之后。
[1]在PowerShell(Core)6+中,如果前面唯一的管道段是 * 无副作用的表达式 * 而不是方法或命令调用,则Out-Null具有优化;例如,1..1e6 | Out-Null几乎没有时间执行,因为表达式看起来甚至没有执行。然而,这样的场景是非典型的,并且功能上等效的Write-Output (1..1e6) | Out-Null需要很长时间来运行,比$null = Write-Output (1..1e6)长得多。

相关问题