ACCESS VBA レコードをコピーする機能(VBAコード公開)

レコードをコピーする機能

ACCESSでは、テーブルのレコードをコピーする機能をよく使います。
例えば売上伝票を入力するフォームで、既存の伝票をコピーして新しい伝票を作ることができれば入力効率が高まります。

Excelではデータのコピーはコピーアンドペーストで貼り付ければ終わりですが、ACCESSではそういうわけにはいきません。

今回は、ACCESS VBAでレコードをコピーする機能をご紹介します。


こんにちは。
はこにわガジェット (@hakoniwagadget) です。

ACCESSを使った売上管理、顧客管理などのデータベース開発を行っています。
ACCESSは使いこなすために少しスキルが必要なものの、うまく活用すればExcelよりも業務の効率化が図れます。
この記事ではACCESSで実際に作成したフォームやレポートを、その作成方法と共にご紹介していきます。

ACCESS VBAでのレコードをコピーする2つの方法

ACCESS VBAでレコードをコピーするには2つの方法があります。

1つめは追加クエリを使う方法です。
コピーするレコードが1つだけの場合などは、この方法が分かりやすくて簡単です。

2つ目はADOを使う方法です。
プログラミングの知識が必要になりますが、追加クエリを使う方法よりは柔軟性が高く、様々な処理が作れますので便利です。
条件が複雑なときはADOの利用を検討するとよいでしょう。

以下、それぞれの方法をご紹介します。

サンプルフォーム

今回の記事用にサンプルフォームを作成しました。

売上情報を入力するフォームで、下段にクエリコピーとADOコピーのボタンを作ってあります。
このフォームのレコードソースになっているのは「TRN_売上サンプル」テーブルです。

クエリコピー、もしくはADOコピーボタンを押すと下記のようにレコードがコピーされ、コピーされた最終レコードに移動したうえでメッセージが表示されます。

追加クエリを使ったレコードコピー

ではまず、追加クエリを使ったレコードコピーについてご紹介します。

先ほどのフォームをデザインビューで開きます。

クエリコピーボタンには、クリック時イベントにイベントプロシージャを設定してあります。
イベントプロシージャの内容は以下の通りです。


 Private Sub クエリコピー_ボタン_Click()

    DoCmd.SetWarnings False
    
    DoCmd.OpenQuery "ADD_レコードコピー"
    
    DoCmd.SetWarnings True

    DoCmd.Requery
    DoCmd.GoToRecord , , acLast
    
    MsgBox "コピーしました。", vbInformation + vbOKOnly, "コピー完了"
    
 End Sub
 

最初に


 DoCmd.SetWarnings False
 

でACCESSのシステムアラートが出ないように設定しています。

ACCESSでは追加クエリや削除クエリなどのアクションクエリを実行する際に、デフォルトではレコード処理の確認メッセージが出ます。
しかし、VBAで自動処理する際は、ユーザーには「レコード追加します」というメッセージが出ても理解できませんし、確認は不要なので、このメッセージを出ないようにしているのです。

そのため、追加クエリが終わった後には


 DoCmd.SetWarnings True
 

で、サイトシステムアラートが出るように設定を戻しています。

次に、ようやく追加クエリです。


 DoCmd.OpenQuery "ADD_レコードコピー"
 

DoCmd.OpenQueryメソッドを使って「ADD_レコードコピー」という追加クエリを実行しています。

ADD_レコードコピークエリは事前に作成した追加クエリです。
デザインビューで見ると以下の内容になっています。

TRN_売上サンプルテーブルのレコードの値を、再度TRN_売上サンプルテーブルに追加するクエリになっています。

追加するレコードの指定は、売上ID(主キー)の抽出条件に設定してあります。


 [Forms]![T_Copy]![売上ID]
 

と入力してありますが、これはつまりT_Copyフォームの売上IDと同じレコードを抽出する、という意味です。
クエリコピーボタンを設置されたフォームがT_Copyフォームですので、フォーム画面上で表示されているレコードを指定していることになります。

このようにクエリの抽出条件にフォームを参照させる方法をこちらに記事に書いておりますので、詳しく知りたい方は見てください。

クエリの抽出条件でフォームを参照させる方法

さらに、追加クエリでは「レコードの追加」行で追加先のフィールドを設定しています。

基本は同じフィールドに追加するのですが、売上IDだけはレコードの追加欄に何も書いていないことに注意してください。
これは、売上IDが主キーなのでここだけは値をコピーするのではなく、追加したレコードには新しい売上IDをオートナンバーで採番するためです。

