如何计算excel中的元素

时间:2014-10-14 10:11:02

标签: excel count

所以我有一个名为化学式的列,用于40,000个条目,我想要做的是计算化学式中包含的元素数量。例如: -

EXACT_MASS  FORMULA
626.491026  C40H66O5
275.173274  C13H25NO5

为此,我需要一些会以

的结果返回的公式
C  H  O
40 66 5
13 25 5

所有作为不同元素的单独列和不同条目的行。是否有可以做到这一点的公式?

3 个答案:

答案 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")会返回“未找到”。

您可以直接在工作簿中使用此公式。 Example of FormulaSplit usage in Workbook

答案 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

<强>输出:

enter image description here

未找到时,公式输出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个字母。

从每个数组中取最大值可以得到所需的原子数。