IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Vos Contributions VBScript Discussion :

Lire/écrire une valeur de clé dans un fichier INI


Sujet :

Vos Contributions VBScript

  1. #1
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 296
    Points : 3 549
    Points
    3 549
    Par défaut Lire/écrire une valeur de clé dans un fichier INI
    bonjour,

    compte-tenu des points communs entre le code d'écriture et de lecture
    j'ai finalement décidé d'écrire une routine regroupant les deux fonctionnalités

    donc le fichier test.ini à placer dans le répertoire "Mes Documents"
    Code ini : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [UserHome]
    Name=
    Handy=21/10/2016 ;ceci est la clé recherchée
    WWW=
    [UserBusiness]
    Name=
    Handy=02/02/2015 ;pas celle-ci
    WWW=

    le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set wshell = CreateObject("WScript.Shell")
    Set oFile = fso.GetFile(wshell.SpecialFolders("MyDocuments") & "\test.ini")
    rep = WriteReadIni(oFile,"UserHome","WWW","nouvelle valeur de clé")
    Msgbox WriteReadIni(oFile,"UserHome","WWW",Null)
     
    Function WriteReadIni(oFile,section,key,value)
    ' écrit/lit la clé <key> de section <section> de l'objet fichier oFile avec la valeur <value> si lecture : value = Null 
    ' en écriture si la section et/ou la clé n'existent pas, elles seront créées
    ' en écriture renvoie toujours vrai, en lecture renvoie soit : la valeur de clé, une chaine vide en cas de clé vide ou Faux si la clé n'existe pas
    Dim oText,iniText,sectText,newSectText,keyText
    	' Initialisation des objets regexp
    	' peut être déplacé dans le code principal en cas d'appels successifs
    	Set reg = New RegExp
    	Set regSub = New RegExp
    	reg.IgnoreCase = True
    	regSub.IgnoreCase = True
    ' lecture du fichier ini et fermeture
    	Set oText = oFile.OpenAsTextStream(1,0)
    	iniText = oText.ReadAll
    	oText.Close
    	reg.Pattern = "\[" & section & "\]([^\[]+)":regSub.Pattern = "\b" & key & " *= *([^;\f\n\r\t\v]*)"
    	On Error Resume Next
    	If IsNull(value) Then   ' lecture clé
    		WriteReadIni = regSub.Execute(reg.Execute(iniText).Item(0).SubMatches(0)).Item(0).SubMatches(0)
    		If Err.Number = 5 then WriteReadIni = False
    	Else						' écriture clé
    		sectText = reg.Execute(iniText).Item(0).SubMatches(0)
    		If Err.Number = 5 Then ' section inconnue
    			iniText = iniText & vbCrLf & "[" & section & "]" & vbCrLf & key & "=" & value
    		Else
    			newSectText = regSub.Replace(sectText,key & "=" & value)
    			If newSectText = sectText Then
    				If Right(sectText,2) = vbCrLf Then keyText = key & "=" & value & vbCrLf Else keyText = vbCrLf & key & "=" & value & vbCrLf
    				newSectText = sectText & keyText
    			End If
    			iniText = reg.Replace(iniText,"[" & section & "]" & newSectText)
    		End If
    		' écriture du fichier ini mis à jour
    		Set oText = oFile.OpenAsTextStream(2,0)
    		oText.Write iniText
    		oText.Close
    		WriteReadIni = True
    	End If
    End Function
    Toute remarque sera la bienvenue avant de placer ce code dans la
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  2. #2
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 296
    Points : 3 549
    Points
    3 549
    Par défaut
    nouvelle version que j'espère définitive...
    nouveautés :
    - supporte les caractères [ et ] dans les valeurs de clés
    - élimine un gros bug (il était possible de créer des doublons de couple clé/valeur)
    - renvoie faux si la tentative d'écriture concerne un couple clé/valeur qui existe déjà

    merci de me signaler les bugs éventuels avant passage dans la

    le fichier test.ini à mettre dans le même répertoire que l'exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [H1]
    key1=val1
    key2=val2
    key3=[aga]
    [H2]
    key5=12  ;comment
    key6=HJUY
    key2=val2
    key2=val2
    [H3]
    key7=val5
    keyx=[KKK]
    key8=val6
    keyxy=]ghghg[s
    [H4]
    key9=klm
    key10=]ghghg[s
    [H5]
    ab=op
    KKName=ss
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set wshell = CreateObject("WScript.Shell")
    Set oFile = fso.GetFile("test.ini")
    Msgbox WriteReadIni(oFile,"H3","keyxy",Null)
    Msgbox WriteReadIni(oFile,"H5","ab",Null)
    Msgbox WriteReadIni(oFile,"H4","testtag","[zz[")
     
    Function WriteReadIni(oFile,section,key,value)
    ' *******************************************************************************************
    ' omen999 - mars 2018 v 1.1 - http://omen999.developpez.com/
    ' écrit/lit la clé <key> de section <section> de l'objet fichier oFile avec la valeur <value> si lecture : value = Null 
    ' en écriture si la section et/ou la clé n'existent pas, elles seront créées
    ' en écriture renvoie faux si le couple clé/valeur existait déjà sinon vrai
    ' en lecture renvoie soit : la valeur de clé, une chaine vide en cas de  clé vide ou Faux si la clé n'existe pas
    ' ********************************************************************************************
    Dim oText,iniText,sectText,newSectText,keyText
      ' Initialisation des objets regexp
      ' peut être déplacé dans le code principal en cas d'appels successifs
      Set reg = New RegExp
      Set regSub = New RegExp
      reg.MultiLine=True 'simplifie le pattern
      reg.IgnoreCase = True
      regSub.IgnoreCase = True
      Set oText = oFile.OpenAsTextStream(1,0)
      iniText = oText.ReadAll
      oText.Close
      reg.Pattern = "^\[" & section & "\]((.|\n[^\[])+)":regSub.Pattern = "\b" & key & " *= *([^;\f\n\r\t\v]*)"
      On Error Resume Next
      If IsNull(value) Then   ' lecture clé
        WriteReadIni = regSub.Execute(reg.Execute(iniText).Item(0).SubMatches(0)).Item(0).SubMatches(0)
        If Err.Number = 5 then WriteReadIni = False
      Else                                              ' écriture clé
        sectText = reg.Execute(iniText).Item(0).SubMatches(0)
        If Err.Number = 5 Then ' section inconnue
          iniText = iniText & vbCrLf & "[" & section & "]" & vbCrLf & key & "=" & value
        Else
          newSectText = regSub.Replace(sectText,key & "=" & value)
          If newSectText = sectText Then ' pas de remplacement constaté. soit le clé/valeur existe déjà soit c'est une nouvelle clé
            If regSub.Test(sectText) Then ' le couple clé/valeur existe déjà -> sortie
              WriteReadIni = False
              Exit Function	
            End If
            If Right(sectText,1) = vbCr Then keyText = key & "=" & value Else keyText = vbCrLf & key & "=" & value
            newSectText = sectText & keyText			
          End If
          iniText = reg.Replace(iniText,"[" & section & "]" & newSectText)
        End If
        Set oText = oFile.OpenAsTextStream(2,0)
        oText.Write iniText
        oText.Close
        WriteReadIni = True
      End If
    End Function
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  3. #3
    Membre du Club
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Janvier 2014
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gers (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2014
    Messages : 36
    Points : 54
    Points
    54
    Par défaut
    Salut merci pour ce code je l'ai mis dans mon code
    malheureusement j'ai remarqué quelques bugs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [CONFIG]
    MAJ=1.0.7
    OK=1
    MUSIC=C:\Users\MOI\Desktop
    [Logiciel]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WriteReadIni (oFile,"CONFIG","WEBHOOKS","KEY2")
    Qui de temps en temps me l'écrit après la balise Logiciel ou qui ne retourne pas a la ligne ou qui colle la balise [Logiciel] a la fin

    Mais je te contacte surtout pour savoir comment modifier une key ou valeur si elle existe déja ? (voir supprimé key ou valeur si possible)


  4. #4
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 296
    Points : 3 549
    Points
    3 549
    Par défaut
    bonjour,

    effectivement la v2 a introduit une régression...
    la v1 ne présente pas ce bug et insère ta clé correctement
    si tu n'essaies pas d'écrire un couple clé/valeur qui existe déjà
    et que tu n'a pas besoin de gérer des valeurs contenant des crochets
    la v1 fera l'affaire....
    j'ai également oublié de préciser que le code n'est pas compatible avec les
    fichiers .INI présentant un BOM. j'en ai une version compatible BOM mais elle
    n'est pas assez générique pour être publiée ici.


    pour modifier la valeur d'une clé existante, il suffit de l'écrire avec une valeur différente
    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WriteReadIni oFile,"CONFIG","WEBHOOKS","KEY3"
    en revanche modifier une clé revient en réalité à la supprimer et à en écrire une nouvelle
    mon code ne prévoyait pas la suppression de clé
    je vais voir si je peux facilement la rajouter tout en supprimant le bug
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  5. #5
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 296
    Points : 3 549
    Points
    3 549
    Par défaut
    mon code ne prévoyait pas la suppression de clé
    je vais voir si je peux facilement la rajouter tout en supprimant le bug
    ..presque deux ans plus tard et avec un peu de confinement méditatif voici la version 1.2 que j'espère définitive

    changelog 1.1 - > 1.2
    - bug insertion des nouvelles clés/valeurs corrigé
    - 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é : \;

    le code est volontairement très commenté et peut être testé avec le fichier test.ini qui suit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ofi = fso.GetFile("test.ini")
    MsgBox WriteReadIni(ofi,"A","A1",Null)
    MsgBox WriteReadIni(ofi,"b","b1",Null)
    'MsgBox WriteReadIni(ofi,"c",Empty,Empty)  ' supprime la section [C]
     
    ' ********************************************************************************************************************
    ' omen999 - avril 2020 v 1.2 - https://omen999.developpez.com/
    '  WriteReadIni(ofi, section, key, value)
    ' 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, regsub, stext, initext, regmatch, newdata
      ' initialisation des objets regexp, peut être déplacé dans le code principal en cas d'appels successifs
      Set reg = New RegExp : Set regsub = New RegExp
      reg.IgnoreCase = True : regsub.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
      reg.Pattern = "(^\[" & section & "\])((.|\n[^\[])*\n?)"   
      ' une 2ème expression régulière (regsub) est appliquée au résultat renvoyé par reg
      ' elle renvoie la 1ère occurrence de la valeur de clé recherchée (.Global=False)
      ' definition du pattern
      ' le début de la capture est défini par le nom de clé éventuellement précédé d'un retour ligne, non précédé
      ' d'un espace ou d'un ; suivi d'un = éventuellement entouré d'espaces
      ' la sous-correspondance renvoie la valeur de clé (tous les caractères non spéciaux y compris = avant un éventuel ; non échappé)
      regsub.Pattern = "(\r\n)?[^; \n]*" & Trim(key) & " *= *((\\;|=|[^;\f\n\r\t\v])*)"
      On Error Resume Next
      Set regmatch = reg.Execute(initext)
      If IsNull(value) Then   ' lecture clé en une seule ligne
        WriteReadIni = Replace(regsub.Execute(regmatch(0))(0).SubMatches(1),"\;",";")
      Else                    ' écriture/suppression section et/ou clé/valeur -> maj d'iniText
        ' suppression section ou clé/valeur
        If IsEmpty(value) Then
          If Err.Number > 0 Then Exit Function
          regsub.Pattern = "(\r\n)?[^; \n]*" & key & " *= *((=|[^\f\n\r\t\v])*)" ' maj pattern capturant également les commentaires de fin de ligne
          ' suppression section existante
          If IsEmpty(key) Then
            iniText = reg.Replace(initext,"")
          Else ' suppression clé/valeur
      	If regsub.Test(regmatch(0)) Then initext = reg.Replace(initext,regsub.Replace(regmatch(0),"")) Else Exit Function
          End If
        Else	
          ' ajout section, clé/valeur ou modif valeur de clé
          If key = "" And value <> "" Then Exit Function   ' pas de valeur sans clé
          If key <> "" Then key = key & "="
          newdata = vbCrLf & key & value
          If Err.Number = 5 Then ' section inconnue : elle est ajoutée en fin de fichier avec son éventuel couple clé/valeur  		
            initext = initext & vbCrLf & "[" & section & "]" & newdata 
          Else ' la section existe, si clé existante -> maj sinon ajoutée au 1er rang de la section
            If regsub.Test(regmatch(0)) Then initext = reg.Replace(initext,regsub.Replace(regmatch(0),newdata)) Else initext =_
                                                       reg.Replace(initext,regmatch(0).SubMatches(0) & newdata & regmatch(0).SubMatches(1))
          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
    le fichier test.ini :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [A]
    A1= ceci est point-virgule \;.    ;comment1
     
    [B]
    B1= b=[value]   ;comment2
    B2=
    [C]
    CName=test
    CSurname = [z]z[
    [D]
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  6. #6
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 296
    Points : 3 549
    Points
    3 549
    Par défaut
    Il y a déjà quelque temps, j'ai reçu ce rapport de bug par MP
    Bonjour,

    A la recherche d'un script pour gérer des fichiers Ini en Vbscript j'ai testé ton script WriteReadIni v.1.2 - Avril 2020

    Compact et efficace (bravo) j'ai simplement un souci lors de la création d'une section inexistante.

    Cela ne semble pas fonctionner

    Il semble que le Err.Number reste à "0" alors que la section n'existe pas
    Au niveau de ton code ce test s'effectue à cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Err.Number = 5 Then ' section inconnue : elle est ajoutée en fin de fichier
    Par contre si la section existe la création d'une nouvelle clé ou modification de valeur fonctionne parfaitement.

    J'ai voulu débugger mais j'avoue ma limite dans la gestion des pattern/reg malgré ton script très documenté

    Je ne sais pas si tu as déjà été confronté à ce cas ?

    Si tu as un peu de temps pour éclairer ma lanterne...

    Par avance merci.
    en jetant un oeil dans mon bazar, j'ai découvert que j'avais pondu seulement quelques jours plus tard une version 1.3 dont le core algo avait été largement réécrit et optimisé...
    donc avec deux bonnes années de retard voici la v1.3
    j'avais dû fumé la moquette mais pour ma défense c'était après plusieurs semaines de confinement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

Discussions similaires

  1. [XL-2010] Chercher une valeur de cellule dans plusieurs fichiers
    Par affre dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 08/04/2016, 16h17
  2. Lire et écrire une valeur binaire dans la base de registre
    Par DelphiCool dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 13/02/2013, 20h46
  3. Réponses: 8
    Dernier message: 15/07/2008, 17h41
  4. (VBA) écrire une valeur dans une table
    Par migaleb dans le forum Access
    Réponses: 1
    Dernier message: 22/06/2006, 12h45
  5. Comment écrire une très longue variable dans un fichier ?
    Par hijodelanoche dans le forum Langage
    Réponses: 8
    Dernier message: 17/11/2005, 16h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo