【问题标题】:Microsoft Access VBA Run Time Syntax Error for SQL QuerySQL 查询的 Microsoft Access VBA 运行时语法错误
【发布时间】:2021-01-11 15:34:24
【问题描述】:

这是我根据@Parfait 建议更新的代码。它仍然无法正常工作,出现以下错误:

运行时错误“3421” 数据类型转换错误

在下面一行:Set rec = qdef.OpenRecordset(strQry)


Option Compare Database

Private Sub Command0_Click()

    Dim db As DAO.Database
    Dim qdef As DAO.QueryDef
    Dim rec As DAO.Recordset
    Dim olApp As Object
    Dim olItem As Variant
    Dim strQry As String
    Dim aHead(1 To 4) As String
    Dim aRow(1 To 4) As String
    Dim aBody() As String
    Dim lCnt As Long
       
    'Prepared Statement No Data
    
    strQry = "PARAMETERS cboParam TEXT(255);" _
        & " SELECT [Loan ID], [Prior Loan ID], [SRP Rate], [SRP Amount] " _
        & " FROM emailtable " _
        & " WHERE [Seller Name:Refer to As] = [cboParam]"
        
    
    Set db = CurrentDb
    Set qdef = db.CreateQueryDef("", strQry)
    
    ' BIND PARAMETER
    qdef!cboParam = Me.Combo296

    ' OPEN RECORDSET
    Set rec = qdef.OpenRecordset(strQry)
    
    'Create the header row
    aHead(1) = "Loan ID"
    aHead(2) = "Prior Loan ID"
    aHead(3) = "SRP Rate"
    aHead(4) = "SRP Amount"
    
    lCnt = 1
    ReDim aBody(1 To lCnt)
    aBody(lCnt) = "<HTML><body><table border='2'><tr><th>" & Join(aHead, "</th><th>") & "</th></tr>"
    
   
    If Not (rec.BOF And rec.EOF) Then
        Do While Not rec.EOF
            lCnt = lCnt + 1
            ReDim Preserve aBody(1 To lCnt)
            aRow(1) = rec("[Loan ID]")
            aRow(2) = rec("[Prior Loan ID]")
            aRow(3) = rec("[SRP Rate]")
            aRow(4) = rec("[SRP Amount]")
            aBody(lCnt) = "<tr><td>" & Join(aRow, "</td><td>") & "</td></tr>"
            rec.MoveNext
        Loop
    End If
    
    aBody(lCnt) = aBody(lCnt) & "</table></body></html>"
                   
    Set objOutlook = CreateObject("Outlook.Application")
       Set objMail = objOutlook.CreateItem(0)
    With objMail
       .Display   'To display message
       .To = Me.Combo88
       .cc = Me.Combo282
       .Subject = "*SECURE* " & Me.Combo296 & " Refund Request (" & Me.Combo212 & " " & Me.Combo284 & ")"
       .HTMLBody = "<p><font face=""calibri"" style=""font-size:11pt;"">Greetings,</p>" _
       & "<p>We recently acquired loans from " & Me.Combo296 & ", some of which have paid in full and meet the criteria for early prepayment defined in the governing documents. We are requesting a refund of the SRP amount detailed on the attached list.</p>" _
       & "<p>Please wire funds to the following instructions:</p>" _
       & "<ul>Bank Name: My Bank</ul>" _
       & "<ul>ABA: 1111111</ul>" _
       & "<ul>Credit To: ABC Mortgage</ul>" _
       & "<ul>Acct: 11111111111</ul>" _
       & "<ul>Description: " & Combo296 & " EPO SRP Refund</ul>" _
       & "<p>Thank you for the opportunity to service loans from " & Me.Combo296 & "!  We appreciate your partnership.</p>" _
       & "<p>If you have any questions, please contact your Relationship Manager, " & Me.Combo336 & " (Cc'd).</p>" _
       & "<p><br>Sincerely,</br>" _
       & "<br>Acquisitions</br>" _
       & "<br>acquisitions@us.com</br></p>"
       
    End With
    
    rec.Close
    Set rec = Nothing: Set qdef = Nothing: Set db = Nothing

End Sub

任何帮助将不胜感激。

【问题讨论】:

  • 你在哪里使用过aBody(lCnt)?它没有放在 HTMLBody 中。
  • 对于第二个错误,不要在名称的字符串文字中包含括号:aRow(1) = rec("Loan ID")aRow(1) = rec![Loan ID]
  • 这是我从某处的帖子中获得并尝试复制的代码。我很好不需要它,但我正在学习,所以不确定。
  • 请参阅上面的评论:名称的字符串文字中不要包含括号

标签: vba ms-access


【解决方案1】:

避免将 VBA 数据连接到 SQL 甚至 HTML 字符串。相反,请考虑SQL parameterization 的行业标准。

Dim db DAO.Database, qdef As DAO.QueryDef, rec AS DAO.Recordset

' PREPARED STATEMENT (NO DATA)
strQry = "PARAMETERS cboParam TEXT(255);" _
        & " SELECT [Loan ID], [Prior Loan ID], [SRP Rate], [SRP Amount] " _
        & " FROM emailtable " _
        & " WHERE [Seller Name:Refer to As] = [cboParam]" 

Set db = CurrentDb 
Set qdef = db.CreateQueryDef("", strQry)

' BIND PARAMETER
qdef!cboParam = Me.Combo296 

' OPEN RECORDSET
Set rec = qdef.OpenRecordset()

... ' REST OF CODE USING rec

rec.Close
Set rec = Nothing: Set qdef = Nothing: Set db = Nothing

另外,考虑将电子邮件 HTML 标记保存为表格中的文本或表单上的文本框,并用组合框值替换占位符:

.HTMLBody = Replace(Replace(Me.EmailMessage, "placeholder1", Me.Combo296), 
                    "placeholder2", Me.Combo336)

【讨论】:

  • 谢谢,我试试看。这是我第一次深入了解 VBA。我在互联网上找到了一些代码,我正在尝试复制以满足我的需要。我一定会尝试参数化。
  • .HTMLBody 建议中,如果组合框已经列在语句中,我不明白占位符的用途。
  • 如何包含我的原始代码,该代码将根据我在原始代码中的内容生成电子邮件的表格代码?我假设我需要的代码将在打开记录集之后和 rec.close 之前出现?
  • 我想发布我修改后的代码供您查看。我现在收到数据类型转换错误。我觉得我的代码可能不合适。如何发布我修改后的代码供您审核?
  • 好的。我不确定它是否相关。我尝试按照您的建议在代码块之间插入表格代码,但出现错误。我只是想确保我正确插入它。如果是这样,那么我可以单独解决转换错误。我将使用新代码编辑我的原始帖子。
【解决方案2】:

我猜(根据您的照片)您的[Seller Name:Refer to as] 列的数据类型应该是string?在这种情况下,您的查询缺少引号来表示比较中的字符串值:

'Create each body row
strQry = "Select * from emailtable where [Seller Name:Refer to As] = """ & Me.Combo296 & """"
Set db = CurrentDb
Set rec = CurrentDb.OpenRecordset(strQry)

【讨论】:

  • 如果组合框值包含引号,则可能会中断。
猜你喜欢
  • 2015-08-15
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多