Mélange Range, cells et if else [Résolu]

Signaler
-
 scribetout -
Bonjour,

For Each cel In pl.Offset(0, 2).SpecialCells(xlCellTypeVisible)         
    Set dest IIf(o.Range("A7").Value "", o.Range("A7"), o.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0)) 'définit la cellule de destination
    'dest.Value = cel.Value 'récupère dans dest la valeur de la cellule cel (code initial)
    dest.Value = cel.Offset(1, 0) & Chr(10) & "PK" & cel.Offset(0, 3) & Chr(10) & cel.Offset(0, 7)
      
    Next cel 


Débutant en VBA, avec le code ci-dessus je parviens à récupérer des données d'une base de données vers d'autres feuilles dont le nom est issu des valeurs d'une colonne de la feuille"BD".
Je voudrai effectuer cette récupération avec condition:
-vérifier si la cellule cel.offset(0, 3) est vide alors on récupère dans dest.value =cel.offset(1,0) & Chr(10) & cel.offset(0,7)
ç-à-d sans la concatenation de "PK" & cel.offset(0,3)

- si elle n'est pas vide récupérer comme sur la dernière ligne de code (avec "PK")

je n'ai pas vraiment le code du set dest et encore moins le mèlange des Range et Cells.

Je vous remercie.

