OVH Cloud OVH Cloud

Optimisation de mon code SVP ?

15 réponses
Avatar
Pascal
Bien le bonjour,
je cherche à optimiser cette partie de mon code
sachant que LstMotAnalyser est variable 18.000 pour un mot de 8 lettres et
plus au dessus
et que le champ à vérifier de la base Access en contient 18.059(pour un mot
de 8 lettres) et 20.000 pour un mot de 10 lettres
cela ne pose pas trop de problème tant que longueurMot = 6, a 8 cela traine
et pour un mot de 10, je peux partir faire mes courses!
j'avais penser à une requête ACCESS, mais ne connait pas suffisament que
pour mettre en place!
si KKun a une idée, voir une très bonne!, serai sympa de m'éclairer
bien à tous
Pascal


'-------------------------------------------------------------------------------------------
'défini le dico à ouvrir
Dim longueurMot As Byte
'prend la longueur du mot
longueurMot = Len(LstMotAnalyser.List(0))
'ouvre la base Access et la table coorespondante
Set db = DAO.Workspaces(0).OpenDatabase(MA_BASE_ACCESS, False,
False)

'compare les mots avec le Dico
' ouverture d 'une requête sur la table
Set rs = db.OpenRecordset("select*from[" & longueurMot & "];", ,
dbForwardOnly)

For f = 0 To Me.LstMotAnalyser.ListCount - 1
Do While Not rs.EOF
If InStr(1, rs.Fields(1).Value,
UCase(LstMotAnalyser.List(f))) > 0 Then
LstMotCompatible.AddItem LstMotAnalyser.List(f)
End If
'passe au suivant
rs.MoveNext
LstMotAnalyser.ListIndex = f
Loop
'repositionne l'index sur le premier
rs.MoveFirst
Next f
'referme la requete proprement
rs.Close
End Sub
'-------------------------------------------------------------------------------------------

5 réponses

1 2
Avatar
Pascal
Excellent Serial, je t'en remercie, je m'empresse de mettre cela en place
tu as bien compris je cherche un mot de n lettres dans une table ne
contenant que des mots de n lettres
j'ai créer en fait 14 Dicos allant de 2 à 15 lettres, ai préféré cette
technique pour limiter le parcours total du Dico, maintenant avec cette
requête, je peux revoir ma façon de faire! vais essayer les 2 possibilités


B àtoi
Pascal

"Serial # 19781010" a écrit dans le message de news:

On Tue, 9 Oct 2007 20:22:29 +0200, "Pascal"
wrote:

hello,
oui, InsStr est de type Variant (long)
le fait de passer de byte à Long, je gagne effectivement 4/10 secondes
sur
l'ensemble(test fait sur mot de 8 lettres)
Autre idée: du fait d'une base ACCESS, je pourrai créer une requête dans
la
base et faire appel à celle-ci à partir de VB6! mais comment ajouter le
résultat de ma requête dans un ListView?



J'inclurais la sélection dans la requête (pas la peine de ramener
toute la table pour chaque mot cherché). Il faudrait aussi indexer le
champ recherché dans chaque table de la base Access. Quelque chose
comme ça en supposant que le champ sur lequel porte la recherche soit
nommé "mot" :


Sub Main()

Dim db As DataBase
Dim sMotFind As String
Dim f As Long
Dim sSql As String
Dim longueurMot As Long
Dim rs As RecordSet

longueurMot = Len(LstMotAnalyser.List(0))
Set db = DAO.Workspaces(0).OpenDatabase(MA_BASE_ACCESS, False,
False)

For f = 0 To LstMotAnalyser.ListCount - 1
sMotFind = LstMotAnalyser.List(f)
sMotFind = Replace(sMotFind, "'", "''")
sSql ="select mot from [" & longueurMot & "] where mot like '" &
sMotFind & "*';"
Set rs = db.OpenRecordset(sSql,dbForwardOnly)
RstToList rs, LstMotCompatible
Next f

rs.Close
Set rs = Nothing
db.Close
Set db = Nothing

End Sub

Private Function RstToList(rs As RecordSet, lst As ListBox)

Do While Not rs.EOF
lst.AddItem rs.Filed("mot")
rs.MoveNext
Loop

End Function


