* erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés *

David69400

XLDnaute Junior
Bonjour le Forum,

Je reviens vers vous sur un fichier que je pensais avoir terminé, mais bien sûr patatras, y'a un petit bug imprévu.

En gros, le fichier tourne bien (il s'agit d'une saisie de quantités à fabriquer suite à calcul d'un petit PDP); j'avais déjà mis un poste pour une étape intermédiaire qui m'avait aidé à avancer...)


Sauf que lorsque d'un rajout d'un nouvel article, le fichier ne marche plus (erreur 91 mentionnés en objet);... si je ferme en enregistrant et que j'ouvre à nouveau, cela remarche...


En regardant l'aide , j'ai essayé de voir si j'avais des variables non définies ou:confused: des problèmes avec des bloc 'with' comme cela est précisés , mais je n'ai rien trouvé.

Bref, je sèche, et je vous joins le fichier explicatif, en vous remerciant par avance pour votre aide et le temps que vous y passerez...

Merci

David
 

Pièces jointes

  • David 180814 v1.xlsm
    287 KB · Affichages: 54

youky(BJ)

XLDnaute Barbatruc
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonjour David,
Tu fais appel à la feuil o2 alors que je pense qu'elle s'appelle F02
Note le zéro et non le o et sans oublier le F
Attention tu en a plusieurs à modifier dans ta macro.
Cela fonctionne avec mes essais.
Bruno de Caluire
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonsoir David, bonsoir le forum,

Je sais que tu adores ta manière mais je t'avoue qu'elle commence vraiment à me pomper l'air ! Il me faut tout réécrire pour essayer de trouver la faille et c'est très pénible. Aussi je viens de décider que c'est la dernière fois que je me casse la tête sur du code écrit en dépit du bon sens...
Tu as déclarer la variable Li comme Private et tu la définis par :

Code:
Li = Me.ComboBox4.ListIndex + 4 'définit la ligne LI sur la base du choix de l'article
Pourquoi vouloir par la suite la redéfinir avec la méthode Find ? Il te suffit d'écrire :
Code:
If TextBox5.Value = "Fab non prévue" Or TextBox5.Value = "" Then
    O2.Cells(Li, 25).Value = 0
Else
    O2.Cells(Li, 25).Value = Me.TextBox5.Value
End If
 

Regueiro

XLDnaute Impliqué
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonsoir le Forum, le Fil
Le problème vient de ton tableau.
Sur la Feuille "STOCK" ton Tableau "TAB_STOCK"
Sur les 3 premières colonnes regarde le format de Cellule que tu as.

Capture001.JPG

Si tu fait un recherche depuis excel normalement, il ne trouve rien.

PHP:
   Dim Trouve
    Dim PlageDeRecherche As Range
    Dim Valeur_Cherchee As String, AdresseTrouvee As String


     'on cherche l'article sélectionné
     'Pas besoin de Valeur_Cherchee
        Valeur_Cherchee = Range("ARTICLE")
        'Pas besoin de spécifier la Feuille
        Set PlageDeRecherche = Range("TAB_STOCK[LIBELLE]")
        MsgBox PlageDeRecherche.Address
        
        
        Set Trouve = PlageDeRecherche.Find(Me.TextBox3, LookAt:=xlWhole)
        Li = Trouve.Row
        MsgBox "Ligne : " & Li
A1
 

David69400

XLDnaute Junior
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonjour le Forum,

Bonjour Bruno de Caluire, Robert de Sète et Regueiro de Bulle !

Déjà merci à tous les 3 pour avoir regardé ma requête:

Dans le désordre, c'est bien la réponse de Robert qui résout le souci.

Pourquoi vouloir par la suite la redéfinir avec la méthode Find ?:

Pour une raison dont je ne me souviens plus (y'en a pas, vraisemblablement...), j'ai redéfini en cours de route la variable Li avec la méthode FIND. Ce qui outre le fait de ne servir à rien, à créé l'erreur lors du rajout d'un nouvel article.
j'ai donc supprimé le code lié, et ca marche donc très bien, donc merci Robert d'avoir décelé l'erreur.

Parenthèse fond/forme sur remarques de Robert:

sur la forme
Je sais que tu adores ta manière
=> un peu de narcissisme maniéré ? j'ai surtout essayé jusque-là de reprendre, maladroitement, des structures de codes qui me semblait fonctionner (notamment avec les indices de colonnes extériorisé à la textbox/combobox) ce qui allourdissait la lecture et irritait Robet
... Donc, j'ai réécris le code en simplifiant au maximum ( cf UF Validation Fab)

sur le fond :
code écrit en dépit du bon sens...
=> hormis l'erreur mentionnée, aussi incompréhensible soit elle, le reste fonctionne plutôt bien... il me semble que tout n'est pas mauvais, et qu'il y a un peu de sens derrière tout cela, en tout cas j'essaye d'en mettre, et qu'en j'en manque ou je m’égare, je sollicite ceux qui en ont bcp

Donc merci Robert, pour cette nouvelle aide; j'espère que tu pourras continuer à m'aider à l'avenir.:rolleyes:


Pour Bruno (youky(BJ),
la numérotation des onglets n'a pas d'incidence, à priori, sur la dénomination des variables (la preuve en est que le fichier tourne avec la correction apportée).
j'avais simplement renommé F01 à F04 pour avoir les feuilles d'en l’ordre souhaité. Mais c'est bien le nom entre parenthèse ie "PDP" qui sert dans la déclaration de la variable onglet
Set O1 = Worksheets("PDP")
Merci encore de ta contribution.:)

Pour Regueiro,
le format des cases du tableau , j'ai vu que le format est bizarre.
Dans la mesure ou j'ai supprimé cette méthode FIND (cf plus haut), le code fonctionne maintenant bien.
Merci d'avoir aussi pris le temps de trouver une solution.:)


Voilà, je vous remets le fichier corrigé final pour l'historique.

Merci à tous les 3 et à plus tard !

David
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonjour le fil, bonjour le forum,

Bon, je me suis calmé... Mais quand je parle de dépit du bon sens, outre le fait que je trouve complètement c.. d'écrire :

Code:
I = 4
Me.Controls("TextBox" & I).Value = cequetuveux
a la place de :
Code:
ComboBox4.Value = cequetuveux

Voici quelques exemples :
• déclaration des variables en haut de module

Code:
Private O1, O2 As Worksheet
Private Col, Cellule As Range
Tu peux déclarer plusieurs variables dans la même ligne mais tu dois impérativement en spécifier le type pour chacune d'entre elles, sinon elle prendra le type par défaut : Variant.
Code:
Private O1 as Worksheet, O2 As Worksheet
Private Col As range, Cellule As Range

• Initialisation de l'UserForm
tu alimentes la ComboBox4 par (je reprends un code normal):
Code:
Me.ComboBox4.List = Col.Value
puis tu répètes ce même code dans la procédure Change de la ComboBox4. Doublon inutile...

tu place le curseur dans la Combobox4 avec :
Code:
Me.ComboBox4.SetFocus
Inutile puisque tu as pris soin de la placer en premier dans l'ordre de tabulation de l'UserForm...

et pour finir quand même par une touche optimiste tu as écris dans la procédure Click du CommandButton1 :
Code:
If TextBox5.Value = "Fab non prévue" Or TextBox5.Value = "" Then
Quoi? aurais-tu été touché par la grâce divine ?

Ton code devrait ressembler à ça :

Code:
Option Explicit
Private O1 As Object, O2 As Object 'déclare les variables onglets
Private Li As Long 'déclare la variable LI (LIgne)
Private Col As Range, Cellule As Range 'déclare la variable de plages
Private I As Byte 'déclare la variable I
Private CTRL As Control 'déclare la variable CTRL (ConTRôLe)


Private Sub UserForm_Initialize()
Set O1 = Worksheets("PDP") 'définit l'onglet
Set O2 = Worksheets("STOCK") 'définit l'onglet
Set Col = O2.Range("TAB_STOCK[SELECTION_ITEM]") ' définit COL comme la colonne de selection
Me.ComboBox4.List = Col.Value 'alimente la ComboBox4
End Sub


Private Sub ComboBox4_Change()
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
If Len(Me.ComboBox4) = 0 Then
    For Each CTRL In Me.Controls
        If TypeOf CTRL Is MSForms.TextBox Or TypeOf CTRL Is MSForms.ComboBox Then CTRL.Value = ""
    Next CTRL
    Exit Sub
End If
Li = Me.ComboBox4.ListIndex + 4
Me.TextBox1.Value = O2.Cells(Li, 1).Value
Me.TextBox3.Value = O2.Cells(Li, 3).Value
O1.Range("CATEGORIE").Value = Me.TextBox1.Value
O1.Range("ARTICLE").Value = Me.TextBox3.Value
Me.TextBox4.Value = O1.Range("FAB_PROP")
If O1.Range("FAB_VAL") = "à Valider" Then
    Me.TextBox5.Value = O1.Range("FAB_PROP")
Else
    Me.TextBox5.Value = O1.Range("FAB_VAL")
End If
Me.TextBox5.SetFocus
End Sub


Private Sub CommandButton1_click() 'quand on clique sur le bouton #VALIDER
O2.Unprotect ("mdp")
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
If Len(Me.ComboBox4) = 0 Then
    For Each CTRL In Me.Controls
        If TypeOf CTRL Is MSForms.TextBox Or TypeOf CTRL Is MSForms.ComboBox Then CTRL.Value = ""
    Next CTRL
    Exit Sub
End If
If TextBox5.Value = "Fab non prévue" Or TextBox5.Value = "" Then
    O2.Cells(Li, 25).Value = 0
Else
    O2.Cells(Li, 25).Value = Me.TextBox5.Value
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Me.ComboBox4.Value = O2.Cells(Li + 1, 4).Value
O2.Protect ("mdp")
End Sub


Private Sub CommandButton3_Click() ' quand on clique sur le bouton "Quitter"
Unload Me
Range("B13") = ""
Range("B23") = ""
Range("A1").Select
End Sub
 

David69400

XLDnaute Junior
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Re Le Forum, Re Robert,

ALors...

1.
Quoi? aurais-tu été touché par la grâce divine
en faiT, je l'avais été dans mon post précédént, dans la V2 quand j'ai dit que j'avais simplifié le code pour l'UF Validation FAB.


2. MERCI pour :

Tu peux déclarer plusieurs variables dans la même ligne mais tu dois impérativement en spécifier le type pour chacune d'entre elles, sinon elle prendra le type par défaut : Variant.
=> je n'ai pas d'excuses, mais je ne savais pas et je pensais que cela fonctionnait en ligne...bref, bien noté!
=> Ensuite, merci pour les doublons et autre inutilités corrigés.


Question pour terminer toujours, dans l'esprit code "divinisé" pour enlever les "fioritures":
( car souvent, différentes façon d’écrire fonctionnent, alors...)

Utilisation du "Me", du ".Value" et de la variable Onglet pour un Range nommé: :

ComboBox4.List = Col.Value Vs Me.ComboBox4.List = Col.Value

If Len(ComboBox4) = 0 vs If Len(Me.ComboBox4) = 0 Vs

Textbox1= O2.Cells(Li, 1) Vs Me.TextBox1.Value = O2.Cells(Li, 1).Value

TextBox4 = Range("FAB_PROP") vs Me.TextBox4.Value = O1.Range("FAB_PROP")

Donc, est il plutôt recommandé de mettre le ME ou pas, le .Value ou pas, et doit on préciser l'onglet pour une variable de type plage nommés ?

Merci beaucoup Robert,

David
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonjour le fil, bonjour le forum,

Le Me n'est absolument pas indispensable. Je l'utilises uniquement par flemme car en tapant Me.Co... apparaît une liste me proposant tous les contrôles commençant par Co... je choisis l'élément de la liste et, d'un appui sur la trouche [TAB], Me.Combobox4 s'écrit tout seul... Il évite donc aussi les fautes de frappe du style CoboBox4...

Sinon, je pense que tout le monde ici sait déjà que la propriété [Value] est la propriété par défaut de certains contrôle comme les textboxes ou comboboxes. Elle n'est donc pas nécessaire. Je fais l'effort de l'écrire uniquement pour une meilleure compréhension du code par un(e) débutant(s)...

Pareil pour l'onglet. Pour éviter de mauvaise surprises je préfère le stipuler. Sauf dans les macros événementielle de l'onglet lui-même (Change, Calculate, etc.), où il fait forcément référence à lui même. Si dans une procédure tu restes toujours dans un onglet il suffit de le sélectionner l'onglet. Mais si tu navigues (pour des copier/coller par exemple) entre plusieurs onglets, tu auras l'avantage d'éviter les erreurs et de na pas être obliger de sélectionner (toujours éviter les Select inutiles). Aussi par flemme d'écrire Sheets("Feuil1").Range("A10"), je préfère déclarer un variable O Private, la définir à l'initialisation d'une UserForm Set O = Sheets("Feuil1") et pouvoir l'utiliser dans toutes les procédures de l'UserForm en évrivant juste O.Range("A1")...

 
Dernière édition:

David69400

XLDnaute Junior
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Merci Robert pour ces compléments très pratiques.

Vois-tu, une des raisons pourquoi j’"externalisais" (maladroitement etc etc) le i du Me.control(textbox&i) , c'était entre autre pour éviter les erreur de frappe que tu as mentionnés, et n'avoir qu'à changer l'indice...

Donc avec l'astuce Me.com+tab... c'est bien pratique !!
C'est aussi claire pour le.Value et la notion de l'onglet.

Je clos la boucle de de post et encore MERCI !!!

Bonne soirée,

David
 

Regueiro

XLDnaute Impliqué
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonsoir Le Fil, David69400, Robert
Robert
Je pense que c'est une erreur de ta part non ?
Bon, je me suis calmé... Mais quand je parle de dépit du bon sens, outre le fait que je trouve complètement c.. d'écrire :

I = 4
Me.Controls("TextBox" & I).Value = cequetuveux
a la place de :

a la place de :
Code :
ComboBox4.Value = cequetuveux

Je pense que tu voulais dire :
Code:
me.Textbox4.value : cequetuveux
David69400
Je transmets ce soir une variante avec :
Les tables font partie de la collection Listobjects qui a été mise en place avec la ...
Ce lien n'existe plus

Très pratique.
A+
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonsoir le fil, bonsoir le forum,

Oui bien pensé Regueiro ! Merci pour la correction...
Est-ce que Regueiro pourrait signifier, comme Salseiro est un danseur de Salsa, que tu es un danseur de Reggae ?
 

Regueiro

XLDnaute Impliqué
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonsoir Le Fil, le Forum,
Robert voilà j'ai fini de danser ?

David69400
Voilà une possibilité de Code :
Dans un module standard pour la déclaration des variables :
PHP:
Option Explicit
Public WS1 As Worksheet
Public WS2 As Worksheet
Public LST As ListObject   'Variable ListObject
Public LST_RG As Range
Public Cible
Public Col As Long
Public Ligne As Long
Public VarArt As Variant
'déclare la variable CTRL (ConTRôLe)
Public CTRL As Control

Dans ton USF
avec la collection Listobjects
PHP:
Option Explicit
'Les Variables sont Public dans le module (Mod_DéclarationVariables)
Private Sub UserForm_Initialize()
'INITIALISATION de l'UserForm précisé dans l'onglet ci-après
Set WS1 = Sheets("STOCK")
Set WS2 = Sheets("PDP")
Set LST = WS1.ListObjects("TAB_STOCK")
Set LST_RG = LST.DataBodyRange.Columns(3).Cells
        With Me.ComboBox4
        'Correspond Range("TAB_STOCK[SELECTION_ITEM]")
        .List = LST.DataBodyRange.Columns(4).Cells.Value
        .SetFocus
        End With
 End Sub
Private Sub ComboBox4_Change()
' #CHOIX d'un article
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
    If Len(Me.ComboBox4) = 0 Then
            For Each CTRL In Me.Controls
            If TypeOf CTRL Is MSForms.TextBox Or TypeOf CTRL Is MSForms.ComboBox Then CTRL.Value = ""
            Next CTRL
            Exit Sub
        End If
        Ligne = Me.ComboBox4.ListIndex + 1
        Me.TextBox1.Value = LST.DataBodyRange.Columns(1).Cells(Ligne).Value
        Me.TextBox3.Value = LST.DataBodyRange.Columns(2).Cells(Ligne).Value
        WS2.Range("CATEGORIE").Value = Me.TextBox1.Value
        WS2.Range("ARTICLE").Value = Me.TextBox3.Value
        Me.TextBox4.Value = WS2.[C3]
        'si l'article n'a pas été encore validé, on renseigne la proposition de fab par défaut
        'sinon, on met la quantité validée
        If WS2.[D3] = "à Valider" Then
            Me.TextBox5.Value = WS2.[C3]
        Else
            Me.TextBox5.Value = WS2.[D3]
        End If
Me.TextBox5.SetFocus
End Sub
Private Sub CommandButton1_click()
'quand on clique sur le bouton #VALIDER
'Recherche du mot sur la colonne N°3 du Tableau

MsgBox "Nom du Tableau : " & LST.Name
    ' enlever le mote de passe
  WS1.Unprotect ("mdp")

    If Len(Me.ComboBox4) = 0 Then
      For Each CTRL In Me.Controls
      If TypeOf CTRL Is MSForms.TextBox Or TypeOf CTRL Is MSForms.ComboBox Then CTRL.Value = ""
      Next CTRL
      Exit Sub
  End If
    
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With
 

  If TextBox5.Value = "Fab non prévue" Or TextBox5.Value = "" Then
      LST.DataBodyRange.Cells(Ligne, 25).Value = 0
  Else
      With LST.DataBodyRange.Cells(Ligne, 25)
      .Value = Me.TextBox5.Value
  End With
  
  End If

      Me.ComboBox4.Value = LST.DataBodyRange(Ligne + 1, 4).Value
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
  End With
End Sub
Private Sub CommandButton3_Click()
' quand on clique sur le bouton "Quitter"

   'enlève le focus au bouton
        ActiveCell.Select
   
   'vide et ferme l'UserForm
        Unload Me
        Range("B13") = ""
        Range("B23") = ""
        Range("A1").Select
    
End Sub
A+
Bonne Soirée

Un petit plus à tester à mettre dans un module standard :
Code:
Sub RechercheMotFixe2()
'Recherche du mot sur la colonne N°3 du Tableau
'Sans Selectionner, la Feuille ou la cellule
'Déclarations des variables
Dim WS As Worksheet
Dim LST As ListObject   'Variable ListObject
Dim LST_RG As Range
Dim Cible
Dim Col As Long
Dim Ligne As Long

Set WS = Sheets("STOCK")
Set LST = WS.ListObjects("TAB_STOCK")
Set LST_RG = LST.DataBodyRange.Columns(3)
Application.ScreenUpdating = False
With LST_RG
Set Cible = .Find(What:="Article B1", LookAt:=xlWhole)
End With
With LST
    'Identifier le N° de ligne Listrow
    'Ligne = .ListRows(Cible.Row - .HeaderRowRange.Row).Index  'Ok Fonctionne
    Ligne = .ListRows(Cible.Row - .Range.Row).Index
    'Identifier le N° de Colonne Listrow
    Col = .ListColumns(Cible.Column - .Range.Column + 1).Index
End With
MsgBox "R E S U L T A T" & Chr(10) & Chr(10) & _
"Ligne N° : " & Cible.Row & " de la Feuille : " & WS.Name & Chr(10) & _
"Colonne N° : " & Cible.Column & " de la Feuille : " & WS.Name & Chr(10) & _
Chr(10) & _
"Ligne N° : " & Ligne & " du Tableau : " & LST.Name & Chr(10) & _
"Colonne N° : " & Col & " du Tableau : " & LST.Name & Chr(10)
Application.ScreenUpdating = True
End Sub
 

David69400

XLDnaute Junior
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonjour le Forum,
Bonjour Regueiro,

Un grand merci à toi pour le regard alternatif que tu apportes avec ta proposition de code.:)

Du coup, j'ai bien étudié ce que tu proposes alternativement à ce que m'a corrigé Robert.

Déjà, je trouve pratique la déclaration publique des Variables.

Pour aller au bout des choses, j'ai donc créé un second UF avec ''ton code", et j'ai fait une comparaison entre les deux ( cf onglet COMPARAISON en jaune dans le fchier V4).

En fait, j'ai peut-être commis une erreur qqpart, mais l'UF version Regueiro, se lance bien, on peut bien choisir l'article, mais après les valeurs Qtés proposées et Validées ne sont par rapatriées dans leurs textbox respectives , ni en C3 et C3 ... :confused:

Tu trouveras une copie écran des 2 UF lancé avec la différence dans l'onglet COMPARAISON.

Ensuite, du coup, j'ai bien vu les différence de code pour la suite, mais n'ai pu le tester...

Voilà, si tu peux regarder ou cela bloque, je comprends pas car c'est relativement proche du code Robert...

Merci !

David 69400
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : * erreur '91' alors que mes 'variables' sont définies et mes bloc 'with' fermés

Bonjour le fil, bonjour le forum,

Il faut quand même se méfier des variables déclarées publiques. Je préfère les déclarer Private, en haut du module de l'UserForm et les définir à l'initialisation de celle-ci. À la fermeture, mes variables sont réinitialisée...
En effet lorsqu'une Userform est fermée (Unload), toutes les variables Private, en haut du module de l'Userform, ou Dim, à l'intérieur des procédures de l'UserForm se vident. Si elles sont déclarées Public elles gardent leur valeur et peuvent perturber le code d'une procédure d'un module standard ou d'on objet Sheet... Il faut penser à les vider !

Mais chacun sa méthode, l'essentiel et de bien déclarer toutes les variables avec le type adéquat et de les déclarer en fonction de la portée (durée de vie) qu'on veut qu'elles aient. Aussi je recommande l'Option Explicit qui oblige à déclarer toutes les variables (sinon bug !) et selon la portée de les déclarer Dim (variable locale niveau procédure), Private (variable niveau module) et Public (variable niveau projet entier)...
 

Discussions similaires

Réponses
7
Affichages
1 K

Statistiques des forums

Discussions
312 239
Messages
2 086 508
Membres
103 238
dernier inscrit
ds776001