【问题标题】:ACCESS VBA code to delete a table if it exists访问 VBA 代码以删除表(如果存在)
【发布时间】:2017-05-07 16:12:25
【问题描述】:

首先,我必须承认,我没有接受过使用 VBA 编码的培训。我使用 MS Access 宏和查询来构建我的应用程序。我使用了一些临时导入文件,需要运行宏或一些 VBA 来测试它们是否存在,如果存在,则删除它们。

我的表名是“TempImport1”

我通过谷歌搜索对此进行了研究,并遇到了一些可能有效的 VBA,但我在试图弄清楚如何将代码放入模块或单击子按钮时迷失了方向。我过去在一个按钮功能下剪切/粘贴了 VBA 代码,它可以工作,但我不知道为什么这次它不能工作。

老实说,我确信这是我对私有函数和公共函数缺乏了解,当然还有我不了解 VBA 的事实。

这是我正在尝试制作的代码:

Function IsTable(sTblName As String) As Boolean
    'does table exists and work ?
    'note: finding the name in the TableDefs collection is not enough,
    '      since the backend might be invalid or missing

    On Error GoTo TrapError
    Dim x
    x = DCount("*", sTblName)
    IsTable = True
    Exit Function
TrapError:
    Debug.Print Now, sTblName, Err.Number, Err.Description
    IsTable = False

End Function

【问题讨论】:

  • 该函数只是试图检查表是否存在。您可以这样称呼它:myTest = IsTable("table_name"),并且此函数会尝试计算此表上的记录数。如果表存在,该函数将能够进行计数,因此将返回IsTable = True。如果不是,那么上面的错误处理将捕获错误并设置IsTable = False。所以你应该使用它的方式只是在你的代码中测试:If isTable("yourTable") Then... do something.... Else.... do something else.

标签: vba ms-access


【解决方案1】:

首先你应该检查表是否存在,然后你应该尝试关闭它,如果它存在。然后您应该将警告设置为 False,这样它就不会询问您是否确定要删除该表。

在下面的示例中,您删除了Table3If Not IsNull 正在检查表是否存在:

Option Compare Database
Option Explicit

Public Sub DeleteIfExists()

    Dim tableName As String
    tableName = "Table3"

    If Not IsNull(DLookup("Name", "MSysObjects", "Name='" & tableName & "'")) Then
        DoCmd.SetWarnings False
        DoCmd.Close acTable, tableName, acSaveYes
        DoCmd.DeleteObject acTable = acDefault, tableName
        Debug.Print "Table" & tableName & "deleted..."
        DoCmd.SetWarnings True
    End If

End Sub

代码应该可以正常工作。

【讨论】:

  • 我会把它分成两个函数:TableExists 和 DeleteTable。如果表不存在,DeleteTable 就没有工作要做,因此在名称中说明这一点没有任何价值。
  • 删除了编辑 在 DLookup 中添加了条件“Type = 1”。否则,即使只有其他具有相同名称的对象(不是表),if 子句也可能为真。,就好像我曾经有一个对象,我认为它是一个表并且我错误地删除了它,因为同名,说不定会是好事。不过,感谢您的编辑。
  • @HackSlash - 这是一个品味问题,我猜(或者听太多 Bob 大叔的话)。无论如何,不​​存在的删除和关闭可能会导致错误,因此我将保持原样。
  • 两者协同工作。 DeleteTable 会说If TableExists(tableName) Then。如果你的鲍勃叔叔把他的问题分解成原子部分,我会听他的。
  • @HackSlash - Bob 叔叔就是这个人 - “Robert Cecil Martin”。正如我所说,这是一个品味问题——在一个大项目中,过多地破坏代码可能并不好。这取决于最资深的开发人员和他/她阅读的最后一本书。 :) 就我而言,我宁愿保持这样。将表名放在参数中是一个更好的主意,但那样答案的说明性目的就没有了。
【解决方案2】:

要删除 TempImport1 表(如果存在),只需使用以下函数。

Function DeleteTables()

    If Not IsNull(DLookup("Name", "MSysObjects", "Name='TempImport1' AND Type = 1")) Then
    DoCmd.DeleteObject acTable, "TempImport1"
    End If

End Function

创建函数后,创建一个宏,添加操作运行代码,然后在函数名称中输入DeleteTables()
然后,您可以运行一个宏来删除该表(如果存在)。

【讨论】:

    【解决方案3】:

    检查MSysObjects(在其他答案中使用)误报了一个表,如果它最近被删除。我发现以下测试更可靠。

    Option Compare Database
    Option Explicit
    
    Public Sub DeleteIfExists()
    
        Dim tableName As String
        tableName = "Table3"
    
        On Error Resume Next
        Set td = db.TableDefs(tableName)
        If Err.Number <> 0 Then
            DoCmd.SetWarnings False
            DoCmd.Close acTable, tableName, acSaveYes
            DoCmd.DeleteObject acTable = acDefault, tableName
            Debug.Print "Table" & tableName & "deleted..."
            DoCmd.SetWarnings True
        End If
    
    End Sub
    

    【讨论】:

      【解决方案4】:

      这是我为摆脱导入错误表而创建的版本。错误。 Number 必须为 0 才能实际删除表。 TRACE 是我的内部标志。

      Public Function RemoveImportErrorTables(Optional strTableBaseName As String = "rngExportDaily_ImportErrors") As Integer
      'Purpose:
      '  Remove ImportError Tables
      'In:
      '  Tables base Name
      'Out:
      '  number of tables flushed
      'History:
      '  Created 2021-12-06 16:10 Anton Sachs; Last modified 2021-12-06 16:15 Anton Sachs
      '
        Dim intResult As Integer
        Dim strTableName As String
        Dim dbCur As Database
        Dim tdfTableDef  As TableDef
        Dim intTableIndex As Integer
      
        On Error GoTo RemoveImportErrorTables_Err
        
        Set dbCur = CurrentDb()
        
        For intTableIndex = 0 To 100
          If intTableIndex = 0 Then
            strTableName = strTableBaseName
          Else
            strTableName = strTableBaseName & CStr(intTableIndex)
          End If
        
          On Error Resume Next
          
          Set tdfTableDef = dbCur.TableDefs(strTableName)
          
          If Err.Number = 0 Then
            DoCmd.SetWarnings False
            DoCmd.Close acTable, strTableName, acSaveYes
            DoCmd.DeleteObject acTable = acDefault, strTableName
            DoCmd.SetWarnings True
            intResult = intResult + 1
          Else
            On Error GoTo RemoveImportErrorTables_Err
            Exit For
          End If
        
        Next intTableIndex
      
      RemoveImportErrorTables_Exit:
        RemoveImportErrorTables = intResult
        If Not tdfTableDef Is Nothing Then
          Set tdfTableDef = Nothing
        End If
        If Not dbCur Is Nothing Then
          Set dbCur = Nothing
        End If
        Exit Function
      
      RemoveImportErrorTables_Err:
        If TRACE = 0 Then TRACE = GetStandard("Trace")
      
      If TRACE <> False Then
        Debug.Print "Error " & Err.Number & " " & Err.Description & " in RemoveImportErrorTables"
        Err.Clear
        If TRACE = CTR±Stop Then
          Stop
          Resume Next
        End If
      Else
        Err.Clear
          Resume Next
      End If
      
      RemoveImportErrorTables_Fail:
        intResult = False
        GoTo RemoveImportErrorTables_Exit
      End Function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-08
        • 2012-06-06
        相关资源
        最近更新 更多