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

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

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

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

Q&A

解決済

2回答

1155閲覧

VBAでFOR文を回してデータを突合させたい

Kazuhiro-ch

総合スコア85

VBA

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

0グッド

0クリップ

投稿2022/11/23 23:59

前提

Sheet1(start)とSheet2(goal)からそれぞれ日付データを取得し、FOR文で突合させて、足りない部分をSheet1からSheet2へコピーしたいです。

詳細

日付データAデータB
11/2210002000

以上のようなデータが入ったシートが2枚あり、日付の部分を突合させ、不足分をコピペするといったものです。ただこれまでPythonしか使ったことがないため、データの型定義など慣れないことが多く、うまくいかないため質問いたしました。

発生している問題・エラーメッセージ

アプリケーション定義またはオブジェクト定義のエラーです

該当のソースコード

VB

1 2Sub compare_date() 3 4Dim L, lRow, M, mRow As Long 5 6lRow = Sheets("start").Cells(Rows.Count, "A").End(xlUp).Row '日付データの最終行 7mRow = Sheets("goal").Cells(Rows.Count, "A").End(xlUp).Row '比較先の日付データの最終行 8 9For L = 2 To lRow 10 If L >= Sheets("goal").Cells(M, "A") Then 11 MsgBox L 12 End If 13Next L 14 15End Sub 16

試したこと

MsgBoxを使っているのはコピーする前に、とりあえず値が適切か拾いたいためです。

試したこととしては、For Each などにして、FOR文を回しましたが、Variant型にしないといけずうまくいきませんでした。

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

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

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

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

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

guest

回答2

0

ベストアンサー

変数Mが未定義です。また、Lはただの行数を表す数値なので時刻比較をしたいならば正しいとは言えません。

Sub compare_date() Dim L as long , lRow as long, M as long, mRow As Long dim wsStart as worksheet:set wsStart=thisworkbook.Sheets("start") dim wsGoal as worksheet:set wsGoal=thisworkbook.Sheets("goal") lRow = wsStart.Cells(Rows.Count, "A").End(xlUp).Row '日付データの最終行 mRow = wsGoal.Cells(Rows.Count, "A").End(xlUp).Row '比較先の日付データの最終行 For L = 2 To lRow for M= 2 to mRow If wsStart.cells(L,1).value >= wsGoal.Cells(M, 1).value Then MsgBox L '時刻を出したいならwsStart.cells(L,1).value '処理的に一行一回ずつしか表示させなくていい気がするので内側のループを飛ばす Exit For End If nest M Next L End Sub

範囲セル指定でfor each を使う場合は変数にrangeオブジェクトが代入されるためrange型でないとエラーが出るのが原因です(variantは自動解釈してくれるので問題ありませんが、Long型だと型違いでエラーが出たということです)

for eachを使う場合

```ここに言語を入力 Sub compare_date() Dim L as Range , lRow as long, Dim M as Range, mRow As Long dim wsStart as worksheet:set wsStart=thisworkbook.Sheets("start") dim wsGoal as worksheet:set wsGoal=thisworkbook.Sheets("goal") lRow = wsStart.Cells(Rows.Count, "A").End(xlUp).Row '日付データの最終行 mRow = wsGoal.Cells(Rows.Count, "A").End(xlUp).Row '比較先の日付データの最終行 For each L in wsStart.Range(wsStart.cells(2,1),wsStart.cells(LRow,1) for M= 2 to mRow '一応、for each分は順番の保障がされてないので比較側は普通に回す If L.value >= wsGoal.Cells(M, 1).value Then MsgBox L.value Exit For End If nest M Next L End Sub

ただ、同じ時刻のデータがあるかどうかを比較するならばVBAにもDictionaryがあるのでこちらを使ったほうが簡潔で便利だと思います。
https://daitaideit.com/vba-dictionary/

投稿2022/11/24 00:26

編集2022/11/24 01:14
pig_vba

総合スコア807

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

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

0

型定義以前にロジックの問題ですね。

L >= Sheets("goal").Cells(M, "A")
L(行番号)と日付(A列の値)を比較しても無意味です。

突合するなら、2つのシートの値を二重ループして比較する必要があります。

下記のようなコードになるでしょう。

vba

1Sub compare_date() 2 3 Dim L As Long, lRow As Long, M As Long, mRow As Long '型宣言は一つずつする必要がある 4 5 lRow = Sheets("start").Cells(Rows.Count, "A").End(xlUp).Row '日付データの最終行 6 mRow = Sheets("goal").Cells(Rows.Count, "A").End(xlUp).Row '比較先の日付データの最終行 7 8 For L = 2 To lRow 9 For M = 2 To mRow 10 If Sheets("start").Cells(L, "A") = Sheets("goal").Cells(M, "A") Then 11 Exit For 12 End If 13 Next M 14 If M > mRow Then MsgBox L 'カウンターが最終行より上なら一致する値無し 15 Next L 16 17End Sub

ただ、Excelなので、関数を使えば2重ループする必要はないです。
あるいは、連想配列(Dictionaryオブジェクト)を使うと高速化できます。

エクセルのMatch関数を使って検索するコード例

vba

1Sub compare_date2() 2 3 Dim rStart As Range, rGoal As Range 4 With Sheets("start") 5 Set rStart = .Range(.Cells(2, "A"), .Cells(Rows.Count, "A").End(xlUp)) '日付データのセル範囲 6 End With 7 With Sheets("goal") 8 Set rGoal = .Range(.Cells(2, "A"), .Cells(Rows.Count, "A").End(xlUp)) '比較先の日付データのセル範囲 9 End With 10 11 Dim l As Variant, i As Long 12 For Each l In rStart 13 On Error Resume Next 14 i = WorksheetFunction.Match(l, rGoal, 0) 'Matchで一致データを検索 15 If Err.Number <> 0 Then MsgBox l.Row '一致データがないとエラーになるのでメッセージ表示 16 On Error GoTo 0 17 Next l 18 19End Sub

投稿2022/11/24 01:11

編集2022/11/24 01:33
hatena19

総合スコア33722

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問