[[20220629163739]] 『セルの値を入れ替える』(るう) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『セルの値を入れ替える』(るう)

離れたセル範囲の値を入れ替えようとしているのですが、エラーが出ます。
どこがおかしいのかわかりません。
どなたか教えていただけませんか。

Sheets("抽出")のCells(x, 3)に"現金"と入力されていたら、
Range(Cells(x, 2), Cells(x, 3))と
Range(Cells(x, 5), Cells(x, 6))の
値を入れ替えたいのですが、下記の'←の部分でエラーが出ます。

Sub セルの値の入替()

  Dim y As Long, x As Long
  Dim rng1 As Range, rng2 As Range, rng3 As Range

  With Sheets("抽出")
    y = .Cells(Rows.Count, 1).End(xlUp).Row

    For x = 1 To y
      If .Cells(x, 3).Value = "現金" Then
        Set rng1 = .Range(Cells(x, 2), Cells(x, 3))
        Set rng2 = .Range(Cells(x, 5), Cells(x, 6))
        .Range(rng1, rng2).Select
        rng3 = .Range(rng1, rng2).Areas(1)  '←エラーの部分
        .Range(rng1, rng2).Areas(1) = .Range(rng1, rng2).Areas(2)
        .Range(rng1, rng2).Areas(2) = rng3
      End If
    Next x
  End With

End Sub

どうぞよろしくお願いします。

< 使用 Excel:Excel2016、使用 OS:Windows10 >


 エラーの原因は、単純に Set がないことだと思いますが、
 エラーがでなくなっても、結果は期待してものと違うとおもいますよ
 やってみてください
(´・ω・`) 2022/06/29(水) 16:51

既に(´・ω・`)さんからコメントがありますが、投稿しておきます。

■1
>エラーが出ます。

 rng3 As Range

↑なのですから少なくとも"Set"しないとだめです。

 rng3 = .Range(rng1, rng2).Areas(1)
            ↓
 Set rng3 = .Range(rng1, rng2).Areas(1)

■2
VBAの世界では基本的にシートやセルを明示すれば、いちいちアクティブにしたり選択したりする必要はありません。
また、提示されたコードではSelectionを使ってないので↓は不要です。

 .Range(rng1, rng2).Select

■3
「■2」で不要と言いましたが、選択したセル範囲を見ればわかるように↓は

 .Range(rng1, rng2)
 .Range(Cells(x, 2), Cells(x, 6))

↑のように解釈されています。(rng1の左上のセル〜rng2の右下のセル)
よってAreaは1つですから、「■1」を直したとしても結局↓でエラーになります。

 〜〜〜 .Range(rng1, rng2).Areas(2)

■4
おそらくイメージとしては↓のような感じだったのでしょうが、

    Sub 研究用()
        Dim x As Long
        Dim rng3 As Range

        Stop

        With Sheets("抽出")
            For x = 1 To .Cells(Rows.Count, 1).End(xlUp).Row
                If .Cells(x, 3).Value = "現金" Then
                    Set rng3 = Union(.Range(.Cells(x, 2), .Cells(x, 3)), .Range(.Cells(x, 5), .Cells(x, 6)))
                    rng3.Areas(1).Value = rng3.Areas(2).Value
                    rng3.Areas(2).Value = rng3.Areas(1).Value
                End If
            Next x
        End With
    End Sub

当然のことながら↓が実行されるときには、既に1行前で書き換えが済んでるから思った処理にならないでしょう。

 rng3.Areas(2).Value = rng3.Areas(1).Value

■5
ということを踏まえて、一旦データを待避する変数を1つ用意するようにしてみてはどうですか?

    Sub 研究用_改()
        Dim x As Long
        Dim rng3 As Range
        Dim tmp As Variant

        Stop

        With Sheets("抽出")
            For x = 1 To .Cells(Rows.Count, 1).End(xlUp).Row
                If .Cells(x, 3).Value = "現金" Then
                    Set rng3 = Union(.Range(.Cells(x, 2), .Cells(x, 3)), .Range(.Cells(x, 5), .Cells(x, 6)))
                    tmp = rng3.Areas(1).Value '←書き換える前に待避
                    rng3.Areas(1).Value = rng3.Areas(2).Value
                    rng3.Areas(2).Value = tmp '←待避したデータを反映
                End If
            Next x
        End With
    End Sub

