Sauvegarder un dictionnaire sur disque

Résolu
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015 - 17 févr. 2015 à 23:32
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015 - 19 févr. 2015 à 21:51
Bonjour,
Voilà,
j'ai créer un dictionnaire.
je désire le sauvegarder sur disque

étant donné sa taille variable (en fonction des éléments mis dedans), je pensais ouvrir un fichier en mode binary et utiliser Put
cependant cela ne fonctionne pas

Sub un()

Const NomFichier1 = "Toto"
Dim mondico2
Dim LesDonnéesDico(5)
Dim intFic1
Dim NbBoucle

Dim LaCol__AP() As String
Dim UnEntier() As Integer
Dim UneDate() As Date

Dim LaCol__ARàCol__AZ() As Single
Dim LaCol__BBàCol__CS() As Integer

ReDim LaCol__ARàCol__AZ(9)
ReDim LaCol__BBàCol__CS(44)

NbBoucle = 10 ' en fait varie, est défini ailleurs
ReDim LaCol__AP(NbBoucle)
ReDim UnEntier(NbBoucle)
ReDim UneDate(NbBoucle)

'ici je rempli les données...pour chaque variable et chaque ligne de 1 à NbBoucle

Set mondico2 = CreateObject("Scripting.Dictionary")
'dans ce dico je mets:
  
For RienL = 1 To NbBoucle
      
       LesDonnéesDico(1) = LaCol__AP(RienL) '="azerty" ou autre chaine
       LesDonnéesDico(2) = UnEntier(RienL)
       LesDonnéesDico(3) = LaCol__ARàCol__AZ
       LesDonnéesDico(4) = LaCol__BBàCol__CS
       LesDonnéesDico(5) = UneDate(RienL) ' #17/02/2015# par exemple
    
    mondico2.Item(LaCol__AP(RienL)) = LesDonnéesDico
    'je crée ainsi mon dico qui aura une taille dépendant de NbBoucle
    'et aussi de la taille des string "LaCol__AP(RienL)"
 Next RienL
 intFic1 = FreeFile
 Open NomFichier1 For Binary As #1
                                 
 Put intFic1, , mondico2
End Sub
 


entraîne sur la ligne Put l'erreur:
"incompatibilité de type"
erreur d'exécution 13

comment sauvegarder mon dictionnaire?
merci de votre aide
cordialement
Claude

15 réponses

jordane45 Messages postés 38138 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 avril 2024 344
18 févr. 2015 à 01:04
Bonjour,

Je n'ai jamais essayé et ne sais pas si ça marche en VBA...
mais peut être avec un
mondico2.save "c:\mondico.dic", False 

http://www.motobit.com/help/asp-dictionary-object/cm692.htm


0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
Modifié par ClaudeDordogne le 18/02/2015 à 10:29
Bonjour,
Merci de ta réponse
cependant cela ne fonctionne pas non plus
j'ai repris l'exemple de save dans :
http://www.motobit.com/help/asp-dictionary-object/cm692.htm
qui décrit plus simplement la question
juste changé F: en C:
je ne sais pas quel VB c'est
en VBA excel:
Set o = CreateObject("multi.Dictionary") entraine l'erreur 429
soit :Un composant ActiveX ne peut pas créer d'objet"
j'ai donc remplacer par le classique:
Set o = CreateObject("Scripting.Dictionary")
ce qui permet d'aller jusqu'à:
o.Save "C:\aa.dic", False
qui entraine l'erreur 438 soit
Propriété ou méthode non gérée par cet objet

merci encore de m'aider
amicalement
Claude


Sub deux()
'Set o = CreateObject("multi.Dictionary")
  Set o = CreateObject("Scripting.Dictionary")


'Add some data to the dictionary
o.Add "vbNullString", vbNullString
o.Add "dbl", CDbl(10)
o.Add "sng", CSng(15)
o.Add "array", Array(1)
o.Add "currency", CCur(11)
o.Add "byte", CByte(12)
o.Add "int", CInt(13)
o.Add "lng", CLng(14)
o.Add "string", "Some text"
o.Add "bool", True

o.Add "empty", Empty
o.Add "null", Null


'Save the dictionary to a file
o.Save "C:\aa.dic", False

'remove all data from the dictionary
o.RemoveAll

