Gestion de Stock

Bonjour ,
J'ai établi un fichier de stock excel qui me permet de faire le suivi de mes stock au quotidien .

Ce fichier doit être alimenter par une saisi d'information régulièrement

je voudrais créer une Macro (Formulaire) qui facilitera la tâche pour tout opérateur de saisir les mouvement qu'il effectue par jour

Sur cette Macro il faudra entrer :
Date du Jour
Base logistique (entrepôt ou magasin) ===> Liste déroulante
Type de Produit (P Fini , P Semi Fini , Mat 1er)===> Liste déroulante
Code Produit ===> Liste déroulante en fonction du type de produit
Quantité

Type de Mouvement : la il y'aura 5 choix à coché
Entré PF
Sortie PSF
Entrée PSF
Livraison Client
Retour Magasin

et bien sur il y'au plusieurs cas de figure exemple :

si on coche : 1 et 2 à la fois il faudra sortir la qtè du stock de Produit semi fini et l'entrer en stock Produit Fini .......

J'espère que c'est un peu clair

Merci d'avance pour votre aide

14 réponses

Résumé de la discussion

Le projet vise à créer une macro/formulaire Excel permettant de saisir quotidiennement les mouvements de stock via des champs Date, Base logistique, Type de produit (P Fini, P Semi Fini, Matière 1er), Code produit, Quantité et Type de mouvement, avec des listes déroulantes dépendantes et l’application de mouvements multiples par jour. La logique implique que des combinaisons comme Entrée PF et Sortie PSF ajustent simultanément les stocks correspondants (augmenter PF, diminuer PSF) et que des calculs automatiques de stock final et total s’appuient sur des formules et sur la dernière ligne du fichier; certains échanges expliquent aussi comment contourner des soucis de comparaison date/nombre en VBA en utilisant des ajustements +1-1. Des difficultés récurrentes concernent la gestion des doublons, la duplication de code pour gérer des couples Produit/Gamme ou Produit/Designation, et l’impression du formulaire, avec des propositions d’adaptativité et de validations complémentaires. L’ensemble des échanges reflète une progression vers une solution robuste de saisie qui lie les choix dans des contrôles dynamiques à des mises à jour de stock et à une consolidation des données, tout en restant centrée sur des règles simples et vérifiables.

