Boucle et soustraction

Fermé
DGVDR - Modifié par DGVDR le 13/11/2012 à 17:39
DGVDR Messages postés 158 Date d'inscription vendredi 10 août 2012 Statut Membre Dernière intervention 20 juillet 2015 - 16 nov. 2012 à 09:38
Bonjour,

Je cherche a filtrer selon un critère ( ça , j'y arrive)


Et dans un second temps à soustraire deux cases de deux lignes voisines, sauvegarder cette valeur (=A)
Recalculer mon A pour la ligne suivante, et faire la moyenne des A.


Tout ceci dans l'objectif de calculer un MTBF ( Mean time between failure), pour ceux qui voit de quoi je parles...

Mon code actuel :

Sub mtbf() 

Dim A As Integer 
Dim l As Integer 
Dim B As Integer 
Dim C As Integer 
Dim D As Integer 

With Worksheets("Enregistrements interventions") 

Range("C2").AutoFilter Field:=1, Criteria1:="Tireuse" 

For l = 1 To 100 
If .Range("C" & l).Value = "Tireuse" Then 
    E = 1 
    .Cells("C" & l + 1).Value -.Cells("C" & l) = A   ' Le problème se situerait ici' 
    B = B + A 
    D = D + C 
    End If 
Next 
End With 
     
Worksheets("Global").Range("A20") = B / D 

End Sub


J'imagines également que mon code n'est pas optimisé.
Si vous avez des idées.

Merci,

DGVDR

5 réponses

Bonsoir Heliotte,

Merci pour ta réponse une nouvelle fois,

Le
.Cells("C" & l + 1).Value 
ne me permet pas de sélectionner la case d'en dessous?

ex :

si l=3

.Cells("C" & l + 1).Value -.Cells("C" & l).Value = C4 - C3


Je me trompe ?

DGVDR
1
chossette9 Messages postés 4239 Date d'inscription lundi 20 avril 2009 Statut Contributeur Dernière intervention 12 septembre 2014 1 308
13 nov. 2012 à 19:42
Non c'est bon, c'est bien ça.
0
Heliotte Messages postés 1491 Date d'inscription vendredi 26 octobre 2012 Statut Membre Dernière intervention 28 janvier 2013 92
13 nov. 2012 à 21:03
- Point important : Pour savoir si une variable est déclarée ou non, il faut ajouter au début de ton module, les mots magiques "Option Explicit"
.. car la variable "E" n'est pas déclarée, donc c'est un variant
- En admettant que "C3" et "C4" sont les cellules dont tu récupères une valeur, alors .Cells("C" & l + 1).Value -.Cells("C" & l).Value = C4 - C3 n'est pas correct.
.. faire plutôt "
A = .Cells("C" & l + 1).Value - .Cells("C" & l).Value
" .. en d'autres termes, la variable "A" est le résultat du calcul (Cl - C(l+1))
- dernière chose, tu mets : "If .Range("C" & l).Value = "Tireuse" Then", une condition que je ne comprend pas! Dans l'ensemble, tu dis : "SI "C3" = "Tireuse" ALORS "A = C4 - C3" : donc, dans ce cas, "C3" aura comme valeur "Tireuse" en String et 0 en Int !!
0
Heliotte Messages postés 1491 Date d'inscription vendredi 26 octobre 2012 Statut Membre Dernière intervention 28 janvier 2013 92
13 nov. 2012 à 18:03
Essaie avec :
.Cells("C" & l + 1).Value -.Cells("C" & l).Value = A   ' Le problème se situerait ici'
Mais ton résultat sera toujours "0", car tu soustrait la valeur d'une cellule "X" de cette même cellule!
0
chossette9 Messages postés 4239 Date d'inscription lundi 20 avril 2009 Statut Contributeur Dernière intervention 12 septembre 2014 1 308
Modifié par chossette9 le 13/11/2012 à 19:41
Bonjour,

1°) Ce n'est pas le .value manquant le problème, c'est qu'il cherche à assigner une variable à une soustraction, et non l'inverse.

2°) Soustraire Cells("C" & l) à Cells("C" & l+1) ne donnera pas forcément zéro, puisqu'il soustrait la ligne l (par exemple 12) à la ligne l+1 (donc 13).
0
chossette9 Messages postés 4239 Date d'inscription lundi 20 avril 2009 Statut Contributeur Dernière intervention 12 septembre 2014 1 308
13 nov. 2012 à 19:37
Bonjour,

je crois que tu n'as pas bien compris le principe du = en programmation. On affecte à gauche la valeur de droite. En gros, tu voudrais par exemple faire A = 3-2, mais toi tu écris 3-2 = A !

Donc change
.Cells("C" & l + 1).Value -.Cells("C" & l) = A
par
A = .Cells("C" & l + 1).Value -.Cells("C" & l) 

