Powershell函数elseif语句不起作用

时间:2018-05-23 01:17:10

标签: function powershell if-statement

我有一个PowerShell功能,它不能正常工作。它应该将$ prm中给出的选择限制为最多5.超过5它应该警告用户。如果在字符串中传递0,则默认为null。

有人可以告知我需要做些什么来解决这个问题:

Function GetListValues($prm, $charCount){ 

$buildStr="Call db.Fruit(" 

#no selection
if ($charCount -eq 0 ){ 
    $buildStr = $buildStr + "NULL,NULL,NULL,NULL,NULL);"
    write $buildStr
}elseif($charCount -ge 1 -and $charCount -le 4 ){

#selections made with then 5 parameter range

$arr = $prm.split(",");
if ($arr[0]) { $buildStr = $buildStr  + $arr[0] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[1]) { $buildStr  = $buildStr + $arr[1] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[2]) { $buildStr  = $buildStr + $arr[2] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[3]) { $buildStr  = $buildStr + $arr[3] + "," } else { $buildStr = $buildStr + "Null," }
if ($arr[4]) { $buildStr  = $buildStr + $arr[4] + ");" } else {$buildStr =  $buildStr + "Null);" }

write $buildStr


}else{
# too many selections

[System.Windows.MessageBox]::Show('Too many selections! A maximum of 5 only!')


}


}
$prm = "'Apple','Orange','Pear','Banana','Grapes'"
$charCount = ($prm.ToCharArray() | Where-Object {$_ -eq ','} | Measure-Object).Count
GetListValues $prm, $charCount

2 个答案:

答案 0 :(得分:3)

您的问题与您的测试代码有关,而不是您的功能。对于powershell,您只使用空格来分隔参数,而不是逗号。

因此,如果您将测试更改为

PS> GetListValues "'Apple', 'Orange', 'Pear', 'Banana', 'Grapes'" 5 Call db.Fruit(Apple,Orange,Pear,Banana,Grapes) PS> GetListValues "" 3 Call db.Fruit(Null,Null,Null)

然后代码就可以了。

您可以忽略我之前的评论,因为我假设您的$ charCount值被设置为元素数量。但仔细观察后我发现你只是计算逗号的数量,所以元素的数量将是#commas + 1(只要你有> 1个元素)

顺便说一句,$ charCount有点多余,因为函数可以自行解决这个问题,并且会使函数更具弹性,因为它会消除调用代码传递不一致值的可能性。

答案 1 :(得分:2)

DeanOC's helpful answer指出了你的参数传递语法的直接问题。

此外,正如他所建议的那样,你不需要确定函数之外的元素数量 - 让函数本身处理它更容易和更健壮。 这是一个PowerShell惯用的函数重构,它就是这样做的:

function GetListValues {
  param(
    [ValidateCount(0,5)] # Allow between 0 and 5 values.
    [string[]] $Columns
  )
  # Create a 5-element array filled with the input column names
  # and 'Null' for any remaining elements.
  $allColumns = New-Object string[] 5
  for ($i = 0; $i -lt $allColumns.Count; ++$i) {
    $allColumns[$i] = if ($i -lt $Columns.Count) { $Columns[$i] } else { 'Null' }
  }
  # Use string expansion (interpolation) to construct the output string.
  "Call db.Fruit($($allColumns -join ','))"
}

将参数定义为[string[]]允许您(a)单独传递列名称,(b)轻松访问其计数,并允许您通过{{1}约束可接受的列名称范围属性。

因此您可以按如下方式调用上述函数:

ValidateCount

变体解决方案(OP稍后要求):

  • 允许传递最大值。列数作为参数

  • 将列名称作为带有嵌入式引号的单个字符串传递(例如# Pass 5 column names. # Note that with the simple names at hand you needn't even quote them. PS> GetListValues Apple, Orange, Pear, Banana, Grapes Call db.Fruit(Apple,Orange,Pear,Banana,Grapes) # Pass no column names at all. PS> GetListValues Call db.Fruit(Null,Null,Null,Null,Null) # Pass too many names -> ValidateCount triggers an error. PS> GetListValues Apple, Orange, Pear, Banana, Grapes, TooMuch GetListValues : Cannot validate argument on parameter 'Columns'. The parameter requires at least 0 value(s) and no more than 5 value(s) - 6 value(s) were provided. )。

"'Apple', 'Orange', 'Pear', 'Banana', 'Grapes'"

示例电话:

function GetListValues {
  param(
    [string] $ColumnList,
    [int]    $MaxColumnCount
  )

  # Split something like "'Apple', 'Orange', 'Pear', 'Banana', 'Grapes'"
  # into an array of tokens.
  $Columns = $ColumnList -split "[, ']" -ne ''
  if ($Columns.Count -gt $MaxColumnCount) { Throw "Too many columns passed." }

  # Create an N-element array filled with the input column names
  # and 'Null' for any remaining elements.
  $allColumns = New-Object string[] $MaxColumnCount
  for ($i = 0; $i -lt $allColumns.Count; ++$i) {
    $allColumns[$i] = if ($i -lt $Columns.Count) { $Columns[$i] } else { 'Null' }
  }
  # Use string expansion (interpolation) to construct the output string.
  "Call db.Fruit($($allColumns -join ','))"
}