Extraire nombre "lié" à un symbole

Bonjour à la communauté.

J'aimerais savoir si il serait possible de réaliser une macro capable d'extraire d'une cellule des nombres liés à leur symbole et de les placer dans "leur" cellule.

Exemple : C6H6O dans la cellule "à extraire" ==> 6 dans une cellule à droite d'une autre contenant C, 6 dans celle à droite de H et 1 dans celle à droite de O. En sachant qu'il y aurait d'autre symbole dont certains de deux lettres (F, N, Br ...)

20exemple.xlsx (12.98 Ko)

En vous remerciant d'avance

Bonjour,

Un fichier ?

J'ai édité mon premier message.

Bonjour,

A tester !!!!

Bien à vous

Jp

Bonsoir,

En attendant mon infirmière ( ) j'ai pensé qu'une fonction personnalisée pour ton dénombrement de chaque élément dans une molécule pouvait être plus facile d'emploi.

Function NBELEMMOL(elem As String, mol As String)
    Dim h%, n%
    Application.Volatile
    h = InStr(1, mol, elem, vbBinaryCompare)
    If h > 0 Then
        n = Val(Right(mol, Len(mol) - h))
        NBELEMMOL = IIf(n > 0, n, 1)
    Else
        NBELEMMOL = ""
    End If
End Function

Utilisation simple : en F4 tu tapes =NBELEMMOL(E4;$I$3) et la formule renvoie 6.

Tu la tires sur la colonne et elle renvoie la valeur pour l'élément figurant en E. Elle renvoie une chaîne vide si l'élément n'est pas trouvé.

Dans la foulée, ayant encore un peu de temps, je me suis penché sur ton calcul de la masse moléculaire (un peu artisanal ).

Pour l'améliorer, il fallait d'abord compléter la Table, j'ai donc ajouté une colonne à gauche pour les symboles. Et je l'ai nommée Table pour faciliter son utilisation.

A ce stade, une formule de recherche permet de faire le calcul par élément. Il suffit d'en additionner les résultats ensuite. Mais calculer en seule formule, serait mieux...

Cette idée m'a conduit à une nouvelle fonction, personnalisée, qui à partir de la formule moléculaire opérerait la décomposition en 2 colonnes : éléments présents dans la molécule et nombre pour chacun. Fonction matricielle.

Et une fois cette fonction établie, une nouvelle fonction pourrait l'utiliser pour opérer le calcul de la masse directement à partir de la formule moléculaire.

J'ai dû attendre un certain temps après le passage de mon infirmière pour finaliser tout cela...

Function DECOMPMOL(mol As String)
    Dim elm(), mlm, c, i%, m%, n As Boolean
    Application.Volatile
    For i = 1 To Len(mol)
        c = Mid(mol, i, 1)
        If c Like "[A-Z]" Then
            If n Then
                mlm = mlm & " " & 1 & " " & c
            Else
                mlm = mlm & " " & c: n = True
            End If
        ElseIf c Like "[a-z]" Then
            mlm = mlm & c
        ElseIf c Like "[0-9]" Then
            If n Then
                mlm = mlm & " " & c
                Do
                    m = m + 1
                    c = Mid(mol, i + m, 1)
                    If c Like "[0-9]" Then
                        mlm = mlm & c
                    Else
                        m = m - 1: Exit Do
                    End If
                Loop While i + m + 1 <= Len(mol)
                i = i + m: n = False: m = 0
            Else
                DECOMPMOL = CVErr(xlErrValue): Exit Function
            End If
        Else
            DECOMPMOL = CVErr(xlErrValue): Exit Function
        End If
    Next i
    If n Then mlm = mlm & " " & 1
    mlm = Split(Replace(mlm, " ", "", 1, 1))
    ReDim elm(UBound(mlm) \ 2, 1)
    For i = 0 To UBound(elm, 1)
        elm(i, 0) = mlm(i + m)
        m = m + 1: elm(i, 1) = CInt(mlm(i + m))
    Next i
    DECOMPMOL = elm
End Function

