0

在 MS Access 中,我有两个表(A 和 B),任务是将 B 插入 A。但是,有一些特殊条件:

  • 所有字段都是文本类型。
  • A和B有一些共同的领域。
  • 保证相同的关键字段存在于两者中,并且其值总是不同的。
  • A 有一些 B 没有的字段。插入的记录应将这些字段留空。
  • B 有一些 A 没有的字段。这些字段必须在 A 中创建,并且 A 中的现有记录应将它们留空。
  • 有很多这样的情况,因此查询不应明确包含字段名称,因为为每种情况个性化查询会很乏味。但是,关键字段的名称始终相同。
  • 创建一个新表 C 而不是直接替换 A 是可以接受的。

例子:

Table A:
key  a       b       c
--- ------- ------- -------
k0  hello   dear    world
k1  bye     cruel   world

Table B:
key  a       d       e
--- ------- ------- -------
k2  welcome john    doe
k3  turulu  ann     harp

Table C (the new A):
key  a       b       c       d       e
--- ------- ------- ------- ------- -------
k0  hello   dear    world
k1  bye     cruel   world
k2  welcome                 john    doe
k3  turulu                  ann     harp
4

2 回答 2

1

创建一个访问模块并使用以下代码。用您的表和目标名称替换测试子中的值

Option Compare Database
Option Explicit

Function SplatTablesSql(pT1 As String, pT2 As String, pDest As String)
    Dim lDb As Database
    Dim lTd1 As TableDef, lTd2 As TableDef
    Dim lField As Field, lF2 As Field
    Dim lS1 As String, lS2 As String, lSep As String

    SplatTablesSql = "Select "
    lS1 = "Select "
    lS2 = "Select "

    Set lDb = CurrentDb
    Set lTd1 = lDb.TableDefs(pT1)
    Set lTd2 = lDb.TableDefs(pT2)

    For Each lField In lTd1.Fields
        SplatTablesSql = SplatTablesSql & lSep & "x.[" & lField.Name & "]"
        lS1 = lS1 & lSep & "a.[" & lField.Name & "]"
        Set lF2 = Nothing
        On Error Resume Next
        Set lF2 = lTd2.Fields(lField.Name)
        On Error GoTo 0
        If lF2 Is Nothing Then
            lS2 = lS2 & lSep & "Null"
        Else
            lS2 = lS2 & lSep & "b.[" & lField.Name & "]"
        End If
        lSep = ", "
    Next

    For Each lField In lTd2.Fields
        Set lF2 = Nothing
        On Error Resume Next
        Set lF2 = lTd1.Fields(lField.Name)
        On Error GoTo 0
        If lF2 Is Nothing Then
            SplatTablesSql = SplatTablesSql & lSep & "x.[" & lField.Name & "]"
            lS1 = lS1 & lSep & "Null as [" & lField.Name & "]"
            lS2 = lS2 & lSep & "b.[" & lField.Name & "]"
        End If
        lSep = ", "
    Next

    SplatTablesSql = SplatTablesSql & " Into [" & pDest & "] From ( " & lS1 & " From [" & pT1 & "] a Union All " & lS2 & " From [" & pT2 & "] b ) x"
End Function

Sub Test()

    CurrentDb.Execute SplatTablesSql("a", "b", "c")

End Sub
于 2013-09-13T21:53:56.937 回答
1

我认为解决这个问题的最简单方法是使用 VBA 创建查询定义。

我将假设有一个名为key两个表共有的列。

我在这里发现您可以使用集合来制作类似字典的结构。我将使用它来构建字段列表。

所以,我们开始:

public function contains(col as Collection, key as variant) as boolean
    dim obj as variant
    on error goto err
        contains = True
        obj = col(key)
        exit function
    err:
        contains = false
end function

public sub create_this_query(tbl1 as String, tbl2 as String, keyField as String)
    ' tbl1 and tbl2 are the names of the tables you'll use
    dim db as DAO.database, rs1 as DAO.recordset, rs2 as DAO.recordset
    dim columns as Collection
    dim strSQL as String
    dim i as integer
    dim obj as variant, colName as String

    set db = currentdb()
    set tbl1 = db.openrecordset(tbl1, dbopendynaset, dbreadonly)
    set tbl2 = db.openrecordset(tbl2, dbopendynaset, dbreadonly)
    set columns = new Collection

    ' Let's create the field list (ommiting the keyField)
    for i = 1 to tbl1.fields.count
        if not contains(columns, tbl1.fields(i).Name) _
           and tbl1.fields(i).Name <> keyField then
            columns.add tbl1.fields(i).Name, tbl1.fields(i).Name
        end if
    next i
    for i = 1 to tbl2.fields.count
        if not contains(columns, tbl2.fields(i).Name) _
           and tbl2.fields(i).Name <> keyField then
            columns.add tbl1.fields(i).Name, 1 ' The value is just a placeholder
        end if
    next i
    ' Now let's build the SQL instruction
    strSQL = "select [a].[" & keyField & "]"
    for colName in columns
        strSQL = strSQL & ", [" & colName & "]"
    next obj
    strSQL = strSQL & " " & _
             "from " & _
             "    (" & _
             "        select [" & keyField & "] from [" & tbl1 & "] " & _
             "        union " & _
             "        select [" & keyField & "] from [" & tbl2 & "] " & _
             "    ) as a " & _
             "left join [" & tbl1 & "] as t1 " & _
             "    on a.[" & keyField & "] = t1.[" & keyField & "] " & _
             "left join [" & tbl2 & "] as t2 " & _
             "    on a.[" & keyField & "] = t2.[" & keyField & "] "
   ' Finally, let's create the query object
   db.createQueryDef("myNewQuery", strSQL)
end sub

希望这可以帮助

于 2013-09-13T22:11:31.570 回答