excel - 为什么 Range.BorderAround 会向控制台发出“True”?
问题描述
使用 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
方法具有返回值,并且在 PowerShell 中,任何输出(返回)数据的命令或表达式...
都会隐式输出到(成功)输出流,默认情况下会发送到主机,通常是控制台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)
; 同样,命令必须始终包含在(...)
;[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 或 Bash)中一样。(虽然传统的 shell 有2 个输出流 - stdout 和 stderr - PowerShell 有6 个,以便提供更复杂的功能 - 请参阅about_Redirection。)cmdlet、脚本或函数可以根据需要随时写入输出流,这样的输出通常可以立即显示,但也可以显示给潜在的消费者,这使得流水线提供的流式、一对一处理成为可能.
这与传统的编程语言形成对比,后者的输出行为基于返回值,通常通过
return
关键字提供,它将输出数据(返回值)与流控制(退出范围并返回给调用者)混为一谈。- 一个常见的陷阱是期望 PowerShell 的
return
语句执行相同的操作,但事实并非如此:return <val>
只是 的语法糖<val>; return
,即隐式输出 of<val>
后跟无条件将控制权返回给调用者;值得注意的是,使用return
不排除从相同范围内的早期语句生成输出。
- 一个常见的陷阱是期望 PowerShell 的
与传统的 shell 不同,PowerShell不需要显式的 write-to-the-output 流命令来生成输出:
虽然 PowerShell 确实有对应的
echo
,即Write-Output
,但很少需要使用它。- 在极少数情况下
Write-Output
有用的是防止在输出上枚举集合-NoEnumerate
,或者使用通用参数-OutVariable
来输出数据并将其捕获到变量中(通常只需要表达式,因为 cmdlet 和高级函数/脚本本身支持-OutVariable
)。
- 在极少数情况下
隐式输出行为:
通常是一种祝福:
- 对于交互式实验 - 只需键入任何语句 - 特别包括诸如
[IO.Path]::GetExtension('foo.txt')
和之类的表达式[math]::Pow(2, 32)
- 并查看其输出(类似于REPL的行为)。 - 用于编写不需要说明隐含行为的简洁代码(参见下面的示例)。
- 对于交互式实验 - 只需键入任何语句 - 特别包括诸如
有时可能是一个陷阱:
适用于习惯于传统编程语言语义的用户。
由于预期不会产生输出的语句可能会意外污染输出流,例如在您的情况下;一个更典型的例子是类的
.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]
这演示了行为的流方面: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)
.
推荐阅读
- php - PHP在扩展时用另一个类替换扩展
- postgresql - POSTGRES 的查询优化器的统计估计器是否为多表连接的中间产品计算最常见的值列表?
- mysql - MySQL 与 subQuery 不同
- python - 读取在引号和换行符内包含两个双引号的 csv 文件
- php - Laravel:添加选择查询时,HasMany 关系返回空数据
- javascript - 升级 React-Redux 后如何解决 TypeError?
- django - 登录django后如何从仪表板中的数据库中获取特定用户的详细信息?
- javascript - 如何在 TypeScript 的 HTML 属性中声明 onclick 函数?
- javascript - 在 js 中发送 cookie 获取 POST 或 GET 请求跨服务器 cors 启用服务器
- excel - 使用python将输出数据存储在CSV中