Erreur 424... objet requis [Résolu]

guillaume - 13 juin 2017 à 16:48 - Dernière réponse :  Guillaume
- 16 juin 2017 à 10:36
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

Afficher la suite 

13 réponses

Répondre au sujet
Kalissi 162 Messages postés jeudi 2 mai 2013Date d'inscription 1 décembre 2017 Dernière intervention - Modifié par Kalissi le 13/06/2017 à 17:28
0
Utile
Bonjour,

À première vue ...

Private Sub CommandButton1_Click()

    Dim L As Integer, C As Integer
    Dim Target As Range
    
    ' Target doit être initialisé quelque part
    Set Target = ActiveCell

    L = Target.Row
    C = Target.Column
    
    If Not Range("D" & L) Is Empty Then

        If Range("D" & L).Value <= 5 Then Range("G" & L).Value = Range("D" & L).Value * 8
        If Range("D" & L).Value > 5 And Range("D" & L).Value <= 10 Then Range("G" & L).Value = Range("D" & L).Value * 7
        If Range("D" & L).Value > 10 And Range("D" & L).Value <= 20 Then Range("G" & L).Value = Range("D" & L).Value * 5
        If Range("D" & L).Value > 20 And Range("D" & L).Value <= 30 Then Range("G" & L).Value = Range("D" & L).Value * 4.5
        If Range("D" & L).Value > 30 And Range("D" & L).Value <= 50 Then Range("G" & L).Value = Range("D" & L).Value * 4
        If Range("D" & L).Value > 50 And Range("D" & L).Value <= 70 Then Range("G" & L).Value = Range("D" & L).Value * 3.5
        If Range("D" & L).Value > 70 And Range("D" & L).Value <= 100 Then Range("G" & L).Value = Range("D" & L).Value * 3
        If Range("D" & L).Value > 100 And Range("D" & L).Value <= 250 Then Range("G" & L).Value = Range("D" & L).Value * 2.5
        If Range("D" & L).Value > 250 Then Range("G" & L).Value = Range("D" & L).Value * 1.5

    End If

End Sub


K
Commenter la réponse de Kalissi
Kuartz 836 Messages postés vendredi 13 février 2015Date d'inscription 1 septembre 2017 Dernière intervention - 13 juin 2017 à 17:35
0
Utile
Bonjour,

Pour la petite explication car il est important de comprendre les erreurs.

Tu n'as jamais défini le "Target" que tu utilises. Tu vois sur le code de Kalissi, on a cette ligne importante que tu oublies, et qui précise que par Target, tu entends la cellule sélectionnée :

Set Target = ActiveCell


Pour aller un peu plus loin, Target est un objet. Et non une variable. C'est la raison pour laquelle on l'initialise avec Set.

En espérant t'avoir éclairé.
Commenter la réponse de Kuartz
0
Utile
1
Bonjour,

Dans ton code VBA, target n'existe pas, mais on peut s'en passer :
j'ai utilisé à la place ActiveCell, puis aussi ActiveCell.Row.

Tu as écris : Dim c As Integer, puis c = target.Column, mais après,
tu n'as pas utilisé c, donc cette variable est inutile !

J'ai réécrit ainsi ton code VBA :


Option Explicit

Private Sub CommandButton1_Click()
  Dim v As Single, k As Single
  v = Val(ActiveCell): If v = 0 Then Exit Sub
  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
  Cells(ActiveCell.Row, 7) = v * k
End Sub


Merci de me dire si ça te convient.
 
nouvelle tentative : cela fonctionne mais il faut que je clique sur la cellule a calculer avant d'appuyer sur le bouton. Et ça ne calcule que cette cellule...
:-(

Private Sub CommandButton1_Click()
Dim v As Single, k As Single

Set ref = Workbooks(1).Worksheets(1).Range("D2:D202")
With ref

v = ActiveCell.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

Cells(ActiveCell.Row, 7) = v * k
End With
Commenter la réponse de nathan
guillaume - 14 juin 2017 à 10:26
0
Utile
Bonjour,

Merci pour votre aide à tous les 3 ! La communauté VBA : un modèle d'entre-aide !
Commenter la réponse de guillaume
guillaume - 14 juin 2017 à 10:56
0
Utile
Bonjour,

Je me suis inspiré de ta réponse Nathan.
Je souhaitais que la macro calcul la formule pour toutes les lignes du tableau. J'ai essayé avec la macro ci-dessous. Ce coup-ci je n'ai pas d'erreur de compilation mais la macro ne fait rien d'autre que sélectionner mon Range... XD

Private Sub CommandButton1_Click()
Dim v As Single, k As Single

Range("D2:D202").Select

v = ActiveCell.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

Cells(ActiveCell.Row, 7) = v * k
End Sub
Commenter la réponse de guillaume
Kalissi 162 Messages postés jeudi 2 mai 2013Date d'inscription 1 décembre 2017 Dernière intervention - 14 juin 2017 à 14:09
0
Utile
6
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
nathan > guillaume - 15 juin 2017 à 01:54
 
@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 > nathan - 15 juin 2017 à 03:21
 
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à.
 
Bonjour Nathan,

Merci pour ton aide, j'ai essayé ton code :
Et ça marche ! J'ai juste un dernier soucis :
-le résultat en colonne G ne prends pas les décimales

Guillaume
nathan > guillaume - 16 juin 2017 à 04:26
 
@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.  ;)
 
Merci beaucoup pour ta dispo et pour ton aide Nathan !
Commenter la réponse de Kalissi