Microsoft 365 VBA - Objet dictionnary limité à 256 items

S[1]t'Yor

XLDnaute Junior
Bonjour tout le monde.

Je dois débugger le programme ci dessous. Il créer un objet dictionnary (appelé Dico) et regarde une grande plage (852 élément minimum) et vérifie s'il y a des #REF dans cette plage. Le problème est que Dico s'arrete à 256 items et pas un de plus. Or j'ai créer des erreurs forcés après la 256eme valeur, elle ne sont pas référencé dans Dico.

A l'aide SVP

Cordialement

S

VB:
Sub CorrigeErrRef()
'replace les références des repères en cas de suppression de lignes
'ne pas lancer cette commande sans avoir recaculé les cellules avant, sinon ça ne sert à rien...
'le mode de calcul doit donc être en automatique, pas manuel

'enlève la protection pour pouvoir travailler
Call Enleve_Protec

'met en dictionnaire la colonne de Repere pour déterminer les lignes en erreur

'mise en cache colonne de Repère
ligne_debut = 1
colonne = Range("Repere").Column
ligne_fin = Range("Der_ligne_Ferr").Row

Dim fer As Worksheet
Set fer = Worksheets("Nomenclature")

'sélectionne la feuille ferrure-170 pour éviter un bug lors de l'ouverture du fichier si une autre feuille est sélectionnée
fer.Select
Dim plage As Range
Set plage = Application.Worksheets("Nomenclature").Range(Cells(ligne_debut, colonne), Cells(ligne_fin, colonne))

'mise en dico de la plage colonne Repere
Set Dico = CreateObject("scripting.dictionary")
cle = ligne_debut
For Each Value In plage
    Dico.Add cle, Value
    cle = cle + 1
Next

'On Error Resume Next
'cherche toutes les lignes #Ref dans le dico
For Each k In Dico.keys
    'si une ligne est une ligne commençant par #
    If IsError(Dico.item(k)) Then
      
        'pour chaque colonne d'items ou de récap items met la formule de la cellule à jour
        fer.Cells(k, colonne).FormulaR1C1 = "=R[-1]C"

    End If
Next



End Sub
 

S[1]t'Yor

XLDnaute Junior
Bjr Bruno, le Fil, le Forum :)
@ S[1]t'Yor : Et pkoi tu ne peux pas ?
Un fichier anonymisé reflétant ton souci est toujours possible à faire !
:)
Mes compétences en vba et le fichier est tellement foireux que si je touche au moindre truc, plus rien ne marche. Actuellement je travaille sur ce fichier qui est sacrement instable. L'anonymiser n'est pas possible car je vais bousculer cet équilibre
 

patricktoulon

XLDnaute Barbatruc
Bonjour @patricktoulon :),

Je ne vois pas en quoi, VBA ferait une erreur. D'ailleurs VBA n'en fait pas. Que le code fasse des choses logiques, c'est une autre question...

La question est pourquoi le dictionary s'arrête-t-il à 256 éléments ? Là aussi, je pense que c'est une illusion de la fenêtre espion quand on lui demande d'afficher le "dico".

La principale question est de savoir ce qu'on met dans le dico en tant qu'item.
Et dans ce cas, on n'y met pas une valeur mais un range qui correspond successivement à chaque "cellule "de la plage (et non à la valeur contenue dans la cellule).

VB:
For Each  x In plage
   Dico.Add cle, x
on insère dans le dico un objet range (identique à In plage.cells)

VB:
For Each  x In plage.value
   Dico.Add cle, x
on insère dans le dico une valeur

Mais dans le cas qui nous préoccupe, l'emploi d'un dictionary me semble totalement superfétatoire.

