Excel 的 VBA 中的线性多项式回归
Linest Polynomial Regression in Excel's VBA
我在查找有关在 Excel 的 VBA 子程序中使用 Linest 的信息时遇到问题。我需要 return 一列 x 值(从第 17 行开始的 A 列)和一列 y 值(从第 17 行开始的 G 列)的多项式系数(三阶或四阶)。
我目前使用的代码如下所示,并且有效。
Dim X
X = Application.Evaluate("=linest(g17:g61,A17:A61^{1,2,3})")
Cells(3, 8) = X(1)
Cells(4, 8) = X(2)
Cells(5, 8) = X(3)
Cells(6, 8) = X(4)
本质上,我需要能够使这个子例程处理任何长度的数据。数据总是从第 17 行开始输入。为此,我一直在尝试使用类似于下面所示的代码。
Range(Cells(i, 1), Cells(Cells(Rows.Count, 1).End(xlUp).Row, 1)), Range(Cells(i, 2), Cells(Cells(Rows.Count, 2).End(xlUp).Row, 2))
但是,当我使用与上述相似的范围而不是 G17:G61
时,我会收到类型不匹配错误。我不明白为什么单元格区域与 G17:G61
格式的单元格区域不同。我也尝试使用简单的 Range(Cells(17,1),Cells(61,1))
而不是 A17:A61
.
我也曾尝试使用 "G" & 17:"G" & 61
而不是 G:17:G61
,正如我在浏览时看到的那样,但这似乎也无法解决我的问题。
还有其他更好的功能吗?
请帮忙!
对您问题的第一个评论让您走上了正确的轨道,Application.Evaluate
接受一个字符串(您必须在该字符串中构建对该范围的引用)。使用 Range
和 Cells
的第二种方法创建对 Range
的对象引用,如果您想使用对象引用,那么您可以将引用传递给 [=17= 而不是计算字符串].
这是一个使用原始问题中的单元格引用的示例。
Public Sub TestLinest()
Dim x
Dim i as long
Dim evalString As String
Dim sheetDisplayName As String
Dim polyOrder as string
' this is whatever the name of your sheet containing data:
sheetDisplayName = "Sheet1"
' this gets the index of the last cell in the data range
i = Range(sheetDisplayName & "!A17").End(xlDown).Row
' Obviously change this depending on how many polynomial terms you need
polyOrder = "{1,2,3}"
evalString = "=linest(" & sheetDisplayName & "!E6:E" & i & ", " & sheetDisplayName & "!D6:D" & i & "^" & polyOrder & ")"
x = Application.Evaluate(evalString)
Cells(3, 8) = x(1)
Cells(4, 8) = x(2)
Cells(5, 8) = x(3)
Cells(6, 8) = x(4)
End Sub
您可以看到在范围、sheet 名称和多项式阶数方面有几个神奇的变量需要填写。也许可以扩展此例程以将这些作为参数传递给函数和 return 系数数组?
此时可能值得一提的是,您可以在不使用 VBA 的情况下实现所有这些,这意味着传播sheet 逻辑对您来说仍然更加可见 and/or 您的用户。以下是一些示例函数,可让您在 sheet 上执行所有这些操作,这是其要点:
获取填充单元格的总数(假设这是在 A1 中)
=COUNT(A17:A10000)
将此作为数组公式输入:
=LINEST(INDIRECT("G17:G"&(A1+16)), INDIRECT("A17:A"&(A1+16))^{1,2,3})
显然可以更改此公式中的 16 和 {1,2,3} 以适合您的情况。
我在查找有关在 Excel 的 VBA 子程序中使用 Linest 的信息时遇到问题。我需要 return 一列 x 值(从第 17 行开始的 A 列)和一列 y 值(从第 17 行开始的 G 列)的多项式系数(三阶或四阶)。
我目前使用的代码如下所示,并且有效。
Dim X
X = Application.Evaluate("=linest(g17:g61,A17:A61^{1,2,3})")
Cells(3, 8) = X(1)
Cells(4, 8) = X(2)
Cells(5, 8) = X(3)
Cells(6, 8) = X(4)
本质上,我需要能够使这个子例程处理任何长度的数据。数据总是从第 17 行开始输入。为此,我一直在尝试使用类似于下面所示的代码。
Range(Cells(i, 1), Cells(Cells(Rows.Count, 1).End(xlUp).Row, 1)), Range(Cells(i, 2), Cells(Cells(Rows.Count, 2).End(xlUp).Row, 2))
但是,当我使用与上述相似的范围而不是 G17:G61
时,我会收到类型不匹配错误。我不明白为什么单元格区域与 G17:G61
格式的单元格区域不同。我也尝试使用简单的 Range(Cells(17,1),Cells(61,1))
而不是 A17:A61
.
我也曾尝试使用 "G" & 17:"G" & 61
而不是 G:17:G61
,正如我在浏览时看到的那样,但这似乎也无法解决我的问题。
还有其他更好的功能吗?
请帮忙!
对您问题的第一个评论让您走上了正确的轨道,Application.Evaluate
接受一个字符串(您必须在该字符串中构建对该范围的引用)。使用 Range
和 Cells
的第二种方法创建对 Range
的对象引用,如果您想使用对象引用,那么您可以将引用传递给 [=17= 而不是计算字符串].
这是一个使用原始问题中的单元格引用的示例。
Public Sub TestLinest()
Dim x
Dim i as long
Dim evalString As String
Dim sheetDisplayName As String
Dim polyOrder as string
' this is whatever the name of your sheet containing data:
sheetDisplayName = "Sheet1"
' this gets the index of the last cell in the data range
i = Range(sheetDisplayName & "!A17").End(xlDown).Row
' Obviously change this depending on how many polynomial terms you need
polyOrder = "{1,2,3}"
evalString = "=linest(" & sheetDisplayName & "!E6:E" & i & ", " & sheetDisplayName & "!D6:D" & i & "^" & polyOrder & ")"
x = Application.Evaluate(evalString)
Cells(3, 8) = x(1)
Cells(4, 8) = x(2)
Cells(5, 8) = x(3)
Cells(6, 8) = x(4)
End Sub
您可以看到在范围、sheet 名称和多项式阶数方面有几个神奇的变量需要填写。也许可以扩展此例程以将这些作为参数传递给函数和 return 系数数组?
此时可能值得一提的是,您可以在不使用 VBA 的情况下实现所有这些,这意味着传播sheet 逻辑对您来说仍然更加可见 and/or 您的用户。以下是一些示例函数,可让您在 sheet 上执行所有这些操作,这是其要点:
获取填充单元格的总数(假设这是在 A1 中)
=COUNT(A17:A10000)
将此作为数组公式输入:
=LINEST(INDIRECT("G17:G"&(A1+16)), INDIRECT("A17:A"&(A1+16))^{1,2,3})
显然可以更改此公式中的 16 和 {1,2,3} 以适合您的情况。