【问题标题】:How to sum chemical compounds using Periodic Table of elements (chemistry class)如何使用元素周期表对化合物求和(化学课)
【发布时间】:2021-05-11 13:02:57
【问题描述】:

我有两张不同的桌子;一个是元素周期表 (PSE) 列 A-C 及其各自的原子质量,另一个表 E-F 列与我需要计算/总质量但使用第一个表作为来源的化合物一致。因此,例如,化合物 H2O(水)的总含量为 18 g/mol(H=1x2,O=16)......但是有像 C6H6Zn 这样的化合物或前面有更多数字,这让我很难理解如何计算/总结它们。在 H 列中是我需要获得的实际值..

我希望有人能以某种方式帮助我,至少任何形式的输入..

【问题讨论】:

  • 我会先分离元素,一旦你有两个或多个元素,带有 match() 或 vlookup() 的 index() 可以得到质量,然后用乘数对结果求和如所须。一个具有挑战性的练习,我将逐步进行......
  • 快速提问 - 您将如何输入公式 - 只需列出成分或像化学家一样编写公式。我的意思是例如乙醇 - 在您的列表中是 c2h5oh 还是 c2h60?我认为你会遇到问题的地方是单个元素,除非你列出隐含的“1”。例如 hcn - 你不能可靠地对数字进行拆分。您可能必须使用例如“.”来拆分元素。所以 h.c.n 和 c2.h5.o.h 给自己一个解析元素的机会。这也将帮助您区分歧义,例如 p.b 与 Pb 不同。一旦你有一个好的命名法应该是 straigfwd
  • @JohnnieL 好点,但我会使用你提到的“分子方法”或 C2H60 ......我需要它准确的整数。我会看看我能做什么。
  • @SolarMike 谢谢,看看我能用公式做什么..

标签: excel vba excel-formula excel-2016


【解决方案1】:

正如@Solar Mike 所指出的,最好将问题分解为多个部分——分而治之!下面的代码执行 2 个不同的步骤:1) 将化合物拆分为单独的元素和数量(使用我找到的函数 here)和 2) 计算化合物中所有元素的总重量。

代码假定您的数据位于工作簿的 sheet1 上,并且布局与您的图像显示的完全相同。它依赖于您在B 列中的元素列表以及它们在C 列中的质量(VLOOKUP() 范围来自B2:C120 - 您可能需要调整它)并且您的化合物从单元格@987654325 中列出@ 下。此外,代码要求列 G 到(右侧未知 - 取决于复合的复杂性)在代码执行期间可用,之后将被清除。

我相信会有比这更优雅的解决方案,但它确实适用于我的测试数据。请把下面的所有代码复制到一个标准模块(包括函数)中,让我知道它是怎么回事。

Option Explicit
Sub GetWeights()
Dim LastRow As Long, LastCol As Long, c As Range
Dim i As Integer, j As String, k As Double, weight As Double

'***Part 1 - split the formulas into separate columns
LastRow = Sheet1.Cells(Rows.Count, 5).End(xlUp).Row

With Sheet1.Range("F2:F" & LastRow)
    .FormulaR1C1 = "=SepChem(RC5)"
    .Value = .Value
End With

Application.DisplayAlerts = False
Sheet1.Range("F2:F" & LastRow).Select
    Selection.TextToColumns Destination:=Range("F2"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Space:=True, FieldInfo _
        :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1)), _
        TrailingMinusNumbers:=True
Application.DisplayAlerts = True

'***Part 2 - get the weights
LastRow = Sheet1.Cells(Rows.Count, 5).End(xlUp).Row
On Error GoTo Skip
For Each c In Sheet1.Range("F2:F" & LastRow)
If IsEmpty(c.Value) = True Or c.Value = "-" Then GoTo Skip
LastCol = c.End(xlToRight).Column - 1

    For i = c.Column To LastCol Step 2
        
        j = Cells(c.Row, i).Value
        
            k = Application.VLookup(j, Sheet1.Range("B2:C120"), 2, False) _
            * Cells(c.Row, i).Offset(0, 1).Value
            
            weight = weight + k
    
    Next i
    
    c.Value = weight
    weight = 0
Skip:
Next c

With Sheet1
    LastCol = .Range("A1").SpecialCells(xlCellTypeLastCell).Column
End With
Sheet1.Range(Cells(2, 7), Cells(LastRow, LastCol)).ClearContents

End Sub

Public Function SepChem(ByVal s As String) As String
Static RegEx As Object

If RegEx Is Nothing Then
    Set RegEx = CreateObject("VBScript.RegExp")
    RegEx.Global = True
End If

With RegEx
    .Pattern = "([a-zA-Z])(?=[A-Z]|$)"
    s = .Replace(s, "$11")
    .Pattern = "([a-zA-Z])(?=\d)|(\d)(?=[A-Z])"
    SepChem = .Replace(s, "$1$2 ")
End With

End Function

【讨论】:

  • 我将在接下来的几个小时内对其进行测试,但似乎它会完成它的工作......我会写回来。
  • 我检查了它,它真的很棒!但是我意识到一件事,例如,当我有“-”或者说空/空白字符串时,代码就在那一刻之前停止,并且就在我可以看到分离的化合物的列上(这很棒)。如果没有“-”或任何字符串,那么它可以正常工作,并进行求和。问题,是否有可能包含一行代码,即使我有非周期性符号,我也可以在其中运行代码?例如破折号“-”?顺便说一句,thnx 很多。无论如何,这已经足够了。
  • 嗯,为什么我实际上得到了额外的列?有没有办法在看到并继续代码时“跳过”破折号?它实际上给了我一个错误... k = Application.VLookup(j, Sheet1.Range("B2:C66"), 2, False) _ * Cells(c.Row, i).Offset(0, 1)。价值
  • 哦,天哪,我的意思不是元素中的“-”,而是数据范围中的空字段,因为有些化合物具有唯一的名称但不是精确的摩尔质量,所以在这种情况下在字段中将是“-”。参见下面的示例:A1 列 = ARAS ; B1 栏 = “-” A2 栏 = 水; B2 列 = H2O
  • OK 现在试试。如果单元格为空白或包含“-”,代码现在将跳过该单元格。
猜你喜欢
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多