L'utilisation de noms de variables (déclarées ou non) comme étant des mots-clefs de VBA ou d'Excel (et des propriétés de sa hiérarchie d'objets) risque d'avoir des effets de bords bizarres et non détectables facilement.

Je ne vois pas pourquoi le Option Explicit est critiqué. C'est la base de la programmation (s'interroger sur les variables qu'on utilise) et ça évite tellement de faute de frappe involontaire.
bonjour @mapomme
Allons!
VB:
Sub test()
Set plage = [a1:b10]
For Each valoche In plage
MsgBox TypeName(valoche)
Next
End Sub

entre nous ,je ne suis pas sur que ce soit des objects range que notre ami veux mettre dans ses items

je le redis encore une fois
c'est dans ce genre de situation ou la notion explicite est de rigueur
et je parle là de déclaration de variable et surtout du bon type

[jeu de Mots de circonstence]
une pomme c'est une pomme
un panier de pomme c'est un pagnier de pomme
[/jeu de Mots de circonstence]

alors oui c'est vrai que nous avons tendance a bénéficier de la largesse de vba a interpréter et par fainéantise a abréger nos codes
par exemple on dira
msgbx range("A1") 'qui nous donnera la valeur de A1
pourtant on devrait coder
msgbox range("A1").value'ou "..text"

dans une plage il y a des areas , des lignes , des colonnes , des cells , des commentaires , etc... etc....
 

S[1]t'Yor

XLDnaute Junior
bonjour @mapomme
Allons!
VB:
Sub test()
Set plage = [a1:b10]
For Each valoche In plage
MsgBox TypeName(valoche)
Next
End Sub

entre nous ,je ne suis pas sur que ce soit des objects range que notre ami veux mettre dans ses items

je le redis encore une fois
c'est dans ce genre de situation ou la notion explicite est de rigueur
et je parle là de déclaration de variable et surtout du bon type

[jeu de Mots de circonstence]
une pomme c'est une pomme
un panier de pomme c'est un pagnier de pomme
[/jeu de Mots de circonstence]

alors oui c'est vrai que nous avons tendance a bénéficier de la largesse de vba a interpréter et par fainéantise a abréger nos codes
par exemple on dira
msgbx range("A1") 'qui nous donnera la valeur de A1
pourtant on devrait coder
msgbox range("A1").value'ou "..text"

dans une plage il y a des areas , des lignes , des colonnes , des cells , des commentaires , etc... etc....
Merci pour ces précisions.

J'ai récupéré le programme tel quel. C'est un enfer pour rentrer dans la tête du gars qui a programmé ça (surtout qu'il est parti de l'entreprise). C'est notamment pour ca que je sollicite votre aide c'est pour comprendre qu'est ce qu'il a voulu faire.
 

S[1]t'Yor

XLDnaute Junior
Je suis d'accord mais il faut que je colle le plus possible au fonctionnement du programme pour le chambouler le moins possible.

Et aussi je cherche à comprendre certains fonctionnement pour éviter de retomber dans des pièges ou des erreurs qui peuvent paraître basiques

CDT
 

mapomme

XLDnaute Barbatruc
Bonjour @S[1]t'Yor] ;),

Comme je l'ai dit, dico n'est pas limité à 256 éléments. Dans la fenêtre espion, espionnez en plus de dico (tout seul), dico.keys (les clefs du dico) et dico.items (les éléments du dico) et dico.count.

Pour ce que j'en au compris :
Vous avez une plage définie par colonne et entre les lignes ligne_debut et ligne_fin.
Cette plage contient (devinette) des constantes ou/et des formules pouvant être une erreur.
Vous désirez remplacer chaque cellule de la plage contenant une erreur par la valeur de la cellule qui se trouve juste au-dessus.

Je vous mets un exemple de ce que votre code pourrait être sans dico et donc avec l'avantage de fonctionner aussi sur Apple (dictionary est dans une bibliothèque propre à Windows).

nota : dans les options de VBA, cochez dans le menu Outils / Options.., Onglet Général l'option : "Arrêt sur les erreurs non gérées".

Le code devrait facilement être adaptable à votre cas et débarrassez-vous de ce dictionary inutile ;) .