これでレコードの追加ができました。
続いてはレコードの移動処理です。


    DoCmd.Requery
    DoCmd.GoToRecord , , acLast
 

DoCmd.ReQueryでフォームの表示を最新化したうえで、DoCmd.GoToRecordで最終レコード、つまり先ほど追加したレコードへ移動しています。

最後にメッセージを出して完了です。

ADOを使ったレコードコピー

もう一つ、ADOを使ってレコードコピーをするパターンもご紹介します。
こちらも同様に、フォームのADOコピーボタンにイベントプロシージャを設定します。

内容は以下の通りです。


 Private Sub ADOコピー_ボタン_Click()

    Dim cnn As ADODB.Connection
    Dim rst1 As ADODB.Recordset
    Dim rst2 As ADODB.Recordset

    '変数にADOオブジェクトを代入
    Set cnn = CurrentProject.Connection
    Set rst1 = New ADODB.Recordset
    rst1.CursorLocation = adUseClient
    Set rst2 = New ADODB.Recordset
    rst2.CursorLocation = adUseClient
    
    'レコードセットを取得
    rst1.Open "TRN_売上サンプル", cnn, adOpenKeyset, adLockReadOnly
    rst2.Open "TRN_売上サンプル", cnn, adOpenKeyset, adLockOptimistic

    rst1.Filter = "売上ID = " & Me!売上ID
       
        rst2.AddNew
        
            rst2!売上日 = rst1!売上日
            rst2!顧客名 = rst1!顧客名
            rst2!数量 = rst1!数量
            rst2!単価 = rst1!単価
            rst2!特記事項 = rst1!特記事項
            
        rst2.Update


    '終了処理
    rst1.Close: Set rst1 = Nothing
    rst2.Close: Set rst2 = Nothing
    cnn.Close: Set cnn = Nothing

    DoCmd.Requery
    DoCmd.GoToRecord , , acLast
    
    MsgBox "コピーしました。", vbInformation + vbOKOnly, "コピー完了"
    
 End Sub
 

内容を説明します。
最初の


    Dim cnn As ADODB.Connection
    Dim rst1 As ADODB.Recordset
    Dim rst2 As ADODB.Recordset

    '変数にADOオブジェクトを代入
    Set cnn = CurrentProject.Connection
    Set rst1 = New ADODB.Recordset
    rst1.CursorLocation = adUseClient
    Set rst2 = New ADODB.Recordset
    rst2.CursorLocation = adUseClient
  

の部分はADOを利用する際の定型処理です。
詳しくは以下の記事を参照ください。

ADOを使ったレコード操作

次に、ADOのオブジェクトにレコードセットを取得します。


    'レコードセットを取得
    rst1.Open "TRN_売上サンプル", cnn, adOpenKeyset, adLockReadOnly
    rst2.Open "TRN_売上サンプル", cnn, adOpenKeyset, adLockOptimistic
 

今回はrst1とrst2という2つのレコードセットを利用しますが、どちらもTRN_売上サンプルテーブルを設定しています。
これは、レコード内容の参照用(rst1)とレコードの追加用(rst2)で分けるためです。

そのため、rst1の方はadLockReadOnlyとして、読み取り専用で設定しています。

その後


    rst1.Filter = "売上ID = " & Me!売上ID
 

でrst1からフォームで開いているレコードを抽出します。
その上で、rst2へのレコード追加処理を以下で実行します。


        rst2.AddNew
        
            rst2!売上日 = rst1!売上日
            rst2!顧客名 = rst1!顧客名
            rst2!数量 = rst1!数量
            rst2!単価 = rst1!単価
            rst2!特記事項 = rst1!特記事項
            
        rst2.Update
 

ここでは、AddNewメソッドを使ってレコードの追加処理を行っています。
左辺がrst2、右辺がrst1で同じフィールド名を指定することで、TRN_売上サンプルテーブルの内フォームで開いているレコードの値を、新規レコードにコピーしています。

最後にUpdateメソッドを使ってレコード追加を確定させます。

以上、レコードをコピーする機能をご紹介しました。


ACCESSを使いこなせば、業務の効率化や自動化が実現できます。
しかし、自分でACCESSを学ぶには時間がない、難しそうで不安、という方も多いでしょう。

そんな時は、ACCESS開発歴20年以上、過去に100以上のACCESSデータベースを開発してきた私(@hakoniwagadget)にお任せください。

ACCESSの新規開発、既存のACCESSの修正、ACCESSの操作レッスンなど様々なサービスをご提供しています。
ご興味のある方は下記のサービス一覧をご覧ください。

サービス一覧

最後までお読みいただき、ありがとうございました。