Microsoft 365 Question sur VBA EXCEL

kondabalo

XLDnaute Nouveau
Bonjour à tous,

Je suis stagiaire et Excel je m’y connais un peu. Cependant je fais face à un problème qui je pense ne puisse pas être résolu par les fonctions « Si » ou « RechercheV ». Il m’a été conseillé de me diriger vers les codes VBA. Je n’ai pas un niveau excellent en VBA c’est pour cela je sollicite votre aide.

- J’ai deux colonnes A et B. dans la colonne A on retrouve les différents produits et dans la colonne B on retrouve le statut des produits.
- On a que trois types de statut pour les produits. Soit le produit est actif, inactif ou dormant.

1- D’abord « Actif » domine sur dormant et « dormant » domine sur « Inactif »

C'est à dire que:

- Si j’ai le produit Banane sur 6 lignes, et que sur ces 6 lignes on a les trois statuts (actif, dormant, inactif) dans le désordre, je veux que le code donne la priorité à "actif "en premier en attribuant actif sur toutes les 6 lignes de Banane.

- Mais si sur ces 6 lignes de Banane on a que « dormant » et « inactif », je veux que le code attribue la priorité à Dormant en affectant Dormant sur toutes ces 6 lignes de Banane.

- si sur ces 6 lignes de Bananes, on a qu’inactif, dans ce cas on peut garder ces 6 lignes en inactif.

- si sur ces 6 lignes de Bananes, on a que Dormant, dans ce cas on peut garder ces 6 lignes en Dormant.

- si sur ces 6 lignes de Bananes, on a que Actif, dans ce cas on peut garder ces 6 lignes en Actif.

Pour mieux vous expliquer, Je vous laisse donc un tableau en exemple de ce que je cherche à obtenir

ProduitStatutCe qui est attendu
BananeinactifActif
BananeActifActif
BananedormantActif
BananeinactifActif
BananeActifActif
BananedormantActif
Mangueinactifdormant
Manguedormantdormant
Mangueinactifdormant
Mangueinactifdormant
Pommeinactifinactif
Pommeinactifinactif
Pommeinactifinactif

Cà va faire déjà plus d'un mois que je suis dessus mais je n'arrive pas à atteindre mon but. J'espère que vous comprenez ma frustration. En effet j'ai pu écrire un petit bout de code VBA avec l'aide de quelques camarades mais on y est toujours pas.

Le code VBA que j'ai réussi à écrire arrive à bien faire la différence entre chaque produit mais le seul soucis est qu'il attribut le statut du produit en première lignes aux autres lignes sans prendre en compte le faite que C'est " Actif " qui prime si il est présent pour le produit sinon c'est "Dormant" et pour finir avec "inactif"

################# Mon code déjà écrit ###########################
Option Explicit

Private Sub AdaptStatus_Click()

Dim sh As Worksheet
Dim myRng As String
Dim fruit, status As String
Dim j As Long: j = 2
Dim cible As Range
Dim addressOne As String

Set sh = ThisWorkbook.Sheets("Fruits")
myRng = "A2:B" & sh.Cells(Rows.Count, 1).End(xlUp).Row

With sh.Range(myRng)

Do While True
If Cells(j, 1) = "" Then Exit Do
fruit = Cells(j, 1).Value
status = Cells(j, 2).Value
Set cible = .Find((fruit), LookIn:=xlValues)

If Not cible Is Nothing Then
addressOne = cible.Address
Do
cible.Offset(0, 1) = status
Set cible = .FindNext(cible)
Loop While Not cible Is Nothing And cible.Address <> addressOne
End If
j = j + 1
Loop

End With

MsgBox "Tous les statuts sont mis à jour !", vbInformation + vbOKOnly, "Mise à jour ds statuts"

End Sub
####################################################################

Dans la colonnes j à partir de la ligne 2 j'ai écrit les trois statut: Actif, Dormant et Inactif

Je vous remercie à l'avance si quelqu'un avait le temps de se pencher sur le sujet
Merci d'avance
icon_sad.gif
 
Solution
Bonjour à tous,

Pourquoi passer par VBA ? Une simple formule suffit.

Le mieux est de convertir votre tableau en tableau structuré. Puis d'insérer la formule :
VB:
=SI(NB.SI.ENS([Produit]; [@Produit];[Statut];"actif")>0;"Actif";SI(NB.SI.ENS([Produit]; [@Produit];[Statut];"dormant")>0;"Dormant";"inactif"))

kondabalo

XLDnaute Nouveau
Bonjour à Tous

