Aide sur erreur code VBA svp

William77

XLDnaute Nouveau
Bonjour à tous,

Je crée un userform malheureusement une erreur s'est immiscée et je n'en trouve pas la cause.
Avant de poster ce message, j'ai regardé les solutions possible, mais je ne trouve pas ......

Pourriez-vous m'indiquer mon erreur dans le code mis en surbrillance par VBA excel?

VB:
Private Sub Cbx_article_Change()

Dim article As String

article = Me.Cbx_article.Value

'Rechercher dans la colonne article de la feuille 4
Part_prix = Application.VLookup(article, Sheets(4).Range("c:i"), 4, 0)
Part_stock = Application.VLookup(article, Sheets(4).Range("c:i"), 3, 0)

'Affichage des informations dans les labels associés
Me.Label_prix_unit.Caption = CCur(Part_prix) & " €"
Me.Label_stock.Caption = Part_stock

End Sub

Les variables Part_prix et Part_stock sont déclarées en Public en début de code.
J'avais testé avec worksheetfunction en lieu et place de Application, mais j'ai la même erreur.

Si besoin, je vous transmettrai le code entier.

Cordialement.
 

patricktoulon

XLDnaute Barbatruc
bonsoir
c'est l'abrégé d'evaluate de sheets("stock").range("F:F")

1°codage classique:

set plage=sheets("stock").range("F:F")

2°codage classique un peu différent :
set plage=range("stock!F:F")

3°codage avec evaluate
set plage=evaluate("stock!f:f ")

4°code avec evaluate abrégé
set plage= [stock!f:f]

voila tu sais tout ;)
 

soan

XLDnaute Barbatruc
Inactif
Bonjour Patrick,

J'aime mieux [stock!f:f] car c'est le plus court ; mais en termes de performances,
crois-tu que c'est plus lent via evaluate et plus rapide avec le plus long :
sheets("stock").range("F:F") ? ou c'est pareil ?

(ceci d'un point de vue général, pas seulement pour set plage=)

Si c'est dans une grande boucle, genre For i = 1 To 10 000 ..
Next i
, ce sera la même réponse ? ou ce sera différent ?


soan
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
Bonjour soan
c'est une très bonne question que tu pose là
en effet evaluate simplifie les choses mais en revanche fait travailler vba pour EVALUER l'expression entre crochet ou dans les parenthèses pour la version entière d'evaluate
il y a donc forcement une charge supplémentaire de mémoire et procc
bon la différence est difficilement contrôlable mais c'est un fait
mais si tu variablise le resultat de l evaluation tu a plus de soucis

alors selon le besoins il est préférable d'avoir tout en magasin mémoire pour exploiter plus vite

par exemple je veux examiner une plage de grande taille je vais me servir de variable tableau
ben pour simplifier l’écriture
je vais faire
montableau=[Stock!A1:J10000].value
ici on a simplifié l’écriture et je peux exploiter les valeurs dans un tableau

on a donc tout gagné

maintenant si je voulais faire un find ou travailler sur cellules
je dois donc variabiliser une plage
et bien je vais faire
set maplage=montableau[Stock!A1:J10000]

voila ou réside l'avantage d'evaluate


@job75 par exemple ;prétend une méthode bien a lui qui consiste a utiliser le resize
je n'ai pas eu la possibilité de vérifier mais ce serait une bonne chose
exemple:
montableau=[Stock!A1].resize(10000,10).value
tout simplement l'evaluation a eu a évaluer une seule cellule donc pas très lourd
reste a savoir si le resize ne génère pas une gourmande consommation
 
Dernière édition:

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonjour Patrick, Soan,
Just for the fun.
Je pensais que le compilo ne ferait pas de différence de temps entre les 4 propositions de Patrick.

J'ai fait une mesure de temps sur les 4 propal avec boucle de 100k sur un range de 5000.
Et, perturbant, j'obtiens en moyenne sur mon PC :

1°codage classique:
set plage=sheets("stock").range("F:F") 1200ms

2°codage classique un peu différent :

set plage=range("stock!F:F") 717ms

3°codage avec evaluate

set plage=evaluate("stock!f:f ") 4500ms

4°code avec evaluate abrégé

set plage= [stock!f:f] 4800ms

Cet écart me laisse pantois. Avez vous le même type d'écart ?
 

Pièces jointes

  • EssaiRange.xlsm
    56.2 KB · Affichages: 19

patricktoulon

XLDnaute Barbatruc
re
bonjour @sylvanu
c'est une mauvaise interprétation
en fait tu répete x fois l’opération et la mémoire se charge au fur et a mesure
donc a chaque fois que l’opération est effectuée la mémoire répondra différemment
ton test est donc pas concluant
pour qu'il soit concluant il faudrait vider la memoire a chaque tour de boucle
c'est une erreur d'interprétation que beaucoup font ;)