(もこな2 ) 2022/06/29(水) 17:34


■余談
Areasに拘らなければ↓でもよいですね。
    Sub 研究用_改二()
        Dim x As Long, tmp As Variant
        Stop
        For x = 1 To .Cells(Rows.Count, 1).End(xlUp).Row
            If Sheets("抽出").Cells(x, 3).Value = "現金" Then
                With Sheets("抽出").Cells(x, 2).Resize(, 2)
                    tmp = .Value
                    .Value = .Offset(, 3).Value
                    .Offset(, 3).Value = tmp
                End With
            End If
        Next x
    End Sub

(もこな2 ) 2022/06/29(水) 19:18


みなさんコメントありがとうございます。
もこな2さん、私のやりたいことを察していただいてありがとうございます。
ちゃんと思い通りになりました。
本当にありがとうございます。

研究用_改二がコードがより簡単なのでそちらを使わせていただきました。

ひとつ質問ですが、3行目の「Stop」をこの場所に入れてる意味は何ですか?
(るう) 2022/06/30(木) 13:26


■6
>研究用_改二がコードがより簡単なのでそちらを使わせていただきました。
>ひとつ質問ですが、3行目の「Stop」をこの場所に入れてる意味は何ですか?

 *STOPステートメント
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/stop-statement
http://officetanaka.net/excel/vba/statement/Stop.htm

要は、ブレークポイントの代わりとして使っています。

意図としては、

 研究資料として提示しているので、丸パクリして完成じゃなくて、なにがどうなっているのかちゃんとステップ実行して確認してみてね。
 おまけでブレークポイントは設定しておいたよ。(位置は、なるべく初めのほうがいいかなと思ったからです)

って感じです。
「ブレークポイント」や「ステップ実行」という言葉がわからなければ↓をご覧ください。

 【ステップ実行】
https://www.239-programing.com/excel-vba/basic/basic023.html
http://plus1excel.web.fc2.com/learning/l301/t405.html

 【ブレークポイント】
https://www.239-programing.com/excel-vba/basic/basic022.html
https://www.tipsfound.com/vba/01010

 【イミディエイトウィンドウ】
https://www.239-programing.com/excel-vba/basic/basic024.html
https://excel-ubara.com/excelvba1/EXCELVBA486.html

 【ローカルウィンドウ】
https://excel-ubara.com/excelvba4/EXCEL266.html
http://excelvba.pc-users.net/fol8/8_2.html

■7
どのくらいのデータ量(行数)があるのか分かりませんが、場合によっては、逐一書き換えずにまとめて処理したほうがよいかもしれません。

    Sub 研究用_別案()
        Stop

        Dim 配列1 As Variant, 配列2 As Variant
        Dim 最終行 As Long, i As Long

        With ActiveSheet
            最終行 = .Cells(Rows.Count, "C").End(xlUp).Row

            配列1 = .Range("B1:C" & 最終行).Value
            配列2 = .Range("E1:F" & 最終行).Value

            For i = 1 To 最終行
                If .Cells(i, "C").Value = "現金" Then
                    配列1(i, 1) = .Cells(i, "E").Value
                    配列1(i, 2) = .Cells(i, "F").Value
                    配列2(i, 1) = .Cells(i, "B").Value
                    配列2(i, 2) = .Cells(i, "C").Value
                End If
            Next i

            .Range("B1:C" & 最終行).Value = 配列1
            .Range("E1:F" & 最終行).Value = 配列2
        End With
    End Sub

(もこな2 ) 2022/06/30(木) 17:49


もなこ2さん、何から何までご親切にありがとうございました。
丸パクリと言われたらそうかもしれません。。。
でも次に何かをする時に応用できませんので私なりにステップ実行して、コードの意味も考えながらやりました。
本当にご親切に色んなコードを提示していただいて勉強になります。
ありがとうございました。
(るう) 2022/07/07(木) 13:20

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.