Ensuite, tu utilises une variable E que tu ne déclares pas, tu fais D = D + C sans donner de valeurs à C....
Peut être que tu voulais mettre C=1. Du coup, autant ne pas utiliser C et faire directement D = D + 1.

Cordialement.
0
Bonjour,

Merci à vous Heliotte et chossette9.

Je n'avais en effet pas bien compris l'utilisation du "="


Pour ce qui est de cette ligne :
"If .Range("C" & l).Value = "Tireuse" Then"


Tu avais raison Heliotte.

Après correction j'arrive à :

Sub mtbf()

Dim A As Integer
Dim l As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer

With Worksheets("Enregistrements interventions")
Range("C2").AutoFilter Field:=1, Criteria1:="Tireuse"
For l = 5 To 100
If .Range("C" & l).Value = "Tireuse" Then
    
    A = .Cells("F" & l + 1).Value - .Cells("F" & l).Value
    
    B = B + A
    D = D + 1
    End If
Next
End With
    
Worksheets("Global").Range("A20") = B / D

End Sub


Ce qui me cré une "run time error 5
Invalid procedure call or argument"

Ça serait de nouveau la ligne :

A = .Cells("F" & l + 1).Value - .Cells("F" & l).Value


J'ai essayé de rajouté la feuille sur laquelle je prends ces cellules :
- en ajoutant devant Worksheets("Enregistrements interventions"), ca ne change rien .

A la recherche d'idées...

Merci,
DGVDR
0
Je me rends compte que l'ajout devant de : Worksheets("Enregistrements interventions"), ne servait à rien étant donner que j'annonce en amont que je travail sur cette feuille avec le :


With Worksheets("Enregistrements interventions")

DGVDR
0
J'ai modifié mes .Cells par des Range , ça ma mener à une erreur 6.

J'ai donc modifier les déclarations de variables d'Integer en Long,

Ça marche, ceci dit la valeur est aberrante...
0
Heliotte Messages postés 1491 Date d'inscription vendredi 26 octobre 2012 Statut Membre Dernière intervention 28 janvier 2013 92
14 nov. 2012 à 10:39
Option Explicit ' pas de compilation si au moins une variable pas déclarée !
Sub mtbf()
    Dim A As Integer
    Dim l As Integer
    Dim B As Integer
    Dim C As Integer
    Dim D As Integer
    '
    With Worksheets("Enregistrements interventions")
        Range("C2").AutoFilter Field:=1, Criteria1:="Tireuse"
        For l = 5 To 100
            If .Range("C" & l).Value = "Tireuse" Then
                A = .Cells("F" & l + 1).Value - .Cells("F" & l).Value
                B = B + A
                D = D + 1
            End If
        Next
    End With
    If (D <> 0) Then ' test obligatoire pour une division: l'ordinateur ne peut pas faire une division par zéro !
        Worksheets("Global").Range("A20") = B / D
    End If
End Sub
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
Modifié par michel_m le 14/11/2012 à 12:20
Bonjour,
Excusez l'incruste

macro paramétrée permettant de travailler sur plusieurs machine (le nom de la machine peut-^tre marquée dans cellule). déclenchement par appel par la macro choisir_machine

on ne boucle que sur les lignes où se trouve la machine

je n'ai pas compris l'intér^te de filtrer alors que ce n'est pas ce qu'on cherche à faire mais...

il est pris en compte le cas où pas de la machine sélectionnée; cela pourrait être supprimé si onmet la liste des bécanes dans une validation de données

