创建日期列表并避免未设置变量(VBA错误91)

创建日期列表并避免未设置变量(VBA错误91),vba,excel,Vba,Excel,我有五张表中关于某些股票的财务数据,我试图创建一个函数,计算给定范围内的指数移动平均数 [第(1)列=日期;第(2)列=收盘价] 此函数的参数是计算EMA所考虑的天数,以及一个整数kol以并排计算多个列上的多个EMA(暂时不使用)。以下是我目前的代码: Public Function MME(Lmme As Double, kol As Long) Dim Cmme As Range Dim Todate, rcell As Range Dim alpha, period, Udate, i,

我有五张表中关于某些股票的财务数据,我试图创建一个函数,计算给定范围内的指数移动平均数

[第(1)列=日期;第(2)列=收盘价]

此函数的参数是计算EMA所考虑的天数,以及一个整数
kol
以并排计算多个列上的多个EMA(暂时不使用)。以下是我目前的代码:

Public Function MME(Lmme As Double, kol As Long)

Dim Cmme As Range
Dim Todate, rcell As Range
Dim alpha, period, Udate, i, j, k As Long
Dim Ustock As String
Dim wsDest As Worksheet

Udate = ThisWorkbook.Worksheets("UserForm").Range("B2").Value
period = ThisWorkbook.Worksheets("UserForm").Range("B3").Value
Ustock = ThisWorkbook.Worksheets("UserForm").Range("B4").Value

' MsgBox (Udate)

Set wsDest = ThisWorkbook.Sheets(Ustock)
wsDest.Activate
With wsDest.Range("A2:A392")
  Set Todate = Cells.Find(What:=Udate, _
                     LookIn:=xlValues, _
                     LookAt:=xlWhole, _
                     SearchOrder:=xlByRows, _
                     SearchDirection:=xlNext, _
                     MatchCase:=False)
  If Todate Is Nothing Then
    MsgBox ("todate wasn't found")
  Else
  End If
End With
i = Todate.Row
j = i + period
k = i - Lmme
Set Cmme = Range(Cells(i, 9 + kol), Cells(j, 9 + kol))
alpha = (2 / (Lmme + 1))
With Cmme
  For Each rcell In Cmme
    If rcell.Row <> i Then
          rcell.Formula = "=B" & rcell.Row & "*" & alpha & "+I" & rcell.Row - 1 & "*" & 1 - alpha & ""\
    Else: rcell.Formula = "=AVERAGE(B" & k & ":B" & i & " )   "
    End If
  Next rcell
End With
End Function
公共功能MME(Lmme为双倍,kol为长)
模糊坐标测量机
模糊Todate,rcell作为范围
暗α,周期,Udate,i,j,k等于长
把乌斯托克当作绳子
将wsDest设置为工作表
Udate=ThisWorkbook.Worksheets(“UserForm”).Range(“B2”).Value
句点=此工作簿。工作表(“用户表单”)。范围(“B3”)。值
Ustock=ThisWorkbook.Worksheets(“用户表单”).Range(“B4”).Value
'MsgBox(Udate)
设置wsDest=ThisWorkbook.Sheets(Ustock)
wsDest.Activate
带wsDest.范围(“A2:A392”)
设置Todate=Cells.Find(What:=Udate_
LookIn:=xlValues_
看:=xlother_
搜索顺序:=xlByRows_
SearchDirection:=xlNext_
匹配案例:=假)
如果Todate算不了什么
MsgBox(“未找到todate”)
其他的
如果结束
以
i=托德。罗
j=i+周期
k=i-Lmme
设置Cmme=范围(单元格(i,9+kol),单元格(j,9+kol))
α=(2/(Lmme+1))
使用Cmme
对于Cmme中的每个RCEL
如果是我的话,我会排在第一排
rcell.Formula=“=B”&rcell.Row&“*”&alpha&“+I”&rcell.Row-1&“*”&1-alpha&“\
Else:rcell.Formula=“=平均值(B”&k&“:B”&i&”)
如果结束
下一个rcell
以
端函数
我在一张单独的表单上创建了一个列表,允许用户选择2008年的日期,另一个列表允许用户选择股票。所以我确实设置了新的变量来实现这个技巧,但它不起作用

Usaction
USdate
Uperiod
是存储用户选择的值的名称范围。但是我在
set=period
上得到了“error 91 or object required”

我真的希望EMA只计算特定时期,从选定日期开始。 编辑:我用我拥有的最新版本更新了代码。我在endate上仍然有一个错误91 EDIT2:代码已更新。我不明白为什么找不到日期。在表单UserForm上,用户选择的日期为“B2”(
USdate
)。它的格式是通用的,但是如果在find函数中使用CDate,它应该被视为一个日期,对吗?我尝试了日期格式,它没有改变任何东西

编辑3:多亏了布兰尼斯拉夫,我把每一个日期都改成了通用格式,使这个发现很有效。既然查找工作正常,是否要使用日期格式使其工作?这样用户就可以看到实际日期,而不是关联的整数


另一个问题:如何绕过单元格。公式直接在vba中运行,并使其在代码运行后在excel的公式栏中显示公式,但SMAs和EMAs操作的结果在范围内除外?

ToDate
已经是一个范围

Set Endate = Todate.Row + period
另外,在到达该点之前,您可以使用
.Find()
设置
ToDate
。由于完全可能有人输入无效日期或您没有数据的日期,我强烈建议添加:

if ToDate is Nothing then
  'do some date not found stuff here
else
  'do your date found stuff here
End If

您还可以考虑将<代码>查找:= xLFrase到<代码>查找:= xLValue<代码>,因为我相信您正在寻找一个单元格值,而不是一个单元格公式。

谢谢您抽出时间。我更新了我使用的代码,因为我现在使用的是列表,所以用户不会出错。我已经改变了外观:=xlvalues实际上我认为我应该去掉endate,用Todate做参考,不是吗?类似于
Cmme=Range(Todate.Offset(,9+kol),Todate.Offset(period,9+kol))
但当您到达
Endate
上的错误行时,它仍然会导致错误,什么是
Todate
?在本地、即时或监视窗口中查看。正如@freeman所说,用简单的
if-Else
语句捕捉“Todate”是否为
Nothing
是一种很好的做法。另外,还要注意
语句中的
和点的位置
。例如,在
Set Endate=Cells(Todate.Row+period,1)
中,
单元格
没有点,这意味着它将使用默认的
ActiveSheet
父项,而不必使用
wsDest
。另外,我认为您希望
Cmme=…
成为一个范围,您需要使用
setcmme=…
来实现这一点。接下来,当声明变量时,您需要将
作为
放在每个变量后面,以便正确地声明它。你是对的,我没有这样做,因为我教他们不会有任何问题,因为用户必须从“有效日期”列表中选择。我更新了上面的代码,所以当我得到msgbox(todate not found)时,查找函数似乎有问题。如果
Udate
的数据类型和
范围(“A1:A392”)
中的值不同,可能会有问题。例如,
Udate=42090(2015年3月27日为整数,请尝试使用excel=Today()并将其设置为通用格式)
但范围中的值是字符串,即“27.03.2015”。这样,就找不到查找的值。这不是我的观点。42090是一个日期,只写为整数。您无法在“27.03.2015”、“26.03.2015”等值中找到42090。关键是区别。确保您正在查找的值(
Udate
)可以在范围内找到。不要被格式化愚弄。在单步执行子任务时检查实际值。将鼠标悬停在实际值上或使用调试窗口。