Ceci dit, j'ai l'impression que tu cherches un mot de n lettres dans
une table ne contenant que des mots de n lettres. Auquel cas la clause
where pourrait même se simplifier en "where mot ='" & sMotFind & "';"
(ce qui serait plus rapide et plus besoin de parcourir le recordset
dans ce cas : s'il est vide le mot n'existe pas, sinon il existe et on
l'ajoute à la liste). D'autre part, on pourrait aussi grouper
plusieurs critères dans chaque requête.



Avatar
Pascal
hello Serial
n'y connaissant pas grand chose dans les requêtes, je te sollicite à nouveau
ai une erreur d'excecution : Argument non valide erreur 3001 arrêt sur cette
ligne
Set rs = db.OpenRecordset(sSql, dbForwardOnly)

merci
Pascal


"Serial # 19781010" a écrit dans le message de news:

On Tue, 9 Oct 2007 20:22:29 +0200, "Pascal"
wrote:

hello,
oui, InsStr est de type Variant (long)
le fait de passer de byte à Long, je gagne effectivement 4/10 secondes
sur
l'ensemble(test fait sur mot de 8 lettres)
Autre idée: du fait d'une base ACCESS, je pourrai créer une requête dans
la
base et faire appel à celle-ci à partir de VB6! mais comment ajouter le
résultat de ma requête dans un ListView?



J'inclurais la sélection dans la requête (pas la peine de ramener
toute la table pour chaque mot cherché). Il faudrait aussi indexer le
champ recherché dans chaque table de la base Access. Quelque chose
comme ça en supposant que le champ sur lequel porte la recherche soit
nommé "mot" :


Sub Main()

Dim db As DataBase
Dim sMotFind As String
Dim f As Long
Dim sSql As String
Dim longueurMot As Long
Dim rs As RecordSet

longueurMot = Len(LstMotAnalyser.List(0))
Set db = DAO.Workspaces(0).OpenDatabase(MA_BASE_ACCESS, False,
False)

For f = 0 To LstMotAnalyser.ListCount - 1
sMotFind = LstMotAnalyser.List(f)
sMotFind = Replace(sMotFind, "'", "''")
sSql ="select mot from [" & longueurMot & "] where mot like '" &
sMotFind & "*';"
Set rs = db.OpenRecordset(sSql,dbForwardOnly)
RstToList rs, LstMotCompatible
Next f

rs.Close
Set rs = Nothing
db.Close
Set db = Nothing

End Sub

Private Function RstToList(rs As RecordSet, lst As ListBox)

Do While Not rs.EOF
lst.AddItem rs.Filed("mot")
rs.MoveNext
Loop

End Function


Ceci dit, j'ai l'impression que tu cherches un mot de n lettres dans
une table ne contenant que des mots de n lettres. Auquel cas la clause
where pourrait même se simplifier en "where mot ='" & sMotFind & "';"
(ce qui serait plus rapide et plus besoin de parcourir le recordset
dans ce cas : s'il est vide le mot n'existe pas, sinon il existe et on
l'ajoute à la liste). D'autre part, on pourrait aussi grouper
plusieurs critères dans chaque requête.



Avatar
Pascal
hello,
ai trouvé le pourquoi, il faut mettre virgule avant dbforwardonly
merci pour ce code HYPER rapide, je suis ravi d'avoir appris cette technique
Bàtoi
Pascal

Set rs = db.OpenRecordset(sSql, dbForwardOnly) => Set rs =
db.OpenRecordset(sSql, ,dbForwardOnly)




"Pascal" a écrit dans le message de news:
%
hello Serial
n'y connaissant pas grand chose dans les requêtes, je te sollicite à
nouveau
ai une erreur d'excecution : Argument non valide erreur 3001 arrêt sur
cette ligne
Set rs = db.OpenRecordset(sSql, dbForwardOnly)

merci
Pascal


"Serial # 19781010" a écrit dans le message de news:

On Tue, 9 Oct 2007 20:22:29 +0200, "Pascal"
wrote:

hello,
oui, InsStr est de type Variant (long)
le fait de passer de byte à Long, je gagne effectivement 4/10 secondes
sur
l'ensemble(test fait sur mot de 8 lettres)
Autre idée: du fait d'une base ACCESS, je pourrai créer une requête dans
la
base et faire appel à celle-ci à partir de VB6! mais comment ajouter le
résultat de ma requête dans un ListView?



J'inclurais la sélection dans la requête (pas la peine de ramener
toute la table pour chaque mot cherché). Il faudrait aussi indexer le
champ recherché dans chaque table de la base Access. Quelque chose
comme ça en supposant que le champ sur lequel porte la recherche soit
nommé "mot" :


