У меня есть функция PowerShell, которая не работает должным образом. Предполагается, что количество вариантов, заданных ему в $ prm, должно быть ограничено максимум 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

Полезный ответ DeanOC указывает на вашу непосредственную проблему с синтаксисом передачи аргументов.
Кроме того, как он предлагает, вам не нужно определять количество элементов вне функции - проще и надежнее позволить самой функции обрабатывать это. Вот идиоматическая переформулировка вашей функции в стиле 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[]] позволяет вам (а) передавать имена столбцов по отдельности и (б) легко дает вам доступ к их количеству и позволяет ограничивать допустимый диапазон имен столбцов с помощью атрибута ValidateCount.
Поэтому вы можете вызвать указанную выше функцию следующим образом:
# 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.
Вариант решения (запрошенный позже OP), который:
позволяет пройти макс. количество столбцов как параметр
передает имена столбцов как одну строку со встроенными кавычками (например, "'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 ','))"
}
Примеры звонков:
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)
Ваша проблема связана с тестовым кодом, а не с функцией. В PowerShell для разделения параметров используются только пробелы, а не запятые.
Итак, если вы измените свой тест на
GetListValues $prm $charCount
Тогда код работает.
Вы можете проигнорировать мой предыдущий комментарий, поскольку я предполагал, что ваше значение $ charCount было установлено равным количеству элементов. Но при ближайшем рассмотрении я вижу, что вы просто подсчитываете количество запятых, и поэтому количество элементов будет # запятые + 1 (если у вас> 1 элементов)
Кстати, $ charCount несколько избыточен, поскольку функция может решить это сама и сделает функцию более устойчивой, поскольку это устранит возможность передачи вызывающим кодом несогласованных значений.
Спасибо Дину за советы. Я не особо разбираюсь в Powershell. Я больше сторонник javascript и кода в этом смысле. Да, вы правы насчет функции, обрабатывающей $ charCount. Я просто переместил его, чтобы попытаться упростить и изолировать свою ошибку.