[Basic] Recherche incrémentale sur Zone de liste

Vos meilleures macros et portions de code sont publiées dans cette section.
Aucun support sur une question de programmation ici !

Modérateur : Vilains modOOs

Règles du forum
Aucune question dans cette section !
Celle-ci rassemble les meilleures macros et portions de code. Vous pouvez en revanche commenter ou argumenter le code exposé. Vous pouvez même remercier l'auteur (cela fait toujours plaisir) en indiquant par exemple dans quel cadre ou contexte vous en avez eu l'utilité.
Si vous avez à poster quelque chose, faites-le depuis la section Macros et API et demandez à un modérateur de l'y déplacer.
Piaf
GourOOu
GourOOu
Messages : 5622
Inscription : 25 nov. 2011 19:07
Localisation : Guyane

[Basic] Recherche incrémentale sur Zone de liste

Message par Piaf »

Bonjour
La recherche dans les longues Zones de liste pouvant être rapidement fastidieuse, je vous propose une petite solution (à tester bien sur :lol: )
Le principe :
à partir d'un contrôle Zone de texte, effectuer une recherche lettre par lettre sur une Zone de liste.

J’ai préféré utiliser un formulaire par flemme de faire un dialogue :D .

Les données de la liste sont stockées dans un fichier texte et récupérées à l’ouverture du document dans un tableau déclaré en Global.
J’avais commencé par la liste complète des villes françaises, mais j’ai dû revenir à une liste moins longue (un peu plus de mille enregistrements).
Le tableau est utilisé pour remplir la liste.

La recherche peut s’effectuer soit sur le code postal, soit sur le nom de la ville.
FormVilles.png
le bouton « CP » bascule la recherche d’un mode à l’autre.

Les macros :
La macro LireFichier dimensionne le tableau, le rempli avec les données du fichier texte, renseigne la liste et initialise la zone de texte de recherche et le bouton de bascule.
Elle est déclenchée à l'ouverture du document.

Code : Tout sélectionner

Sub LireFichier()
Dim monTexte As Object, SFA As Object, flux As Object
Dim uneLigne As String, URLfich As String
Dim X as Long
Dim fenetre as Object,Inverse as Object,txtRecherche as Object
On Error Goto LireFichier_Err
	oForm = thisComponent.DrawPage.Forms.getByName("Formulaire")
	fenetre = thisComponent.CurrentController.Frame.ContainerWindow
	thisComponent.lockControllers
	fenetre.Enable = False
	URLfich = getDirectory(thisComponent.URL) & "Bretagne.csv"
	SFA = createUnoService("com.sun.star.ucb.SimpleFileAccess")
	flux = SFA.openFileRead(URLfich)
	monTexte = createUnoService("com.sun.star.io.TextInputStream")
	monTexte.InputStream = flux
	monTexte.Encoding = "utf-8"
	X = 0
	Do While Not monTexte.isEOF
		uneLigne = monTexte.readLine
		If X = 0 Then 
			ReDim monTab(CLng(uneLigne))
			X = X + 1
		Else	
			monTab(x - 1) = uneLigne
			X = X + 1
		End If	
	Loop
	maListe = oForm.getbyName("maListe")
	maListe.StringItemList = monTab()
	Inverse = oForm.getByName("BasculeCPV")
	txtRecherche  = oForm.getByName("FiltreCP")
	Inverse.Label = "CP"
	txtRecherche.Text = ""
	txtRecherche.MaxTextLen = 5
	oForm.getbyName("lblCount").Label = maliste.ItemCount & " Enregistrement(s)"
	thisComponent.unlockControllers
	fenetre.Enable = True
	flux.closeInput
	monTexte.closeInput
	On Error Goto 0
	Exit Sub
LireFichier_Err:
	Resume LireFichier_Exit
LireFichier_Exit:
	On Error Resume Next
	flux.closeOutput
	monTexte.closeOutput
	thisComponent.unlockControllers
	fenetre.Enable = True
	MsgBox("Erreur " & err & ": " & Error$ & chr(13) & "à la ligne : " & Erl,16,"Une erreur s'est produite")
	On Error Goto 0		
End Sub
La macro ToucheKeyCode limite les touches utilisables en fonction du type de recherche.
Elle est déclenchée sur l'événement Touche enfoncée de la zone de texte de recherche.

Code : Tout sélectionner

