VBA 中的数据转换类型错误

Posted

技术标签:

【中文标题】VBA 中的数据转换类型错误【英文标题】:Data Conversion Type Error in VBA 【发布时间】:2016-01-14 19:58:49 【问题描述】:

我正在尝试将 Access VBA 中的表元素作为函数的一部分进行访问。但是,我收到一条错误消息“数据类型转换错误”。我无法弄清楚我在这里做错了什么。

以下子例程填充了我尝试访问的表的元素“HolderTable”。

Sub SampleReadCurve()

Dim rs As Recordset
Dim rs2 As Recordset
Dim iRow As Long, iField As Long
Dim strSQL As String
Dim CurveID As Long
Dim MarkRunID As Long
Dim MaxOfMarkAsofDate As Date
Dim userdate As String

DoCmd.RunSQL "DELETE * FROM HolderTable"
'Clears out the old array from the holder table.

CurveID = 15

Dim I As Integer
Dim x As Date

userdate = InputBox("Please Enter the Date (mm/dd/yyyy)")

x = userdate

For I = 0 To 150

MaxOfMarkAsofDate = x - I


strSQL = "SELECT * FROM VolatilityOutput WHERE CurveID=" & CurveID & " AND MaxOfMarkAsofDate=#" & MaxOfMarkAsofDate & "# ORDER BY MaxOfMarkasOfDate, MaturityDate"

Set rs = CurrentDb.OpenRecordset(strSQL, Type:=dbOpenDynaset, Options:=dbSeeChanges)
Set rs2 = CurrentDb.OpenRecordset("HolderTable")

If rs.RecordCount <> 0 Then

    rs.MoveFirst

    rs.MoveLast

    Dim BucketTermAmt As Long
    Dim BucketTermUnit As String
    Dim BucketDate As Date
    Dim MarkAsOfDate As Date
    Dim InterpRate As Double

    BucketTermAmt = 3
    BucketTermUnit = "m"
    BucketDate = DateAdd(BucketTermUnit, BucketTermAmt, MaxOfMarkAsofDate)
    InterpRate = CurveInterpolateRecordset(rs, BucketDate)
    Debug.Print BucketDate, InterpRate
    rs2.AddNew
    rs2("BucketDate") = BucketDate
    rs2("InterpRate") = InterpRate
    rs2.Update

End If

Next I

Dim vol As Long

vol = EWMA(0.94)

Debug.Print vol


End Sub

这是 EWMA 函数,它给了我错误信息。基本上它只是对 HolderTable 的元素设置一系列简单的操作,这些操作由 SampleReadCurve 子例程中派生的值填充。

Function EWMA(Lambda As Double) As Double

    Dim Price1 As Double, Price2 As Double
    Dim vInterpRate() As Variant
    Dim SumWtdRtn As Double
    Dim I As Long
    Dim m As Double
    Dim rec As Recordset
    Dim BucketTermAmt As Long

    BucketTermAmt = 3

    Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double

m = BucketTermAmt

Set rec = CurrentDb.OpenRecordset("SELECT InterpRate FROM HolderTable")

Do While rec.EOF = False

rec("InterpRate") = vInterpRate

    Price1 = Exp(vInterpRate(I - 1, 1) * (m / 12))

    Price2 = Exp(vInterpRate(I, 1) * (m / 12))

    LogRtn = Log(Price1 / Price2)

    RtnSQ = LogRtn ^ 2

    WT = (1 - Lambda) * Lambda ^ (I - 2)

    WtdRtn = WT * RtnSQ

    SumWtdRtn = SumWtdRtn + WtdRtn

Loop

EWMA = SumWtdRtn ^ (1 / 2)

End Function

HolderTable 有两个字段,BucketDate 和 InterpRate,这两个字段的数据类型都是“短文本”。我在

行收到数据类型转换错误消息
   Price1 = Exp(vInterpRate(I - 1, 1) * (m / 12))

运行时更改数据类型仍会导致相同的错误消息。我做错了什么?

【问题讨论】:

现在我看到了这个,我不太确定 vInterpRate(I - 1, 1) 是否有意义。如果 vInterpRate 是一个函数,它会。但是 vInterpRate 是一个变量。如果你用数字 5 代替 vInterpRate,那就没有意义了。 5(我 - 1, 1)。你需要弄清楚你想在那里做什么,并做出调整。 【参考方案1】:

原文: 你确定它不应该是:

vInterpRate = rec("InterpRate")

而不是

rec("InterpRate") = vInterpRate()

修订:

dim x as integer
Set rec = CurrentDb.OpenRecordset("SELECT InterpRate FROM HolderTable")
x = 0
Do While rec.EOF = False
redim(vInterpRate, x+1) 'need to preserve don't remember if this is default in vba
  vInterpRate(x) = rec("InterpRate")
  x = x + 1
  rec.next
Loop

for i = 1 to x do

  Price1 = Exp(vInterpRate(I - 1, 1) * (m / 12))

  Price2 = Exp(vInterpRate(I, 1) * (m / 12))

  LogRtn = Log(Price1 / Price2)

  RtnSQ = LogRtn ^ 2

  WT = (1 - Lambda) * Lambda ^ (I - 2)

  WtdRtn = WT * RtnSQ

  SumWtdRtn = SumWtdRtn + WtdRtn
next i

代码中可能存在错误,因为我没有 vba 编译器,而且我已经有很长时间没有使用它了,但我认为如果我正在解释什么,这应该为您指明正确的方向您正在寻找正确的。

【讨论】:

对不起,我越看代码越糊涂——你希望这行rec("InterpRate") = vInterpRate 到底能做什么? rec("InterpRate") 不是数组的问题更大。它是记录集的一行的单个值。我会更新我的答案以显示我认为您正在尝试做的事情。 那是我的错,瓦伦。起初我没有意识到您绝对必须为此使用数组。布赖恩的回答应该纠正我的错误。我很抱歉。 是的,正确的写法是:ReDim Preserve vInterpRate(x + 1) 接下来我 - 很抱歉,就像我说的,有一段时间没有工作了

以上是关于VBA 中的数据转换类型错误的主要内容,如果未能解决你的问题,请参考以下文章

vba中如何将单元格内容强制转换为文本类型?

vba中怎么用代码将单元格内容转换为文本类型?

VBA:只有在公共对象模块中定义的用户定义类型才能被强制转换为变体或从变体强制转换或传递给后期绑定函数

将 varchar 值“xxx”转换为数据类型 int 时,函数错误中的光标转换失败

vba怎么存储17位数字

mySQL 存储过程中未知的无效类型转换