le code (testé avec succès")
Option Explicit 

Sub choisir_machine() 
mtbf "Tireuse" 
End Sub 
'------- 
Sub mtbf(Machine) 
Dim Cptr As Byte, Lig As Byte 
Dim Total As Byte 
Dim Nbre As Byte 

With Worksheets("Enregistrements interventions") 
     Nbre = Application.CountIf(.Range("C5:C100"), Machine) 
     If Nbre = 0 Then GoTo vide 
     'Range("C2").AutoFilter Field:=1, Criteria1:="machine" 
     Lig = 4 
     For Cptr = 1 To Nbre 
               Lig = .Columns("C").Find(Machine, .Cells(Lig, "C"), xlValues).Row 
          Total = Total + .Cells(Lig + 1, "F") - .Cells(Lig, "F") 
     Next 
End With 
Worksheets("Global").Range("A20") = Total / Nbre 
Exit Sub 

vide: 
MsgBox Machine & ": machine inconnue dans la liste", vbCritical
End Sub



edit 12:20 modifié Msgbox
Michel
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
14 nov. 2012 à 12:32
Re
Je me rends compte que l'ajout devant de : Worksheets("Enregistrements interventions"), ne servait à rien étant donner que j'annonce en amont que je travail sur cette feuille avec le :


Au contraire: il est vivement conseillé d'employer les blocs With-end with m^me si tu travailles avec une seule feuille -sauf avec des macros événementielles "worksheet"-

L'absence de ces blocs en cours d'essais, modifications ou de maintenance (80% de la vie de l'appli), sans compter avec le petit curieux qui "maitrise excel"(cf son CV) et qui touche à tout, le déclenchement maladroit des macros à partir d'une autre feuille peut amener pas mal de dégâts....
0
Bonjour michel_m

Tu t'adresses ici à un novice (moi)

Donc si tu n'expliques pas ton code, je n'y comprendrai rien.

"
macro paramétrée permettant de travailler sur plusieurs machine (le nom de la machine peut-^tre marquée dans cellule). déclenchement par appel par la macro choisir_machine

on ne boucle que sur les lignes où se trouve la machine

je n'ai pas compris l'intér^te de filtrer alors que ce n'est pas ce qu'on cherche à faire mais...

il est pris en compte le cas où pas de la machine sélectionnée; cela pourrait être supprimé si onmet la liste des bécanes dans une validation de données "

-> Ca n'est pas claire
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
Modifié par michel_m le 14/11/2012 à 15:22
l'avantage avec les 2 macros est que tu peux choisir une bécane ou une autre: par ex chose, , machin ,truc, bidule, tireuse....

si on veut les "truc"s:
Sub choisir_machine()
mtbf "Truc"
End Sub

quand tu lances choisir_machine, tu appelles la macro mtbf ayant pour paramètre machine:="truc"
si le nombre de "truc" dans la colonne C est égal à 0 (il n'y a pas de truc) on va à la ligne vide et on annonce l'erreur (les erreurs sortant de la macro se placent de préférence en fin de macro pour ne pas faire râler les développeurs diplômés des écoles)

sinon on cherche les lignes où il ya "truc " et seulement celles là par la fonction Find(What:=machine;after:= la cellule/.... où il y avait " truc" (voir l'aide F1)
et on a l'addition (Total est plus parlant pour la maintenance que B (lettre ==>apprentissage de la signification des lettres))m^me punition pour le nombre de "truc" (Nbre vs D)
ainsi si tu as 10 trucs, on ne bouclera que 10 fois au lieu de 95 (for j=5 to 100)

tu crées un filtre: d'accord on ne verra plus que les "truc (tireuses dans ton cas) mais quelle est l'utilité pour indiquer le résultat dans A20?.... de plus tu utilises la ligne du dessous qu'on ne verra pas et je défie la personne qui regardera la liste filtrée de dire comment on a obtenu la valeur inscrite dans A20

Pour la validation de données, regardes dans les astuces CCM: il y a des tutos là dessus: l'avantage est que l'utilisateur ne peut sélectionner que des bécanes existantes et sans faute d'orthographe et ainsi on peut supprime la ligne if nbre=0 et la gestion d'erreur en fin de macro
0
Si j'ai bien compris...

Avec ton code, quand j'activerais, je devrais rentrer le nom de la machine dont je veux sortir le mtbf? D'accord , mais je le rentre ou ?

Je comprends pas ce que tu veux faire avec :

- Nbre = Application.CountIf(.Range("C5:C100"), Machine)

Et


- Lig = .Columns("C").Find(Machine, .Cells(Lig, "C"), xlValues).Row



Merci d'avance,
DGVDR
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
14 nov. 2012 à 18:27
- Nbre = Application.CountIf(.Range("C5:C100"), Machine)
C'est la fonction NB.SI d'excel donc ca te renvoie le nombre de fois ou il y a "tireuse"dans la colonne C !

pour
Lig = .Columns("C").Find(Machine, .Cells(Lig, "C"), xlValues).Row
as tu suivi mon conseil d'aller voir l'aide en ligne ?
ca dit ceci:
dans la colonne C trouve la prochaine ligne de la valeur affectée à machine ("tireuse") sous la ligne où on a déjà trouvé trouvé cette valeur
pour la première, on part au dessus de la première donc ici 4

si tu inscris la valeur à chercher ("tireuse" dans une cellule (par ex: K2) tu pourras attaquer directement la macro mybf et supprimer choisir_machine

le code
Sub mtbf(Machine)
Dim Machine as string 
Dim Cptr As Byte, Lig As Byte 
Dim Total As Byte 
Dim Nbre As Byte 

With Worksheets("Enregistrements interventions")
     Machine=Range("K2")
     Nbre = Application.CountIf(.Range("C5:C100"), Machine)
     etc....


Sans vouloir te minorer (on a tous galérer au départ et ca continue toujours des années après), l'apprentissage d'un langage demande beaucoup de patience et de lecture; dans VBA, tu avances en pas à pas(F8) , tu regardes ce que ça donne sur la feuille, si tu ne comprends un mot, tu regardes dans l'aide en ligne et/ou tu regardes dans une brochure
celle la est gratuite et complète pour débuter
https://bidou.developpez.com/article/VBA/
0