'Load the data to the dictionary.from the file
o.Load "C:\aa.dic"
End Sub
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 18/02/2015 à 19:58
Bonjour,
Un objet dictionnary est composé de couples (deux membres) et ne saurait, sous VB6 ou VBA, être ainsi sauvegardé.
Une possibilité : l'utilisation d'une structure (un type personnalisé) composée des deux membres nécessaires (la clé et l'item) de l'article dans le dictionnaire.
Cela peut se faire en ouvrant le fichier en Random.
Exemple d'utilisation (ici : deux membres : nom et prénom)

Private Type titi
nom As String * 15
prenom As String * 30
End Type


Private Sub CommandButton1_Click()
Dim enregistrement As titi, unnumero
Open "c:\essai.txt" For Random As #1 Len = Len(enregistrement)
For unnumero = 1 To 5
enregistrement.nom = "un nom" & unnumero As Long
enregistrement.prenom = "un prenom" & unnumero
Put #1, unnumero, enregistrement
Next unnumero
Close #1
End Sub

Private Sub CommandButton2_Click()
Dim enregistrement As titi, maposition As Long
Open "c:\essai.txt" For Random As #1 Len = Len(enregistrement)
For maposition = 1 To 5
Get #1, maposition, enregistrement
MsgBox "enregistrement n° " & maposition & vbCrLf & _
"nom = " & enregistrement.nom & vbCrLf & "prénom = " & enregistrement.prenom
Next maposition
Close #1
End Sub


CommandButton1 pour écrire et commandbutton2 pour lire

Une autre possibilité serait celle d'écrire, puis de lire un fichier XML.
Mais je doute que ce soit vraiment plus rapide

________________________
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'interviend
0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
18 févr. 2015 à 21:45
Bonsoir ucfoutu,

je ne sais quoi te répondre, à part que j'ai eu la chance incroyable de te rencontrer sur ce forum.

ici, encore, tu as su me répondre rapidement, précisément et clairement en me solutionnant un difficile problème (pour moi) et en m'en expliquant les raisons!

je ne sais comment t'en remercier!

juste un petit truc :
enregistrement.nom = "un nom" & unnumero  As Long

as long : est bien sur de trop.
mais je pense que tu l'avais déjà vu :), (c'est juste pour si un autre l'utilise aussi).

je désire également te dire que tes remarques, depuis ma première question, ont été très profitables pour moi et m'ont permis ainsi d'améliorer considérablement ma façon d'aborder la programmation :)

simplement Merci Encore
Claude
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
18 févr. 2015 à 22:33
oui, le As Long était à mettre ici ===>>
Dim enregistrement As titi, unnumero as long
Bonne nuit
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
18 févr. 2015 à 22:08
Là encore je peux écrire, GRACE à toi :

Marquer comme résolu
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
18 févr. 2015 à 23:48
Oui ...
Je m'aperçois de ce que, dans mon exemple écrit à main levée, j'avais mis en dur le nombre à lire en lecture (5). Il est bien évident que tu ne le connais pas forcément d'avance. Il suffit de modifier ainsi ===>>
Private Sub CommandButton2_Click()
Dim enregistrement As titi, maposition As Long
Open "c:\essai.txt" For Random As #1 Len = Len(enregistrement)
For maposition = 1 To FileLen("c:\essai.txt") \ Len(enregistrement)
Get #1, maposition, enregistrement
MsgBox "enregistrement n° " & maposition & vbCrLf & _
"nom = " & enregistrement.nom & vbCrLf & "prénom = " & enregistrement.prenom
Next
Close #1
End Sub


le signe \ est à laisser ainsi (division entière)
Bonne nuit.

0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
19 févr. 2015 à 00:23
encore un petit point:

Private Type titi
nom As String * 15
prenom As String * 30
End Type


String * 15 pour 15 caractères max dans nom?
String représente donc la taille d'un caractere?

cette question car dans l'aide de vba excel ("Put, instruction") il est noté :

Si la variable écrite est de type Variant de VarType 8 (String), l'instruction Put écrit 2 octets qui identifient le type VarType, 2 octets qui indiquent la longueur de la chaîne puis les données de la chaîne. La longueur d'enregistrement indiquée par la clause Len dans l'instruction Open doit être supérieure d'au moins 4 octets à la longueur réelle de la chaîne.
et
L'instruction Put écrit les chaînes de longueur variable qui ne sont pas des éléments de type défini par l'utilisateur, sans rechercher le descripteur de 2 octets. Le nombre d'octets écrits est égal au nombre de caractères de la chaîne. Par exemple, les instructions suivantes écrivent 10 octets dans le fichier numéro 1 :
VarString$ = String$(10," ")
Put #1,,VarString$


le charabia habituel de l'aide excel......

merci de ton précieux avis.

je pense que tu dors déjà :)
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 19/02/2015 à 08:01
Houlà ! ...
De bon matin !
En ce qui concerne le point 1 : ne pas confondre la cause et l'effet.
15 est un nb de caractères. C'est une longueur réservée (la cause). La conséquence est que l'on ne peut dépasser la longueur ainsi réservée.
Je vais te "reprendre" lorsque tu auras fait ce petit test qui devrait m'éviter ensuite de très longs palabres ===>>
Private Sub CommandButton1_Click()
Dim titi As String, toto As String * 9
titi = "couic"
toto = titi
voyons_clair titi, toto, 1
'------------------------------------------------
MsgBox "voyons alors ce que pourrait également être toto"
toto = Format(titi, "@@@@@@@@@")
voyons_clair titi, toto, 2
MsgBox "pas pareil ... essayons autrement"
Dim tata
toto = "012345678"
LSet toto = titi
voyons_clair titi, toto, 3
MsgBox "ah ! l'essai 3 traduit la même chose que le 1"
toto = titi & String(9 - Len(titi), " ")
voyons_clair titi, toto, 4
MsgBox "ah ! l'essai 4 traduit également la même chose que le 1"
toto = String(Len(titi), " ")
Mid(toto, 1, Len(titi)) = titi
voyons_clair titi, toto, 5
MsgBox "ah ! l'essai 5 traduit également la même chose que le 1"
End Sub