je me permet de vous joindre un fichier Excel dans lequel vous pourrez facilement comprendre l'exécution de mon code déjà écrit mais qui fait pas exactement ce que j'attend.

Merci encore d'avance à celui qui prendra son temps là dessus
 

Pièces jointes

  • Produits.xlsm
    24.4 KB · Affichages: 8

dysorthographie

XLDnaute Impliqué
Bonjour,
VB:
Public Cn As Object
Public Function FruitStatut(v As String) As String
If TypeName(Cn) = "Nothing" Then
    Set Cn = CreateObject("ADODB.Connection")
      With Cn '==>Open connection
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
            & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=YES;"""
        .Open
     End With
End If
With Cn.Execute("Select top 1 [Statut]FROM [Feuil1$] WHERE [Produit]= '" & v & "' ORDER BY  [Statut]")
    If Not .EOF Then FruitStatut = .Fields("Statut")
    .Close
End With
End Function
Sub test()
Debug.Print FruitStatut("Banane")
End Sub
 

Pièces jointes

  • Produits.xlsm
    21.1 KB · Affichages: 5

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour à tous,

Pourquoi passer par VBA ? Une simple formule suffit.

Le mieux est de convertir votre tableau en tableau structuré. Puis d'insérer la formule :
VB:
=SI(NB.SI.ENS([Produit]; [@Produit];[Statut];"actif")>0;"Actif";SI(NB.SI.ENS([Produit]; [@Produit];[Statut];"dormant")>0;"Dormant";"inactif"))
 

Pièces jointes

  • kondabalo- Nouveaux statuts- v1.xlsx
    10.7 KB · Affichages: 6

mapomme

XLDnaute Barbatruc
Supporter XLD
Re,
Bonjour @dysorthographie ;)

Une méthode par VBA :
VB:
Sub NouveauStatut()
Dim t, dico, i&, arr, clef

   With Sheets("Data")
      If .FilterMode Then .ShowAllData
      t = Intersect(Range("a1").CurrentRegion, .Columns("a:b"))
     
      Set dico = CreateObject("scripting.dictionary"): dico.CompareMode = TextCompare
      For i = 2 To UBound(t)
         If Not dico.exists(t(i, 1)) Then dico.Add t(i, 1), Array(0, 0, 0)
         arr = dico(t(i, 1)): t(i, 2) = LCase(t(i, 2))
         If t(i, 2) = "actif" Then arr(0) = arr(0) + 1 Else If t(i, 2) = "dormant" Then arr(1) = arr(1) + 1 Else arr(2) = arr(2) + 1
         dico(t(i, 1)) = arr
      Next i
     
      For Each clef In dico
         arr = dico(clef)
         If arr(0) > 0 Then dico(clef) = "Actif" Else If arr(1) > 0 Then dico(clef) = "dormant" Else dico(clef) = "inactif"
      Next clef
     
      For i = 2 To UBound(t): t(i, 2) = dico(t(i, 1)): Next
     
      Range("a1").Resize(UBound(t), 2) = t
   End With
End Sub
 

Pièces jointes

  • kondabalo- Nouveaux statuts- v1.xlsm
    18.7 KB · Affichages: 4

Roblochon

XLDnaute Barbatruc
Bonjour,

Vous pouvez également le faire par Power Query (Données/A partir d'un tableau ou d'une plage) :
Quand les données changent, il suffit de faire un click-droit sur une cellule du tableau (vert) et 'Actualiser'.

Cordialement
 

Pièces jointes

  • Produits-PQ.xlsm
    32.5 KB · Affichages: 2

kondabalo

XLDnaute Nouveau
Bonjour à tous

Je tiens à vous remercier de votre intervention face à cette difficulté et du temps que vous avez pu y consacrer.

@mapomme vos deux proposions: celui du code VBA et celui avec la fonction SI répondent tout à fait à ce que je cherchais à obtenir pour cela je vous dit un grand merci. En effet si c'était que j'avais connaissance de la fonction "nb.si.ens" peut être que cela m'aurait éviter le temps consacrer sur le code VBA mais cela m'a quand permis de m'initier.

@dysorthographie votre code ne fonctionne pas exactement comme je le souhaiterais. Mais j'ai appris quelques petits astuces en plus donc merci à vous.

@Roblochon je tiens à vous remercier aussi. Mais Dans le cas du power Query, ce n'est pas tout à fait ce à quoi je m'attendais.

Tous ce que je peux dire c'est que vous êtes tous des génies et un grand merci 😊

En espérant un jour pouvoir être à votre niveau
 
Haut Bas