Bobot (l’IA à votre service)
  1. Bonjour tout le monde

    j'ai toujours un tit souci à éviter qu'on enregistre les donnée de mon formulaire 2 fois via le bouton enregistrer j'ai essayer différent script comme :

    (script de mèlanie)

    If Range("A" & DernLigne).Value = TextBox_date.Value and Range("B" & DernLigne) = ComboBox_bases.Value and Range("D" & DernLigne) = TextBox_lot.Value and Range("E" & DernLigne) = ComboBox_produit.Value and Range("F" & DernLigne) = ComboBox_designation.Value and Range("H" & DernLigne) = ComboBox_format.Value and Range("J" & DernLigne) = TextBox_quant.Value Then

    MsgBox ("Mouvement viens d'être enregistrer NE PAS ENREGISTRER 2 FOIS LE MEME MOUVEMENT")

    'Séparé :

    If Range("A" & DernLigne) = TextBox_date.Value + 1 - 1 Then
    If Range("B" & DernLigne) = ComboBox_bases.Value Then
    If Range("D" & DernLigne) = TextBox_lot.Value + 1 - 1 Then
    If Range("E" & DernLigne) = ComboBox_produit.Value Then
    If Range("F" & DernLigne) = ComboBox_designation.Value Then
    If Range("H" & DernLigne) = ComboBox_format.Value Then
    If Range("J" & DernLigne) = TextBox_quant.Value + 1 - 1 Then

    MsgBox ("Mouvement viens d'être enregistrer NE PAS ENREGISTRER 2 FOIS LE MEME MOUVEMENT")

    et ça ne donne rien

    ça ne bug pas mais ça ne donne aucun résultat il continu d'enregistrer quand j'appui 2 fois sur le bouton enregistrer

    Une petite ou grande idée ??
    0
    1. le mieux car je suis quasiment seule à te répondre.
      Rouvre un nouveau post avec ce pb et tu auras les réponses à tes questions.
      0
  2. Bonjour

    Pour ton probleme de If
    peux tu donner ton fichier pour voir mieux l'ensemble de ton code

    A+

    Maurice
    0
    1. Bonjour

      j'ais oublier de mettre le Clear

      With Feuil6 ' CodeName
      ComboBox_designation.Clear
      For L = 3 To .Cells(Rows.Count, Col).End(xlUp).Row
      ComboBox_designation.AddItem .Cells(L, Col)
      Next L
      End With
      A+

      Maurice
      0
      1. Bonjour Maurice ,

        Merci pour tes réponse c'est vraiment très intéressant ce que tu me donne
        0
        1. Bonjour

          tien tu a pas recu ma reponse sur " Limonade"

          Private Sub ComboBox_produit_Change()
          '" Limonade " = ListIndex 0
          '" Bière " = ListIndex 1
          '" BST " = ListIndex 2
          Col = ComboBox_produit.ListIndex + 5
          ' Feuil6 = CodeName
          ' (Feuil3) = Non de l'onglet
          With Feuil6 ' CodeName
          For L = 3 To .Cells(Rows.Count, Col).End(xlUp).Row
          ComboBox_designation.AddItem .Cells(L, Col)
          Next L
          End With
          End Sub

          joue avec les index ses plus simple

          A+

          Maurice
          0
          1. j'apprécie bcp votre aide mais je pense qu'il faudra voir par vous même j'ai essayer les 2 solution que vous m'avez proposer ça ne marche pas

            je sais plus d'ou viens le problème

            http://cjoint.com/?CHbmiYrmJI2

            jetez un coup d'oeil si vous pouvez et dites moi , Merci
            0
            1. Modérateur
              Faudrait aussi arrêter les doublons....
              ICI

              ça doit faire plaisir à mélanie qui se décarcasse pour toi depuis le 24/07 et une bonne trentaine de réponses......
              0
            2. je sais je travaillais sur les 2 formulaire en même temps , je ne voulais pas trop en demander à Mélanie c'est tout .
              0
            3. c normal que ca ne marche pas.
              Dans ta combobox_produit : tu écris " Limonade"
              dans le code tu dis si combobox_produit = "Limonade"
              " Limonade" n'est pas égal à "Limonade"

              soit tu laisses l'espace et tu dis :
              If ComboBox_produit.Value = " Limonade" Then

              soit tu enlèves l'espace quand tu remplis la comboobx et tu laisses le code comme suit.
              0
            4. oui ça doit surement être ça merci :)
              0
            5. coucou mèlanie :) j'espère que tu vas bien

              je voudrais te demander si tu sais pourquoi cette formule ne marche pas :

              If Sheets("Commande").Range("A" & DernLigne).Value = TextBox_date.Value And Sheets("Commande").Range("C" & DernLigne).Value = ComboBox_enseigne.Value Then

              si tu as une idée je suis prenante
              merci :)
              0
          2. ah d'accord il faut que je mette mes instruction avant le script d'enregistrement !! merci c parfait .

            juste une ptite dernière chose que j'aimerais faire , je voudrais éviter qu'on puisse enregistrer 2 fois les même données en cliquant sur le bouton enregistrer 2 fois sans aucun changement au niv des données saisi

            ça peut se faire je pense ! non ?
            0
            1. alors avant ton enregistrement voici ce qu'il faut que tu dises :

              Dim DernLigne As Long
              dim ligne,a as variant

              DernLigne = Columns(1).Find("*", , , , xlByColumns, xlPrevious).Row

              for ligne = 2 to dernligne

              if Range("A" & ligne) = TextBox_date.Value and Range("B" & ligne) = ComboBox_bases.Value
              if Range("D" & ligne) = TextBox_lot.Value and Range("E" & ligne) = comboBox_produit.Value
              if Range("F" & ligne) = ComboBox_designation.Value and Range("H" & ligne) = ComboBox_format.Value and Range("J" & ligne) = TextBox_quant.Value
              ligne = dernligne
              a = "erreur"
              end if
              end if
              end if

              if a = "erreur" then
              msgbox "doublon"
              else
              'enregistrement
              end if
              0
            2. ça ne donne rien quand je clic 2 fois sur enregistrer ça m'enregistre 2 fois les mm donner

              http://cjoint.com/?0GFkYzrA4xc
              0
            3. et ça marche qu'on tu l'exécute chez toi , moi ça me m'affiche un débogage au niv de :

              If Range("A" & ligne) = TextBox_date.Value + 1 - 1 And Range("B" & ligne) = ComboBox_bases.Value And Range("D" & ligne) = TextBox_lot.Value + 1 - 1 And Range("E" & ligne) = ComboBox_produit.Value And Range("F" & ligne) = ComboBox_designation.Value And Range("H" & ligne) = ComboBox_format.Value And Range("J" & ligne) = TextBox_quant.Value + 1 - 1 Then

              je comprend pas les -1 +1 en fait ?
              0
            4. je sais pourquoi. Je l'avais découpé et je l'ai recollé et j'ai enlevé les if, remplace le code par celui-ci :

              If Range("A" & ligne) = TextBox_date.Value + 1 - 1 And if Range("B" & ligne) = ComboBox_bases.Value And if Range("D" & ligne) = TextBox_lot.Value + 1 - 1 And if Range("E" & ligne) = ComboBox_produit.Value And if Range("F" & ligne) = ComboBox_designation.Value And if Range("H" & ligne) = ComboBox_format.Value And if Range("J" & ligne) = TextBox_quant.Value + 1 - 1 Then

              Le +1-1 s'explique par le fait que dans les cellules excel, les dates et les nombres sont considérées comme des chiffres.
              Les valeurs que tu rentres dans les textbox sont considérées comme du texte.
              Donc excel comparait 01/01/2013 avec "01/.01/2013" pour lui il existe une différence, pour toi il n'yen a aucune.
              Pour transformer un texte en nombre, il suffit de lui faire une action pour lui dire un nombre comme une addition.
              Mais si tu fais le nombre indiqué dans la textbox +1 ==> tu as un écart de 1 entre ta saisie et ce que tu veux comparer donc j'annule l'addition par une soustraction.

              Ainsi, la date 01/01/2013 est comparé avec 01/.01/2013 (soit "01/01/2013"+1-1 est devenu 01/01/2013).

              Voilà pourquoi tes doublons ne fonctionnaient pas.
              0
          3. bonjour tt le monde ,

            voila je suis arriver presque à la fin de ce premier formulaire ce qu'il me reste c'est de lui dire d'appliquer des formule entrée sur le tableau sur l'ensemble des valeurs saisi , voila mes formule :
            exemple la saisi ce fait au niveau de la ligne 212

            Qté stock =SI(K212= "SORT";-J212;J212)
            stock initiale =INDEX($N$3:N212;MAX(SI((SUPPRESPACE($I$9:I212)=SUPPRESPACE(I213))*(LIGNE($N$3:N212)<LIGNE());LIGNE($N$3:N212)))-1)

            Stock finale = stock initiale + Qté en stock

            voila quelqu'un a une idée , j'ai besoin d'en finir avec ce formulaire et avancer sur les autres

            merci d'avance
            0
            1. coucou,

              voici comment tu fais :
              'calcul de la qté stoxk en J et dernière ligne
              Range("J" & DernLigne + 1) .select
              ActiveCell.FormulaR1C1 = "=IF(R212C11= ""SORT"",-R212C10,R212C10)"

              'calcul du stock final en K
              Range("K" & DernLigne + 1) .select
              ActiveCell.FormulaR1C1 = "=INDEX(R3C14:R212C14,MAX(IF((TRIM(R9C9:R212C9)=TRIM(R213C9))*(ROW(R3C14:R212C14)<ROW()),ROW(R3C14:R212C14)))-1)"

              'calcul de la somme

              Range("L" & DernLigne + 1).select
              ActiveCell.FormulaR1C1 = "=RC[-1]+RC[-2]"

              ==> te donne des formules incluant des $
              si tu veux que ca inclut les dernières lignes :

              'calcul de la qté stoxk en J et dernière ligne
              Range("J" & DernLigne + 1) .select
              ActiveCell.FormulaR1C1 = "=IF(R" & Dernligne & "C11= ""SORT"",-R" & & Dernligne & "C10,R212C10)"

              'calcul du stock final en K
              Range("K" & DernLigne + 1) .select
              ActiveCell.FormulaR1C1 = "=INDEX(R3C14:R" & Dernligne & "C14,MAX(IF((TRIM(R9C9:R" & Dernligne & "C9)=TRIM(R213C9))*(ROW(R3C14:R" & Dernligne & "C14)<ROW()),ROW(R3C14:R" & Dernligne & "C14)))-1)"

              'calcul de la somme

              Range("L" & DernLigne + 1).select
              ActiveCell.FormulaR1C1 = "=RC[-1]+RC[-2]"
              0
            2. ok je comprend mais la on admet qu'on connais le numéro de la dernière ligne , la saisi se fait à chaque dans une lignes et plus on avance plus ce numéro augmente donc si j dois exécuter cette formule pour chaque saisi j voudrais qu'il raisonne par rapport à la dernière ligne pas forcement la 212 . vous voyez ?
              0
            3. si tu copies colles ce code, c aprendra en compte la dernière ligne :

              'calcul de la qté stoxk en J et dernière ligne
              Range("J" & DernLigne + 1) .select
              ActiveCell.FormulaR1C1 = "=IF(R" & Dernligne & "C11= ""SORT"",-R" & & Dernligne & "C10,R212C10)"

              'calcul du stock final en K
              Range("K" & DernLigne + 1) .select
              ActiveCell.FormulaR1C1 = "=INDEX(R3C14:R" & Dernligne & "C14,MAX(IF((TRIM(R9C9:R" & Dernligne & "C9)=TRIM(R213C9))*(ROW(R3C14:R" & Dernligne & "C14)<ROW()),ROW(R3C14:R" & Dernligne & "C14)))-1)"

              'calcul de la somme

              Range("L" & DernLigne + 1).select
              ActiveCell.FormulaR1C1 = "=RC[-1]+RC[-2]"
              0
            4. j'ai essayer avec ces formules et ça ne marche pas , il ne beugue pas mais il n'affiche rien sur les cellule que je veux .

              voici le lien si tu peux jeter un coup d'oeil

              http://cjoint.com/?CGEkKwiZWzr

              merci
              0
            5. il est possible de mettre un code VBA qui correspond un peu à sélectionner les cellules et descendre mais on lui disant de s'arrêter au niveau de la dernière ligne :

              exemple :

              Range(L221:("L" & DernLigne + 1)).Select
              Selection.AutoFill Destination:=Range(L221:("L" & DernLigne + 1)), Type:=xlFillDefault
              Range("L221:("L" & DernLigne + 1)).Select

              ça ne marche pas comme ça mais ça doit être qq chose dans ce genre peut être ?
              0
          4. coucou

            j'ai vu ce que tu as fait mais essai de l'exécuter tu verras que ça ne change pas de liste pour chaque type de produit ça se rajoute l'une sur l'autre .
            0
            1. oui en effet l'ajout de combobox.clear arrange les choses

              voila j'ai essayer de continuer sur ton script et de faire la même chose par rapport au : produit et désignation ensuite désignation et gamme

              Private Sub ComboBox_produit_change()

              Dim nb_lignes As Integer

              ComboBox_designation.Clear

              If ComboBox_produit.Value = "Limonade" Then
              b = 11
              Else
              If ComboBox_produit.Value = "Bière" Then
              b = 12
              Else
              If ComboBox_produit.Value = "Malte" Then
              b = 13
              Else
              If ComboBox_produit.Value = "Cartons" Then
              b = 14

              End If
              End If
              End If
              End If

              nb_lignes = Sheets("Feuil2").Cells(1, b).End(xlDown).Row

              For i = 2 To nb_lignes
              ComboBox_designation.AddItem Sheets("Feuil2").Cells(i, b)

              Next
              End Sub

              quand j'essay avec ce script ça marche sauf pour les produit qui n'ont pas de désignation

              exemple : Mat 1er == scotch normale ==pas de désignation == pas de gamme == pas de format

              il faudra que je lui dise que pour tout le reste la case désignation sera inactive (vide)
              0
            2. Pour le faire,

              et tu rajoutes ce code :

              Private Sub ComboBox_produit_change()

              Dim nb_lignes As Integer

              ComboBox_designation.Clear

              If ComboBox_produit.Value = "Limonade" Then
              designation.Enabled=false ' rend inactif la désignation
              b = 11
              Else
              If ComboBox_produit.Value = "Bière" Then
              designation.Enabled=true ' rend actif la désignation
              b = 12
              Else
              If ComboBox_produit.Value = "Malte" Then
              designation.Enabled=false ' rend inactif la désignation

              b = 13
              Else
              If ComboBox_produit.Value = "Cartons" Then
              designation.Enabled=true ' rend actif la désignation

              b = 14

              End If
              End If
              End If
              End If

              nb_lignes = Sheets("Feuil2").Cells(1, b).End(xlDown).Row

              For i = 2 To nb_lignes
              ComboBox_designation.AddItem Sheets("Feuil2").Cells(i, b)

              Next
              End Sub
              0
            3. coucou ,

              en fait je comprend pas pourquoi d'un coup c'est actif et d'un coup c'est inactif , quand je l'applique ça beugue toujours au niveau des produit qui n'ont pas de désignation

              du coup je me demande si j devrais pas essayer ça :

              Private Sub ComboBox_produit_change()

              Dim nb_lignes As Integer

              ComboBox_designation.Clear

              If ComboBox_produit.Value = "Limonade" Then
              b = 11
              Else

              If ComboBox_produit.Value = "Bière" Then
              b = 12
              Else

              If ComboBox_produit.Value = "Malte" Then
              b = 13
              Else

              If ComboBox_produit.Value = "Cartons" Then
              b = 14
              Else

              designation.Enabled = False 'designation inactif pour tout les produit qui reste

              End If
              End If
              End If
              End If

              nb_lignes = Sheets("Feuil2").Cells(1, b).End(xlDown).Row

              For i = 2 To nb_lignes
              ComboBox_designation.AddItem Sheets("Feuil2").Cells(i, b)

              Next
              End Sub

              Ça beugue encore au niveau : nb_lignes = Sheets("Feuil2").Cells(1, b).End(xlDown).Row

              une idée prk ??

              Merci pour ton aide en tt cas
              0
            4. envoies moi ton fichier tel quel, je pense avoir une idée, mais vaut mieux que je vois car ce n'est peut être pas ca.

              Quand est ce que tu veux que ta désignation soit inactif pour tous les autres produits qui ne sont pas limonade, malte, bière ou cartons?
              0
          5. coucou,

            ce que tue ssaies de faire, je l'ai déjà fait dans le fichier:

            https://www.cjoint.com/c/CGzpRhfpA6e
            0
            1. Modérateur
              Bonjour le fil,
              Mélanie,

              Lorsque tu remplis une combobox à partir d'une autre, il ne faut pas oublier de la vider. Sinon les contenus se cumulent. Exemple :
              Private Sub ComboBox1_Change()
              If ComboBox1 = "" Then Exit Sub 'pratique!!!
              For i = 1 To 15
                  If Cells(i, 1) = ComboBox1 Then ComboBox2.AddItem Cells(i, 2)
              Next i
              End Sub

              Il convient d'y ajouter : ComboBo2.Clear

              Private Sub ComboBox1_Change()
              If ComboBox1 = "" Then Exit Sub 'pratique!!!
              ComboBox2.Clear
              For i = 1 To 15
                  If Cells(i, 1) = ComboBox1 Then ComboBox2.AddItem Cells(i, 2)
              Next i
              End Sub
              0
          6. coucou
            voila j'ai rajouter 2 ou 3 truc à ce que tu m'a donner
            http://cjoint.com/?0GzsJHuivmB

            j'ai essayer de faire exemple : si c'est produit fini , la liste de la gamme sera .....ect

            exemple :
            If ComboBox_typeproduit.value = "P.Fini" then
            ComboBox_produit.AddItem "BST"
            ComboBox_produit.AddItem "Bière"
            ComboBox_produit.AddItem "Limonade"

            If ComboBox_typeproduit.value = "Mat 1er" then
            ComboBox_produit.AddItem "Etiquette"
            ComboBox_produit.AddItem "Collerette"
            ComboBox_produit.AddItem "Malte"
            ComboBox_produit.AddItem "Cartons"
            ComboBox_produit.AddItem "Valisette"
            ComboBox_produit.AddItem "ScotchTransp"
            ComboBox_produit.AddItem "ScotchImprimé"
            ComboBox_produit.AddItem "Bouchons Mécaniques"
            ComboBox_produit.AddItem "RouDLUO"
            ComboBox_produit.AddItem "Film Etirable"

            End If
            End If

            mais ça ne marche pas , je travaille encore sur le reste (j'ai 2 ptites idée ) dès je les met en oeuvre je t'envoie le nouveau fichier

            Allez bonne soirée

            et merci encore
            0
            1. Bonjour Mélanie

              voila je vous envoie le fichier . j'arrive pas à exécuter le formulaire à partir d'un bouton de commande sur la feuille 1 enfin si je l'exécute mes les données des liste déroulante sont vides.

              et surtout je ne sais pas comment afficher le stock initial avant le mouvement et puis le modifier en fonction du type de mouvement pour affiche un stock final

              comment puis-je vous envoyer mon fichier excel ?
              0
              1. coucou,

                tu peu le mettre sur cjoint.com

                j'arrive pas à exécuter le formulaire à partir d'un bouton de commande sur la feuille 1

                ==> tu crées un bouton, tu l'affectes à une macro.
                Dans la macro, tu tapes le code : Userform1.show 'fait apparaître le userform

                je l'exécute mes les données des liste déroulante sont vides.

                ==> Indiqué dans le lien fournit. Quand tu as créées ton formulaire, tu peux voir le code qui se cache derrière. Simple, tu double clic sur un contrôle ou sur le formulaire lui-même.
                Dans cette feuille, tu cherches sinon tu ajoutes :
                Private Sub UserForm_Initialize()

                End Sub

                ==> ce bout de code s'exécute à l'initialisation de ton formulaire.
                Pour ajouter des données à tes listes déroulantes :

                Private Sub UserForm_Initialize()
                ListBox1.AddItem "1ère valeur" ' entre guillemet la valeur ajoutée à la listebox1
                ListBox1.AddItem "2ème valeur"
                Listbox2.additem "Atchoum"
                End Sub

                et surtout je ne sais pas comment afficher le stock initial avant le mouvement et puis le modifier en fonction du type de mouvement pour affiche un stock final

                ==> dans le même endroit que sub userform_initialize, tu peux ajouter un code

                Private Sub OptionButton1_Click()
                if optionbutton1.value = true 'si l'optionbouton1 est cochée
                a=a+1 'alors a=a+1
                else
                a=a-1 'alors a = a-1
                end if
                End Sub

                essaies et vois si tu as encore besoin de moi.
                0
              2. je pense que tu devrais voir un peu ce que j'ai fait , c'est un peu différent .

                http://cjoint.com/?0GzoqD3oB6O

                Regarde et dis moi si tu vois un peu ce que je veux faire
                0
              3. ok, je sais pas is j'aurais le temps cet am mais peut être ce soir.
                0
            2. Merci c'est vrai que ça m'a aider un débuter mon formulaire !

              Mais je ne sais toujours par comment renvoyer le type de mouvement coché à une procédure à savoir par exemple :

              si entré stock PF et sortie stock PSF sont coché : il faudra rechercher le stock théorique le plus récent en produit x Fini (ajouter la quantité) et en produit x Semi Fini ( soustraire la même quantité)
              0
              1. coucou,

                te serait-il possible de m'envoyer ton fichier, le code que tu demandes est assez simple je pense mais il est préférable que je vois ton fichier
                0