Petite question sur moyenne si

Signaler
-
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
-
Bonjour, je découvre actuellement libre office calc et je dois réaliser un tableau de moyenne, sur ce tableau il y'a plusieurs notes, avec le même coef ( pour ça y'a pas de problème particulier ), le souci est que sur deux des matières, je dois les compter uniquement si la note est supérieur ou égal à 10 .
Déjà j'ai du mal à comprendre la fonction moyenne.si, je ne peux pas mettre 9.9999 ou ≥ 10, ensuite si je met > 10 elle marche uniquement si parmi les deux matières une note est supérieur à la moyenne mais sinon si les deux sont plus petit que 10 il me met #div/0
j'utilise la formule =MOYENNE.SI(X5:Y5;"> 10") mais elle doit être complétement fausse, merci d'avance ^^'






Configuration: Windows / Firefox 87.0

8 réponses

Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133
Salut,

Même si c’est pour Excel, ça devrait fonctionner pareil. La fonction porte sur la somme mais ça devrait être équivalent avec la moyenne : https://www.excel-pratique.com/fr/fonctions/somme_si
merci mais malheureusement ça ne me convient pas, c est pas vraiment ce que je cherche, déjà je n'ai pas de plage, ensuite ici il n y'a que du vide, moi je cherche comment entrer plus grand ou égal à 10 :/
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133
Euh, comment tu n’as pas de plage ? Pour calculer la moyenne tu en as forcément une. Tes valeurs ne sont pas contigües peut-être ?
Messages postés
53739
Date d'inscription
lundi 13 août 2007
Statut
Contributeur
Dernière intervention
26 avril 2021
15 748
Bonjour sto.

Si tu veux de l'aide, envoie ton fichier Calc.
 1) Tu vas dans https://www.cjoint.com/ 
2) Tu cliques sur [Parcourir] pour sélectionner ton fichier (15 Mo maxi)
3) Tu défiles vers le bas pour cliquer sur le bouton bleu [Créer le lien Cjoint]
4) Au bout de quelques secondes la deuxième page s'affiche, avec le lien en gras ; tu fais un clic-droit dessus et tu choisis "Copier le lien"
5) Tu reviens dans ta discussion sur CCM, et dans ton message tu fais "Coller".
=>Voir la fiche https://www.commentcamarche.net/faq/29493-utiliser-cjoint-pour-heberger-des-fichiers
Il existe aussi :
1) https://mon-partage.fr/
2) https://www.transfernow.net/

La fonction MOYENNE.SI ne convient pas dans ce cas de figure ; en effet si la cellule X5 ou Y5 est <10 elle est considérée comme une valeur nulle ; donc si l'une des cellules est >=10, ça marche ; si les 2 sont <10, la fonction tombe sur une division par zéro et te l'affiche !
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133
Salut Raymond,

Je confirme.

Je bosse sur le sujet actuellement, et je galère. Je me demande s'il ne faut pas plutôt passer par une macro personnalisée.
Messages postés
53739
Date d'inscription
lundi 13 août 2007
Statut
Contributeur
Dernière intervention
26 avril 2021
15 748 >
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021

On y verra plus clair quand le demandeur, Sto, aura envoyé son fichier ...
MOYENNE.SI n'est pas adéquat pour ce calcul inhabituel.
Il faudra certainement ajouter une ou deux colonnes avec les formules appropriées.
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133 >
Messages postés
53739
Date d'inscription
lundi 13 août 2007
Statut
Contributeur
Dernière intervention
26 avril 2021

J'en bave encore. Je déteste VBA et Basic qui est l'équivalent VBA de LibreOffice. Mais, j'ai bien avancé. Mon code est mal fichu, mais, en un clic sur un bouton, après avoir sélectionné à la souris la plage de cellules des notes. Le calcul des moyennes se fait correctement.

Il me faut gérer les absences. Je viens de tester et ça ne recalcule pas correctement les moyennes. J'ai fait une erreur de sémantique dans mes conditions.
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133
Il faut sélectionner la plage des notes à la souris et uniquement les notes (absences comprises). Puis cliquer sur le bouton Calculer moyennes.

https://mon-partage.fr/f/AzbVaCO8/
Messages postés
3210
Date d'inscription
dimanche 3 mai 2009
Statut
Membre
Dernière intervention
26 avril 2021
896
Salutations à tous

Sto si je comprends bien ta demande tu dois sommer les nombres >=10 et faire la moyenne uniquement de ces nombres.

Si les deux nombres sont >=10 somme des deux nombres / 2 ; si un seul est >=10 ce nombre / 1 ; si aucun des deux n'est >=10 alors 0.

MOYENNE.SI ne marche pas à cause de la division par 0, alors une autre formule

Les deux nombres en A1 et A2 :

=SI(NB.SI(A1:A2;">=10")>0;SOMME.SI(A1:A2;">=10")/NB.SI(A1:A2;">=10");0)


Si c'est un autre calcul des précisions sont attendues en même temps que le fichier demandé.

Cordialement
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133 >
Messages postés
24023
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
25 avril 2021

Pas de soucis. Je comprenais pas ton message 13.

De l’aide sur mon code basic ne serait pas de refus. Je vais essayer vos propositions. Et non je ne suis pas le demandeur. C’est juste que j’aime bien écrire des scripts et j’ai trouvé le problème intéressant.

Je suis d’accord avec Luc, mais le problème, selon moi, c’est bien de prendre en comptes les notes modulo celles en dessous de 10 qui ont une condition (sans doute comme les épreuves facultatives du bac).

J’avais fait un premier code basic qui fonctionnait. C’est quand j’ai voulu gérer les imprévus (absence à un contrôle, …) que ça faisait n’importe quoi.
Messages postés
24023
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
25 avril 2021
6 744 >
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021

Je pense qu'on doit pouvoir faire plus simple.
Ca parait bien long pour une simple moyenne ;-)

D'autre part, je partirai plutôt sur une fonction personnalisée qui retournerait la moyenne d'un élève.
Beaucoup plus souple à l'utilisation et ré-utilisable quelle que soit la mise en page de la feuille.
Tu boucles sur la plage passée en paramètre, si valeur admise tu additionnes et tu comptes 1 de plus dans une autre variable.
Et tu renvoies la moyenne en sortie.
Je te laisse faire.
eric
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133 >
Messages postés
24023
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
25 avril 2021

"Tu boucles sur la plage passée en paramètre, si valeur admise tu additionnes et tu comptes 1 de plus dans une autre variable.
Et tu renvoies la moyenne en sortie."

C'est ce que j'ai codé dans le if de la deuxième boucle for (la première est une boucle ligne par ligne), en amont, je l'ai réfléchi en algorithmique.

Oui, mon objectif, avec la macro est d'adapter facilement. Par exemple, ma ligne remarque qui prend en compte les notes conditionnées ou non se situe relativement juste au-dessus des notes. C'est dans le but d'ajouter un élève.

J'avais aussi pensé à nommer la plage des notes.

"Ca parait bien long pour une simple moyenne ;-)"

Le traitement fait 20 lignes. Il faut bien que je déclare les variables en amont. Je sais que ce n'est pas optimal, mais, je bosse d'abord sur le bon fonctionnement avant d'optimiser.

En tout cas, je suis tout à fait d'accord sur la création de fonction. Ça allège le code, et il suffit de modifier la fonction ou d'en créer une autre si le traitement change.

Tu n'en parles pas, mais, je tiens à le préciser. J'ai activé la compatibilité VBA pour utiliser la fonction Round(val, n) qui arrondi val à n chiffres après la virgule. Fonction qui n'a pas d'équivalent en basic. Mais, je veux conserver un code basic et non un code VBA.

C'est bien de proposer sur les fofo. On a un œil extérieur.

Anecdote marrante : j'avais mon précédent code qui boguait mais, une ligne fonctionnait. sur le deuxième code, la même ligne : BUG ! J'ai mis 10 minutes pour voir que j'avais déclarer la variable en objet et non en object :facepalm:
Messages postés
24023
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
25 avril 2021
6 744 >
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021

pour utiliser la fonction Round(val, n)
Je ne sais pas ce qu'il en est sur libreoffice, mais attention qu'en vba cette fonction exécute l'arrondi de banquier.

C'est à dire que si la dernière décimale est 5, l'arrondi se fait vers le nombre paire le plus proche et non supérieur. Le but est de générer des gains et des pertes qui auront tendance à s'annuler plutôt que de cumuler des gains.
Debug.Print Round(10.115, 2) => 10.12 (arrondi sup)
mais aussi
Debug.Print Round(10.125, 2) => 10.12 (arrondi inf)
Risque de contestations pour des moyennes dont l'enjeu peut-être très fort à un point près...

Si c'est le cas il vaut mieux utiliser la fonction feuille :
Debug.Print Application.WorksheetFunction.Round(10.115, 2)
Debug.Print Application.WorksheetFunction.Round(10.125, 2)
qui donnent 10.12 et 10.13
Au passage ça t'évite d'utiliser la compatibilité vba si tu préfères t'en passer.
eric
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133 >
Messages postés
24023
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
25 avril 2021

Ah mais c'est génial alors. Je n'avais pas trouvé cette fonction. Merci. Tu as un lien sur une doc de cette fonction je te prie ? Je suis étonné de ne pas l'avoir trouvée dans la doc incluse dans LO ni sur le web. J'avais tapé, pourtant, "equivalent vba round function in libreoffice basic" sur Google.

Peut-être que je confonds, je viens de trouver cette fonction sur le site d'MS : https://docs.microsoft.com/fr-fr/office/vba/api/excel.worksheetfunction

En fait, l'OP et moi-même, par un pur hasard, on utilise LibreOffice Calc et non pas Microsoft Office Excel. Basic est le langage de macro pour LO, et VBA celui pour Office.

La fonction que tu me proposes est mieux, oui, mais, je serai contraint d'activer la compatibilité VBA

Bon, au pire, j'utiliserai celle-là, mais, c'était pour éclaircir ce point.

Bonne soirée.
Messages postés
24023
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
25 avril 2021
6 744
Bonjour à tous,

ou bien
=SIERREUR(MOYENNE.SI(X5:Y5;">=10");"")

eric
Messages postés
2466
Date d'inscription
mercredi 3 février 2010
Statut
Membre
Dernière intervention
20 avril 2021
963
Bonjour,
Ajouter une ligne 6 avec : A6=A5, B6=B5, ...X6=Si(X5>=10; X5;"") ,Y6=Si(Y5>=10; Y5;"") Z6=Z5.
Calculer sur la ligne 6: =Moyenne(A6:Z6)
Messages postés
1655
Date d'inscription
samedi 12 septembre 2020
Statut
Membre
Dernière intervention
25 avril 2021
133
Salut,

J'ai réussi à régler mon problème sémantique. Je ne maîtrise pas les booléens en basic.

Voici le code :

function arrondirV2(valeur as double, apresVirgule as integer) as double
  dim baseDecimale as integer, reference as integer, moitie as integer
  baseDecimale = 10
  reference = 0
  moitie = 2
  valeur = valeur * (baseDecimale^apresVirgule)
  valeur = valeur + (baseDecimale^reference) / moitie
  arrondirV2 = fix(valeur) / (baseDecimale^apresVirgule)
end function

function Traitement(cellule as object, _
  celluleRemarque as object, _
  noteMin as double, _
  noteMax as double, _
  noteMinFac as double, _
  remarque as string) as boolean
  
  if cellule.getType = 1 then
    if celluleRemarque.string = remarque then
      if cellule.value >= noteMinFac then
        if cellule.value <= noteMax then
          Traitement = True
        end if
      end if
    end if
  end if
  
  if cellule.getType = 1 then
    if celluleRemarque.string <> remarque then
      if cellule.value >= noteMin then
        if cellule.value <= noteMax then
          Traitement = True
        end if
      end if
    end if
  end if
end function


Sub Moyenne

dim classeur as object, feuille as object, plageDesNotes as object
dim celluleEnCours as object, celluleRemarque as object
dim celluleMoyenne as object

dim noteMinimale as double, noteMaximale as double
dim noteMinimaleFacultative as double, cumul as double, moyenne as double

dim compteur as integer, premiereLigne as integer, derniereLigne as integer
dim premiereColonne as integer, derniereColonne as integer
dim ligne as integer, colonne as integer, ligneRemarque as integer
dim colonneMoyenne as integer, apresVirgule as integer

dim absence as string, remarque as string

classeur = thisComponent
feuille = classeur.currentController.activeSheet

plageDesNotes = classeur.currentSelection
premiereLigne = plageDesNotes.rangeAddress.startRow
derniereLigne = plageDesNotes.rangeAddress.endRow
premiereColonne = plageDesNotes.rangeAddress.startColumn
derniereColonne = plageDesNotes.rangeAddress.endColumn

ligneRemarque = premiereLigne - 1
colonneMoyenne = derniereColonne + 1
apresvirgule = 2
noteMinimale = 0
noteMaximale = 20
noteMinimaleFacultative = 10

'absence = "abs"
remarque = "F"

for ligne = premiereLigne to derniereLigne
  compteur = 0
  cumul = 0
  celluleMoyenne = feuille.getCellByPosition(colonneMoyenne, ligne)
  for colonne = premiereColonne to derniereColonne
    celluleEnCours = feuille.getCellByPosition(colonne, ligne)
    celluleRemarque = feuille.getCellByPosition(colonne, ligneRemarque)

    if Traitement(celluleEnCours, _
      celluleRemarque, _
      noteMinimale, _
      noteMaximale, _
      noteMinimaleFacultative, _
      remarque) then
        compteur = compteur + 1
        cumul = cumul + celluleEnCours.value
    end if
  next
  if compteur > 0 then 
    moyenne = cumul / compteur
    moyenne = arrondir(moyenne, apresVirgule)
    celluleMoyenne.value = moyenne
  end if
next

End Sub


Si on ne modifie aucun paramètre, il faut que les notes d'un élève se suivent sur une ligne. Il faut aussi que la remarque (contrôle facultatif) soit sur la même colonne de la note et la ligne des remarques soit juste au-dessus des notes du premier élève.
La colonne, en suivant à droite des notes, est la colonne des moyennes conditionnées.
On a une ligne par élève.

Chez moi, sur la ligne 1, j'ai :
en A : rien, en B : note 1, en C : note 2 ... en F : note 5 (la dernière), en G : moyenne
ligne 2 :
en A : remarque, en B : F et pareil en C. Ces 2 notes sont facultatives donc prises en compte si la note est supérieure ou égale à 10. Rien après
ligne 3 :
en A : le nom de l'élève 1, en B : sa note au contrôle (note 1) et ainsi de suite
ligne 4 : l'élève 2
et ainsi de suite.

On crée un bouton "calculer moyennes" qu'on mettra sur la feuille à un endroit visible et qui ne gène pas.

Pour ce faire :
Insertion > Contrôle de formulaire > Bouton
On place le bouton et on le dimensionne
On le renomme en cliquant droit dessus : Contrôle
à l'onglet Général : on entre un nom à l'étiquette : calculer moyennes
à l'onglet Événements : à Exécuter l'action : on clique sur les (...) et on va récupérer la macro
On quitte le mode conception :
Affichage > Barres d'outils > Contrôle de formulaires (doit être coché)
On déselectionne le bouton "mode conception" pour rendre le bouton actif.

Pour que la macro fonctionne et inscrive les moyennes, il faut :
1/ sélectionner la plage de TOUTES les notes à la souris. Donc, de la note 1 du premier élève à la dernière note du dernière élève, absences comprises.
2/ cliquer sur le bouton "calculer moyennes" et laisser faire la magie !

Attention, il n'y a pas de gestion d'erreur, si la valeur est incohérente, exemple la note est 25 alors que le max est 20, la note ne sera pas prise en compte mais l'erreur ne sera pas indiquée.

J'envoie le lien :
https://mon-partage.fr/f/l7MbswN5/