Sub Main()

Dim db As DataBase
Dim sMotFind As String
Dim f As Long
Dim sSql As String
Dim longueurMot As Long
Dim rs As RecordSet

longueurMot = Len(LstMotAnalyser.List(0))
Set db = DAO.Workspaces(0).OpenDatabase(MA_BASE_ACCESS, False,
False)

For f = 0 To LstMotAnalyser.ListCount - 1
sMotFind = LstMotAnalyser.List(f)
sMotFind = Replace(sMotFind, "'", "''")
sSql ="select mot from [" & longueurMot & "] where mot like '" &
sMotFind & "*';"
Set rs = db.OpenRecordset(sSql,dbForwardOnly)
RstToList rs, LstMotCompatible
Next f

rs.Close
Set rs = Nothing
db.Close
Set db = Nothing

End Sub

Private Function RstToList(rs As RecordSet, lst As ListBox)

Do While Not rs.EOF
lst.AddItem rs.Filed("mot")
rs.MoveNext
Loop

End Function


Ceci dit, j'ai l'impression que tu cherches un mot de n lettres dans
une table ne contenant que des mots de n lettres. Auquel cas la clause
where pourrait même se simplifier en "where mot ='" & sMotFind & "';"
(ce qui serait plus rapide et plus besoin de parcourir le recordset
dans ce cas : s'il est vide le mot n'existe pas, sinon il existe et on
l'ajoute à la liste). D'autre part, on pourrait aussi grouper
plusieurs critères dans chaque requête.






Avatar
parci
On Thu, 11 Oct 2007 11:27:15 +0200, "Pascal"
wrote:

hello,
ai trouvé le pourquoi, il faut mettre virgule avant dbforwardonly
merci pour ce code HYPER rapide, je suis ravi d'avoir appris cette technique
Bàtoi
Pascal

Set rs = db.OpenRecordset(sSql, dbForwardOnly) => Set rs =
db.OpenRecordset(sSql, ,dbForwardOnly)





Oui (mauvais copier/coller de ma part) ou de préférence :
Set rs = db.OpenRecordset(sSql, dbOpenForwardOnly)

D'autre part, puisque tu recherches des mots de même longueur, il sera
beaucoup plus rapide de tester l'égalité dans la clause where (where
mot = '"& sMotFind & "';").

J'imagine que la liste des mots à analyser avec 18000 occurrences
n'est pas saisie à la main. Pour optimiser encore, le mieux serait de
charger ces mots (à partir d'un fichier?) dans une table et de faire
une jointure dans ta requête avec la table des mots de référence. Je
ne sais pas ce que ton programme doit faire mais de toute façon il
n'est pas très réaliste d'afficher une liste avec 18000 occurrences
(pense à l'utilisateur : qu'est ce qu'il peut en faire ?).

Et je vois que tu as des doublons : tu peux les éviter en ajoutant le
mot clé distinct à la requête sql (select distinct mot from ...)

A+
Avatar
Pascal
hello parci,

D'autre part, puisque tu recherches des mots de même longueur, il sera


beaucoup plus rapide de tester l'égalité dans la clause where (where
mot = '"& sMotFind & "';").



oui c'est ce qui à été fait

J'imagine que la liste des mots à analyser avec 18000 occurrences
n'est pas saisie à la main. Pour optimiser encore, le mieux serait de
charger ces mots (à partir d'un fichier?) dans une table et de faire
une jointure dans ta requête avec la table des mots de référence. Je
ne sais pas ce que ton programme doit faire mais de toute façon il
n'est pas très réaliste d'afficher une liste avec 18000 occurrences
(pense à l'utilisateur : qu'est ce qu'il peut en faire ?).



c'est effectivement ce qui est fait chargement à partir d'une table
cette liste n'est pas affichée car pas d'utlité


Et je vois que tu as des doublons : tu peux les éviter en ajoutant le
mot clé distinct à la requête sql (select distinct mot from ...)



ca c'est génial, ceci m'évitera de retraiter la liste
grand merci

Pascal
1 2