PowerShell prüfen, ob Wert in Array schon da ist
Hallo Community,
ich versuche mich in PowerShell einzuarbeiten und komme momentan nicht weiter.
Ich will ein Arrey mit zahlen füllen, doppelte Eingaben jedoch vermeiden, da der Inhalt nacheinander abgearbeitet werden soll.
hier mein Code:
Das funktioniert in dieser Form, wie ich es mir vorstelle. Wenn ich jedoch die Prüfung aktiviere, ob eine Filiale schon eingegeben wurde, passiert nichts und es wird doppelt eingetragen. Ich vermute, dass zum Zeitpunkt der Prüfung der Inhalt von $Filialliste nicht bekannt ist.
Kann mich bitte jemand erleuchten?
Danke!
ich versuche mich in PowerShell einzuarbeiten und komme momentan nicht weiter.
Ich will ein Arrey mit zahlen füllen, doppelte Eingaben jedoch vermeiden, da der Inhalt nacheinander abgearbeitet werden soll.
hier mein Code:
write-host
"
Filialnummern:
Ort1 = 1
Ort2 = 2
Ort3 = 3
Ort4 = 4
Ort5 = 5
Programm beenden = 6
$Filialliste = @()
do {
$input = (Read-Host "Bitte die Filiale auswaehlen, beenden mit 6")
if ($input -lt '1') { write-host 'Die Eingabe ist keine Zahl zwischen 1 und 6' -foregroundcolor red }
elseif ($input -gt '6') { write-host 'Die Eingabe ist keine Zahl zwischen 1 und 6' -foregroundcolor red }
elseif ($input -ne '') {$Filialliste += $input}
#elseif ($Filialliste -contains $input) {write-host 'Die Filiale ist schon vorhanden' -foregroundcolor red }
#elseif ($Filialliste.Contains("1")) {Write-Host "Eintrag vorhanden"} else {Write-Host "Eintrag nicht vorhanden"}
}
#Loop will stop when user enter '6' as input
until ($input -eq '6')
$Filialliste
Das funktioniert in dieser Form, wie ich es mir vorstelle. Wenn ich jedoch die Prüfung aktiviere, ob eine Filiale schon eingegeben wurde, passiert nichts und es wird doppelt eingetragen. Ich vermute, dass zum Zeitpunkt der Prüfung der Inhalt von $Filialliste nicht bekannt ist.
Kann mich bitte jemand erleuchten?
Danke!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 3019990677
Url: https://administrator.de/contentid/3019990677
Ausgedruckt am: 17.11.2024 um 23:11 Uhr
10 Kommentare
Neuester Kommentar
Moin,
zwei Dinge:
Ich würde das Array am Ende noch mal neu aufbauen lassen, nur mit | Get-Unique abschließend
Dein Fehler ist zudem die Reihenfolge der Prüfung: Es gilt "First Match Wins"
du hast in Zeile 17 immer geprüft, ob das Feld nicht leer ist, wenn ja, ergänze. Weitere Prüfungen greifen dann nicht mehr. Hier mal, wie es aussehen könnte
Gruß
em-pie
zwei Dinge:
- es heißt Array, nicht Arrey
- Nutze Get-Unique()
Ich würde das Array am Ende noch mal neu aufbauen lassen, nur mit | Get-Unique abschließend
Dein Fehler ist zudem die Reihenfolge der Prüfung: Es gilt "First Match Wins"
du hast in Zeile 17 immer geprüft, ob das Feld nicht leer ist, wenn ja, ergänze. Weitere Prüfungen greifen dann nicht mehr. Hier mal, wie es aussehen könnte
$Filialliste = @()
write-host "
Filialnummern: `r`n
[1] = Ort1
[2] = Ort2
[3] = Ort3
[4] = Ort4
[5] = Ort5
[6] = Programm beenden`r`n"
do {
$i = Read-Host -Prompt 'Bitte die Filiale auswaehlen, beenden mit 6'
if ($Filialliste -contains $i) {write-host "Die Filiale ist schon vorhanden" -foregroundcolor red }
elseif ($i -ge 1 -and $i -le 5) {$Filialliste += $i}
else {write-host "Die Eingabe '$i' ist keine Zahl zwischen 1 und 6" -foregroundcolor red }
}
#Loop will stop when user enter '6' as input
until ($i -eq 6)
$Filialliste
Gruß
em-pie
Moin,
ich würde mir die Ganze Überprüferei einfach sparen.
Wenn du willst, dass der Nutzer nur Eingaben von 1-6 tätigt, lass einfach keine anderen zu
Gruß Thomas
ich würde mir die Ganze Überprüferei einfach sparen.
Wenn du willst, dass der Nutzer nur Eingaben von 1-6 tätigt, lass einfach keine anderen zu
@"
Filialnummern:
[1] = Ort1
[2] = Ort2
[3] = Ort3
[4] = Ort4
[5] = Ort5
[6] = Programm beende
"@
write-host -NoNewLine "Auswahl: "
# Frage nach Eingabe, bis diese eine Zahl von 1-6 enthält
do {$Eingabe = [console]::ReadKey($true).Keychar} until (1..6 -Contains "$Eingabe")
write-host $Eingabe
Gruß Thomas
Zitat von @conquestador:
ich verstehe deinen Code noch nicht ganz, nehme es aber als Studiengrundlage
An welchem Teil hakt es denn mit dem Verständnis?ich verstehe deinen Code noch nicht ganz, nehme es aber als Studiengrundlage
Moin,
Und genau aus dem Grund rate ich allen immer: Finger weg von der ISE!!!
Die Produziert zum Teil andere Ausgaben als die Richtige Shell - was aber will man mit einer IDE, wenn das fertige Skript hinterher gänzlich anders abläuft?!
Wenn man unbedingt eine IDE benötigt, sollte man lieber Visual Studio Code nutzen.
Ich persönlich schreibe alle Skripte einfach mit Notepad++.
Wenn man sich dort unter "Ausführen > Externes Programm ausführen" folgenden Befehl abspeichert, kann man die Skripte auch bequem daraus ausführen (das Skript muss nur vorher immer gespeichert werden):
Zur Info: '$(CURRENT_DIRECTORY)' und '$(FILE_NAME)' sind bei diesem Befehl Variablen von Notepad++, nicht von Powershell.
Gruß Thomas
Zitat von @conquestador:
Die ISE macht ein Endlosloop beim Testen. Hier der Fehlertext:
Der Fehler ist ja eindeutig: Die ISE besitzt keine Konsole, kann daher die Read-Key Methode auch nicht ausführen.Die ISE macht ein Endlosloop beim Testen. Hier der Fehlertext:
Ausnahme beim Aufrufen von "ReadKey" mit 1 Argument(en): "Schlüssel können
nicht gelesen werden, wenn keine der Anwendungen eine Konsole besitzt, oder
wenn die Konsoleneingabe aus einer Datei umgeleitet wurde. Verwenden Sie
Console.Read."
In Zeile:15 Zeichen:5
+ do {$Eingabe = [console]::ReadKey($true).Keychar} until (1..6 -Contai ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) , MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
Und genau aus dem Grund rate ich allen immer: Finger weg von der ISE!!!
Die Produziert zum Teil andere Ausgaben als die Richtige Shell - was aber will man mit einer IDE, wenn das fertige Skript hinterher gänzlich anders abläuft?!
Wenn man unbedingt eine IDE benötigt, sollte man lieber Visual Studio Code nutzen.
Ich persönlich schreibe alle Skripte einfach mit Notepad++.
Wenn man sich dort unter "Ausführen > Externes Programm ausführen" folgenden Befehl abspeichert, kann man die Skripte auch bequem daraus ausführen (das Skript muss nur vorher immer gespeichert werden):
powershell -NoExit -ExecutionPolicy ByPass -Command "cd -Lit '$(CURRENT_DIRECTORY)';. '.\$(FILE_NAME)'"
Gruß Thomas
Moin,
oder willst du, das der Benutzer eine Auswahl aus den Filialen treffen kann?
Dies geht viel leichter und sogar mit GUI:
Da kann man einfach eine Mehrfachauswahl treffen.
Aber um auch deinen bisherigen Versuch zu vervollständigen, etwa so:
Dann in Aktion:
Oder sogar eine Enumeration als Bit-Flags. Diese besitzt den Vorteil, dass auch jede Kombinationsmöglichkeit der einzelnen Filialen einen eigenen Wert besitzt:
in Aktion:
Gruß Thomas
Leider bekomme ich deinen Code nicht integriert. Nehme ich dein Beispiel und führe es in sich geschlossen aus, kann ich einmalig eine Zahl zwischen 1 und 6 einfügen. Jetzt will ich aber damit ein Array befüllen. Das funktioniert nicht. Was mache ich falsch?
das liegt u.a. daran, dass mir nicht ganz klar war, was genau du bezwecken willst. Du kannst leicht einen Array von 1-5 füllen:$ArrayFilialliste = 1..5
oder willst du, das der Benutzer eine Auswahl aus den Filialen treffen kann?
Dies geht viel leichter und sogar mit GUI:
$Filialen = @(
"Hamburg"
"München"
"Frankfurt"
"Köln"
"Stuttgart"
)
$Auswahl = $Filialen | Out-Gridview -Title "Bitte Filialen auswählen: " -Passthru
"Folgende Filialen wurden ausgewählt: "
$Auswahl
Aber um auch deinen bisherigen Versuch zu vervollständigen, etwa so:
@"
Filialnummern:
Ort1 = 1
Ort2 = 2
Ort3 = 3
Ort4 = 4
Ort5 = 5
Eingabe beenden = 6
"@
while ($true) {
Write-Host -NoNewLine "Auswahl: "
# Nach Eingabe fragen, bis diese eine Zahl von 1-6 enthält
do {$Eingabe = [Console]::ReadKey($true).KeyChar} until (1..6 -Contains "$Eingabe")
# Wenn 6, While-Schleife beenden
if ("$Eingabe" -eq 6) {break}
# Wenn Auswahl schon vorhanden
if ($FilialAuswahl -Contains $Eingabe) {Write-host -ForegroundColor Yellow "`rFiliale $Eingabe ist schon in Auswahl vorhanden. "}
else {
[Array]$FilialAuswahl += $Eingabe
Write-Host -ForegroundColor Green "`rFiliale $Eingabe wurde hinzugefügt"
}
}
write-host "`rGewähle Filialen: "
$FilialAuswahl | Sort
Was für dich dann auch noch interessant sein könnte dürfte: Enumerationen
So werden den Filialen direkt ihrer persönliche Nummer zugewiesen - und du kannst die Filialnummer ganz leicht in den Filialnamen oder umgekehrt den Namen in die nummer konvertieren. Beispiel:Enum Filiale {
Hamburg = 1
München = 2
Frankfurt = 3
Köln = 4
Stuttgart = 5
}
PS C:\Users\Thomas> [Filiale]3
Frankfurt
PS C:\Users\Thomas> [int][Filiale]"Stuttgart"
5
Oder sogar eine Enumeration als Bit-Flags. Diese besitzt den Vorteil, dass auch jede Kombinationsmöglichkeit der einzelnen Filialen einen eigenen Wert besitzt:
[Flags()] Enum Filiale {
Hamburg = 1
München = 2
Frankfurt = 4
Köln = 8
Stuttgart = 16
}
PS C:\Users\Thomas> [Filiale]25
Hamburg, Köln, Stuttgart
PS C:\Users\Thomas> [int][Filiale]("Hamburg","München","Stuttgart")
19
PS C:\Users\Thomas> 1..31 | Foreach-Object {
>> [pscustomobject]@{
>> Nummer = $_
>> Wert = [Filiale]$_
>> }
>> }
Nummer Wert
------ ----
1 Hamburg
2 München
3 Hamburg, München
4 Frankfurt
5 Hamburg, Frankfurt
6 München, Frankfurt
7 Hamburg, München, Frankfurt
8 Köln
9 Hamburg, Köln
10 München, Köln
11 Hamburg, München, Köln
12 Frankfurt, Köln
13 Hamburg, Frankfurt, Köln
14 München, Frankfurt, Köln
15 Hamburg, München, Frankfurt, Köln
16 Stuttgart
17 Hamburg, Stuttgart
18 München, Stuttgart
19 Hamburg, München, Stuttgart
20 Frankfurt, Stuttgart
21 Hamburg, Frankfurt, Stuttgart
22 München, Frankfurt, Stuttgart
23 Hamburg, München, Frankfurt, Stuttgart
24 Köln, Stuttgart
25 Hamburg, Köln, Stuttgart
26 München, Köln, Stuttgart
27 Hamburg, München, Köln, Stuttgart
28 Frankfurt, Köln, Stuttgart
29 Hamburg, Frankfurt, Köln, Stuttgart
30 München, Frankfurt, Köln, Stuttgart
31 Hamburg, München, Frankfurt, Köln, Stuttgart
Gruß Thomas