1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| ' changelog 1.1 - > 1.2
' - insertion corrigée des nouvelles clés/valeurs
' - support des caractères = et ; (échappé) dans les valeurs de clés
' - ajout des options de suppression de section et de clé
' syntaxe conforme au format de l'API ini Windows sauf exception (*)
' accepte les lignes blanches
' pas sensible à la casse
' support des commentaires ligne entière
' pas d'espace dans le nom de clé ou en début de ligne
' pas de caractère = dans le nom de clé
' * support des commentaires de fin de ligne : implique que le point virgule n'est pas accepté dans les valeurs de clé sauf échappement (cf infra)
' * les espaces de fin de valeur sont conservés
' * pas de suppression auto des quotes de valeurs de clé ("')
' * support de l'échappement du caractère ; dans les valeurs de clé : \;
' changelog 1.2 -> 1.3
' réécriture du core algorithm pour optimisation et suppression bug
Set fso = CreateObject("Scripting.FileSystemObject")
Set ofi = fso.GetFile("test.ini")
'MsgBox WriteReadIni(ofi,"XCX","KK","55")
'MsgBox WriteReadIni(ofi,"A","A1",Null)
'MsgBox WriteReadIni(ofi,"b","b1",Null)
'MsgBox WriteReadIni(ofi,"c",Empty,Empty) ' supprime la section [C]
MsgBox WriteReadIni(ofi,"XCX","KK","55")
' ********************************************************************************************************************
' omen999 - avril 2020 v 1.3 - https://omen999.developpez.com/
' un regexp pour les gouverner toutes,
' un regexp pour les trouver,
' un seul regexp pour les amener toutes,
' et dans l'ini les lier
' 1. lit la valeur de clé <key> de section <section> de l'objet fichier ofi
' 2. écrit la clé <key> de section <section> de l'objet fichier ofi avec la valeur <value>
' 3. supprime la section <section> et/ou la clé <key> de l'objet fichier ofi
' lecture : value = Null
' écriture : si la section et/ou la clé n'existent pas, elles seront créées
' suppression clé/valeur : value = Empty
' suppression section entière : key et value = Empty
'
' valeur renvoyée :
' lecture : la valeur de clé, une chaine vide en cas de clé sans valeur ou faux si la clé n'existait pas
' écriture : faux si le couple clé/valeur existait déjà sinon vrai
' suppression : faux si la section ou clé à supprimer n'existait pas ou vrai en cas de succès
' ********************************************************************************************************************
Function WriteReadIni(ofi, section, key, value)
Dim reg, stext, initext
' initialisation des objets regexp, peut être déplacé dans le code principal en cas d'appels successifs
Set reg = New RegExp : reg.IgnoreCase = True
WriteReadIni = False ' valeur par défaut de la fonction
' lecture intégrale du fichier ini
Set stext = ofi.OpenAsTextStream(1,0)
initext = stext.ReadAll
stext.Close
' definition du pattern
' reg va renvoyer le contenu de la section entière avec toutes ses clés
' 1ère occurrence car .Global est laissé à False donc toute section suivante portant le même libellé sera ignorée
' le début de la capture est défini par le nom de section placé en début de ligne entre crochets
' [nom de section] est placé dans une 1ère sous-correspondance (index 0) : (^\[" & section & "\])
' la suite est définie comme tous les caractères suivants le crochet fermant jusqu'à
' un saut de ligne suivi d'un crochet ouvrant ou de la fin de chaine avec ou sans saut de ligne
' le tout également placé dans une 2ème sous-correspondance (index 1) : ((.|\n[^\[])*\n?)
' l'insertion de toute clé/valeur nouvelle se fera à la jonction entre les sous-correspondances d'index 0 et 1
reg.MultiLine = True ' évite la capture du début de ligne
If IsNull(value) Then ' lecture clé
On Error Resume Next
reg.Pattern = "^\[" & section & "\](.|\n[^\[])*\n" & Trim(key) & " *= *((\\;|=|[^;\f\n\r\t\v])*)" ' submatch (valeur de clé)
WriteReadIni = Replace(reg.Execute(initext)(0).SubMatches(1),"\;",";") ' lève l'erreur 5 si clé absente
Else ' écriture/suppression section et/ou clé/valeur -> maj d'iniText
' suppression section ou clé/valeur
If IsEmpty(value) Then
' suppression section existante
If IsEmpty(key) Then
reg.Pattern = "^\[" & section & "\](.|\n[^\[])*\n?" ' capture la section entière
iniText = reg.Replace(initext,"")
Else ' suppression clé/valeur
' capture avec les commentaires, submatch section..clés antérieures sans crlf final
reg.Pattern = "(^\[" & section & "\](.|\n[^\[])*)\r\n" & Trim(key) & " *= *(=|[^\f\n\r\t\v])*"
If reg.Test(initext) Then initext = reg.Replace(initext,"$1") Else Exit Function
End If
Else
' ajout section, clé/valeur ou modif valeur de clé
' pas de valeur sans clé mais key peut être vide si création de section seule
' pas d'espace dans les noms de clés
' un ; peut figurer en début de nom de clé, le couple clé/valeur sera alors créé en commentaire et donc inaccessible en lecture
If (key = "" And value <> "") Or InStr(key," ") > 0 Then Exit Function
reg.Pattern = "^\[" & section & "\]" ' recherche section
If reg.Execute(initext).Count = 0 Then ' section inconnue : elle est ajoutée en fin de fichier avec son éventuel couple clé/valeur
initext = Join(Array(initext, vbCrLf, "[", section, "]", vbCrLf, key, "=", value),"")
'initext = initext & vbCrLf & "[" & section & "]" & vbCrLf & key & "=" & value ' à tester
Else ' la section existe, si clé existante -> maj sinon ajoutée au 1er rang de la section
reg.Pattern = "(^\[" & section & "\](.|\n[^\[])*\n" & Trim(key) & " *=) *(\\;|=|[^;\f\n\r\t\v])*" ' submatch (section...nom de clé=)
If reg.Test(initext) Then ' maj valeur de clé
initext = reg.Replace(initext,"$1" & value)
Else
reg.Pattern = "^\[" & section & "\]"
initext = reg.Replace(initext,"$&" & vbCrLf & key & "=" & value) ' clé/valeur insérées en 1er rang de la section
End If
End If
End If
' iniText maj sauvegarde du fichier ini
Set stext = ofi.OpenAsTextStream(2,0)
stext.Write initext
stext.Close
WriteReadIni = True
End If
End Function |
Partager