0

私は会社でプロジェクトに取り組んでおり、そのため、XP で動作する MS ACCESS 2003 を使用する必要があります (ただし、ここでは OS は関係ないと思います)。この会社は他のアプリケーション (および外部ソース) を使用しているため、テーブルの入力として使用されるデータは常にサニタイズされているわけではありません。ただし、データは常に .XLS (Excel) 形式で取得できることに気付きました。

データベースは 40 を超えるテーブルで構成され、冗長性があり、キーもインデックスもありませんでした。言い換えれば、それは混乱でした。苦労の末、デザインを改善し、テーブルの数を減らすことができました。

それでも、私はいくつかの課題に直面していることに気づきました。これらの課題のほとんどはトリガーで克服できますが、さまざまなフォーラムで多くの回答を読んだ後、アクセス 2003 にはトリガーが存在せず、フォームにリンクされたクエリに置き換える必要があることがわかりました。このようなソリューションの問題の 1 つは、フォームとボタンが必要なことです。そこで、フォームを使用してExcelファイルからデータをインポートするときに、そのようなクエリを実装すると思いました。テーブルは Excel ファイルの形式に正確に従っていないため、ディレクトリを変更して特定のシートから特定の Excel 列を Db のテーブルの対応する列にインポートする方法を学ぶための指示が必要です。

また、これは(少なくとも私にとっては)より困難な場所です。直接接続されていないさまざまなテーブルがあります(たとえば、ブリッジテーブルのため)。それでも、すべてのテーブルのデータ間の整合性を維持する必要があります。テーブル A、B、C があるとします。テーブル C に接続されているテーブル B に接続されているテーブル A: テーブル A に行を挿入するときに、テーブル C の行を挿入または削除する必要があります。また、テーブル C のいくつかの列を一貫させる必要があります (これは最初は設計上の問題のように思えるかもしれませんが、そうではないことを保証します。テーブルの詳細をお伝えできなくて申し訳ありませんが、機密保持条項に署名しました。

最後に、これは「ばかげた」質問のように思えるかもしれませんが、他の列に応じていくつかの列に数学的な検証規則を課すテーブル設計の場所を Access で見つけることができません。単一の列に検証ルールを設定できることがわかりました (たとえば Is Null Or >= 0) が、一部の列では値が他の列に依存する必要があります。たとえば、列 B は 1.2*列 A に等しい必要があります (これらの列が同じテーブルにある場合もありますが、常にではありません)。

ご協力ありがとうございました。私が直面している問題についてあなたが提供できる支援に感謝します。そして、あなたが必要とする追加情報があれば、私はあなたの処分にとどまります.

4

2 に答える 2

2

私はuser2174085に同意します。あなたの質問にはかなり多くのものがあります。

私のアプローチは、データをクラスでモデル化し、これらを使用してデータベースに書き込むことです。これにより、必要に応じてデータを検証し、必要な数のテーブルにデータをインポートできます。

このアプローチは、CRUD アプリケーションでは標準です。

これは、説明目的の簡単な例であり、手順が明確に説明されていることを願っています):

1) サンプル データベースを定義します。

表 1: クライアント (ID、名前、AddressID)

表 2: 住所 (ID、番地)

2) サンプル スプレッドシートを定義します。

クライアント: ID、名前、住所 ID 1、ボブ、1 2、ジム、2

住所: ID、Street 1、Gold Street 2、Derp Street

3) 単一のクライアントと単一のアドレスをモデル化できる 2 つのクラスを定義します。

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

この時点で検証を実行できます。たとえば、クライアント レコードを作成してから、データに問題がないかどうかを示す検証メソッドを呼び出すことができます。

ID が書き込まれない理由は、データベース内の自動採番であるためです。データベース内のデータからクライアント/アドレスレコードを作成し、その情報を使用して別のレコードを書き込む必要がある場合があるため、これはまだクラスに含まれています。たとえば、クライアント レコードを書き込むには、クライアント レコードの書き込みに使用される AddressID を備えたアドレス レコードを取得する必要がある場合があります。

4) 上記のクラスはクエリ (ストアド プロシージャ) を使用してデータベースに書き込みます。クエリの例を次に示します。

usp_Clients_InsertRecord

パラメータ pName テキスト (255)、pAddressID ロング。Clients(Name, AddressID) 値 (pName, pAddressID) に挿入します。

5)これで問題ありませんが、データを Excel からクラスに取得し、データベースに書き込むにはどうすればよいでしょうか? これを行うには、管理クラスを使用します。これらは、スプレッドシートからロードされ、コレクションに格納された Client または Address レコードのロードを含むクラスです。このコレクションはループ処理され、Insert メソッドを呼び出してレコードをデータベースに書き込みます。

これは、テーブル A、B、C の順にデータを書き込む方法に関する質問への回答を提供します。3 つのクラスを作成し、それらにデータを入力してから、A をデータベースに書き込み、最後に書き込まれたレコードの ID を使用して B を書き込みます。テーブル A (クエリを使用して取得) などに。

以下は、管理クラスの例です。

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

私は少し行ったと思います。これが役立つ場合は、私に知らせてください/質問してください。少し肉付けできます:)

于 2013-06-18T17:52:21.843 に答える