38 réponses

Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Coucou,
Excuse-moi. Je ne t'avais pas laissé tombé, mais une gouttière ma obligé à intervenir sur ma toiture.
Revenons à nos moutons :*
Dernière étape :
Toujours dans le nouveau projet (avec la feuille entreprises renseignée proprement et la feuille BD également renseignée proprement, comme nous l'avons vu en étapes 1 et 2) :
Tu mets ce code dans le module des macros :
Option Explicit
Public Sub traitement()
  Dim c As Range, derlig As Long, i As Long, ou As Long, enA As String, taborig
  derlig = Worksheets("BD").Range("B" & Rows.Count).End(xlUp).Row
  If derlig < 8 Then MsgBox "pas de données à traiter !": Exit Sub
  taborig = Worksheets("BD").Range("A8:L" & derlig)
  For Each c In Worksheets("entreprises").Range("A:A").SpecialCells(xlCellTypeConstants)
    If c.Text <> "" Then
      With Worksheets(c.Value)
        .Range(.Cells(7, 1), .Cells(Rows.Count, Columns.Count)).ClearContents ' on vide chaque feuille après ligne 7
      End With
    End If
  Next
  For i = 1 To UBound(taborig)
    With Worksheets(taborig(i, 2))
       ou = ou_ecrire(Worksheets(taborig(i, 2)))
       enA = taborig(i, 4) & Chr(10) & taborig(i, 8) & Chr(10) & taborig(i, 12)
       enA = Replace(enA, Chr(10) & Chr(10), Chr(10))
      .Range("A" & ou).Value = enA
      .Range("B" & ou).Value = taborig(i, 2)
      .Range("C" & ou).Value = taborig(i, 3)
      .Range("D" & ou).Value = taborig(i, 5)
      .Range("E" & ou).Value = taborig(i, 6)
      .Range("F" & ou).Value = taborig(i, 7)
      .Range("G" & ou).Value = taborig(i, 9)
      .Range("H" & ou).Value = taborig(i, 10)
      .Range("I" & ou).Value = taborig(i, 11)
    End With
  Next
End Sub

Private Function ou_ecrire(f As Worksheet) As Long
  ou_ecrire = f.Range("A" & Rows.Count).End(xlUp).Row + 1
  If ou_ecrire <7 Then ou_ecrire 7
End Function

Et tu lances et nous dis (je n'ai pas de données pour vérifier, mais je pense que tout sera bon).
Tu dis.





________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
toutes mes excuses, j'ai omis un mot dans la dernière phrase:
je n'ai pas vraiment compris le code du set dest et encore moins le mèlange des Range et Cells.

mes remerciements.
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Salut

... donc tu as lu assidûment l'aide de ces fonctions et ?

Tu as décrit en français ce que tu voulais faire.
Ton code y ressemble, en effet.
Que lui reproches-tu ?

Regarde simplement l'aide de la fonction Iff et tu sauras où placer ta ligne de concaténation.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on le partage (Socrate)
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Arg, j'avais pas vu :
Tu fais une jolie boucle pour scruter les cellules d'un ensemble de cellules.
La cellule pointée par la boucle est 'cel'
Mais dans l'instruction 'Set', tu n'utilises pas 'cel' !
Alors quel intérêt de boucler autant de fois pour évaluer toujours la même expression ?
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
J'ai un doute.
A quoi correspond l'objet 'o' dans ton Iff ?

Cette instruction n'a ni queue ni tête.
D'où sort-elle ?
Coller des lignes venant d'ailleurs et venir sur le forum avec un tel montage : c'est pas sérieux.
Bonjour,

Etant néophyte en VBA, en effet ce bout de code n'est pas de moi, je l'ai adapté pour mes besoins. Pour le peu de questions que j'ai posé sur ce forum, je suis un peu déçu par certaines "petites phrases". Je voudrai savoir si ce forum est dédié spécialement aux initiés, si c'est le cas, je vous prie d'excuser mon intrusion.
Dans l'éventualité qu'il est aussi dédié à de pauvres bougres comme moi, je vous soumets le code complet, qui fonctionne très bien. Je voudrai remplacer le "IIf" pour concaténer des cellules avec conditions comme mentionner dans mon précédent message.
Je vous remercie.
Sub Macro2()
Dim bd As Object 'déclare la variable bd (onglet BD)
Dim dico As Object 'déclare la variable dico (DICtiOnnaire)
Dim dl As Integer 'déclare la variable dl (Dernière Ligne)
Dim pl As Range 'déclare la variable pl (PLage)
Dim cel As Range 'déclare la variable cel (CELlule)
Dim temp As Variant 'déclare la variable temp (tableau TEMPoraire)
Dim i As Integer 'déclare la variable i (Incrément)
Dim dics As Object 'déclare la variable dics (DICtionnaireS)
Dim o As Object 'déclare la variable o (Onglet)
Dim dest As Range 'déclare la variable dest (cellule de DESTination)
Dim teo As Variant 'déclare le tableau de variables teo (tableau TEmporaire Outils)
Dim x As Integer 'déclare la variable x
Dim y As Integer 'déclare la variable y
Dim dercol As Integer

Set bd = Sheets("ConsultCMDP") 'définit l'onglet bd
Set dico = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
dl = bd.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée dl de la colonne 1 (=A) de l'onglet bd
Set pl = bd.Range("B8:B" & dl) 'définit la plage pl

bd.Range("A1").AutoFilter 'annule le filtre automatique

For Each cel In pl 'boucle sur toutes les cellules cel de la plage pl
    dico(cel.Value) = "" 'alimente le dictionnaire dico
Next cel 'prochaine cellule de la boucle
temp = dico.keys 'récupère le dictionnaire sans doublon dans le tableau temp

For i = 0 To UBound(temp) 'boucle 1 : sur toutes les valeurs uniques du tableau temp
    Set o = Sheets(temp(i)) 'définit l'onglet o
    
    o.Range("I2") = UCase(temp(i))
    o.Range("I2").Font.ThemeColor = xlThemeColorDark1
    
   o.Range("A5").CurrentRegion.ClearContents
    
    bd.Range("A1").AutoFilter 'lance le filtre automatique
    bd.Range("A1").AutoFilter field:=2, Criteria1:=temp(i) 'filtre automatique sur la colonne 2 (=B) avec la valeur temp(i) comme critère
    Set dics = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dics
    For Each cel In pl.Offset(0, 1).SpecialCells(xlCellTypeVisible) 'boucle 2 : sur toutes les cellules visibles cel de la plage pl déclalée d'un colonne à droite
        dics(cel.Value) = "" 'alimente le dictionnaire dics
    Next cel 'prochaine cellule de la boucle 2
    teo = dics.keys 'définit le tabeau teo
    y = 2 'initialise la variable y
    
    For x = 0 To UBound(teo) 'boucle 3 : sur toutes les outils (sans doublon)
        o.Cells(5, y + 2).Value = teo(x) 'place l'outil dans le tableau
        y = y + 2 'incrément y
       
    Next x 'prochain outil de la boucle 3
    
    For Each cel In pl.Offset(0, 2).SpecialCells(xlCellTypeVisible) 'boucle 4 : sur toutes les cellules visibles cel de la plage pl déclalée de deux colonnes à droite
       If cel.Offset(0, 3) = "" Then
     Set dest = o.Range("A7").(o.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0)) 'définit la cellule de destination
    dest.Value = cel.Value 'récupère dans dest la valeur de la cellule cel (code initial)
    
    Next cel 'prochaine cellule de la boucle 4
      
    bd.Range("A1").AutoFilter 'annule le filtre automatique
    Next i 'prochaine valeur de la boucle 1
End Sub


Le savoir est la seule matière qui s'accroit quand on le partage (Socrate)
Absolument d'accord, encore faut-il qu'il le soit dans l'humilité (Scribetout)
Bonsoir,

Toute structure complexe est constituée d'éléments simples.
Partant de ce qui précède, j'ai contourné le problème.
Solution peu élégante (pour un développeur), mais qui répond parfaitement à mes attentes. J'ai rajouté une colonne dans laquelle j'ai concaténé mes données et dans le code j'ai juste modifié la référence de la colonne (cette colonne s'affiche et se masque par un "hidden=true ou false" et le tour est joué!)

