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

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

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

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

Access

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

Q&A

解決済

EXCEL VBAを使ってAccessからデータを取得したい。

Kazuhiro-ch
Kazuhiro-ch

総合スコア82

VBA

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

Access

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

1回答

0グッド

0クリップ

413閲覧

投稿2022/11/28 03:16

コード的な質問というよりは、方法についての質問です。

まず、実現したいことですが、以下のようなものを想定しています。

以前質問:startとgoalのAセルの日付データを比較し、goalにないデータを start から行ごとコピペするプログラムを考えています。
=>startからAccessDBに変更。つまりstartとAccessDBのAセルの日付データを比較し、AccessDBにないデータを start から行ごとコピペするプログラムを考えています。そのためAccessからデータを取得する必要があります。

書籍を見ていると、比較するためのデータ取得のために、Accessの日付データを取得する方法とSQLによりデータを出力する方法があるかと思うのですが、どちらが良いのでしょうか?どちらでも取得できるデータは同じですか?一般的にはどちらで記載されることが多いでしょうか?よろしくお願いいたします。

こちら以前質問した続きです。
前回質問URLです。
質問1:https://teratail.com/questions/8x4hz58p7q8s21
質問2:https://teratail.com/questions/6w0221ourt8sda

したいことイメージ

元データ(start)

日付数値データ数値データ
11/2612344567
11/2712344567
11/2812344567

コピペ先データ(AccessDB)

日付数値データ数値データ
11/2612344567
11/2712344567

コピペ先データ(コピペ後)

日付数値データ数値データ
11/2612344567
11/2712344567
11/2812344567

以下、コード参照

vba

1Sub compare_and_copy_date() 2 3 Dim L As Long, lRow As Long, M As Long, mRow As Long 4 Dim wsStart As Worksheet: Set wsStart = ThisWorkbook.Sheets("start") 5 Dim wsGoal As Worksheet: Set wsGoal = ThisWorkbook.Sheets("goal") 6 Dim myConn As New ADODB.Connection 7 8 myConn.Open ConnectionString:= _ 9 "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 10 "Data Source=C:\Users\test.accdb" 11 myRS.Open Source:="test", ActiveConnection:=myConn, _ 12 CursorType:=adOpenStatic 13 14 '行すべてを表示 15 wsStart.Rows.Hidden = False 16 '行の最終行を取得 17 lRow = wsStart.Cells(Rows.Count, "A").End(xlUp).Row 18 mRow = wsGoal.Cells(Rows.Count, "A").End(xlUp).Row 19 20 '日付に一致しないデータをコピペ(現状はエクセル別シートだがアクセスのテーブルに変更) 21 For L = 2 To lRow 22 For M = 2 To mRow 23 If wsStart.Cells(L, 1).Value = wsGoal.Cells(M, 1).Value Then 24 Exit For 25 End If 26 Next M 27 If M > mRow Then 28 wsStart.Rows(L).Copy Destination:=wsGoal.Cells(Rows.Count, "A").End(xlUp).Offset(1) 29 End If 30 Next L 31End Sub

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

hatena19

2022/11/29 03:07 編集

Accessファイル内のテーブルにデータを追加するということですよね。 ならば、Access側で実行した方がはるかに楽ですが、それではだめですか。
Kazuhiro-ch

2022/11/30 00:09

ご連絡ありがとうございます。 基本的にVBAでは追加される側にマクロを組んだ方が楽なのでしょうか?
hatena19

2022/11/30 00:15

Accessの方が外部データとの連携機能が豊富ということと、SQLが簡単に使えるという点で楽ですね。

回答1

2

ベストアンサー

エクセルでするなら下記のようなコードでしょうか。

vba

1Sub compare_and_copy_date() 2 3 Dim L As Long, lRow As Long, M As Long, mRow As Long 4 Dim wsStart As Worksheet: Set wsStart = ThisWorkbook.Sheets("start") 5 Dim myConn As New ADODB.Connection 6 myConn.Open ConnectionString:= _ 7 "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 8 "Data Source=C:\Users\test.accdb" 9 Dim myRS As ADODB.Recordset 10 myRS.Open Source:="test", ActiveConnection:=myConn, _ 11 CursorType:=adOpenDynamic 12 13 '行すべてを表示 14 wsStart.Rows.Hidden = False 15 '行の最終行を取得 16 lRow = wsStart.Cells(Rows.Count, "A").End(xlUp).Row 17 18 With myRS 19 For L = 2 To lRow 20 .MoveFirst 21 .Find "日付=#" & Format(wsStart.Cells(L, 1).Value, "yyyy/mm/dd") & "#", 0, adSearchForward 22 If .EOF Then '一致する日付がなければ、行データを追加 23 .AddNew 24 !日付.Value = wsStart.Cells(L, 1) 25 !数値1.Value = wsStart.Cells(L, 2) 26 !数値2.Value = wsStart.Cells(L, 3) 27 .Update 28 End If 29 Next L 30 End With 31 myRS.Close: Set myRS = Nothing 32 myConn.Close: Set myConn = Nothing 33 34End Sub

Access側でするなら、
テーブルの日付フィールドを主キーにするか、インデックスを設定しておきます。
そのうえで、このテーブルにエクセルのstartシートをインポートするだけで、コード無しに希望のことが実現できます。
主キーまたはインデックスが設定してあると、重複データは自動ではじいて取り込んでくれます。

投稿2022/11/30 02:44

hatena19

総合スコア32031

spoofy_dragon, Kazuhiro-ch👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Kazuhiro-ch

2022/11/30 07:00

ありがとうございます。一点質問なのですが、 .Find "日付=#" & Format(wsStart.Cells(L, 1).Value, "yyyy/mm/dd")の部分がアプリケーションの定義及びオブジェクト定義エラーになります。おそらくFormatのValueがおかしいのではと考えておりますが、いかがでしょうか? また日付=#がどういう意味なのかもあわせて教えていただけると幸いです。
hatena19

2022/11/30 08:16

startシートの1列目(日付)のセルの書式はどうなってますか。 .Find "日付=#" & Format(wsStart.Cells(L, 1).Value, "yyyy/mm/dd") の前に下記のコードを挿入して実行したときに、 Debug.Print wsStart.Cells(L, 1).Value イミディエイトウィンドウにどのような値が出力されますか。
Kazuhiro-ch

2022/12/01 01:38

2022/11/26という最新の日付が出力されました。
hatena19

2022/12/01 02:15

Debug.Print Format(wsStart.Cells(L, 1).Value, "yyyy/mm/dd") としたときはどうなりますか。 あと、Accessのtestテーブルにには、「日付」という名前のフィールドはありますか。また、そのフィールドの名前は日付/時刻型ですか。
Kazuhiro-ch

2022/12/01 05:47

同じく最新の日付が出力されます。 また日付:日付/時刻型というフィールドが存在します。
hatena19

2022/12/01 06:57

いままでの中では問題点は見当たらないですね。 実物を見ることができないこちら側から原因を推測するのはてかなか難しいです。 ADOでレコードセットを開いてFindで検索して見つからなかったらAddNewで追加するというロジックでできるはずですので、ADOについての解説ページを研究していろいろトライしてください。 うまく行かないようなら、Access側でインポートするという方法も検討してみてください。
Kazuhiro-ch

2022/12/03 15:06

承知しました。ひとまずそういたします。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

VBA

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

Access

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