在特定条件下使用来自其他数据库的记录填充当前数据库

时间:2018-06-04 07:48:52

标签: vba ms-access

首先,我对编码很新,所以请耐心等待,其次;

我目前正在尝试将网络中其他数据库的记录绘制到我的数据库中。事实证明这有点麻烦,因为我想填写所有具有相同主键的表中的所有字段。

我目前的代码如下所示

varPrimaryKey = InputBox("Specify primary key:")
strPrimaryKey = module1.Item1

If Not varPrimaryKey = "" Then
    MsgBox ("Get data from: " & varPrimaryKey)

    If Not (tdf.Name Like "MSys*" Or tdf.Name Like "~*") Then
        For Each tdf In externalDb.TableDefs
            For Each fld In tdf.Fields

                db.Execute ("INSERT INTO CurrentDb.fld.Name SELECT fld.Name FROM tdf.Name WHERE fld.Name = 'Value' AND varPrimaryKey = 'Value'")

            Next fld
        Next tdf
    End If
End If

现在我从.CurrentDb收到类型不匹配错误,但我觉得这个代码也有其他问题,只是不能指责它。如果有人可以提供帮助,我会非常感激!

2 个答案:

答案 0 :(得分:1)

You just reference the table you want to INSERT into. What you need is path to the other db. Need to concatenate variables. You don't show declaring and setting variables db, tdf, fld, externalDB. Need to swap the If and first For lines. Your INSERT SELECT will not work the way you think, unless you really want each field inserted into its own record. Consider:

For Each tdf In CurrentDb.TableDefs
    If Not (tdf.Name Like "MSys*" Or tdf.Name Like "~*") Then

        CurrentDb.Execute ("INSERT INTO [" & tdf.Name & "] SELECT * FROM [" & tdf.Name & _
        "] IN 'other db path\filename.accdb' WHERE [Value] = '" & varPrimaryKey & "'")

    End If
Next tdf

However, autonumber fields will interfere with this simple INSERT SELECT. Also, fields in both tables must be arranged in same order in table design.

Value is a reserved word and really should avoid using reserved words as names for anything. If Value is a number data type then eliminate the apostrophe delimiters.

Why have that MsgBox?

But then why all this effort anyway and not just link to the backend tables?

答案 1 :(得分:1)

重新考虑整个方法。对于用户应用程序需求,不应将数据库复制为从上面的注释中收集的彼此版本:

  

我的意思是我想从所有表中绘制所有记录   具有与用户输入的主键ID相同的主键ID   在输入框内

关系数据库的核心原则之一是避免重复数据。此外,如果用户添加/编辑数据,它将在系统上实时反映。数据库之间的数据传输只应在迁移时运行,其中一个用于存档,另一个用于生产。

话虽如此,请考虑以下步骤来构建您的用户应用程序:

    来自网络数据库的
  1. Link all needed tables。 GUI对话框允许选择全部功能或为多个表保持 SHIFT 和/或 CTRL

  2. 构建临时表以保存当前用户的主键并通过VBA插入数据值。这是在应用程序数据库中保存数据(一列/一行结构)的唯一表。见以下步骤:

    使用代码或通过表格设计创建一个表(一行/一列)

     
    CREATE TABLE TmpPrimaryKey (
        PrimaryID Long
    )
    

    使用用户输入附加如下所示,使用VBA进行参数化。对于PK的任何更改,应定期运行此代码。理想情况下,在启动应用程序时运行它。

     
    Dim qdef As QueryDef
    Dim strSQL As String
    Dim varPrimaryKey As Variant
    
    varPrimaryKey = InputBox("Specify primary key:")
    
    ' CLEAN OUT TEMP TABLE
    CurrentDb.Execute "DELETE FROM TmpPrimaryKey", dbFailOnError
    
    ' APPEND TO TEMP TABLE 
    strSQL = "PARAMETERS [PkParam] LONG;" _ 
                & " INSERT INTO TmpPrimaryKey (PrimaryID) VALUES ([PkParam])"
    
    Set qdef = CurrentDb.CreateQueryDef("", strSQL)
    qdef![PkParam] = varPrimaryKey
    qdef.Execute dbFailOnError
    
    Set qdef = Nothing
    
  3. 为每个链接表创建一个筛选查询,与 TmpPrimaryKey (即目标主键)对齐。这样,用户只会看到这样的记录。将这些查询用于表单/报表记录源或模块记录集。

    查询可以使用JOININEXISTS子句,例如以下单独SQL语句的示例。下表是来自网络数据库的链接表(步骤#1)。

    查询1

     
    SELECT src.* 
    FROM [Table1] src
    INNER JOIN TmpPrimaryKey tmp ON src.ID = tmp.PrimaryID;
    

    QUERY2

     
    SELECT src.* 
    FROM [Table2] src
    WHERE src.ID IN (SELECT PrimaryID FROM TmpPrimaryKey);
    

    QUERY3

     
    SELECT src.* 
    FROM [Table3] src
    WHERE EXISTS
       (SELECT 1 FROM TmpPrimaryKey tmp WHERE src.ID = tmp.PrimaryID);
    

    因为您可能有许多表,所以使用TableDefsQueryDefs在VBA循环中构建上述SQL查询。注意:创建查询的循环例程应该只运行一次

     
    Dim tdef As TableDef
    Dim qdef As QueryDef
    Dim strSQL As String
    
    ' LOOP THROUGH ALL TABLES OF APP DB (I.E., LINKED TABLES)
    For Each tdef in CurrentDb.TableDefs
        If tdef.Name <> "TmpPrimaryKey" And tdef.Name Not Like "MSys*" Then
            ' ASSUMING EACH TABLE'S PK IS NAMED ID
            strSQL = "SELECT src.* FROM [" & tdef.Name & "] src"  _
                      & " INNER JOIN TmpPrimaryKey tmp ON src.ID = tmp.PrimaryID;"    
    
            ' NAME EACH QUERY SAME AS TABLE WITH "Q_PK" SUFFIX
            Set qdef = CurrentDb.CreateQueryDef(tdef.Name & "Q_PK", strSQL)
            Set qdef = Nothing
        End If
    Next tdef
    
    Set tdef = Nothing
    

    再次,将所有需要的应用程序对象(表单,报表,模块等)设置为指向这些查询作为数据源而不是链接表,保存所有数据。查询应该可以更新,以便用户添加/编辑记录。

  4. 从那里,将此应用程序数据库的副本分发给前端/后端拆分架构中的所有用户,维护一个集中式和规范化数据库以及许多包含的应用程序文件数据(当然,临时PK值除外)。

    Split Database Design