次の操作を行うマクロの構文を教えてください。

シート1 Range("A1")=1, Range("A2")=2,Range("A3")=3,Range("A4")=4,
シート2  Range("A1")=3, Range("A2")=4
シート1を検索してシート2に含まれない1、2の値ををシート2にとってきたい

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2010/03/14 13:57:41
  • 終了:2010/03/14 16:42:54

ベストアンサー

id:GreenStar No.3

GreenStar回答回数192ベストアンサー獲得回数462010/03/14 14:46:27

ポイント28pt

こんな感じ!!

Sub Macro1()
    Dim r1 As Range, r2 As Range, c As Variant, m As Object
    Set r1 = Worksheets("Sheet1").Range("A1:A" & Range("A65536").End(xlUp).Row): 'シート1のデータ範囲
    Set r2 = Worksheets("Sheet2").Range("A65536").End(xlUp): 'シート2のデータ範囲
    
    r2.Select: ' シート2選択!
    ActiveCell.Offset(1, 0).Select: ' あらかじめ書き込み位置へ移動!
    For Each c In r1: 'シート1から1つずつ取って来る!
        Set m = r2.Find(c): 'シート2上で探す!!
        If m Is Nothing Then: 'シート2に無ければ!
            ActiveCell.Value = c: '書き込んで!
            ActiveCell.Offset(1, 0).Select: ' 次書き込み位置へ移動!
        End If
    Next
End Sub
id:nmfo4n67

早速ありがとうございます。実行時に

コンパイルエラー

End ifに対するIfブロックがありません

のエラーメッセージが出ます。

アドバイスおねがいします

2010/03/14 16:20:42

その他の回答(3件)

id:p332 No.1

p332回答回数36ベストアンサー獲得回数32010/03/14 14:17:46

ポイント29pt

下記のコードが素朴な書き方です。

一行目から、空白のセルにあたるまで繰り返し処理します。

処理速度を考えていない書き方なので、行数が数千行を超えると遅く感じるかもしれません。

Sub main()
    
    Dim Rng1 As Range
    Dim Rng2 As Range
    
    Set Rng1 = Sheets(1).Cells(1, 1)
    Set Rng2 = Sheets(2).Cells(1, 1)
    
    size1 = Rng1.CurrentRegion.Rows.Count
    size2 = Rng2.CurrentRegion.Rows.Count
    lastRow = size2
    
    For i = 1 To size1
        
        found = False
        For j = 1 To size2
            If Rng1(i, 1) = Rng2(j, 1) Then
                found = True
                Exit For
            End If
        Next
        
        If Not found Then
            lastRow = lastRow + 1
            Rng2(lastRow, 1) = Rng1(i, 1)
        End If
        
    Next
    
End Sub
id:nmfo4n67

size1 =

のところで

コンパイルエラー

変数が定義されていません

のメッセージがでます

アドバイスお願いします

2010/03/14 16:24:19
id:fuma10131 No.2

sakura-fuma回答回数10ベストアンサー獲得回数02010/03/14 14:36:36

ポイント6pt

こうやってこうやってこうだ!!(意味不明WW

id:GreenStar No.3

GreenStar回答回数192ベストアンサー獲得回数462010/03/14 14:46:27ここでベストアンサー

ポイント28pt

こんな感じ!!

Sub Macro1()
    Dim r1 As Range, r2 As Range, c As Variant, m As Object
    Set r1 = Worksheets("Sheet1").Range("A1:A" & Range("A65536").End(xlUp).Row): 'シート1のデータ範囲
    Set r2 = Worksheets("Sheet2").Range("A65536").End(xlUp): 'シート2のデータ範囲
    
    r2.Select: ' シート2選択!
    ActiveCell.Offset(1, 0).Select: ' あらかじめ書き込み位置へ移動!
    For Each c In r1: 'シート1から1つずつ取って来る!
        Set m = r2.Find(c): 'シート2上で探す!!
        If m Is Nothing Then: 'シート2に無ければ!
            ActiveCell.Value = c: '書き込んで!
            ActiveCell.Offset(1, 0).Select: ' 次書き込み位置へ移動!
        End If
    Next
End Sub
id:nmfo4n67

早速ありがとうございます。実行時に

コンパイルエラー

End ifに対するIfブロックがありません

のエラーメッセージが出ます。

アドバイスおねがいします

2010/03/14 16:20:42
id:taknt No.4

きゃづみぃ回答回数13481ベストアンサー獲得回数11982010/03/14 16:31:30

ポイント27pt
Sub settest()
    For a = 1 To 65536
        Debug.Print Worksheets("Sheet1").Cells(a, "A")
        If Worksheets("Sheet1").Cells(a, "A") = "" Then Exit For
        If Worksheets("Sheet2").Range("A1:A65536").Find(Worksheets("Sheet1").Cells(a, "A"), LookAt:=xlWhole) Is Nothing Then
            Worksheets("Sheet2").Range("A1").End(xlDown).Offset(1, 0) = Worksheets("Sheet1").Cells(a, "A")
        End If
    Next a
End Sub

A列のみやってます。

  • id:SALINGER
    p332 さんの回答は宣言していない変数も使ってるので、
    宣言を強制する先頭のOption Explicitを削除すれば動作すると思うよ。
  • id:SALINGER
    GreenStar さんの回答は行末のコロン「:」を全部とってみてください。
  • id:p332
    ご指摘いただいたコンパイルエラーは、
    ・同一モジュールにOption Explicitステートメントがあり、かつ
    ・宣言していない変数を使う
    と発生します。
    よって、

    ・同一モジュール内の「Option Explicit」を消す
    ・モジュールを新しく作り、そこに私のコードを移す
    ・下記のコードを追加し変数の宣言を追加する
    Dim size1
    Dim size2
    Dim lastRow
    Dim found
    Dim i
    Dim j
    Dim k

    のいずれかを行うことにより解決できます。
  • id:SALINGER
    それと、水をさすようで悪いですが、優秀回答の方の回答は間違いですよ。
    別のデータで試してみるとわかると思います。
  • id:p332
    ベストアンサーのコードには、行末コロンの他に2箇所修正すべき点があるかと思うので指摘させていただきます。


    ひとつめ、は3行目です
    Set r1 = Worksheets("Sheet1").Range("A1:A" & Range("A65536").End(xlUp).Row): 'シート1のデータ範囲

    2回目に出てくるRange("A65536")は、アクティブシート(表示されているシート)のセル範囲を意味します。
    また、このコードはシート2をアクティブにした状態で実行されることを想定しています。
    (そうでないと、6行目
    r2.Select: ' シート2選択!
    で、アクティブでないシートのセル範囲をselectしようとするためエラーが発生します。


    よって、r1に正しいセル範囲が代入されません。

    2つめは、9行目です
    Set m = r2.Find(c): 'シート2上で探す!!

    Findメソッドは、セル範囲の中から値を探してヒットしたセルを返しますが、r2は末端の単一セルが代入されているため、
    正しく検索できません。

    サンプルデータだと、ひとつめの問題により、シート1の4行のデータのうち、シート2の末端行である2行目までしか、
    対象としないため、たまたま正しい結果が得られます。

    修正するとしたら、下記のようになるかと思います。

    3行目
    修正前:Set r1 = Worksheets("Sheet1").Range("A1:A" & Range("A65536").End(xlUp).Row)
    修正後:Set r1 = Worksheets("Sheet1").Range("A1:A" & Worksheets("Sheet1").Range("A65536").End(xlUp).Row)

    9行目
    修正前:Set m = r2.Find(c)
    修正後:Set m = Range(Cells(1,1),r2).Find(c)

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません