Toutes mes réponses sur les forums
-
AuteurMessages
-
Stéphane Lorin
ParticipantBonjour
Votre question n’est pas très précise : dans quelle plage se trouve vos données ? Un petit fichier exemple pourrait aider.En tout cas, je viens de tester votre code :
Avec en B2:E2 les titres REFERENCE, DESIGNATION, QUANTITE, PRIX.
et la plage B3:E10 en plage normale, pas en tableau.
les désignations et les prix des colonnes C et E sont des RECHERCHEV sur une autre tableje saisie une référence en colonne B, puis une quantité en colonne D. A ce moment là, un tri est effectué suivant l’ordre croissant des références de la colonne B
cela fonctionne également si la plage B3:B10 est un tableau (avec les titres en ligne 3)
Stéphane
Stéphane Lorin
ParticipantRe-bonjour
En fusionnant votre table avec elle-même sur le champ “référence” et en développant les semaines.
Je renomme la semaine “initiale” en “semaine choix” et la semaine développée en “semaine graphe”
Ensuite une mesure COUNTROWS pour compter le nombre de lignes résultante
Au niveau graphique : un segment sélection simple sur le champ “semaine choix” et un graphique avec la mesure et la “semaine graph”Stéphane
Attachments:
You must be logged in to view attached files.Stéphane Lorin
ParticipantBonjour
si je comprends bien la question l’exemple de la semaine 1 est erroné.
On devrait lire : 4, 2, 2, 4 et non 4, 2, 1 2
en effet, en semaine 3, il y a A et D qui sont déjà en semaine 1Voir une solution avec une formule Excel ci-joint
En considérant qu’il n’y a pas de doublon de référence dans la liste et que les semaines sont dans l’ordre croissantAprès avoir mis sous forme de tableau les données et nommé la cellule contenant la semaine de référence “référence” je propose :
=SOMMEPROD(NB.SI.ENS(
Données[Semaine];[@Semaine];
Données[Référence];INDEX(Données[Référence];EQUIV(Référence;Données[Semaine];0)):INDEX(Données[Référence];EQUIV(Référence;Données[Semaine];0)+NB.SI(Données[Semaine];Référence)-1)
))Pour une semaine donnée, la formule va compter les références présentent dans la semaine de référence
INDEX(Données[Référence];EQUIV(Référence;Données[Semaine];0)):INDEX(Données[Référence];EQUIV(Référence;Données[Semaine];0)+NB.SI(Données[Semaine];Référence)-1)
permet d’obtenir la liste des références de cette semaine de référence (si pas de doublon et si semaine triée).Il existe sûrement des solutions Power Query ou DAX mais je n’ai pas le temps de chercher !
Stéphane
Attachments:
You must be logged in to view attached files.Stéphane Lorin
ParticipantBonjour
Pour changer le nom d’une colonne il existe une fonction dédiée : Table.RenameColumns
let
Source = Excel.CurrentWorkbook(){[Name=”Tableau1″]}[Content],
Changement_nom_colonne = Table.RenameColumns(
Source,
{“Commentaires”, “Commentaires autre”},
MissingField.Ignore
)
in
Changement_nom_colonneSi j’ai une table nommée “Tableau1” avec un champ “Commentaires” celui-ci est renommé en “Commentaires autre”.
Si le champ n’existe pas, la fonction n’a pas d’impact grâce à l’argument MissingField.IgnoreStéphane
Stéphane Lorin
ParticipantBonjour
Je me permets de proposer une solution alternative qui ne compare pas les lignes successives entre-elles mais qui utilise une option de la fonction de regroupement Table.Group.Le principe est de regrouper les lignes sur les champs “Capteur” (M1 ou M2) et “Statut” (0 ou 1), de récupérer la date/heure minimum (pour le début) et le nombre de lignes (pour la durée)
A la main, dans la formule créée avec le menu “regroupement”, j’ajoute le mot clé “GroupKind.Local” pour spécifier que le regroupement ne sera pas sur la totalité de la table mais sur chaque groupe de lignes successives qui ont le même capteur et le même statut.
= Table.Group(#”Type modifié”, {“Capteur”, “Statut”}, {{“Début”, each List.Min([Date Heure]), type datetime}, {“Durée”, each Table.RowCount(_), type number}}, GroupKind.Local)
Je n’ai plus qu’à multiplier par 5 le nombre de lignes pour avoir la durée en secondes de chaque statut.
Un inconvénient est qu’on perd le petit engrenage pour modifier le regroupement
Cette option de la fonction Table.Group ne peut pas être utilisée à chaque fois que l’on veut comparer une ligne avec la précédente mais elle permet de simplifier certaines requêtes et elle est moins gourmande en mémoire que la technique des index décalés d’un.
Cordialement
Attachments:
You must be logged in to view attached files.Stéphane Lorin
ParticipantBonjour
Si je comprends bien la question, vous pouvez appliquez une mise en forme conditionnelle “utiliser une formule pour déterminer pour quelles cellules le format sera appliqué”=A1=”un petit bonjour au début c’est plus poli” alors fond vert
la cellule A1 sera en vert si elle contient la phrase complète
un peu plus complexe :
=ESTNUM(TROUVE(A1;”un merci à la fin ça ne fait pas de mal non plus”)) alors orangela cellule A1 sera en orange si elle contient un des mots (“merci” par exemple)
Stéphane
Stéphane Lorin
ParticipantBonjour
Vous pouvez aussi convertir votre texte en nombre puis utiliser les fonctions de division par un entier et modulo.
La division par l’entier 100 de 1120 donnera 11 : champ “Division entière” = Number.IntegerDivide([heure], 100)
Le modulo par 100 de 1120 donnera 20. champ “Modulo” = Number.Mod([heure], 100)
la fonction #time([Division entière], [Modulo], 0) renverra l’heure soit 11:20.
Sinon, la fonction Text.PadStart([Votre champ heure en texte],4,”0″) est pratique pour ajouter un 0 devant afin d’avoir 4 caractères
Stéphane
Stéphane Lorin
ParticipantBonjour Philippe
Vous pouvez obtenir le nom de votre colonne 1 par la formule Table.ColumnNames(#”étapeprécédente”){0}
et de votre colonne 5 par Table.ColumnNames(#”étapeprécédente”){4}
En effet, Table.ColumnNames renvoie une liste et la première valeur de cette liste est obtenue par le {0} et la cinquième par {4}
Vous remplacez donc “Column1” et “Column5” de la formule de Kim par les formules ci-dessus.En partant de l’étape “Source” cela donne :
= Table.ReorderColumns(Source,{Table.ColumnNames(Source){4},Table.ColumnNames(Source){0}} & List.RemoveItems(Table.ColumnNames(Source), {Table.ColumnNames(Source){4}, Table.ColumnNames(Source){0}}))Autre possibilité, vous rétrogradez les en-têtes en première ligne (Table.DemoteHeaders), les colonnes d’appellent maintenant Column1 … vous appliquez la formule de Kim et vous n’avez plus qu’à remonter la première ligne en en-tête (Table.PromoteHeaders).
Stéphane
Stéphane Lorin
ParticipantRebonjour
il suffit simplement de supprimer les colonnes G et suivantes pour retrouver votre V1.
ensuite pour travailler avec PowerQuery il faut mettre sous forme de tableau votre plage (avec comme nom = tableau1).d’autre part, en ligne 10 votre REFART est A2 ce qui modifie normalement le calcul. vous ne pouvez vendre l’article A2 si vous ne l’avez pas acheté avant.
en mettant A1 partout dans mon fichier vous trouverez exactement le résultat que vous attendezce sont des opérations de base d’Excel qu’il faut maîtriser avant d’aller plus loin avec PowerQuery.
J’ai passé déjà pas loin de 2 heures à réfléchir à votre problème et à écrire un long message très détaillé sur les différentes étapes. Sophie avant moi avait également déjà passé du temps.
Je vous laisse donc adapter ma solution à votre fichier de travail, je pense qu’il n’y a pas que ces quelques date et une référence
C’est comme cela qu’on apprend.Stéphane
Stéphane Lorin
ParticipantBonjour
Je suis reparti de votre V4 d’hier.
Je n’utilise que les colonnes SENS, DATE, QTTE, PA Un et REFART
C’est tout.
Les colonnes G à K sont les vôtres.
Par contre pour tester le fonctionnement du fichier avec plusieurs références, j’ai remplacé A1 par A2 et A3 sur certaines lignes. Mettez A1 partout et vous retrouverez vos données initiales.La requête Power Query ajoute une seule colonne : le CUMP.
Cordialement
StéphaneStéphane Lorin
ParticipantBonjour
le menu contextuel ne le propose pas mais c’est possible dans le menu “accueil”
StéphaneAttachments:
You must be logged in to view attached files.Stéphane Lorin
ParticipantBonjour
Comme votre situation nécessite de calculer un élément en fonction du précédent, j’ai pensé à une fonction Power Query un peu complexe : List.Accumulate
Voici comment je procède :
– j’ajoute une colonne “Index” pour pouvoir trier dans le même ordre à la fin
– j’ajoute une colonne “Quantité_signée” pour mettre en négatif les ventes
– je regroupe par article (car il faut que ça fonctionne avec plusieurs références) je compte le nombre de lignes et je récupère “toutes les lignes” pour avoir une table avec l’ensemble des entrées et des sorties de chacun des articles
– j’ajoute un “Index2” à cette sous-table afin d’identifier chaque ligne
– je calcule avec un List.Accumulate la quantité en stock et le montant en stock.
voir plus bas les explications
– je ne conserve que les tables et les listes générées à l’étape précédente, je développe les tables et je trie suivant l’index initial. Les listes sont dupliquées sur chacune des lignes
– je calcul le CUMP en divisant le montant stocké par la quantité en me servant de l’index2 pour récupérer le bon élément de la liste. j’indique que le stock est nul s’il n’y a plus de produit. Votre formule génère un DIV/0 dans ce cas.Voici la formule au coeur du calcul : c’est une liste de listes
chaque “sous-liste” comprenant 2 éléments : le stock en cours et son montant
le champ [Données] contient les tables avec les achats et les ventes de chacun des articlesList.Accumulate(
{1..[Nb_Lignes]-1},
{{[Données][Quantité_signée]{0},[Données][Quantité_signée]{0}*[Données][#”PA Un”]{0}}},
(state,current)=>
List.Combine (
{state,{{state{current-1}{0}+[Données][Quantité_signée]{current},
state{current-1}{1}+[Données][Quantité_signée]{current} *
(if [Données][Quantité_signée]{current}>0
then [Données][#”PA Un”]{current}
else state{current-1}{1}/state{current-1}{0})}}}))){1..[Nb_Lignes]-1} crée une liste à partir de 1 pour aller chercher les infos dans chaque ligne de la table de l’article (power query commence à 0 et termine à Nb_Lignes -1)
{{[Données][Quantité_signée]{0},[Données][Quantité_signée]{0}*[Données][#”PA Un”]{0}}}
défini la première valeur de ma liste : c’est une liste avec la première quantité et le premier montant (quantité *prix)(state,current)=>
List.Combine (
{state,…à partir de la première liste de ma liste, j’agrège les sous-listes les unes derrière les autres
{{state{current-1}{0}+[Données][Quantité_signée]{current},
le premier élément de ma nouvelle sous-liste est la quantité en stock : la quantité précédente avec le “current-1″ + la quantité en cours (négative si vente)
et
state{current-1}{1}+[Données][Quantité_signée]{current} *
(if [Données][Quantité_signée]{current}>0
then [Données][#”PA Un”]{current}
else state{current-1}{1}/state{current-1}{0})}}le second élément de ma sous-liste est le montant : le montant précédent + la quantité en cours multipliée par le prix en cours si achat ou le CMUP précédent si vente
J’obtiens ainsi une liste pour tous les achats et les ventes de l’article avec à chaque fois le stock et sa valeur résultant de l’entrée ou de la sortie de cet article.
J’ai dupliqué vos données 100 fois pour avoir 900 lignes, le temps de calcul est de l’ordre de 10 secondes sur mon PC qui n’est pas de première jeunesse !
J’espère que cela vous sera utile,
Stéphane
Attachments:
You must be logged in to view attached files.27 avril 2020 à 1 h 44 min en réponse à : [Excel 2016] – Syntaxe Target.SpecialCells(xlCellTypeAllValidation) #63925Stéphane Lorin
ParticipantBonjour
Si je comprends bien ce que vous voulez faire, il faut que la macro ne se déclenche que lorsque l’utilisateur clique dans la colonne B par exemple et pas dans les autres colonnes.
Pour cela il suffit d’ajouter un critère dans le If… Exit Sub
If Target.Count > 1 Or Target.Column <> 2 Then Exit SubOu d’ajouter un critère Range(“B:B”) dans l’Intersect
If Not Intersect(V1, Target, Range(“B:B”)) Is Nothing ThenCela dit, vous pouvez aussi limiter le nombre de caractère directement dans une validation
Cordialement
StéphaneStéphane Lorin
ParticipantBonjour
Ces fonctions List.Sum et List.Product ne tiennent pas compte des éléments “null”, elles ne les considèrent pas dans l’opération d’addition ou de multiplication. Les éléments non nulls de la liste sont additionnés ou multipliés.
Je voulais donc dire que c’était comme si ces “nulls” étaient “neutres” dans l’opération et, si je me souviens bien de mes cours d’algèbre, l’élément neutre de l’addition est 0 et celui de la multiplication est 1.Détrompez-vous sur un comportement différent entre Excel et Power Query.
Vous pouvez facilement faire un parallèle entre List.Sum et SOMME (bien qu’il y ait quand même des différences)
Par contre pour List.Product il faut penser à la fonction PRODUIT et non à la multiplication classique.Sûrement méconnue, cette fonction PRODUIT ne tient pas compte non plus des cellules vides : elle multiplie entre-eux les arguments numériques.
Essayez sous Excel : A1 = 3 et laissez vide la cellule A2
La formule =A1*A2 donnera 0, l’opérateur * transforme le “vide” en 0
Alors que la formule =PRODUIT(A1:A2) donnera 3, cette fonction ne tient pas compte des cellules vides.Stéphane
Stéphane Lorin
ParticipantBonjour
L’erreur indique
Désolé… Nous n’avons pas trouvé le champ « Value » de l’enregistrement.
Détails :
Parameter=Prod
value=fraiseil est très important de savoir que Power Query est sensible à la casse.
Donc …else Record.Field(ParamRow{0},”value”)…
Stéphane
-
AuteurMessages