MS ACCESS 2003触发器(查询事件)和Excel导入

我正在一个公司的项目中工作,因此我必然会使用MS ACCESS 2003在XP上运行(尽pipe我不认为这里的操作系统是相关的)。 由于公司正在使用其他应用程序(以及外部来源),所以在表格中用作input的数据并不总是被消毒。 但是,我注意到我们总是可以以.XLS(excel)格式获取数据。

数据库由40多个表组成,有冗余,无密钥,无索引。 换句话说,这是一个烂摊子。 在经历了很多麻烦之后,我改进了devise并减less了桌子的数量。

然而,我发现自己面临的挑战很less。 这些挑战中的大多数都可以通过触发器来克服,但是在不同的论坛上阅读了很多答案之后,我明白了他们不存在于访问2003中,应该replace为与表单相关的查询。 这种解决scheme的一个问题是它需要一个表单和一个button。 所以我想,我会实施这样的查询时,从excel文件中导入数据使用表单来这样做。 由于这些表并不完全遵循excel文件的格式,因此我需要指导,以了解如何从特定工作表中将特定工作表中的特定工作表导入到Db中相应的列表中。

此外,这也是一个更具挑战性的地方(至less对我而言),我有不直接连接的不同表(例如桥表),但是我仍然需要在所有表的数据之间保持一定的完整性。 如果我们有表A,B,C; 表A连接到连接到表C的表B:我需要在插入表A中的行时插入或删除表C的行。另外,我需要表C的一些列是一致的(根据值)与表A列。我知道这可能看起来像一个devise问题,但我向你保证它不是。 我很抱歉没有提供表格的细节,但我签署了一个不公开的条款。

最后,这可能看起来像一个“愚蠢”的问题,但我不能在表格devise中find一个位置,根据其他列对某些列施加一些mathvalidation规则。 我发现我们可以在单个列上有validation规则(例如是Null Or> = 0),但对于某些列,它们的值应该依赖于其他列。 例如,列B应该等于1.2 *列A(有时这些列在同一个表中,但并不总是)。

感谢您的帮助。 我非常感谢您在任何我遇到的问题上提供的帮助。 而且我会根据自己的意愿来处理您可能需要的任何额外信息。

我同意user2174085,你的问题有很多。

我的方法是在类中build模数据,并使用它们写入数据库。 这将允许您根据需要validation您的数据,并根据需要将数据导入到多个表中。

这种方法在CRUD应用程序中是标准的。

下面是一个简单的例子,用于说明(我希望)明确描述的步骤):

1)定义我们的示例数据库:

表1:客户端(ID,名称,地址ID)

表2:地址(ID,街道)

2)定义我们的示例电子表格:

客户:身份证,姓名,地址ID 1,鲍勃,1 2,吉姆,2

地址:身份证,街1号,金街2号,德普街

3)定义我们的两个类,它们允许我们build模一个客户端和一个地址。

若要在MS Access中使用这些,请在代码编辑器窗口中添加一个类,然后粘贴下面的类。有关详细信息,这是一个很好的vba类资源: http ://www.cpearson.com/excel/classes.aspx

客户端类:

Option Compare Database Option Explicit Dim intID As Integer Dim strName As String Dim intAddressID As Integer 'here we define a query (QueryDef) which is in the database (usp_Clients_InsertRecord), populate its parameters from the class variables and execute it to write the record Public Sub Insert() Dim qdfTemp As QueryDef Set qdfTemp = CurrentDb().QueryDefs("usp_Clients_InsertRecord") With qdfTemp .Parameters("pName") = strName .Parameters("pAddressID") = pAddressID End With qdfTemp.Execute End Sub 

地址类别:

 Option Compare Database Option Explicit Dim intID As Integer Dim strStreet As String 'here we define a query (QueryDef) which is in the database (usp_Addresses_InsertRecord), populate its parameters from the class variables and execute it to write the record Public Sub Insert() Dim qdfTemp As QueryDef Set qdfTemp = CurrentDb().QueryDefs("usp_Addresses_InsertRecord") With qdfTemp .Parameters("pStreet") = strStreet End With qdfTemp.Execute End Sub 

您可以在此处执行validation,例如可以创build客户端logging,然后调用validation方法,告诉您数据是否正常。

ID不写的原因是因为它是数据库中的自动编号。 它仍然包含在这个类中,因为我们可能需要从数据库中的数据创build一个客户/地址logging,并使用它的信息来写另一个logging。 例如,要编写客户logging,我们可能需要检索一个地址logging,其中包含用于写入客户logging的AddressID。

4)上面的类使用查询(存储过程)写入数据库,这里是一个示例查询:

usp_Clients_InsertRecord

参数pName文本(255),pAddressID长; 插入到客户端(名称,地址ID)值(pName,pAddressID);

5)这一切都很好,但是我们如何从excel中获取数据,并将其写入数据库呢? 要做到这一点,我们使用pipe理类,这些类是包含一个客户端或地址logging的负载,从电子表格加载并存储在一个集合。 这个集合被循环,调用Insert方法将logging写入数据库。

这为如何将数据写入表A,然后B和C这一问题提供了答案。您将创build3个类,使用数据填充它们,然后将A写入数据库,然后使用最后写入的logging的ID写入B到表A(使用查询检索)等等。

这是一个pipe理类的例子:

 Option Explicit 'our clients collection Private mcolClients As Collection 'adding objects to the clients collection Public Function AddByParameter(byval Name as string, byval AddressID as integer) dim objClient as Client Set objClient = New Client with objClient .strName = Name .intAddressID = AddressID end with mcolClients.Add objClient, Name end function 'constructor Private Sub Class_Initialize() Set mcolClients = New Collection End Sub 'you need this to be able to iterate over a collection Public Function NewEnum() As IUnknown Set NewEnum = mcolImportQuestions.[_NewEnum] End Function 'you can then iterate over the collection, calling the insert method on each record: public Sub InsertAllClients dim objClient as Client for each objClient in mcolClients objClient.Insert next objClient end function 

我想我已经走了一些,如果这是有用的,请让我知道/提出问题,我可以充实一点:)

老实说,你可能要分别问这些问题。 我们都有一天的工作,只能奉献一点时间来帮忙! :O)

我可以快速回答的一个问题是关于数据完整性的问题。 如果您点击工具,然后点击关系,您可以设置表格之间的关系。 正是在这些关系中,您可以“执行意向诚信”。 这是Access将自动删除相关表中的logging,以保持您的数据清洁。