Le code dans module1 :
VB:
Sub CorrigeErr()
Dim ligne_debut As Long, ligne_fin As Long, colonne As Long, plage As Range, xrgErr As Range
   Application.ScreenUpdating = False
   ligne_debut = 11: ligne_fin = 5000: colonne = 1
   With Worksheets("Toto")
      Set xrg = .Range(.Cells(ligne_debut, colonne), .Cells(ligne_fin, colonne))
      On Error Resume Next
      xrg.SpecialCells(xlCellTypeConstants, xlErrors).FormulaR1C1 = "=R[-1]C"
      xrg.SpecialCells(xlCellTypeFormulas, xlErrors).FormulaR1C1 = "=R[-1]C"
      On Error GoTo 0
   End With
End Sub
 

Pièces jointes

  • S(1)t'Yor- Remplacer erreur- v1.xlsm
    129.2 KB · Affichages: 4
Dernière édition:

Usine à gaz

XLDnaute Barbatruc
Mes compétences en vba et le fichier est tellement foireux que si je touche au moindre truc, plus rien ne marche. Actuellement je travaille sur ce fichier qui est sacrement instable. L'anonymiser n'est pas possible car je vais bousculer cet équilibre
Tu pourrais créer un nv fichier test.
- y copier ta grande plage (852 élément minimum) et l'anonymises,
- y copier ton code et ce serait mieux pour te répondre,
:)
 

mapomme

XLDnaute Barbatruc
[jeu de Mots de circonstence]
une pomme c'est une pomme
un panier de pomme c'est un pagnier de pomme
[/jeu de Mots de circonstence]
Salut @patricktoulon :) ,

Et quand ma pomme dit "mapomme" croque une pomme, cela ne sous-entend-il pas qu'il est cannibale 🤪? Tout ça c'est un jeu de pomme (jeu de mot).

Il me vient une question : un vegan a-t-il le droit de manger une plante carnivore ?
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Pour moi c'est non, sinon il aura un risque de manger de la viande
Je me suis toujours posé la question pourquoi le véganisme (moderne):
  • Est-ce pour ne pas manger d'animal ?
  • Est-ce pour ne pas manger du vivant ? (ça c'est compliqué car une plante semble vivante)
  • Pour ne pas manger d'Être avec une conscience (vu une émission d'ARTE sur la conscience notamment des mouches - pour l'instant la conclusion selon moi, il n'y a pas vraiment de définition univoque de la conscience et les tentatives de définitions sont des extensions du rapport avec notre propre conscience humaine)
  • Pour éviter la sur-consommation d'animaux qui consomment énormément de végétaux, d'eau et qui pètent du méthane à n'en plus savoir que faire ?
  • Parce que c'est mauvais pour notre santé ?
  • Pourquoi les vegans appellent-ils une galette de légumes un steack ? Ira-t-on bientôt chez le boucher demander une galette de viande ?
 

patricktoulon

XLDnaute Barbatruc
re
la on a perdu @mapomme je crois
être ou ne pas être tel est la question

qu'est ce que l'on se fent la poire ici !!! heu pardon ok je sort
diabolo.gif
 

TooFatBoy

XLDnaute Barbatruc
- J'enleve la protection de la feuille avec une fonction propre au fichier
- Je me place sur la bonne feuille pour éviter toute erreur
- je stocke les valeurs de la colonne "Repere" dans un Dico
- Je parcoure chaque varaible de ce dico
- Si je rencontre un #REF dans Dico ou une erreur quelconque je copie colle une formule du dessus dans ma cellue erroné
Apparemment tu copies la formule de la cellule du dessus et tu la colles dans la cellule qui donne une erreur.

Du coup, ne peux-tu tout simplement copier la formule de la première cellule de la colonne et la coller dans toute la colonne ?
 

Statistiques des forums

Discussions
315 127
Messages
2 116 534
Membres
112 770
dernier inscrit
vetosalah