首先,我对编码很新,所以请耐心等待,其次;
我目前正在尝试将网络中其他数据库的记录绘制到我的数据库中。事实证明这有点麻烦,因为我想填写所有具有相同主键的表中的所有字段。
我目前的代码如下所示
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收到类型不匹配错误,但我觉得这个代码也有其他问题,只是不能指责它。如果有人可以提供帮助,我会非常感激!
答案 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 在输入框内
关系数据库的核心原则之一是避免重复数据。此外,如果用户添加/编辑数据,它将在系统上实时反映。数据库之间的数据传输只应在迁移时运行,其中一个用于存档,另一个用于生产。
话虽如此,请考虑以下步骤来构建您的用户应用程序:
Link all needed tables。 GUI对话框允许选择全部功能或为多个表保持 SHIFT 和/或 CTRL 。
构建临时表以保存当前用户的主键并通过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
为每个链接表创建一个筛选查询,与 TmpPrimaryKey (即目标主键)对齐。这样,用户只会看到这样的记录。将这些查询用于表单/报表记录源或模块记录集。
查询可以使用JOIN
,IN
,EXISTS
子句,例如以下单独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);
因为您可能有许多表,所以使用TableDefs和QueryDefs在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
再次,将所有需要的应用程序对象(表单,报表,模块等)设置为指向这些查询作为数据源而不是链接表,保存所有数据。查询应该可以更新,以便用户添加/编辑记录。
从那里,将此应用程序数据库的副本分发给前端/后端拆分架构中的所有用户,维护一个集中式和规范化数据库以及许多包含否的应用程序文件数据(当然,临时PK值除外)。