【问题标题】:Checking Null Value in Access VBA recordset throws null exception?检查 Access VBA 记录集中的空值会引发空异常?
【发布时间】:2021-08-30 17:42:44
【问题描述】:

我已经尝试了各种不同的方法,昨天还可以,所以我真的不知道发生了什么变化。

我将电子表格导入 Access 应用程序中的临时表。然后我将它设置为 dao.recordset,并开始循环。我检查 ID 是否为空,如果不是,则检查字段的值,并根据需要进行更新。在我输入 null 的那一刻,我得到一个系统错误“94 - null 的使用无效”

它不提供调试,但我在整个代码中都有调试,所以我可以看到它失败的地方。当我做这个检查时它失败了: If IsNull(rstImportCList("columnx")) = False Then

我试过 nz(rstImportCList("columnx"),"") "" 我试过 rstImportCList("columnx") 不为空,还有我能想到的一切。为什么应该防止这个错误的检查,导致这个错误?

编辑:

这是我声明记录集的开始,我无法通过记录集字段做任何事情。

Dim db As DAO.Database
Dim rstImportCList As DAO.Recordset
Dim RSsql As String
Set db = CurrentDb()
    RSsql = "Select * from tblTempImportCList"
    Set rstImportCList = db.OpenRecordset(RSsql)
    If rstImportCList.EOF Then Exit Sub
            
    Do While Not rstImportCList.EOF

我是否尝试检查

IsNull(rstImportCList("xyz").Value) = False 

nz(rstImportCList("xyz").Value,"") <> ""

dim x as string 
x = rstImportCList!xyz.value

我得到同样的错误 94 无效使用 null。

知道这是为什么吗? --用更多代码编辑。

我花了一些时间来了解代码的开头和每个部分的一些部分,所以我可以将其通用化,看看是否有人可以提供帮助。这是我正在做的事情。 Code1 和 Code2 部分似乎不是问题。有时它在是/否列中的空值上失败(我只是在寻找 Y,但值为空),有时在注释为空时失败。它不一致,这就是为什么我很难确定这个问题。

Private Sub cmdImportList_Click()
On Error GoTo cmdImportExcel_Click_err:
Dim fdObj As FileDialog
Set fdObj = Application.FileDialog(msoFileDialogFilePicker)
Dim varfile As Variant
Dim importCT As Integer
Dim dbu As DAO.Database
Dim cBadXVal, cBadYVal As Integer
Dim preNotes As String
Dim RSsql As String
Dim uNotesql, uVal1sql, uVal2sql As String
Dim db As DAO.Database
Dim rstImportCList As DAO.Recordset
Dim CheckB4Import As Integer


CheckB4Import = MsgBox("Are you SURE the sheet you are importing has the following column names in the same order:" & vbCrLf & vbCrLf & _
"IDName/ First/ Mid/ Last/ Sfx/ Age/ Telephone/ Code1/ Code2/ YN1/ YN2/ NY3/ Notes/ AsYN1edTo" & vbCrLf & vbCrLf & _
"AND that there are NO empty rows or empty columns?" & vbCrLf & vbCrLf & _
"Click OK to proceed, Click CANCEL to go double-check your CallSheet before importing.", vbOKCancel, "WITH GREAT POWER COMES GREAT RESPONSIBILITY TO QC DATA")

If CheckB4Import = vbOK Then

    CurrentDb.Execute "DELETE * FROM tblTempImportCList", dbFailOnError
    With fdObj
        'CAN ONLY SELECT 1 FILE
        .allowmultiselect = False
        .Filters.Clear
        .Filters.Add "Excel 2007+", "*.xlsx"
        .Title = "Please select the completed list to import:"
        .Show
    
        If .SelectedItems.Count = 1 Then
            varfile = .SelectedItems(1)
            
            DoCmd.TransferSpreadsheet acImport, , "tblTempImportCList", varfile, True, "Sheet1!"
            
            cBadXVal = DLookup("BadXCount", "qryImpCheckBadXVal")
            Debug.Print "cBadXVal - " & cBadXVal
            If cBadXVal <> 0 Then
                DoCmd.OpenForm "frmImportError", acNormal
                Forms!frmImportError.Form.lblErrorMsg.Caption = _
                    "Oh No! Your list import failed!" & vbCrLf & _
                    cBadXVal & " X values are not valid." & vbCrLf & _
                    "Don't worry. You can fix your sheet and re-import!" & vbCrLf & _
                    "Would you like to open the documentation for the valid codes" & vbCrLf & _
                    "Or are you all set?"
            End If
            
            cBadYVal = DLookup("BadYCount", "qryImpCheckBadYVal")
            Debug.Print "cBadYVal - " & cBadYVal
            If cBadYVal <> 0 Then
                DoCmd.OpenForm "frmImportError", acNormal
                Forms!frmImportError.Form.lblErrorMsg.Caption = _
                    "Oh No! Your list import failed!" & vbCrLf & _
                    cBadYVal & " YN1 values are not valid." & vbCrLf & _
                    "Don't worry. You can fix your sheet and re-import!" & vbCrLf & _
                    "Would you like to open the documentation for the valid codes" & vbCrLf & _
                    "Or are you all set?"
            Exit Sub
            End If
            
        Else
            MsgBox "No file was selected. Try again!", vbCritical, "Uh-oh Spaghettios!"
        End If
    End With
    
 
'PASSED CHECKS
    Set db = CurrentDb()
    RSsql = "Select * from tblTempImportCList"
    Set rstImportCList = db.OpenRecordset(RSsql)
    If rstImportCList.EOF Then Exit Sub
            Debug.Print "got here"
    Do While Not rstImportCList.EOF
    
        Debug.Print "Start Processing: " & Nz(rstImportCList("IDName").Value, "")
        
        'GET NOTES ALREADY ON RECORD
        If Nz(rstImportCList("IDName").Value, "") <> "" Then
            Debug.Print "got past if IDName is not null"
            If Nz(rstImportCList("Notes").Value, "") <> "" Then
            Debug.Print "got past if notes is not null"
                preNotes = Replace(Nz(DLookup("Notes", "tblVFileImport", "IDName = " & rstImportCList("IDName").Value), ""), """", "")
                'UPDATE NOTES
                If Nz(preNotes, "") <> "" Then
                    uNotesql = "Update tblVFileImport SET tblVFileImport.Notes = '" & preNotes & "; " & Replace(Nz(rstImportCList("Notes").Value, ""), """", "") & "' " & _
                    "WHERE tblVFileImport.IDName = " & rstImportCList("IDName").Value
                    'debug.print "Notes"
                    'debug.print "uNotesql - " & uNotesql
                Else
                    uNotesql = "Update tblVFileImport SET tblVFileImport.Notes = '" & Replace(Nz(rstImportCList("Notes").Value, ""), """", "") & "' " & _
                    "WHERE tblVFileImport.IDName = " & rstImportCList("IDName").Value
                End If
                RunMySql (uNotesql)
                'DoCmd.RunSQL (uNotesql), dbFailOnError
            End If
        
            
            If Nz(rstImportCList("YN1").Value, "") = "Y" Then
                'UPDATE YN1
                uYN1sql = "Update tblVFileImport SET tblVFileImport.YN1 = '" & rstImportCList("YN1") & "', tblVFileImport.callprocessed = 'Y' " & _
                "WHERE tblVFileImport.IDName = " & rstImportCList("IDName")
                Debug.Print "YN1 = Y or y"
                Debug.Print "uYN1sql - " & uYN1sql
                RunMySql (uYN1sql)
                'DoCmd.RunSQL (uYN1sql), dbFailOnError
            End If

            If Nz(rstImportCList("YN2").Value, "") = "Y" Then
                'UPDATE YN2
                uYN2sql = "Update tblVFileImport SET tblVFileImport.YN2 = '" & rstImportCList("YN2") & "', tblVFileImport.callprocessed = 'Y' " & _
                "WHERE tblVFileImport.IDName = " & rstImportCList("IDName")
                Debug.Print "YN2 = Y or y"
                Debug.Print "uYN2sql - " & uYN2sql
                RunMySql (uYN2sql)
                'DoCmd.RunSQL (uYN2sql), dbFailOnError
            End If

'START Code1 PROCESSING

            If Nz(rstImportCList("Code1").Value, "") <> "" Then
'Code1 Case abc
                vdispo = DLookup("Code1", "tblvFileImport", "IDName = " & rstImportCList("IDName"))
                
                If rstImportCList("Code1") = "ABC" Then
                    Debug.Print "Dispo Case ABC"
                    'DELETE RECORD
                    dMDsql = "DELETE from tblVFileImport " & _
                    "WHERE tblVFileImport.IDName = " & rstImportCList("IDName")
                    Debug.Print "dMDsql - " & dMDsql
                    RunMySql (dMDsql)
                    'DoCmd.RunSQL (dMDsql), dbFailOnError

'Code1 Case DEF OR GHI OR JKL 
                ElseIf Nz(rstImportCList("Code1"), "") = "DEF" Or Nz(rstImportCList("Code1"), "") = "GHI" Or Nz(rstImportCList("Code1"), "") = "JKL" Then
                    Debug.Print "Dispo Case DEF OR GHI OR JKL "
                    'IF DEF
                    If rstImportCList("Code1") = "DEF" Then
                        'IF CELL SAME - UPDATE NULL
                        ccellsame = DLookup("IDName", "tblVFileImport", "IDName = " & rstImportCList("IDName") & " AND nz(Cell,'') = Phone ")
                        If ccellsame = rstImportCList("IDName") Then
                            uCellsql = "Update tblVFileImport SET tblVFileImport.Cell = NULL, tblVFileImport.CellString = NULL, tblVFileImport.mobileflag = NULL " & _
                            "WHERE tblVFileImport.IDName = " & rstImportCList("IDName")
                            Debug.Print "uCellsql - " & uCellsql
                            RunMySql (uCellsql)
                            'DoCmd.RunSQL (uCellsql), dbFailOnError
                        End If
                    End If
                End If
            End If
        End If
        Debug.Print "End Processing: " & rstImportCList("IDName")
        rstImportCList.MoveNext
    Loop

    Debug.Print "Finished Looping"
    rstImportCList.Close
    
    importCT = DCount("IDName", "tblTempImportCList")
    MsgBox importCT & " Records imported for list.", vbOKOnly, "List Processed"
Else
    MsgBox "Good Call. Check twice, import once!", vbOKOnly, "Better Safe Than Sorry"
End If
Exit Sub

cmdImportExcel_Click_err:
Select Case Err.Number
Case Else
Call MsgBox(Err.Number & " – " & Err.Description, vbCritical + vbOKOnly, "System Error …")
End Select
End Sub

非常感谢任何建议。我有 1/2 想把它吸进一个 SQL 表中,然后执行一个存储过程。我想我可以让它在那里工作。

【问题讨论】:

  • 我们需要看看您是如何实现像enum types and options 这样的DAO 记录集行的。请为minimal reproducible example 发布一些代码。
  • 根据stackoverflow.com/questions/664162/… 测试IsNull(rstImportCList("xyz").Value) 应该没有问题,但有趣的是没有调试选项。
  • 尝试切换到“Break in Class 模块”进行错误处理(如果尚未选择)。
  • 我把它切换回这个 Nz(rstImportCList("xxx").Value, "") "" 并且由于某种原因它现在可以工作了。
  • 我收回了。它失败了,但不一致。我检查了记录集表中的每个字段值,在那里我检查 nz(x,"") = "something" 或 "" 是否像这样 Nz(rstImportCList("xxx").Value, "") = “是”。我的调试消息显示它循环遍历为 null 的记录,没有问题,但是在一条记录中,我得到了 null 的无效使用。尝试了不同的列表,它仍在发生,但不在同一个地方。

标签: vba ms-access exception null isnull


【解决方案1】:
If IsNull(rstImportCList("columnx").Value) Then

否则,您将检查 Field 对象本身是否为空。

https://docs.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/field-object-dao#:~:text=To%20refer%20to,Fields(%22name%22)

这是依赖默认属性(在本例中为值)导致问题的情况。

【讨论】:

  • 所以我尝试了 Nz(rstImportCList("xxx").Value, "") = "Y" 仍然抛出错误。如果我添加一个图层来进行空检查,我需要一个 not null 来检查 Y 。我不明白为什么这不能更好地处理空值。
  • 如果您包含您正在使用的实际代码,这将对您的问题有很大帮助。
  • 如果我有时间我会的,但这是很多代码,而且我正处于杂草之中,时间紧迫,所以继续寻找解决这个愚蠢问题的任何方法。
  • 您只需要显示问题所在的线条。这样你更有可能得到有用的回复。
猜你喜欢
  • 2010-10-14
  • 2017-06-15
  • 1970-01-01
  • 2017-03-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多