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
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
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.
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....
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....
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.
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
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,
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,
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 ?
- 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é