Excel saisie de chaine de caractères

bibiman23 Messages postés 45 Statut Membre -  
eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,

Je souhaite faire une recherche d'une chaîne de caractères entre deux séparateurs.

Exemple

FII+OR+5150060006:RIRI::FIFI+:::18100:25:137:titi+AT

Dans chaque ligne, je vais avoir des parties dites "mères" (ou enregistrements) entre "+" et des parties filles (ou sous enregistrements) entre ":"

Si je cherche la chaîne du second sous enregistrement du troisième enregistrement (2nd fille de la troisième mère pour les sentimentaux) et bah ça sera RIRI.
Parce que :
FII =1er enreg
OR =2nd enreg
5150060006:RIRI::FIFI = 3ème enreg
FIFI= 4 ss enreg du 3ème enreg
Voilà j'espère que j'ai été claire.
Type d'enregistrement: FII
J'ai essayé de créer une fonction extract(type enreg, no enreg, no ss enreg)
avec des loop mais moi pas arriver!

Merci d'avance pour votre aide.

4 réponses

  1. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonsoir à tous les deux

    un début, du moins comme je l'ai compris

    Function rangcar(ch As String, nucar As Long, car As String) 
    Dim rc As Long, c As Long 
    rc = 0 
    For c = 1 To Len(ch) 
      If Mid(ch, c, 1) = car Then 
        rc = rc + 1 
        If rc = nucar Then 
          rangcar = c 
          Exit Function 
        End If 
      End If 
    Next c 
    End Function 
    
    Function extract(ByVal ch As String, no_enreg As Long, no_ss_enreg As Long) As String 
    Dim deb As Long, fin As Long 
    Dim enreg As String 
    ch = "+" & ch & "+" 
    deb = rangcar(ch, no_enreg, "+") 
    fin = rangcar(ch, no_enreg + 1, "+") 
    enreg = Mid(ch, deb + 1, fin - deb - 1) 
    enreg = ":" & enreg & ":" 
    deb = rangcar(enreg, no_ss_enreg, ":") 
    fin = rangcar(enreg, no_ss_enreg + 1, ":") 
    extract = Mid(enreg, deb + 1, fin - deb - 1) 
    End Function

    RQ1. la fonction extract renvoie #VALEUR si la requête n'est pas fondée (dons pas de test sur la validité de la requête)
    RQ2. j'ai supposé que si on a "+:" ou "::" il y a un sous enregistrement vide entre + et : ou entre : et :

    bonne suite
    1
    1. Bibiman23
       
      Merci ccm81, je teste demain!
      0
    2. bibiman23 Messages postés 45 Statut Membre 3
       
      Salut Permalink,

      Ton code est super, mais je n'arrive pas à gérer le cas où il ne doit rien envoyer par ce qu'il n'y justement rien à envoyer. Par exemple:
      Dans l'exemple que j'ai cité il n'y a pas de 2nd sous enregistrement pour le premier enregistrement donc extract(ma_ligne,1,2) devrait envoyen un blank.
      Ou par exemple la ligne est finie elles se terminent toutes par des ' (contrairement à l'exemple que j'ai fournis..)
      Merci en tout cas ça m'a vachement avancer..
      0
    3. bibiman23 Messages postés 45 Statut Membre 3
       
      C'est tout bon pour moi il fallait que je rajoute une petite bricole cf; le code suivant pour gérer le dernier cas que je viens d'évoquer:

      Function extract(ByVal ch As String, no_enreg As Long, no_ss_enreg As Long) As String
      Dim deb As Long, fin As Long
      Dim enreg As String
      ch = "+" & ch & "+"
      deb = rangcar(ch, no_enreg, "+")
      fin = rangcar(ch, no_enreg + 1, "+")
      enreg = Mid(ch, deb + 1, fin - deb - 1)
      enreg = ":" & enreg & ":"
      deb = rangcar(enreg, no_ss_enreg, ":")
      fin = rangcar(enreg, no_ss_enreg + 1, ":")
      If (fin - deb - 1) <= 0 Then
      extract = ""
      Else
      extract = Mid(enreg, deb + 1, fin - deb - 1)
      End If
      0
  2. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Re,

    Bon, ben je vais faire ma proposition mais je ne sais pas s'il faut tenir compte du type ou si tu le testes avant de demander l'extraction.

    J'ai donc mis type_enreg en optional en 4ème paramètre.
    S'il est présent on le teste, si ok on extrait.
    Si nok on retourne "type_enreg incorrect" (remplacer par "" si on préfère)

    Si type_enreg est absent on extrait.

    Function extract(enreg As String, no_enreg As Long, no_ss_enreg As Long, Optional type_enreg As String) As String 
        If Not IsEmpty(type_enreg) Then 
            If Split(enreg, "+")(0) <> type_enreg Then 
                extract = "type_enreg incorrect" 
                Exit Function 
            End If 
        End If 
        extract = Split(Split(enreg, "+")(no_enreg - 1), ":")(no_ss_enreg - 1) 
    End Function

    syntaxe :
    =extract(A1;3;2;"FII")
    ou
    =extract(A1;3;2)

    Si le test de type_enreg est fait avant de demander l'extraction on peut se contenter de :
    Function extract(enreg As String, no_enreg As Long, no_ss_enreg As Long) As String 
        extract = Split(Split(enreg, "+")(no_enreg - 1), ":")(no_ss_enreg - 1) 
    End Function

    syntaxe : =extract(A1;3;2)

    eric
    1
    1. bibiman23 Messages postés 45 Statut Membre 3
       
      bonjour,
      en effet je fais un
      Select Case Mid(ma_ligne, 1, 4)
      Case "FII+"
      et après je vais extraire donc pas de prise de tête avec le type d'enregistrement (le premier enregistrement).
      Merci Eric
      0
    2. bibiman23 Messages postés 45 Statut Membre 3
       
      Salut Eric,

      Ta fonction marche pas trop bien (j'ai testé la seconde version).
      0
    3. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      Re,

      Ta fonction marche pas trop bien (j'ai testé la seconde version).
      Ah, moi je trouve qu'elle marche plutôt bien, que ce soit la 1ère ou la 2nde version
      http://www.cijoint.fr/cjlink.php?file=cj201109/cijvX7nY0v.xls

      eric
      0
    4. ccm81 Messages postés 11033 Statut Membre 2 434
       
      bonjour eriiic
      effectivement ta fonction marche très bien et pour moins cher que la mienne .... bien vu le split-split
      cordialement
      0
    5. bibiman23 Messages postés 45 Statut Membre 3
       
      Voici une version super light de mon script Eric:
      sub extraction
      fichier = "C\essai.txt"

      Dim alphanum As String
      numero = FreeFile

      Open fichier For Input As #numero

      While Not EOF(numero) And Not i > 256 '(max colonne)
      Line Input #numero, alphanum
      Worksheets("test").Select

      'selection des 4 premiers caractères (statiques) de la ligne lue

      Select Case Mid(alphanum, 1, 4)
      Case "FII+"
      ligne = Mid(alphanum, 1, Len(alphanum))
      Cells(10, 1) = extract(ligne, 2, 2)
      end select

      wend

      end sub

      J'ai le message d'erreur (qui pointe ta fonction ) suivant:
      Erreur d'exécution 9
      L'indice n'appartient pas à la sélection.
      sinon en terme de nomre de parenthèses ouvertes et fermées il y a un souci.
      0
  3. bibiman23 Messages postés 45 Statut Membre 3
     
    Je me tiens à disposition pour plus amples informations.

    En effet je pense à deux fonctions split imbriquées, mais ça ne me résussi pas!
    0
  4. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    Bonjour,

    juste une question :
    Tu as mis le type en paramètre dans ta fonction.
    Peux confirmer que c'est important, qu'il faut le tester et qu'il apparait toujours (en enregistrement 1) ?
    Parce que tu n'en parles pas dans la description du problème....
    eric
    0
    1. Bibiman23
       
      Éric tu as bien compris, le type est toujours le premier enregistrement.
      Parce que je lis le fichier ligne par ligne. Dès que je chope mon type je récupère ma chaîne de caractère.
      0