Split en fonction de majuscule ou minuscule

nicroq

XLDnaute Occasionnel
bonsoir,
voici ma problematique, je souhaiterai par VBA séparer les caracteres d une cellule en fonction de si il s agit de majuscule ou minuscule ou d un chiffre et de reconcatener tout ca apres modification...

Mon fichier joint sera bien plus clair et evitera des explications pas claires afin d obtenir la case reformulation.

Merci bcp pour votre aide!!!!

cdlt
 

Pièces jointes

  • Split.xlsx
    9.9 KB · Affichages: 33

Dranreb

XLDnaute Barbatruc
Bonsoir.
Cette fonction traite les 2 1ers cas, en attendant, déjà…
VB:
Function Reformu(ByVal Z As String) As String
Dim P As Long, C As String * 1, N As Long
For P = 1 To Len(Z)
   C = Mid$(Z, P, 1)
   If C Like "#" Then
      N = 10 * N + C
   Else
      If C = UCase(C) And Reformu <> "" Then
         If N = 0 Then N = 1
         Reformu = Reformu & N
         N = 0: End If
      Reformu = Reformu & C: End If
    Next P
If N = 0 Then N = 1
Reformu = Reformu & N
End Function
 

Dranreb

XLDnaute Barbatruc
Je ne comprends pas la logique du cas particulier.
Pour "Zn(CH3COO)2P", celle ci après trouve "Zn1C2H6C2O2O2P1" ce qui, par contre, me parait plus logique que "Zn1C4H6O4P1" :
VB:
Function Reformu(ByVal Z As String) As String
Dim TSpl() As String, Déb As String, Mil As String, Fin As String, M As Long
TSpl = Split(Z, "(")
If UBound(TSpl) > 0 Then
   Déb = TSpl(0): TSpl = Split(TSpl(1), ")")
   Mil = TSpl(0): Fin = TSpl(1)
   While Left$(Fin, 1) Like "#": M = 10 * M + Left$(Fin, 1): Fin = Mid$(Fin, 2): Wend
   Reformu = RFMult(Déb, 1) & RFMult(Mil, M) & RFMult(Fin, 1)
Else
   Reformu = RFMult(Z, 1)
   End If
End Function
Function RFMult(ByVal Z As String, ByVal M As Long) As String
Dim P As Long, C As String * 1, N As Long
If Z = "" Then Exit Function
For P = 1 To Len(Z)
   C = Mid$(Z, P, 1)
   If C Like "#" Then
      N = 10 * N + C
   Else
      If C = UCase(C) And RFMult <> "" Then
         If N = 0 Then N = 1
         RFMult = RFMult & N * M
         N = 0: End If
      RFMult = RFMult & C: End If
    Next P
If N = 0 Then N = 1
RFMult = RFMult & N * M
End Function
 

nicroq

XLDnaute Occasionnel
Bonjour Dranreb,
oui effectivement votre logique est bonne, j'avais mis Zn1C2H6C2O2O2P1 pour que être plus clair sur comment les parenthèses interviennent dans ces formules!
cependant etant novice en vba, comment faire agir vos fonctions dans un sub du module..
Pourriez vous m indiquer la voie.

cdlt
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Par exemple :
VB:
Feuil1.{A1].Value = Reformu(Feuil2.[A1].Value)

Edit: J'espère qu'il ne risque pas d'y avoir plusieurs séquences entre parenthèses…
Ou pire encore: des séquences imbriquées !
 
Dernière édition:

nicroq

XLDnaute Occasionnel
Franchement merci bcp j'ai regarder comment me servir de la function et c'est vrm tres simple!
merci enormement!!!

un dernier cas particulier apparait cependant :
Zn(CH3COO)2, 2H2O
resultat avec reformu : Zn1C2H6C2O2O2,1 2H2O1

C6H5FeO7, H2O
resultat avec reformu : C6H5Fe1O7,1 1H2O1

MgSO4, 7H2O
resultat avec reformu : Mg1S1O4,1 7H2O1

est il posssible avec la fonction de ne pas considerer la virgule et de ne pas mettre le "1" apres la virgule?

cdlt
 

Dranreb

XLDnaute Barbatruc
Dans RFMult, en replaçant Else par ElseIf UCase(C) <> LCase(C) Then
Il ne considère vraiment que les lettres et les chiffres.
Mais Reformu("Zn(CH3COO)2, 2H2O" trouve alors"Zn1C2H6C2O2O2H22O1"
Je doute que ce soit correct. C'est nouveau, ça, un chiffre en tête de quelque chose au lieu d'à la fin.
RFMult exige un facteur multiplicatif en plus du texte à analyser.
 

Dranreb

XLDnaute Barbatruc
Essayez comme ça :
VB:
Function Reformu(ByVal Z As String) As String
Dim TS1() As String, P As Long, TS2() As String, TS3() As String, Fin As String, M As Long
TS1 = Split(Replace(Z, " ", ""), ",")
For P = 0 To UBound(TS1)
   TS2 = Split(TS1(P), "(")
   If UBound(TS2) > 0 Then
      TS3 = Split(TS2(1), ")")
      M = TêteÉliminée(TS3(1))
      TS1(P) = RFMult(TS2(0), 1) & RFMult(TS3(0), M) & RFMult(TS3(1), 1)
   Else
      TS1(P) = RFMult(TS1(P), 1)
      End If: Next P
Reformu = Join(TS1, "")
End Function

Function RFMult(ByVal Z As String, ByVal M As Long) As String
Dim P As Long, C As String * 1, N As Long
M = M * TêteÉliminée(Z)
If Z = "" Then Exit Function
For P = 1 To Len(Z)
   C = Mid$(Z, P, 1)
   If C Like "#" Then
      N = 10 * N + C
   ElseIf UCase(C) <> LCase(C) Then
      If C = UCase(C) And RFMult <> "" Then
         If N = 0 Then N = 1
         RFMult = RFMult & N * M
         N = 0: End If
      RFMult = RFMult & C: End If
    Next P
If N = 0 Then N = 1
RFMult = RFMult & N * M
End Function

Function TêteÉliminée(ByRef Z As String) As Long
While Left$(Z, 1) Like "#": TêteÉliminée = 10 * TêteÉliminée + Left$(Z, 1): Z = Mid$(Z, 2): Wend
If TêteÉliminée = 0 Then TêteÉliminée = 1
End Function
J'ai supposé que des chiffres en tête d'un truc était aussi un facteur multiplicatif de l'ensemble de ce truc.
 

nicroq

XLDnaute Occasionnel
Je vous remercie pour votre aide c est vrm super ca fonctionne tres tres bien.
j'aurais une dernière requête pour cloturer ma macro, serait possible maintenant de faire la somme de tous les atomes par exemple :
Zn1C2H6C2O2O2H4O2
C6H5Fe1O7H2O1
Mg1S1O4H14O7

Zn =1
C=10
H=31
Mg=1
O=17
..
..
...
 

cp4

XLDnaute Barbatruc
Bonjour Nicroq, Dranreb,:)

Désolé de m'incruster. En fait, J'ai consulté cette discussion et je n'ai pas compris la déclaration de la variable
C as string*1.
Bonsoir.
Cette fonction traite les 2 1ers cas, en attendant, déjà…
VB:
Function Reformu(ByVal Z As String) As String
Dim P As Long, C As String * 1, N As Long
Merci Dranreb d'éclairer ma lanterne. Pourquoi String*1?
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 198
Messages
2 086 153
Membres
103 136
dernier inscrit
Zoulander