Trier une listbox
RésoluErich-Oueb Messages postés 5 Date d'inscription Statut Membre Dernière intervention -
Bonjour, je charge un fichier texte (zones séparées par ; et pas d'entêtes) dans une listebox. Je ne prends que la 1ère zone et je souhaiterais la triée et si possible sans doublons. J'ai essayé avec Sort-Object | Get-Unique mais ça ne fonctionne pas. Quelqu'un pourrait-il m'aider ?
Voici le code qui rempli la listebox :
$ListePC = New-Object System.Windows.Forms.ListBox
$ListePC.Location = New-Object System.Drawing.Point(350,40)
$ListePC.Size = New-Object System.Drawing.Size(300,20)
$ListePC.Height = 160
$Computers = Get-Content \\chemin\Parc.txt
foreach($Computer in $Computers)
{
$Zone=$Computer.split(';')
[void]$ListePC.items.add($Zone[0])
}
$form.Controls.Add($ListePC)
Windows / Edge 128.0.0.0
- Trier une listbox
- Excel trier par ordre croissant chiffre - Guide
- Logiciel pour trier les photos automatiquement - Guide
- Trier tableau word nom de famille - Forum Word
- Le fichier contient une liste de prénoms. triez ce tableau par ordre alphabétique des prénoms - Forum LibreOffice / OpenOffice
- Excel trier par date ne fonctionne pas ✓ - Forum Excel
2 réponses
Bonjour,
Pour faire cela, tu peux utiliser quelques fonctionnalités intégrées de PowerShell.
Get-Content "\\chemin\Parc.txt" | ForEach-Object { $_.split(';')[0] } extrait la première zone de chaque ligne.
Sort-Object | Select-Object -Unique trie la liste et élimine les doublons.
Ensuite, la boucle foreach ajoute chaque élément unique et trié à la ListBox.
# Création de la ListBox $ListePC = New-Object System.Windows.Forms.ListBox $ListePC.Location = New-Object System.Drawing.Point(350,40) $ListePC.Size = New-Object System.Drawing.Size(300,20) $ListePC.Height = 160 # Lecture du fichier et extraction de la première zone $Computers = Get-Content "\\chemin\Parc.txt" | ForEach-Object { $_.split(';')[0] } # Trier les éléments et supprimer les doublons $UniqueSortedComputers = $Computers | Sort-Object | Select-Object -Unique # Ajouter les éléments triés et uniques dans la ListBox foreach($Computer in $UniqueSortedComputers) { [void]$ListePC.items.add($Computer) } # Ajout de la ListBox au formulaire $form.Controls.Add($ListePC)
Oui, si tu veux afficher plusieurs colonnes dans ton interface graphique, comme la zone [2] et la zone [3] en plus de la zone [1] tout en triant par la zone [1], une ListView serait effectivement plus adaptée qu'une ListBox, car elle permet de gérer plusieurs colonnes.
Voici comment tu peux adapter ton script pour utiliser une ListView avec plusieurs colonnes, et trier les éléments uniquement en fonction de la première zone (zone [0]).
# Création de la ListView $ListView = New-Object System.Windows.Forms.ListView $ListView.Location = New-Object System.Drawing.Point(350,40) $ListView.Size = New-Object System.Drawing.Size(500,200) $ListView.View = [System.Windows.Forms.View]::Details $ListView.FullRowSelect = $true # Ajout des colonnes $ListView.Columns.Add("Zone 1", 150) # Pour afficher la zone [0] $ListView.Columns.Add("Zone 2", 150) # Pour afficher la zone [2] $ListView.Columns.Add("Zone 3", 150) # Pour afficher la zone [3] # Lecture du fichier et extraction des zones 1, 2 et 3 $Computers = Get-Content "\\chemin\Parc.txt" | ForEach-Object { $Zone = $_.split(';') [PSCustomObject]@{ Zone1 = $Zone[0] Zone2 = $Zone[2] Zone3 = $Zone[3] } } # Trier les éléments par Zone1 $SortedComputers = $Computers | Sort-Object Zone1 # Ajouter les éléments triés dans la ListView foreach($Computer in $SortedComputers) { $item = New-Object System.Windows.Forms.ListViewItem($Computer.Zone1) $item.SubItems.Add($Computer.Zone2) $item.SubItems.Add($Computer.Zone3) [void]$ListView.Items.Add($item) } # Ajout de la ListView au formulaire $form.Controls.Add($ListView)
La ListView est configurée avec trois colonnes (Zone 1, Zone 2, Zone 3).
Le mode d'affichage est défini sur Details pour pouvoir afficher les colonnes.
FullRowSelect permet de sélectionner toute la ligne.
Le fichier est lu et transformé en objets personnalisés (PSCustomObject) avec trois propriétés : Zone1, Zone2, et Zone3 correspondant aux zones [0], [2], et [3] du fichier.
Sort-Object Zone1 trie les éléments uniquement en fonction de la première zone (Zone1).
Pour chaque élément trié, un objet ListViewItem est créé avec la première zone comme élément principal, et les deux autres zones sont ajoutées en tant que SubItems.
Super, il manquait juste $ListView.Height = 160 (sinon on ne voyait que les entêtes des colonnes). Par contre, un truc tout bête, je ne trouve pas comment récupérer la Zone1 sélectionnée dans une variable ? Par exemple ci-dessous, ça m'affiche du blanc. J'ai essayé avec des propriétés .text ou .value mais pas mieux.
if ($ListView.SelectedItems) {
$NomPC = $ListView.SelectedItems.items[0]
[System.Windows.Forms.MessageBox]::Show($NomPC)
}
Pour récupérer l'élément sélectionné dans un ListView, la bonne méthode est d'accéder à la propriété Text de l'élément sélectionné. Le problème dans votre exemple est que vous tentez d'accéder à items[0] qui n'existe pas à ce stade.
Voici comment vous pouvez correctement récupérer la valeur de la Zone1 (première colonne) de l'élément sélectionné :
if ($ListView.SelectedItems.Count -gt 0) { # Récupérer le texte de la première colonne (Zone1) de l'élément sélectionné $NomPC = $ListView.SelectedItems[0].Text [System.Windows.Forms.MessageBox]::Show($NomPC) } else { [System.Windows.Forms.MessageBox]::Show("Aucun élément sélectionné.") }
Si vous souhaitez récupérer les valeurs des autres colonnes (par exemple Zone2 et Zone3), vous pouvez utiliser la propriété SubItems :
if ($ListView.SelectedItems.Count -gt 0) { $NomPC = $ListView.SelectedItems[0].Text # Zone 1 $Zone2 = $ListView.SelectedItems[0].SubItems[1].Text # Zone 2 $Zone3 = $ListView.SelectedItems[0].SubItems[2].Text # Zone 3 [System.Windows.Forms.MessageBox]::Show("Zone 1: $NomPC`nZone 2: $Zone2`nZone 3: $Zone3") }
$ListView.SelectedItems[0].SubItems[1].Text accède à la Zone2 (index 1).
$ListView.SelectedItems[0].SubItems[2].Text accède à la Zone3 (index 2).
Ainsi, vous pourrez afficher les différentes zones sélectionnées dans une boîte de message.
if ($ListView.SelectedItems.Count -gt 0) { # Récupérer les valeurs des différentes zones de l'élément sélectionné $Zone1 = $ListView.SelectedItems[0].Text # Zone 1 $Zone2 = $ListView.SelectedItems[0].SubItems[1].Text # Zone 2 $Zone3 = $ListView.SelectedItems[0].SubItems[2].Text # Zone 3 # Afficher les zones dans une boîte de message [System.Windows.Forms.MessageBox]::Show("Zone 1: $Zone1`nZone 2: $Zone2`nZone 3: $Zone3") } else { # Message si aucun élément n'est sélectionné [System.Windows.Forms.MessageBox]::Show("Aucun élément sélectionné.") }
Merci Bruno, en plus avec les commentaires ça parait si simple. Est-ce que je peux abuser en corsant le problème : si je veux afficher dans la listbox 2 autres zones du fichiers en plus par ex. [2] et [3] et ne trier que par rapport à la zone [1] , il faut que j'utilise listview je pense ?