访问 VBA 代码以删除表(如果存在)

Posted

技术标签:

【中文标题】访问 VBA 代码以删除表(如果存在)【英文标题】:ACCESS VBA code to delete a table if it exists 【发布时间】: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. 【参考方案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

【讨论】:

以上是关于访问 VBA 代码以删除表(如果存在)的主要内容,如果未能解决你的问题,请参考以下文章

删除 VBA 中不存在的工作表

VBA excel添加新工作表并删除原来的

如果 Microsoft Access 中存在表,则删除表

几次迭代后访问 VBA 宏卡住

使用表单和子表单访问 VBA 代码格式更新表

excelvba锁定单元格图片不被删除