Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql MS ACCESS 2003触发器(查询事件)和Excel导入_Sql_Excel_Ms Access - Fatal编程技术网

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

Sql MS ACCESS 2003触发器(查询事件)和Excel导入,sql,excel,ms-access,Sql,Excel,Ms Access,我在一家公司从事一个项目,因此我必须使用在XP上运行的MS ACCESS 2003(尽管我认为操作系统与此无关)。由于该公司正在使用其他应用程序(以及外部源),因此表中用作输入的数据并不总是经过清理。然而,我注意到我们总是可以以.XLS(excel)格式获取数据 数据库由40多个表组成,具有冗余、无键和无索引;换句话说,这是一片混乱。在经历了很多麻烦之后,我能够改进设计并减少表的数量 然而,我发现自己面临的挑战很少。这些挑战中的大多数都可以通过触发器来克服,但在阅读了不同论坛中的许多答案后,我了

我在一家公司从事一个项目,因此我必须使用在XP上运行的MS ACCESS 2003(尽管我认为操作系统与此无关)。由于该公司正在使用其他应用程序(以及外部源),因此表中用作输入的数据并不总是经过清理。然而,我注意到我们总是可以以.XLS(excel)格式获取数据

数据库由40多个表组成,具有冗余、无键和无索引;换句话说,这是一片混乱。在经历了很多麻烦之后,我能够改进设计并减少表的数量

然而,我发现自己面临的挑战很少。这些挑战中的大多数都可以通过触发器来克服,但在阅读了不同论坛中的许多答案后,我了解到access 2003中不存在这些问题,应该用链接到表单的查询来取代它们。这种解决方案的一个问题是它需要一个表单和一个按钮。所以我想,当使用表单从excel文件导入数据时,我会实现这样的查询。由于表格并不完全遵循excel文件的格式,因此我需要了解如何将更改目录中的特定工作表中的特定excel列导入数据库中表格的相应列

而且,这也是它变得更具挑战性的地方(至少对我来说),我有不同的表没有直接连接(因为例如桥接表),但我仍然需要在所有表的数据之间保持一些完整性。 如果我们有表A、B、C;表A连接到表B,表B连接到表C: 我需要在插入表A中的行时插入或删除表C中的行。此外,我需要表C中的某些列与表A中的列保持一致(在值方面)。我知道这一点一开始可能看起来像是设计中的一个问题,但我向您保证不是。很抱歉,我没有提供表格的详细信息,但我签署了一项保密条款

最后,这似乎是一个“愚蠢”的问题,但我在access中找不到表设计中的一个位置来根据其他列对某些列施加一些数学验证规则。我发现我们可以在单个列上有验证规则(例如为Null或>=0),但对于某些列,它们的值应该依赖于其他列。例如,列B应该等于1.2*列A(有时这些列在同一个表中,但并不总是如此)


谢谢你的帮助。我非常感谢您在我面临的任何问题上提供的任何帮助;如果您需要更多的信息,我将随时听从您的安排。

老实说,您可能想分别问这些问题。我们都有白天的工作,只能花一点时间来帮忙!:o)


我能很快回答的一个问题是关于数据完整性的问题。如果单击“工具”,然后单击“关系”,则可以设置表之间的关系。正是在这些关系中,您可以“强制执行引用完整性”。这是Access将自动删除相关表中的记录以保持数据干净的地方。

老实说,您可能需要分别询问这些问题。我们都有白天的工作,只能花一点时间来帮忙!:o)


我能很快回答的一个问题是关于数据完整性的问题。如果单击“工具”,然后单击“关系”,则可以设置表之间的关系。正是在这些关系中,您可以“强制执行引用完整性”。这是Access将自动删除相关表中的记录以保持数据干净的地方。

我同意user2174085,您的问题很多

我的方法是在类中对数据建模,并使用这些类写入数据库。这将允许您根据需要验证数据,并根据需要将数据导入到多个表中

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

以下是一个简单的示例,用于说明(我希望)步骤:

1)定义示例数据库:

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

表2:地址(ID、街道)

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

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

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

3)定义两个类,这两个类允许我们对单个客户机和单个地址进行建模。

要在MS Access中使用这些类,请在“代码编辑器”窗口中添加一个类,然后将下面的类粘贴到中。有关详细信息,这是一个很好的vba类资源:

客户端类:

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
您可以在此时执行验证,例如,您可以创建一个客户机记录,然后调用一个validate方法来告诉您数据是否正常

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

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

usp_客户_插入记录

参数pName Text(255),填充字符长; 插入到客户端(名称、地址ID) 值(pName,pAddressID)

5)这一切都很好,但我们如何将数据从excel中获取到课堂中,并将其写入数据库?为此,我们使用管理类,这些类包含大量客户机或地址记录,从电子表格加载并存储在集合中。这个学院
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