Je vous remercie quand même et à la prochaine! peut être
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
68
Concernant les "petites phrases", on voit trop souvent des gens qui n'ont même pas ouvert l'aide pour essayer de comprendre; alors excuse, mais ton code (le Iff), sorti de son contexte que nous ne connaissons pas, semble tellement extraterrestre que je me suis posé la question.

Dans ta boucle 4, tu as mis un If, mais je ne vois pas de End If : Le compilo ne doit pas aimer ça.

o.Range("A7").(o.Cells...
Cette syntaxe n'est pas correcte.
C'est sensé faire quoi ?
Que veux-tu faire ?

En supposant que cette syntaxe soit bonne, tu es bien d'accord que dans cette ligne
Set dest = o.Range("A7").(o.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0))
il n'est pas fait référence à 'cel', l'objet de ta boucle.
Donc cette instruction fait toujours la même chose à chaque tour de boucle.
Puisque 'dest' ne change jamais, tu peux la mettre devant le For afin qu'elle ne soit exécutée qu'une seule fois.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Bonjour,
Je ne veux pas être un méchant, mais je vais rajouter ma "petite phrase".
Le problème n'est pas que, sur ce forum de développeurs, on y vienne en débutant ou en initié.
Le problème est que tu y viens avec un bout de code que tu as "trouvé", copié, "arrangé" et que tu nous demandes de le "corriger", alors même que nous ne connaissons ni les tenants ni les aboutissants.
Il vaudra mieux que tu exposes les tenants et aboutissants, clairement et avec précision, plutôt que de procéder comme tu l'as fait.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
J'ajoute, pour conforter ce que j'ai dit dans mon message précédent, que l'auteur de ce code que tu as "trouvé" et mal copié, en dépit de ce que tu affirmes qu'il "fonctionne très bien" (l'absence du End If dénoncée par jack ne peut que conduire à l'erreur !), n'est pas un virtuose.
J'en veux pour preuve cette ligne :
For Each cel In pl.Offset(0, 1).SpecialCells(xlCellTypeVisible)

Elle conduirait à la catastrophe dans certains cas de figure ! Par exemple lorsque, à la fois, le colonne traitée contenait un très grand nombre de lignes remplies, qu'un grand pourcentage d'entre elles seraient visibles et qu'un également grand pourcentage d'entre elles ne le seraient pas (ex : 1 000 000 de lignes remplies, dont 500 000 visibles et les autres cachées).
J'ai déjà eu l'occasion d'en parler.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Messieurs, je vous salut et vous remercie de votre intervention. Comme je l'ai déjà précisé, je suis débutant et ce code n'est pas de moi (je n'ai pas encore atteint un niveau suffisant pour concocter un tel code). Par contre, je précise que ce code fonctionne bien. Je n'ai constaté aucun défaut. En tant que développeurs vous me confirmés que ce code n'est pas fiable. Je n'ai pas vérifié les résultats sur toutes les feuilles.