d'autant plus que tu inscrit le résultat dans une cell est c'est cela le plus gourmand
car le calcule timer-t s’arrête quand c'est inscrit
par exemple si je reprends ton code comme ceci je réduis les temps d'un tiers chez moi
mais je vide la variable certe mais pas vraiment la mémoire
c'est le defaut de vba

VB:
Sub essai()
Dim plage As Range, T0 As Long
[B:B].ClearContents
'----------------------------
T0 = Timer
For t = 1 To 100000
'1 °codage classique:
Set plage = Nothing
Set plage = Sheets("stock").Range("F1:F5000")
Next t
x = Int(1000 * (Timer - T0))
[B2] = x
'----------------------------
T0 = Timer
For t = 1 To 100000
'2°codage classique un peu différent :
Set plage = Nothing
Set plage = Range("stock!F1:F5000")
Next t
x = Int(1000 * (Timer - T0))
[B3] = x
'----------------------------
T0 = Timer
For t = 1 To 100000
'3°codage avec evaluate
Set plage = Nothing
Set plage = Evaluate("stock!f1:f5000")
Next t
x = Int(1000 * (Timer - T0))
[B4] = x
'----------------------------
T0 = Timer
For t = 1 To 100000
'4°code avec evaluate abrégé
Set plage = Nothing
Set plage = [stock!f1:f5000]
Next t
x = Int(1000 * (Timer - T0))
[B5] = x
'----------------------------
End Sub
 
Dernière édition:

sylvanu

XLDnaute Barbatruc
Supporter XLD
Re,
Je ne m’intéressais pas aux valeurs absolues. Et je suis d'accord avec vous. D'ailleurs on le voit sur la dispersion des mesures.
Mais comme les 4 structures sont identiques, ce qui m'a interpellé c'est l'écart de temps entre les soluces 1 et 2 par rapport à 3 et 4.On a un rapport 4.
C'est d'ailleurs répétables. Et si on inverse l'ordre des modules, on obtient toujours les même écarts.
( j'avais oublié de préciser: avec XL2007. peut être cela joue t-il )
 

patricktoulon

XLDnaute Barbatruc
re
C'est d'ailleurs répétables. Et si on inverse l'ordre des modules, on obtient toujours les même écarts.

j'etais justement en train de modifier l'ordre des modules pour te montrer la non pertinence
chez moi excel 2013
si je fait la plus lourde en premier de 5620 je tombe a 2374
vba n'a pas le temps de vider la mémoire

reste que evaluate est plus lourd ca c'est un fait
mais selon l'exploitation on le fait une fois et la c'est plus court ;)

c'est pour ca que ce test n'est pas valide
dans une boucle for i tu charge et change i a chaque tour donc deja ca
apres tu change plage meme si c'est la même tu réécrit en mémoire

perso je n'ai pas de soucis a utiliser evaluate
il est rare d'avoir besoins d'evaluer dans une plage dans une boucle ;)

ps je vien d'ajouter le test @job75 et si je tiens pas compte de ce que je viens de dire précedement c'est le plus long

module job75
T0 = Timer
For t = 1 To 100000
'4°code avec evaluate abrégé 1 cell + resize
Set plage = Nothing
Set plage = [stock!A1].Resize(5000, 6)
Next t
x = Int(1000 * (Timer - T0))
[B6] = x
 

patricktoulon

XLDnaute Barbatruc
un autre exemple
une autre methode un range evaluate + resize
car la l'adresse est entiere vba doit donc evaluer l'expression entre guillemets
a ma grande surprise c'est le plus rapide
nouveau module
T0 = Timer
For t = 1 To 100000
'4°code avec evaluate abrégé
Set plage = Nothing
Set plage = Range("stock!A1").Resize(5000, 6)
Next t
x = Int(1000 * (Timer - T0))
[B1] = x


chez moi 633
étonnant non?;)

donc job75 a raison
 
Dernière édition:

soan

XLDnaute Barbatruc
Inactif
Bonjour @sylvanu et @patricktoulon, le fil,

J'ai beaucoup tardé à répondre car j'ai été très pris par diverses affaires personnelles,
mais j'ai quand même lu attentivement tous les posts qui ont suivi mon post #19 :
du post #20 au post #26.


---------------------------------------------------------------------------------------------

Merci sylvanu pour avoir fait ton fichier très intéressant du post #20 ; à moi aussi,
ton écart me laisse pantois ; malgré les notes de patrick du post #21 (mauvaise
interprétation, vider la mémoire ou une variable), pour le fun, j'ai complété ton
fichier (qui est joint ci-dessous).


---------------------------------------------------------------------------------------------

Je n'ai pas bien compris tout ce qu'a écrit patrick dans le post #21 :

* « la mémoire se charge au fur et à mesure » : ce n'est pas tout simplement :
après qu'il y ait eu allocation mémoire, pour l'utilisation de cet emplacement
mémoire, ça écrit dedans la valeur voulue (nombre, texte, ou autre) ; et de
toute façon, au final, uniquement en binaire : que des 1 et des 0 ; c'est beau,
cette uniformisation, hein ? aussi miraculeux que le codage génétique d'une
chaîne d'ADN, lollll ! :p et en plus, c'est avec un simple PC : ce n'est même
pas avec un ordinateur biologique de 5ème ou 6ème génération ! à quand
l'ère de RoboCop ? des agents bioniques Steve Austin et Super Jaimie ?

