由于 table/object 为只读,使用 CreateQueryDef 创建查询失败

Creating a Query with CreateQueryDef Failing due to table/object being read only

我修改了一段代码,从一行 SQL 代码中创建了一个查询,并将其导出到一个文本文件中。

我以前有过这个工作,但在尝试在更大的子例程中实现它后,它现在给出一个错误,指出 table/object 不能更新,因为它是只读的(错误 3027)。

无论代码是自己执行还是从其他代码中执行,都会发生这种情况。

请在下面找到导出代码:

Public Sub exportQuery(exportSQL As String, FileName As String)

    Dim db As DAO.Database, qd As DAO.QueryDef
    Dim i As Integer
    Dim InitialFileName As String
    Set db = CurrentDb
    'Check to see if querydef exists and delete it if it exists  
    For i = 0 To (db.QueryDefs.Count - 1)

        If db.QueryDefs(i).Name = "tmpExport" Then
            db.QueryDefs.Delete ("tmpExport")
            Debug.Print "Deleted"
            Exit For

        End If

    Next i
    Debug.Print "This far"

    Set qd = db.CreateQueryDef("tmpExport", exportSQL)

    'Set intial filename to default if none is chosen
    If (FileName <> "") Then
        InitialFileName = "export_" & Format(Date, "mmddyyy") & ".csv"
    Else
        InitialFileName = FileName   
    End If

    'Write the query results to a File
    DoCmd.TransferText transferType:=acExportDelim, TableName:="tmpExport", FileName:="Pathtoexport\Export" & InitialFileName, HasFieldNames:=False
    'Cleanup
    db.QueryDefs.Delete "tmpExport"
    db.Close
    Set db = Nothing
    Set qd = Nothing
    Debug.Print "ExportQuery" & vbCrLf
End Sub

另请在下面找到有问题的 SQL:

Select phone_number FROM Master WHERE list_id IN ('230');

如果有人能阐明造成这种情况的原因,我将不胜感激。

正如 Wayne 在评论中正确指出的那样,代码中以下 if 语句中实现的逻辑是相反的:

'Set intial filename to default if none is chosen
If (FileName <> "") Then
    InitialFileName = "export_" & Format(Date, "mmddyyy") & ".csv"
Else
    InitialFileName = FileName   
End If

以上暗示有效的文件名将导致输出路径:

Pathtoexport\Export

你也应该省略这里的括号:

db.QueryDefs.Delete ("tmpExport")

但是,从更大的角度来看,我个人会避免在此函数中构建文件路径,而会选择提供完整的文件路径作为参数。

这样,函数只有一个目的:

"Export the result of the supplied SQL to a file with the supplied filename."

您将不再需要将父文件夹硬编码到函数中。

例如,类似以下内容:

Function ExportQuery(sql As String, fnm As String)
    Dim qry As String: qry = "tmpExport"

    Dim dbs As DAO.Database
    Set dbs = CurrentDb

    On Error Resume Next
    dbs.QueryDefs.Delete qry
    On Error GoTo 0

    dbs.CreateQueryDef qry, sql
    DoCmd.TransferText acExportDelim, , qry, fnm, False
    dbs.QueryDefs.Delete qry

    Set dbs = Nothing
End Function