Jul*_*ian 6 excel vba excel-vba excel-formula chemistry
如果已经提出并回答了这个问题,我很抱歉,但我找不到满意的答案.
我有一个化学公式列表,按顺序包括:C,H,N和O.我想在每个字母之后提取数字.问题是并非所有公式都包含N.但是,所有公式都包含C,H和O. 并且数字可以是单数,双数或(仅在H的情况下)三位数.
因此数据看起来像这样:
我想在单独的列中列出列表的每个元素编号.所以在第一个例子中它将是:
20 37 1 5
Run Code Online (Sandbox Code Playgroud)
我一直在努力:
=IFERROR(MID(LEFT(A2,FIND("H",A2)-1),FIND("C",A2)+1,LEN(A2)),"")
Run Code Online (Sandbox Code Playgroud)
分离出C#.然而,在此之后我被卡住了,因为H#侧面是O或N.
是否有excel公式或VBA可以做到这一点?
Pᴇʜ*_*Pᴇʜ 10
这对于正则表达式(正则表达式)来说是一个很好的任务.由于VBA不支持开箱即用的正则表达式,因此我们需要首先引用Windows库.
将此功能添加到模块
Option Explicit
Public Function ChemRegex(ChemFormula As String, Element As String) As Long
Dim strPattern As String
strPattern = "([CNHO])([0-9]*)"
'this pattern is limited to the elements C, N, H and O only.
Dim regEx As New RegExp
Dim Matches As MatchCollection, m As Match
If strPattern <> "" Then
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With
Set Matches = regEx.Execute(ChemFormula)
For Each m In Matches
If m.SubMatches(0) = Element Then
ChemRegex = IIf(Not m.SubMatches(1) = vbNullString, m.SubMatches(1), 1)
'this IIF ensures that in CH4O the C and O are count as 1
Exit For
End If
Next m
End If
End Function
Run Code Online (Sandbox Code Playgroud)在单元格公式中使用这样的函数
CH3OH或CH2COOH请注意,上面的代码不能计算CH3OH元素出现多次的情况.然后只有第一个H3是计数,最后省略.
如果您还需要以类似CH3OH或CH2COOH(并总结元素的出现)的格式识别公式,那么您需要更改代码以识别这些...
If m.SubMatches(0) = Element Then
ChemRegex = ChemRegex + IIf(Not m.SubMatches(1) = vbNullString, m.SubMatches(1), 1)
'Exit For needs to be removed.
End If
Run Code Online (Sandbox Code Playgroud)
NaOH或CaCl2除了多次出现的元素更改之外,还可以使用以下模式:
strPattern = "([A-Z][a-z]?)([0-9]*)" 'https://regex101.com/r/nNv8W6/2
Run Code Online (Sandbox Code Playgroud)
CaCl2工作但不是cacl2或CACL2.请注意,这不能证明这些字母组合是否是元素周期表的现有元素.所以这也将承认例如.Xx2Zz5Q作为虚构的元素Xx = 2,Zz = 5和Q = 1.
要仅接受元素周期表中存在的组合,请使用以下模式:
strPattern = "([A][cglmrstu]|[B][aehikr]?|[C][adeflmnorsu]?|[D][bsy]|[E][rsu]|[F][elmr]?|[G][ade]|[H][efgos]?|[I][nr]?|[K][r]?|[L][airuv]|[M][cdgnot]|[N][abdehiop]?|[O][gs]?|[P][abdmortu]?|[R][abefghnu]|[S][bcegimnr]?|[T][abcehilms]|[U]|[V]|[W]|[X][e]|[Y][b]?|[Z][nr])([0-9]*)"
'https://regex101.com/r/Hlzta2/3
'This pattern includes all 118 elements up to today.
'If new elements are found/generated by scientist they need to be added to the pattern.
Run Code Online (Sandbox Code Playgroud)