* « vider la mémoire ou une variable » : pourquoi donc y aurait-il un vidage ?
et à quoi servirait-il ? pour moi : a) les variables globales de niveau module ne
sont pas initialisées lors de leur déclaration ; b) les variables locales d'une sub
ou d'une function sont initialisées à 0 pour les variables numériques, à une
chaîne vide "" pour les variables de type string, à null pour les variables de
type objet ; mais bon, s'il y a une vidange pour les voitures, faut croire qu'il
y a aussi une vidange pour la RAM des PC !
:p (des fois, je dois dégivrer
mon frigo, mais je sais pas si ça a un rapport)


---------------------------------------------------------------------------------------------

Si je me rappelle mes très vieux souvenirs de programmation en Turbo-Pascal,
la mémoire était allouée ainsi : la table des vecteurs d'interruptions (sur 1 Ko) ;
des données du BIOS ; le BIOS (IO.SYS) ; le DOS (MSDOS.SYS) ; les drivers qui
étaient chargés par CONFIG.SYS (éventuellement présent) ; l'interpréteur de
commandes (COMMAND.COM) ; les variables d'environnement (qui étaient
mises en place par CONFIG.SYS) ; les programmes résidents de type TSR
(Terminate and Stay Resident) ; le programme exécutable .exe (code compilé
du programme, dont les constantes et variables) ; le tas (Heap), sa gestion
étant faite par le HeapPointer (pointeur du tas).

Au-dessus de la mémoire conventionnelle, il y avait la mémoire haute : le bloc-
gruyère UMB (Upper Memory Bloc), pour des choses diverses telles que la RAM
Vidéo EGA, le BIOS des cartes ISA/PCI, le BIOS EGA, la fenêtre d'accès EMS.

Au-dessus encore, il y avait la zone du BIOS principal (qui était un mappage
de la ROM système).

Puis la zone HMA, la mémoire HMA étant les 64 premiers Ko de la RAM
étendue (les blocs XMS).

Et c'est ainsi que la fameuse « barrière des 640 Ko » avait pu être contournée
par un « extenseur DOS » : le driver EMM386.EXE permettait d'accéder à la
RAM située au-delà de 1 Mo, à condition de passer en mode protégé ; non,
je n'ai pas dit « située dans l'au-delà », ni « trépasser » ! :D

Je sais que les applications Windows (donc y compris Excel), ne s'embêtent pas
avec tout ça, puisque de toute façon Windows se réserve toute la RAM qui est
située à partir du 1er Mo ; mais peut-être qu'il doit vidanger la RAM de 640 Ko
conventionnelle, pour mieux faire table rase du passé ? et ainsi mieux pouvoir
continuer ses opérations, sans se morfondre et culpabiliser pour avoir renié ses
anciennes origines ; c'est pour ça qu'il y a autant de bugs Windows : le Dos se
venge en faisant planter Windows !!! :p


soan
 

Pièces jointes

  • EssaiRange.xlsm
    58.9 KB · Affichages: 3

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonjour tout le monde,
@soan,
autant de bugs Windows
Sérieux ? Cela fait des siècles que je n'ai pas vu d' "écran bleu". Si c'était vrai avec Win 95 ou Win98, depuis XP, Seven, Win10 les plantages sont inexistant.
Pour les temps, les ordres de grandeurs sont les mêmes. Ca dépend de tellement de paramètres, matériels et logiciels, que ce n'est pas significatif.

Par contre ce qui m' "interpelle" c'est que quatre formules faisant la même chose conduisent à des algos et des temps aussi différent. passer de 300 à 5000 ms, c'est vraiment étonnant.
Donc tant qu'à faire je vais adopter set plage=range("stock!F:F") qui est le plus rapide et simple à écrire.
 

soan

XLDnaute Barbatruc
Inactif
Re,

Pour les bugs Windows dont j'ai parlé, je ne pensais pas du tout aux écrans bleus !

Je pensais à tous les bugs Windows qu'il y a de nos jours, par exemple des mises
à jour de Windows qui font planter le PC ; ou carrément quand c'est Windows
Update lui-même qui plante, au point qu'il m'avait fallu utiliser un logiciel tiers
pour le débloquer : WSUS Offline Update.

Je parle ici pour mon Windows 7 ; mais je sais qu'il y a aussi le même genre
de problèmes avec Windows 8.0, 8.1, ou 10 ; peut-être pas pour le Update,
mais pour des mises à jour foireuses qui apportent plus d'inconvénients
que de vraies résolutions de problèmes.


soan
 

Statistiques des forums

Discussions
311 725
Messages
2 081 940
Membres
101 845
dernier inscrit
annesof