Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Excel计算分子量_Excel_Excel Formula_Vba - Fatal编程技术网

用Excel计算分子量

用Excel计算分子量,excel,excel-formula,vba,Excel,Excel Formula,Vba,我在这里遇到了一些问题。我有一个包含9000种有机化合物的电子表格,我正试图计算它们的分子量 通常情况下,这很简单:分子式中元素的数量乘以元素的分子量,然后把它们加起来。问题是,电子表格将分子式列为字符串 例如,“乙腈”的分子量列在列中为:C2H3N 我想做的是编写一个函数,扫描该单元格的内容,并说,“好的,每次我遇到文本内容时,请看紧跟其后的数字,直到你找到另一个文本,然后停止。然后,取该数字乘以该元素的分子量。”(稍后我会处理分子量的总和,因为我觉得这是最简单的部分)。 这是否可能与Exce

我在这里遇到了一些问题。我有一个包含9000种有机化合物的电子表格,我正试图计算它们的分子量

通常情况下,这很简单:分子式中元素的数量乘以元素的分子量,然后把它们加起来。问题是,电子表格将分子式列为字符串

例如,“乙腈”的分子量列在列中为:C2H3N

我想做的是编写一个函数,扫描该单元格的内容,并说,“好的,每次我遇到文本内容时,请看紧跟其后的数字,直到你找到另一个文本,然后停止。然后,取该数字乘以该元素的分子量。”(稍后我会处理分子量的总和,因为我觉得这是最简单的部分)。


这是否可能与Excel的内置函数有关,或者我是否必须使用VBA(我确实没有使用VBA的经验)。如果您有任何帮助,我们将不胜感激。

而您的请求通过一些非常复杂的(和CPU密集型的)操作几乎是可能的只使用本机Excel函数、VBA用户定义函数或UDF的公式更合适。我不是化学家,请原谅我在提供的单个样本中添加的内容,因为它们是从.TBH无耻地偷来的,我甚至不确定我是否有一半的术语是正确的

步骤1-创建分子量表并命名

您需要某种形式的交叉引用,才能从元素的周期符号中检索分子量。以下是我搜集的内容。我将在下面的示例工作簿中提供指向完整数据表的链接

在名为“元素数据”的工作表上,转到
公式► 定义名称► 命名管理器
,并为交叉引用矩阵指定一个已定义的名称

这里我使用了一个公式(
=OFFSET('Element Data'!$a$1,0,0,COUNTA('Element Data'!$a:$a),6)
)来定义范围,但是数据的大小是相当静态的,所以单元格范围引用应该足够了

步骤2-添加用户定义函数的代码

点击Alt+F11,当VBE打开时,立即使用下拉菜单插入► 模块(Alt+I+M)。将以下内容粘贴到名为Book1-Module1(代码)的新窗格中

其中只有第一个问题与您发布的问题相关。后两个问题使用Unicode下标字符对化合物的化学式进行样式化,并颠倒过程

粘贴完成后,点击Alt+Q返回工作表。这些自定义函数现在可以像任何原生Excel函数一样在工作簿中使用。语法非常简单

=udf_分子量()

对于您的样品化合物(在上面的数据图像中),这将是

=udf分子量(B2)

…或

=udf分子量(“C2H3N”)

对于9000多个这样的函数,我怀疑您会使用前一种方法。根据需要填写。虽然此UDF比使用
间接
和其他本机工作表函数的卷积数组公式要高效得多,但它们并不是神奇的。在提交9000+之前,请在几百行上测试公式,这样您就知道会发生什么。ot如果你选择使用她的两个UDF,它们的工作方式基本相同

简要说明:

我猜你说的“变量声明”实际上是指“变量赋值”。我倾向于编写相当紧凑的代码,并且通过将变量的零位用冒号堆叠起来,将其他人可能放入最多4行代码中的内容放在一行中。我将此

sTMP = sCMPND
dAWEIGHT = 0
sSB = "0"
sEL = vbNullString
…在这方面

sTMP = sCMPND: dAWEIGHT = 0: sSB = "0": sEL = vbNullString
在重新进入循环之前需要重置变量,但这是一项平凡的任务,所以我只需将所有四个赋值塞进一行


两个
Do While…循环
遍历一个字符一个字符地传递到函数中的字符串。内部循环专门处理数字。每次遍历循环都会从左侧截断字符串,将其缩短一个或多个字符,并将这些字符作为元素的符号或n进行收集与在有机化合物中的使用有关的数字。最终没有任何东西可以截断(长度=0),这就是
CBool(Len(sTMP))
变为False,循环结束。内部循环的执行方式大致相同,但收集数字,直到它达到无长度或字母字符为止。在元素之后(和一个可能的数字修饰符)已收集,化合物中该元素的分子量根据分子量表用VLOOKUP计算并添加到一个不断增长的数字中。当所有元素及其相关数字已收集并添加到总计中时,总计作为函数的结果返回。

@Jeeped有一个很棒的VBA解决方案。我在上发布了一个相关问题的非VBA解决方案。很容易扩展到这个问题

将每个元素放在一个单独的柱中,其原子质量在其上方

此公式将计算分子中每个原子的重量:

=B$1*
 MAX(IFERROR(IF(FIND(B$2&ROW($2:$100),$A3),ROW($2:$100),0),0),
     IFERROR(IF(FIND(B$2&CHAR(ROW($66:$91)),$A3&"Z"),1,0),0)
 )
按数组公式输入:Ctrl+Shift+Enter

总分子量就是这些重量的总和

示例:


是的,我发现了一些类似的东西,但它并没有完全回答我的问题。我会到处寻找。如果我找不到一个好方法,我可能不得不强制所有9000列。在我的情况下,我需要“C”来表示int
=B$1*
 MAX(IFERROR(IF(FIND(B$2&ROW($2:$100),$A3),ROW($2:$100),0),0),
     IFERROR(IF(FIND(B$2&CHAR(ROW($66:$91)),$A3&"Z"),1,0),0)
 )