Cette fonction est matricielle. On sélectionne une plage comportant autant de lignes qu'il y a d'éléments dans la molécule (ce qui s'évalue rapidement en observant la formule moléculaire) et 2 colonnes.

On tape la formule : =DECOMPMOL(I3) I3 contenant : C6H6O, on a donc sélectionné préalablement une plage de 3 lignes et 2 colonnes. On valide la formule par la combinaison de touches Ctrl+Maj+Entrée et les éléments sont listés dans la plage en 1re colonne avec leur nombre en 2e colonne.

La formule renvoie #VALEUR! si la formule moléculaire à décomposer n'est pas strictement conforme : respect de la casse (majuscule/minuscule), les symboles doivent avoir la première lettre majuscule, la seconde minuscule s'il y a lieu...

Dernière fonction pour calculer la masse moléculaire :

Function MASSMOL(mol As String)
    Dim elm(), mm, i%, e%
    Application.Volatile
    elm = DECOMPMOL(mol)
    On Error GoTo noelm
    With [Table]
        For i = 0 To UBound(elm, 1)
            e = WorksheetFunction.Match(elm(i, 0), .Columns(1), 0)
            mm = mm + elm(i, 1) * .Cells(e, 3)
        Next i
    End With
    MASSMOL = mm
    Exit Function
noelm:
    MASSMOL = CVErr(xlErrNA)
End Function

Cette fonction utilise la précédente pour décomposer la molécule en éléments, elle recueille le tableau (qui est affecté à une plage de cellules lorsqu'on utilise la fonction en feuille de calcul). Elle peut alors récupérer les masses unitaires dans la Table et opérer le calcul.

En tapant : =MASSMOL(I3) on obtient directement le renvoi de la masse moléculaire.

Si un élément ne peut être calculé la formule renvoie #N/A.

Nb: La fonction qui renvoie la composition de la molécule ne contrôle pas l'existence des éléments. Il est donc tout à fait possible d'avoir un symbole (dont l'écriture est conforme) mais ne correspondant à aucun élément... Dans un tel cas, l'élément n'étant pas trouvé dans la Table, le calcul de la masse n'aboutira pas.

Cordialement.


20alex10-exemple.xlsm (24.71 Ko)

Merci à tous les deux de vous être occupé de mon problème.

Ca marche du tonnerre !

Pour jpbt84, la formule prend seulement en compte les chiffres 1 à 9, mais pas les nombres, peut-être une petite chose à modifier ?

Pour MFerrand, j'ai l'impression que je dois remercier l'infirmière d'avoir été en retard ou bien vous qui aimait être en avance Ca fonctionne très bien pour toute la table. Vous aller me faire économiser un temps précieux pour ses trois prochaines années !

Merci à tous les deux.

Bonne continuation.

Me signaler si des bogues apparaissent...

Finalement j'ai un petit souci de "compatibilité".

J'ai copié toutes les fonctions personnalisées dans ma feuille Excel qui est composée de plusieurs tableaux.

Pour la fonction permettant de dénombrer chacun des éléments, aucun problème. En revanche je n'arrive pas à faire fonctionner celle qui me permet de calculer la masse. Je pense que la fonction n'arrive pas à retrouver le tableau à utiliser. J'ai essayé de modifier, mais quelque chose m'échappe visiblement. Le tableau est compris entre K4:M4 et K119:M119 en sachant qu'il y a l'entrée Symbol en K3.

Je déteste ma méconnaissance des langages informatique

Si ta table est en K4:M119, tu nommes cette plage Table.

Ou tu la nommes autrement, mais tu modifies en conséquence le nom dans le code de la fonction (il n'apparaît qu'une fois).

C'est bon à force de me d'essayer tout ce qui était imaginable j'ai enfin réussi XD

Merci encore.

Ces deux lignes sont inutiles :

    Dim Table()
    Table = Sheets("Calculs").Range("K4:M119").Value

et conduisent à des erreurs !

réfère à un nom de plage, nommée Table dans le classeur.

Tu affectes le contenu de plage à un tableau nommé Table. Cela ne correspond plus !

Supprime ces deux lignes et nomme la plage.

NB- Il est recommandé de placer les déclarations de variables systématiquement en tête de procédure. Les diluer dans le corps du code exécutable est un moyen de ne pas s'y retrouver par la suite !

Cordialement.

C'est bon, c'est réglé, merci MFerrand

Rechercher des sujets similaires à "extraire nombre lie symbole"