Private Sub voyons_clair(ByVal titi, ByVal toto, essai As Byte)
MsgBox "essai " & essai
MsgBox toto = titi
MsgBox "nous avions pourtant dit que toto = titi !"
MsgBox Len(titi) & " " & Len(toto)
MsgBox "-" & titi & "-" & " " & "-" & toto & "-" & vbCrLf & _
"nous voyons là la différence entre toto et titi ==>> voyons la suite"
For i = 1 To Len(toto)
MsgBox Mid(toto, i, 1) & " caractère n° " & i & " ==>> " & Asc(Mid(toto, i, 1)) & vbCrLf & _
"dans toto"
Next
MsgBox "ah ! çà, alors ! et en effet ===>> " & vbCrLf & Replace(toto, " ", "/")
End Sub

Lorsque tu en seras totalement imprégné ===>> reviens ===>> le reste sera facile à exposer et comprendre



________________________
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'interviend
0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
19 févr. 2015 à 10:45
Bonjour,
Tu commences avant que le soleil ne se lève .....

merci de ton exemple :)
d'abord:
toto = Format(titi, "@@@@@@@@@")
je ne vois pas pourquoi "@@@@@@@@@" donne ce résultat (alors que d'autres caractères que @ ne le donne pas...

ensuite
ton test est très clair et montre bien que :

- toto As String * 9 :

String * 9 sert à réserver une longueur correspondant à 9 caractères et y place 9 " ", et que si l'on y place un texte de moins de 9 caractères alors l'espace restant reste des " ", ce qui permet de donner une longueur fixe à la variable texte, et donc de donner une len(toto) connu puisque fixe.

-titi As String
String sert simplement à réserver une place en mémoire, sans en donner la longueur
ceci permet de donner à chaque modification de titi une len(titi) variable (égale à la longueur du texte titi), plus souple mais ayant le gros inconvénient de ne pas pouvoir attribuer par avance une len et donc ne pas pouvoir l'enregistrer dans un
Open "c:\essai.txt" For Random As #1 Len = Len(enregistrement)

car on ne peut connaitre Len(enregistrement) à l'avance.

ai-je bien compris?
merci
Claude
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 19/02/2015 à 12:26
Tu as bien compris.
En ce qui concerne l'utilisation des "@", c'est tout simplement l'un des paramètres possibles pour Format (oblige en caractères). L'analogue, pour l'alphanumérique, au "#" utilisé pour les numériques
Regarde ceci
toto = 121.3 '====>> un numérique
MsgBox "-" & Format(toto, "0000.00") & "-"
MsgBox "-" & Format(toto, "###") & "-"
MsgBox "-" & Format(toto, "#\x#\%#") & "-"

et cela
toto = "121.3" '===>> un string
MsgBox "-" & Format(toto, "@@@@@@@") & "-"
MsgBox "-" & Format(toto, "@@@") & "-"
MsgBox "-" & Format(toto, "@\x\v\o\i\l\à@\%@") & "-"


Je reviens après la sieste pour la suite ...
Ce sera très facile car je vois que tu "captes" très vite et très bien.
Tu es, je le devine, un futur excellent intervenant sur ce site. Je ne vais donc pas te "lâcher".. (hé oui !)
________________________
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'interviend
0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
19 févr. 2015 à 16:14
pigé!
pourra m'être utile...
J'ai encore progressé grâce à toi.... :)
bonne sieste....
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 19/02/2015 à 18:22
Bien.
Donc, une longueur d'enregistrement fixe est ce qui permet de s'y retrouver.
Aucun problème ne se pose en ce qui concerne les types numériques, les dates ... (la longueur en mémoire est pour eux forcément fixe et dépend du type).
Seules les chaînes de caractères nécessitent un "forçage" de longueur.
Avant de passer à l'essai suivant : ouvre le fichier essai.txt avec le bloc-notes et observe comment il est "construit"
Fait ? ===>> passons maintenant à l'essai (le tout dernier) suivant :
Private Type titi
nom As String * 15
unedate As Date
stock As Long
End Type


Private Sub CommandButton1_Click()
Randomize Timer
Dim enregistrement As titi, unnumero As Long
Kill "c:\essai.txt"
Open "c:\essai.txt" For Random As #1 Len = Len(enregistrement)
For unnumero = 1 To 5
enregistrement.nom = "un nom" & unnumero
enregistrement.unedate = DateAdd("d", Int((5 * Rnd) + 1), Date)
enregistrement.stock = Int((100000 * Rnd) + 1)
Put #1, unnumero, enregistrement
Next unnumero
Close #1
End Sub

Private Sub CommandButton2_Click()
Dim enregistrement As titi, maposition As Long
Open "c:\essai.txt" For Random As #1 Len = Len(enregistrement)
For maposition = 1 To FileLen("c:\essai.txt") \ Len(enregistrement)
Get #1, maposition, enregistrement
MsgBox "enregistrement n° " & maposition & vbCrLf & _
"nom = " & Trim(enregistrement.nom) & vbCrLf & "ladate = " & enregistrement.unedate & _
vbCrLf & "en stock = " & enregistrement.stock
Next
Close #1
End Sub

pareil : commandbutton1 pour écrire et l'autre pour lire.
Bon, hein ?
Va voir comment est écrit maintenant essai.txt.

PS : Ah oui ===>> observe que j'ai d'abord zigouillé essai.txt.
Ce qui a rendu la chose nécessaire ? : il existait déjà, mais avec une structure différente. ===>> si on modifie la structure utilisée, il faut repartir à zéro. Non nécessaire sinon
Voilà. Tu sais maintenant tout ce que tu devais savoir, je pense.
Bonne étude.

________________________
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'interviend
0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
19 févr. 2015 à 21:31
Merci
effectivement complet, appuyé d'exemples, clair, sympa, ...
comme d'ab!
comme cela me change!
"Tu es, je le devine, un futur excellent intervenant sur ce site" ... surtout pour poser des questions, car je suis loin d'avoir une compétence comme toi :)
"Je ne vais donc pas te "lâcher".. (hé oui !) " -> j'espère bien ... LOL

si je viens tard sur l'ordi, c'est que j'ai une ravissante fille de 6 ans IEP qui m'accapare beaucoup......et donc après la lecture du soir..., je viens sur le site:)
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 févr. 2015 à 21:37
si je viens tard sur l'ordi, c'est que j'ai une ravissante fille de 6 ans IEP qui m'accapare beaucoup

A choyer sans modération.
Moi, j'en ai 3 (de filles). L'ainée, toutefois, vient de fêter son 51ème anniversaire.
0
ClaudeDordogne Messages postés 47 Date d'inscription mardi 13 janvier 2015 Statut Membre Dernière intervention 7 mars 2015
19 févr. 2015 à 21:51
elles doivent moins d'occuper....
la mienne me pose quelques problèmes de scolarité : elle parle couramment 4 langues et résout les équations du 1er degré (en version "Princesse Inconnue" que l'on nomme donc X (en rose bien sûr !) dont le vaillant chevalier doit retrouver le nom....
vois-tu le bazar???
enfin, on s'écarte du sujet....LOL
0
Rejoignez-nous