J'ai bien suivi le déroulement du code (pas à pas) et j'ai peut-être conclu à tort de solliciter votre aide pour modifier seulement les 4 lignes de code qui reportent les données sur chacune des feuilles concernées.

Je me suis efforcé à comprendre ce code, mais pour certaines lignes, je n'ai pas compris grand chose (surtout le mélange des Range et cell et surtout set dest= avec le "IIf").
D'après l'aide IIf(expr, truepart, falsepart), si j'ai bien compris c'est un test de l'expression. C'est l'imbrication du "Set", "IIf", "Range" et "Cells" qui m'a dérouté.

J'ai passé une nuit blanche à faire des tests pour des prunes.

je vous expose donc mes attentes:
- la feuille nommée ("ConsultCMDP") constitue ma BD, en colonne B (de ligne 8 à dernière ligne non vide) sont saisis des entreprises (celles-ci peuvent figurer plusieurs fois dans la colonne B)
- pour chaque entreprise, j'ai créé une feuille qui porte le nom de l'entreprise
- je filtre dans la BD sur chaque entreprise, et concatène avec condition:
*si en colonne H cellule vide, concaténer D et L sur la feuille de l'entreprise concernée en colonne A (à partir de A7)
*si en colonne H cellule nonvide, concaténer D,H et L sur la feuille de l'entreprise concernée en colonne A (à partir de A7)

(la BD commence en A8 jusqu'à N dernière cellule non vide; toutes les autres feuilles (nom entreprise) commencent en A7 jusqu'à colonne variable selon besoin par rapport à l'entreprise)

Mes remerciements anticipés.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Voilà qui est devenu beaucoup plus clair et qui me permettra (je le ferai ce soir après ma pêche) de t'écrire un code ad-hoc bien plus logique et rapide que l' "adaptation" que tu avais faite d'un code destiné à un but très distinct du tien.
Mais pendant que l'on y est, à ce mettre à un travail plus orthodoxe :
1)
- pour chaque entreprise, j'ai créé une feuille qui porte le nom de l'entreprise

a) Bien, mais ... quid le jour où tu créeras une entreprise nouvelle ? Il te faudra également penser à créer la feuille correspondante
b) Si tu laisses à l'utilisateur le soin de saisir en colonne B, tu cours le risque d'une erreur de frappe ===>> et la feuille correspondante n'existant alors pas, tu auras une erreur. Il vaudra bien mieux le contraindre à un choix dans une liste déroulante, elle-même liée à la plage d'une feuille spéciale, dans laquelle tu :
--- écrirais les entreprises "acceptées"
--- à chaque ajout sur cette feuille spéciale ===>> création de la feuille "destinataire" correspondante
2) mon choix de méthode différera en fonction du nombre prévisible d'entreprises. A combien l'estimes-tu (environ) ?

Curieusement, ce sont ces deux aspects-là qui demanderont un travail plus délicat. Le reste (ton export des données sur les feuilles correspondantes) sera par contre un jeu d'enfant.
Je lirai tes réponses ce soir.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Je te salue et te remercie pour ta célérité. Ta remarque est très pertinente. En effet, je n'avais pensé à l'ajout d'autres entreprises. Pour leur nombre, je n'en ai aucune idée car c'est un fichier de suivi d'entreprises soumissionnaires dans plusieurs corps d'état et s'étalant sur plusieurs années (historique), donc appelé à évoluer.

Sur la feuille BD, en colonne B, j'ai mis une liste déroulante des entreprises (par validations des données). Par contre, je n'ai pas su créer la feuille correspondante en VBA. Donc dès que je rajoute une entreprise, je lui crée sa feuille. Un code allant dans ce sens ne sera pas de refus bien au contraire.

