質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

2回答

2856閲覧

Access VBA 特定のフィールド&レコードのデータ複製

Yoshikun_0945

総合スコア224

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

0クリップ

投稿2019/03/24 00:51

編集2019/03/24 05:44

###AccessのVBAにてテーブルの特定のフィールド&レコードのデータを複製する
AccessのVBAにてcsvのデータをテーブルに取り込み後、特定のフィールドにて格納されているデータを同一フィールドのデータが格納されていないレコードにデータの複製はできますでしょうか?

#####csvの中身

日付社員番号金額
2019/04/01
22255,000
224010,000
22732,000

csvに出力するデータの都合でこのようになっています。

#####データ複製後のテーブル

日付社員番号金額
2019/04/0122255,000
2019/04/01224010,000
2019/04/0122732,000

日付のデータを社員番号が格納されているフィールドに複製し、代わりに、日付データのみのフィールドを削除するという流れです。

'テキストファイルを取り込む DoCmd.TransferText acImportDelim, "IN 金額合計", "T01_金額合計" _ , "C:\Users\Documents\01-1 売上管理\01 金額合計.txt" '金券カードテーブルを開く Set db = CurrentDb() Set rs = CurrentDb.OpenRecordset("T01_金額合計", dbOpenTable) ReDim vArray(rs.RecordCount - 1, 2) i = 0 '最後のレコードまで繰り返す Do Until rs.EOF '有効な社員番号かつ取引がある場合 If (rs(1) >= 2200 And rs(1) <= 2473) And rs(2) > 0 Then rs.Edit '取引番号の初期値として『99999』を出力する rs(3) = "99999" '変更をアップデートする rs.Update Else If IsDate(rs(0)) And i = 0 Then i = 1 Else 'レコードを削除する rs.Delete End If End If '次のレコードに移動する rs.MoveNext Loop

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2019/03/24 01:02

csvファイルの1行目は日付のみが入っていて、2行目以降は日付以外の2項目が入っている、という事ですか? それとも、日付のみの行があって、その後に日付以外が入っている行が続いて、というパターンが繰り返されているのでしょうか?
Yoshikun_0945

2019/03/24 05:22

1行目は必ず日付のみで、2行目以降がデータとなり、データが約20行ほどあったのちに、また日付行、データ行×約20行という感じです。
sazi

2019/03/24 05:25

厄介な仕様ですね。
Yoshikun_0945

2019/03/24 05:28

元データ(Csvに出力する電子データ)の都合で・・・。申し訳ありません。
sazi

2019/03/24 06:10 編集

前の質問でのファイルごとの日付もこの仕様では見直しが必要にならないのですか?
guest

回答2

0

ベストアンサー

更新クエリーで更新したのちに、不要なデータを削除クエリーで削除します。
[更新クエリー]

SQL

1UPDATE インポートテーブル 2SET 日付 = DLookUp("日付","インポートテーブル","日付 is not null and 社員番号 is null") 3WHERE 日付 Is Null

[削除クエリー]

SQL

1delete from インポートテーブル 2WHERE 社員番号 Is Null

追記

1行目は必ず日付のみで、2行目以降がデータとなり、データが約20行ほどあったのちに、また日付行、データ行×約20行という感じです。

この仕様の場合、日付の入力があるものがヘッダーで、日付が無いものがデータという括りになり、データがどのヘッダーに含まれるかを識別する必要があります。
ですので、基本的にCSVを順読みするしかありません。
テーブルにインポートする場合はオートナンバーフィールドを持たせて追加後にそのオートナンバーで範囲を限定させる必要があります。

投稿2019/03/24 02:40

編集2019/03/24 05:32
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yoshikun_0945

2019/03/24 02:42

回答いただきましてありがとうございました。 この方法を実行してみます。
sazi

2019/03/24 02:42

確認できてからクローズした方が良いですね。
Yoshikun_0945

2019/03/24 05:21

上記のコードはどこかの行がSQL = でしょうか?
sazi

2019/03/24 05:22

VBAでSQLを記述したいという事ですか?
Yoshikun_0945

2019/03/24 05:29

上記のコードだとSQL = が必要でしょうか?
Yoshikun_0945

2019/03/24 05:39

日付、社員番号、金額以外にオートナンバー型フィールドが必要という意味でよろしかったでしょうか?
sazi

2019/03/24 05:45

最初に回答した部分はCSVに複数の日付データが含まれるという事なので、使えませんから、無視して下さい
Yoshikun_0945

2019/03/24 05:49

私が記載したコードに追記する形で、日付の複製処理を行う場合はどのような処理になりますでしょうか?
sazi

2019/03/24 05:51 編集

オートナンバーを利用する為には、TransferTextを使用する場合はインポート定義が必要です。 また、オートナンバーは確実に順序が保証されるとは言い切れない(大丈夫でしょうが、保証はされていない)ですし、CSVを直接読み出す方法の方が良さそうな気がします。
Yoshikun_0945

2019/03/24 05:52

csvを直接読みだすとはどういう方法でしょうか?
Yoshikun_0945

2019/03/24 06:04

ありがとうございました。
sazi

2019/03/24 06:13

リンクテーブルで順読みの方が簡単かもしれません。 但し、order byは絶対に措定しないで。
guest

0

Accessの場合(他のデータベースも同様ですが)、テーブルとして取り込んだ場合、入力順は保持されません。
次に開いたときに、どのような順になるかは不定です。

ですので、saziさんも指摘してるようにオートナンバー型のフィールドを持たせたテーブルにインポートして、オートナンバーで並べ替えて順次走査するか、
あるいは、csvをリンクテーブルにしておいて、それをVBAで順次読み込んで取り込みテーブルに順次追加していくという方法がいいでしょう。(リンクテーブルならテキストファイルを順次読み込みするので並び順はテキストと同じになる)

リンクテーブル案のコード例

  • あくまで例ですのでそのままでは動作しません。
  • ロジックを参考にしてください。
  • 変数宣言、エラー処理は適宜追加してください。

vba

1 'テキストファイルをリンク 2 DoCmd.TransferText acLinkDelim, , "LinkTbl" _ 3 , "C:\test\data.txt" 4 5 'テキストファイルをリンク 6 DoCmd.TransferText acLinkDelim, , "LinkTbl" _ 7 , "C:\test\data.txt" 8 9 Set db = CurrentDb() 10 'リンクテーブルを開く 11 Set rs1 = db.OpenRecordset("LinkTbl;") 12 '追加先テーブル 13 Set rs2 = CurrentDb.OpenRecordset("DataTbl") 14 15 16 '最後のレコードまで繰り返す 17 Do Until rs1.EOF 18 '日付がNullでなければ、変数に格納して次レコードへ 19 If Not IsNull(rs1!日付.Value) Then 20 varDate = rs1!日付.Value 21 rs1.MoveNext 22 End If 23 '追加先テーブルに追加 24 rs2.AddNew 25 rs2!日付.Value = varDate 26 rs2!社員番号.Value = rs1!社員番号.Value 27 rs2!金額.Value = rs1!金額.Value 28 rs2.Update 29 30 '次のレコードに移動する 31 rs1.MoveNext 32 Loop

投稿2019/03/24 06:38

編集2019/03/24 07:26
hatena19

総合スコア33699

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2019/03/24 06:41

order byは外しておいた方が良いかと。
hatena19

2019/03/24 07:25

そうでした。サンプルのを修正し忘れてました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問