Erreur 424... objet requis
Résolu
Bonjour,
selon la grandeur de la valeur en cellule D, je souhaite multiplier celle-ci par un coef différent et à renvoyer le résultat en colonne G.
Je débute tant bien que mal dans le monde épanouissant de VBA et rencontre des difficultés à desceller mes erreurs... Merci d'avance pour votre aide !
Je vous met ci-dessous ma macro.
cdt
Guillaume
Private Sub CommandButton1_Click()
Dim L As Integer
Dim c As Integer
L = target.Row
c = target.Column
If Not Range("D" & L) Is Empty Then
If Range("D" & L).Value <= 5 Then Range("G" & L) = Range("D" & L).Value * 8
If Range("D" & L).Value > 5 And Range("D" & L).Value <= 10 Then Range("G" & L) = Range("D" & L).Value * 7
If Range("D" & L).Value > 10 And Range("D" & L).Value <= 20 Then Range("G" & L) = Range("D" & L).Value * 5
If Range("D" & L).Value > 20 And Range("D" & L).Value <= 30 Then Range("G" & L) = Range("D" & L).Value * 4.5
If Range("D" & L).Value > 30 And Range("D" & L).Value <= 50 Then Range("G" & L) = Range("D" & L).Value * 4
If Range("D" & L).Value > 50 And Range("D" & L).Value <= 70 Then Range("G" & L) = Range("D" & L).Value * 3.5
If Range("D" & L).Value > 70 And Range("D" & L).Value <= 100 Then Range("G" & L) = Range("D" & L).Value * 3
If Range("D" & L).Value > 100 And Range("D" & L).Value <= 250 Then Range("G" & L) = Range("D" & L).Value * 2.5
If Range("D" & L).Value > 250 Then Range("G" & L) = Range("D" & L).Value * 1.5
End If
End Sub
selon la grandeur de la valeur en cellule D, je souhaite multiplier celle-ci par un coef différent et à renvoyer le résultat en colonne G.
Je débute tant bien que mal dans le monde épanouissant de VBA et rencontre des difficultés à desceller mes erreurs... Merci d'avance pour votre aide !
Je vous met ci-dessous ma macro.
cdt
Guillaume
Private Sub CommandButton1_Click()
Dim L As Integer
Dim c As Integer
L = target.Row
c = target.Column
If Not Range("D" & L) Is Empty Then
If Range("D" & L).Value <= 5 Then Range("G" & L) = Range("D" & L).Value * 8
If Range("D" & L).Value > 5 And Range("D" & L).Value <= 10 Then Range("G" & L) = Range("D" & L).Value * 7
If Range("D" & L).Value > 10 And Range("D" & L).Value <= 20 Then Range("G" & L) = Range("D" & L).Value * 5
If Range("D" & L).Value > 20 And Range("D" & L).Value <= 30 Then Range("G" & L) = Range("D" & L).Value * 4.5
If Range("D" & L).Value > 30 And Range("D" & L).Value <= 50 Then Range("G" & L) = Range("D" & L).Value * 4
If Range("D" & L).Value > 50 And Range("D" & L).Value <= 70 Then Range("G" & L) = Range("D" & L).Value * 3.5
If Range("D" & L).Value > 70 And Range("D" & L).Value <= 100 Then Range("G" & L) = Range("D" & L).Value * 3
If Range("D" & L).Value > 100 And Range("D" & L).Value <= 250 Then Range("G" & L) = Range("D" & L).Value * 2.5
If Range("D" & L).Value > 250 Then Range("G" & L) = Range("D" & L).Value * 1.5
End If
End Sub
6 réponses
-
Bonjour,
Il y a un désordre dans ce code ...
Range("D2:D202").Select v = ActiveCell.Value
Un range de 200 cellule est sélectionné ...
Alors ActiveCell.Value n'existe pas, il n'y a pas qu'une seule cellule de sélectionnée.
Il serait probablement judicieux de penser ...
Private Sub CommandButton1_Click() Dim Boucle As Integer Dim v As Single, k As Single Range("D2").Select For Boucle = 0 To 199 v = ActiveCell.Offset(Boucle, 0).Value Select Case v Case Is <= 5: k = 8 Case Is <= 10: k = 7 Case Is <= 20: k = 5 Case Is <= 30: k = 4.5 Case Is <= 50: k = 4 Case Is <= 70: k = 3.5 Case Is <= 100: k = 3 Case Is <= 250: k = 2.5 Case Else: k = 1.5 End Select ActiveCell.Offset(Boucle, 7).Value = v * k Next Boucle End Sub
Déclenchement de la macro ...
Il est possible de déclencher automatiquement le calcul directement comme une formule Excel. Pour ce faire, tu convertis la procédure "Sub" en fonction "Function" et la première instruction de cette fonction doit être :
Application.Volatile
Cette fonction doit être placé derrière la feuille visé.
Ainsi, sur tous les évènements de la feuille, le calcul sera effectué.
Bon, il est clair que je ne possède pas tous les éléments de ton classeur ...
Bonne continuité
K-
-
@guillaume
@guillaume
Hier, j'ai dû m'absenter, c'est pourquoi je n'ai pas pu t'aider ; j'ai lu les autres
messages de la discussion, et voici la suite que je propose.
----------------------------------------------------------------
1) Sur ton énoncé initial (ton 1er message), tu avais écrit :
« selon la grandeur de la valeur en cellule D ».
Cela précise bien la colonne D ; mais rien ne précise que c'est pour les lignes
2 à 202 (ce que j'ai vu dans les messages qui ont suivi) ; ça explique que mon
1er code est pour une seule cellule, la cellule active, car j'ai utilisé ActiveCell ;
et j'ai oublié que c'est pour la colonne D ; sinon, au lieu de v = Val(ActiveCell)
j'aurais mis : v = Val(Cells(ActiveCell.Row, 4)) ; mais ceci toujours pour une
seule cellule : celle de la ligne active, colonne D.
----------------------------------------------------------------
2) IMPORTANT : dans ton 1er code de ce même énoncé initial, tu avais écrit :
If Not Range("D" & L) Is Empty Then
Appelons X une cellule de la colonne D ; c'est seulement si X est non vide qu'on
fera ce travail : écrire un nombre sur la même ligne, colonne G ; à l'inverse, si X
est vide, on ne fera rien du tout : aucun nombre en colonne G.
----------------------------------------------------------------
3) J'ai vu le code de Kalissi ; c'est assez bien, mais 2 choses ne vont pas :
a) La colonne des résultats sera la colonne K, et pas la colonne G ! :(
b) Le point 2) n'est pas respecté, puisque si X est vide, le nombre 0 sera écrit :
la valeur de la cellule vide X est 0 ; ce 0 fait qu'avec le 1er cas <= 5 on a k = 8 ;
puis v * k = 0 * 8 = 0 ; et ce 0 est écrit en colonne K ! :(
----------------------------------------------------------------
4) Voici mon 2ème code VBA ; il est pour D2:D202, il respecte le point 2),
et il écrit les résultats en colonne G :
Option Explicit Private Sub CommandButton1_Click() Application.ScreenUpdating = False Dim lig As Byte, v1 As Range, v2 As Single, k As Single [G2:G202].ClearContents ' efface les anciens résultats For lig = 2 To 202 Set v1 = Cells(lig, 4) If Not IsEmpty(v1) Then v2 = Val(v1) Select Case v2 Case Is <= 5: k = 8 Case Is <= 10: k = 7 Case Is <= 20: k = 5 Case Is <= 30: k = 4.5 Case Is <= 50: k = 4 Case Is <= 70: k = 3.5 Case Is <= 100: k = 3 Case Is <= 250: k = 2.5 Case Else: k = 1.5 End Select v1.Offset(, 3) = v2 * k End If Next dv End Sub
De plus, j'ai remis Val() car v2 est de type Single : si quelqu'un a saisi par erreur
un texte (ou juste une lettre) dans une cellule de D2:D202, mettre ce texte dans
la variable numérique v2 fera planter le code ! c'est évité car Val() d'un texte
retourne 0. :)
Pour le type de lig, j'ai mis Long par sécurité, au cas où tu aurais envie d'ajouter
d'autres lignes ; car sinon, Byte suffit : la boucle For lig va de 2 à 202, et un Byte
peut contenir un nombre de 0 à 255 ; pour D256 et jusqu'à D32767, tu peux
mettre Integer au lieu de Long.
Merci de me dire si ça te convient.
-
@nathan
Edit n° 1 : pour la ligne #25 de la sub, il faut mettre Next lig ; pas Next dv !
(j'avais changé de système et de variable => de dv en lig)
Edit n° 2 : Pour le type de lig, j'ai remis Byte, qui est ok pour 2 à 202,
car il peut contenir 0 à 255 ; mettre Integer si tu dépasses 255 lignes
(256 à 32767) ; mettre Long pour 32768 et au-delà.
-
-
@guillaume
@guillaume
En général (même en dehors d'Excel) :
Le séparateur décimal pour les nombres décimaux (ou fractionnaires) est :
la virgule pour les nombres français ; le point pour les nombres anglais.
-----------------------------------------------------------
Ceci est pour Excel en version français :
Sur une feuille de calcul, c'est en français => séparateur décimal : la virgule ;
en VBA, on programme en anglais => séparateur décimal : le point.
Donc dans une cellule, on saisit par exemple 4,5 ; mais en VBA, on code 4.5
Exemple : voir le 4ème cas du Select Case : Case Is <= 30: k = 4.5
-----------------------------------------------------------
Comme k doit pouvoir contenir un nombre décimal, j'ai choisi le type Single :
nombres décimaux en simple précision ; v2 est la valeur d'une cellule de la
plage D2:D202 (via v1) ; comme v2 peut aussi être un nombre décimal,
lui aussi est de type Single.
La multiplication de v2 * k donne un résultat fractionnaire qui est placé en
colonne G ; donc il n'y a pas de raison que cette colonne G n'affiche pas
les décimales, sauf si tu y as mis des formats de nombre entier => avec
un format Standard ou un format de nombre décimal, tu dois voir les
décimales ! Mais peut-être as-tu voulu dire que tu ne les vois pas toutes ?
dans ce cas, c'est juste un problème de précision des décimales : il suffit
de remplacer Single par Double pour avoir des nombres fractionnaires
plus précis, en double précision ; ce qui donne ce code VBA :
Option Explicit Private Sub CommandButton1_Click() Application.ScreenUpdating = False Dim lig As Byte, v1 As Range, v2 As Double, k As Double [G2:G202].ClearContents ' efface les anciens résultats For lig = 2 To 202 Set v1 = Cells(lig, 4) If Not IsEmpty(v1) Then v2 = Val(v1) Select Case v2 Case Is <= 5: k = 8 Case Is <= 10: k = 7 Case Is <= 20: k = 5 Case Is <= 30: k = 4.5 Case Is <= 50: k = 4 Case Is <= 70: k = 3.5 Case Is <= 100: k = 3 Case Is <= 250: k = 2.5 Case Else: k = 1.5 End Select v1.Offset(, 3) = v2 * k End If Next lig End Sub
Cela devrait résoudre ton problème ; sinon, indique-moi ce qui ne va pas ;
et je crois aussi que tu devras joindre ton fichier (sans données privées).
Pour des calculs monétaires, il y a le type Currency : calculs à virgule fixe
en grande précision (pour des montants en € et cents) ; regarde l'aide
de VBA pour plus de détails.
Si ton problème est réglé, tu peux passer le sujet en résolu. ;)
-