utilisation de ce fichier:
Dès qu'on reçoit, la liste des entreprises avec les critères (la concaténation en colonne A de chaque entreprise), On communique certaines informations sur ces entreprises pour sélection.

NB: Ce fichier n'est exploité que par moi et mon collègue quand je suis en absent.

Mon cher Ucfoutu, à défaut de grive je me suis contenté de merle ou si tu préfère à défaut de truite je me suis contenté de carpe.

En "Bleu" comme on dit, j'ai essayé d'adapté un code (qui fonctionne, du moins pour le grand nombre de feuilles, je n'ai pas vérifié les données sur toutes les feuilles existantes).

Je te remercie et te souhaite une très bonne pêche. la chance!
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Hé bien ! Nous y voilà.
Nous allons ensemble apprendre à concevoir astucieusement à à travailler de manière plus sûre.
J'espère simplement que le déroulement de la présente discussion sera suivi par quelques développeurs.
Nous allons tous les deux travailler en trois étapes :
ETAPE NUMERO 1 :
Création d'un petite "base de données" des entreprises "recensées et acceptées", avec, à chaque fois, création d'une feuille correspondant à cette entreprise-là
Tu vas, pour suivre plus aisément le déroulement de la pensée, ouvrir un nouveau classeur tout neuf, dans lequel tu vas créer une feuille nommée "entreprises".
Dans le code du module de cette feuille "entreprises", tu vas mettre le code qui suit, par copier/coller :
Private Sub Worksheet_Change(ByVal Target As Range)
  Set encours = ActiveSheet
  If Target.Column <> 1 Or Target.Count > 1 Or Target.Value = "" Then Exit Sub
  On Error Resume Next
  xx = Worksheets(Target.Value).Name
  If Err <> 0 Then
    With Worksheets.Add
      .Name = Target.Value
    End With
    encours.Activate
    On Error GoTo 0
  Else
     MsgBox "cette entreprise a déjà été créée !"
     Target.Value = ""
   End If
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   If Target.Column <> 1 Or Target.Count > 1 Then Exit Sub
   If Target.Value <> "" Then
     MsgBox "non modifiale"
     Target.Offset(0, 1).Activate
   End If
End Sub

Voilà pour ce qui est de la première étape (les autres suivront).
Va maintenant dans la feuille entreprises > en colonne A : ajoute des entreprises >> une feuille sera créée pour chaque entreprise nouvelle. Un message te parviendra si déjà existante...
Fais tes essais et reviens après cette première étape.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Bonjour,

je te remercie infiniment pour ton initiative de me donner un cours en quelque sorte. J'ai fait ce que tu as demandé et ça fonctionne parfaitement.
j'attends la suite avec impatience malgré un état un peu fébrile cette matinée. J'ai nommé ce fichier ucfoutu pour le garder précieusement.

Bonne journée! J'espère que tu as fait un bonne pêche.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Bien.
Deuxième étape après le déjeuner. A plus


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
Je suis de retour, si j'ai bien compris "Target" représente toutes les cellules de la feuille.

j'ai fait quelques manipulations et me suis aperçu que:
- si j'effectue des saisies dans la colonne B rien ne se passe (normal le code concerne la colonne 1=A)
- par contre quand j'efface ces saisies, j'ai une erreur code 13.
-au déboggage la ligne suivante est surlignée en jaune
 If Target.Column <> 1 Or Target.Count > 1 Or Target.Value = "" Then Exit Sub

du code de "worksheet_change" (pour chaque changement de cette feuille)

Peut-on interdire l'utilisation des autres colonnes?

Pour la gestion des erreurs, j'ai consulté l'aide mais je n'ai pas tout compris.
"On Error Resume Next": si erreur passer à l'instruction suivante;
"If Err <> 0 Then" : si aucune une erreur d’exécution ne se produit, alors ajout d'une nouvelle feuille dont le nom reprend la valeur de saisie, dans cas contraire affichage du message (MsgBox);
"On Error GoTo 0" : annule en quelque sorte les erreurs précédentes.

Merci.
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
225
Nous verrons ces détails à la fin (facile).
Concentrons-nous pour l'instant sur les mécanismes.

Passons maintenant à la seconde étape ===>>

[u]ETAPE 2
/u
Cette étape à pour finalité d'imposer la saisie, en colonne B de la feuille "BD", de seules entreprises déclarée en colonne A de la feuille "entreprises"

Tu retournes dans le projet neuf précédent (oçù tu as créé la feuille "entreprises" avec le code que nous avons vu.
- Tu y ajoutes maintenant une feuille nommée "BD".
- sur cette feuille BD, tu insères (n'importe où), une combobox (prise dans la boite des contrôles activex) Combobox1. Tu donnes la valeur false à la propriété Visible de cette combo.
- dans le module de cette feuille BD tu colles ce code :
Private encours As Range, quoi

Private Sub ComboBox1_Click()
  If ComboBox1.ListIndex >= 0 Then
    encours.Value = ComboBox1.List(ComboBox1.ListIndex)
  End If
  ComboBox1.Visible = False
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  If Target.Column = 2 Then
    If ComboBox1.ListIndex < 0 And Not encours Is Nothing Then
      encours.Value = quoi
    End If
    derlig = Worksheets("entreprises").Range("A" & Rows.Count).End(xlUp).Row
    With ComboBox1
       .ListFillRange = "entreprises!A1:A" & derlig
       .Top = Target.Top
       .Left = Target.Left
       .Height = Target.Height
       .Width = Target.Width
       .ListIndex = -1
       .Visible = True
    End With
    Set encours = Target
  Else
    Set encours = Nothing
  End If
End Sub

Je te laisse "gratter" mon code. S'il est bon : chaque fois que tu tenteras de saisir en colonne B (celle de tes entreprises), tu te trouveras forcé de choisir parmi les articles d'une combobox (ceux, finalement, de la feuille "entreprises")à
A toi de "gratter". Je n'ai personnellement vérifié que l'essentiel (fonctionne). J'attends tes remarques éventuelles et les traiterai après que se seront dissipés les effets du vin qui a accompagné mon repas.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
J'ai suivi tes instructions mais ça ne fonctionne pas.
je récapitule ce que je viens de faire:
1- je nomme une nouvelle feuille "BD"
2- sur cette feuille je mets une combobox (activeX) (pas une combobox Formulaire)
3- Propriété "visible" de cette combo à "False"
4- clic-droit sur l'onglet de la feuille "BD", je visualise le code et là j'insère ton code

J'ai remarqué qu'il manque peut-être un "End sub"

Private Sub ComboBox1_Click() a son End sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range) a aussi son end sub

mais pas la ligne suivante qui est tout au début:
Private encours As Range, quoi

à moins que: je dois copier le code: Private Sub ComboBox1_Click() dans la comboBox. malgré cela, je pense qu'il manque 1 "end sub".

ah! je pense que tu as forcé un peu sur le bouchon ce midi.

j'essaie de m'y retrouver. à tantôt
de retour,

je viens de faire un clic-droit sur la combobox pour visualiser le code et je constate que c'est la même feuille de code qui s'ouvre que celle de la feuille "BD". voilà, je viens d'apprendre encore quelque chose.

Désolé, je viens de m'apercevoir que la première ligne de code
"Private encours As Range, quoi", il n'y a ni sub, ni () donc pas de end sub s'il n'y a pas de sub au début. Alors à quoi ça sert?

Toutes mes excuses, un bleu est un bleu. Ton code fonctionne bien, il fallait que je clique sur la cellule B1 pour que l'activeX se mette en place. C'est à peu près ce que j'avais fait mais en passant par validation de données (Liste) et j'avais mis une formule avec "Décaler" pour avoir une liste dynamique. Je n'ai jamais utilisé de contrôle ActiveX. je te remercie, j'apprends des choses avec toi.

Je voudrai que la BD commence à partir de la Ligne 8, car les lignes au-dessus sont réservés aux entêtes. Et la même chose pour les feuilles des entreprises (début transfert en ligne 8). Merci.