所以我有一个名为化学式的列,用于40,000个条目,我想要做的是计算化学式中包含的元素数量。例如: -
EXACT_MASS FORMULA
626.491026 C40H66O5
275.173274 C13H25NO5
为此,我需要一些会以
的结果返回的公式C H O
40 66 5
13 25 5
所有作为不同元素的单独列和不同条目的行。是否有可以做到这一点的公式?
答案 0 :(得分:4)
你可以制作自己的公式。
使用 ALT 和 F11 打开VBA编辑器并插入新模块。
点击工具,然后点击引用,添加对Microsoft VBScript Regular Expressions 5.5
的引用。
现在添加以下代码:
Public Function FormulaSplit(theFormula As String, theLetter As String) As String
Dim RE As Object
Set RE = CreateObject("VBScript.RegExp")
With RE
.Global = True
.MultiLine = False
.IgnoreCase = False
.Pattern = "[A-Z]{1}[a-z]?"
End With
Dim Matches As Object
Set Matches = RE.Execute(theFormula)
Dim TheCollection As Collection
Set TheCollection = New Collection
Dim i As Integer
Dim Match As Object
For i = (Matches.Count - 1) To 0 Step -1
Set Match = Matches.Item(i)
TheCollection.Add Mid(theFormula, Match.FirstIndex + (Len(Match.Value) + 1)), UCase(Trim(Match.Value))
theFormula = Left(theFormula, Match.FirstIndex)
Next
FormulaSplit = "Not found"
On Error Resume Next
FormulaSplit = TheCollection.Item(UCase(Trim(theLetter)))
On Error GoTo 0
If FormulaSplit = "" Then
FormulaSplit = "1"
End If
Set RE = Nothing
Set Matches = Nothing
Set Match = Nothing
Set TheCollection = Nothing
End Function
用法:
FormulaSplit("C40H66O5", "H")
将返回66。FormulaSplit("C40H66O5", "O")
将返回5. FormulaSplit("C40H66O5", "blah")
会返回“未找到”。您可以直接在工作簿中使用此公式。
答案 1 :(得分:3)
我已经在公式中做了这样做,并提出以下内容:
=IFERROR((MID($C18,FIND(D17,$C18)+1,2))*1,IFERROR((MID($C18,FIND(D17,$C18)+1,1))*1,IFERROR(IF(FIND(D17,$C18)>0,1),0)))
它不是很整洁,如果你的任何元素出现超过99次,就必须进一步扩展 - 我还在我的工作表上使用随机放置,因此标题H,C和O在第17行。我个人会接受Jamie的回答,但只是想尝试一下,看看我是否可以在一个公式中做到这一点,并认为它值得分享,就像另一个观点。
答案 2 :(得分:1)
尽管这有一个优秀的(并且被接受的)VBA解决方案,但我无法在不使用VBA的情况下抵制这样做的挑战。
我之前发布了一个解决方案,但在所有情况下都无法解决。这段新代码应始终有效:
=MAX(
IFERROR(IF(FIND(C$1&ROW($1:$99),$B2),ROW($1:$99),0),0),
IFERROR(IF(FIND(C$1&CHAR(ROW($65:$90)),$B2&"Z"),1,0),0)
)
以数组公式输入: Ctrl + Shift + Enter
<强>输出:强>
未找到时,公式输出0,我只是使用条件格式将零变为灰色。
工作原理
公式的这一部分查找元素,后跟1到99之间的数字。如果找到,则返回原子数。否则,返回0。结果存储在一个数组中:
IFERROR(IF(FIND(C$1&ROW($1:$99),$B2),ROW($1:$99),0),0)
在C13H25NO5的情况下,搜索&#34; C&#34;返回此数组:
{1,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,...,0}
1是第一个数组元素,因为C1是匹配的。 13是第十三个数组元素,这是我们感兴趣的内容。
公式的下一部分查找元素,后跟一个大写字母,表示一个新元素。 (字母A到Z是字符65到90.)如果找到,则返回数字1。否则,返回0。结果存储在一个数组中:
IFERROR(IF(FIND(C$1&CHAR(ROW($65:$90)),$B2&"Z"),1,0),0)
&#34; Z&#34;附加到化学式上,以便在最后一个元素没有数字时找到匹配。 (例如,&#34; H2O&#34;。)没有元素&#34; Z&#34;在周期表中,这不会导致问题。
在C13H25NO5的情况下,搜索&#34; N&#34;返回此数组:
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}
1是数组中的第15个元素。那是因为它找到了字母&#34; NO&#34;,O是字母表的第15个字母。
从每个数组中取最大值可以得到所需的原子数。