Sub ToucheKeyCode(oEv as Object)
Dim Inverse as Object, vueCtrl as Object,awtSel as Object
	oForm = thisComponent.DrawPage.Forms.getByName("Formulaire")
	Inverse = oForm.getByName("BasculeCPV")
	Select Case Inverse.Label
		Case "CP"
			oEv.Source.Model.MaxTextLen = 5
			Select Case oEv.KeyCode
				Case 256 To 265
				Case 1283
				Case Else
					MsgBox("Vous ne pouvez taper qu'un caractère numérique",16,"Caractère invalide")
					oEv.source.Model.Text = ""
					MAJListe
			End Select
		Case "Villes"
			oEv.Source.Model.MaxTextLen = 10
			Select Case oEv.KeyCode
				Case 512 To 537
				Case 1288
				Case 1283
				Case Else
					MsgBox("Vous ne pouvez taper qu'une lettre",16,"Caractère invalide")
					vueCtrl = thiscomponent.CurrentController.getControl(oEv.Source.Model)
					awtSel = vueCtrl.Selection
					oEv.source.Model.Text = Left(oEv.source.Model.Text, Len(oEv.source.Model.Text) - 1)
					awtSel.min = awtsel.min -1
					vueCtrl.SetSelection(awtSel)
					MAJListe
			End Select	
	End Select		
End Sub
La macro BasculeClic, alterne le mode de recherche.
Elle est déclenchée par le bouton « CP ».

Code : Tout sélectionner

[code]Sub BasculeClic(oEv as Object)
Dim TxtRecherche as Object, vueRecherche as Object
	oForm = oEv.Source.Model.Parent
	txtRecherche  = oForm.getByName("FiltreCP")
	vueRecherche = thisComponent.CurrentController.getControl(txtRecherche)
	Select Case oEv.Source.Model.Label
        Case "CP"
            oEv.Source.Model.Label = "Villes"
        Case "Villes"
            oEv.Source.Model.Label = "CP"
    End Select
	txtRecherche.Text = ""
	MAJListe
	vueRecherche.setFocus
End Sub
la macro MAJListe filtre la liste des villes en fonction du texte tapé dans la zone de texte en remplissant un deuxième tableau avec les enregistrements correspondants aux critères de filtre.
Si la zone de texte de recherche est vide, la source de la liste est le tableau initial.
Elle est déclenchée sur l'événement Texte modifié de la zone de texte et appelée par d’autres procédures.
Sub MAJListe()
Dim Inverse as Object
Dim x as Long, txt as String, i as Integer
oForm = thisComponent.DrawPage.Forms.getByName("Formulaire")
maListe = oForm.getbyName("maListe")
Inverse = oForm.getByName("BasculeCPV")
x = 0
txt = oForm.getByName("FiltreCP").Text
If Len(txt) = 0 Then
maListe.StringItemList = monTab()
maListe.Refresh
oForm.getbyName("lblCount").Label = maliste.ItemCount & " Enregistrement(s)"
Else
Redim monTab2()
Select Case Inverse.Label
Case "CP"
For i = LBound(monTab()) to UBound(monTab())
If Left(monTab(i),Len(txt)) = acCapSansAccent(txt) Then
Redim Preserve monTab2(x)
monTab2(X) = monTab(i)
X = X + 1
End If
Next
Case "Villes"
For i = LBound(monTab()) to UBound(monTab())
If Mid(monTab(i),9,Len(txt)) = acCapSansAccent(txt) Then
Redim Preserve monTab2(x)
monTab2(X) = monTab(i)
X = X + 1
End If
Next
End Select
maListe.StringItemList = montab2()
oForm.getbyName("lblCount").Label = maliste.ItemCount & " Enregistrement(s)"
End If
End Sub[/code]
Pour la comparaison des caractères tapés en mode « Ville », j'utilise une fonction récupérée sur le Forum Contrôle de texte en majuscule
Toutes corrections, suggestions etc... seront les bienvenues.
 Ajout : Une petite mise à jour dans la macro ToucheKeyCode sur la limitation de la saisie des lettres.
La macro est changée ainsi que le fichier. 
A+
Pièces jointes
Increment.zip
(24.92 Kio) Téléchargé 432 fois
Libre Office Version: 6.1.6 et Apache OpenOffice 4.1.6 Sur Xubuntu 18.04 AMD64
Répondre