[[20210228111621]] 『最下行を取得して最下行に貼り付け』(ふぅ) ページの最後に飛ぶ

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

 

『最下行を取得して最下行に貼り付け』(ふぅ)

余りに基礎的な質問で申し訳ありません。
基礎的過ぎて、どこが間違っているのか、分からなくなってしまいました。

Sheet1のA列、B列をコピーして、Sheet2のA列に貼り付けるマクロのつもりが
Sheet2のA列には、Sheet1の1行目しか貼りつきません。
どの記述がおかしいのでしょうか?
(列はC,D‥と続きますが、ここではB列しか書いていません)

すみませんが、宜しくお願いします。

 Sub 貼付5()
'
    Columns("A:A").Select
    Selection.Clear

    Sheets("Sheet1").Select
    Range("A2").End(xlUp).Select
    Selection.Copy

    Sheets("Sheet2").Select
    Range("A1").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False

    Sheets("Sheet1").Select
    Range("B2").End(xlUp).Select
    Selection.Copy

    Sheets("Sheet2").Select
      n = Cells(Rows.Count, "C").End(xlUp).Row + 1
    Range("A" & n).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False

 End Sub

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


■1
VBAの世界では基本的に、ブックやシート(オブジェクトと言います)を明示すれば、いちいちアクティブにしたり選択したりする必要はありません。

■2
「標準モジュール」でシートの指定を省略した場合、ActiveSheetが指定されたものと見なされます。
したがって、「■1」のこととも併せて、ブックやシートはきちんと明示することをお勧めします。

■3
ステップ実行という方法を使うと1行ずつ順番に実行することができるので、想定通りに動かない原因を調べることが容易になりますのでトライしてみてはどうでしょうか。

※ステップ実行とは初耳だと言うのであれば↓を読んでみてください。

 【ステップ実行】
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/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

■4
PasteSpecialメソッドについて、Operation, SkipBlanks, Transpose は規定値を指定していますので記述を省略しても結果は同じです。

■5
「n」という変数について宣言がされていません。
ダメとはいいませんが、↓を読んでみてください。
http://officetanaka.net/excel/vba/beginner/06.htm

■6
上記を踏まえて提示のコードを整理するとこうなります。
(一部想像で補完しています)

    Sub 貼付5_整理()
        Dim n As Long
        Stop 'ブレークポイントの代わり

        Sheets("Sheet2").Columns("A:A").Clear                                            '(1)

        Sheets("Sheet1").Range("A2").End(xlUp).Copy                                 '(2)
        Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteValues    '(3)

        Sheets("Sheet1").Range("B2").End(xlUp).Copy                                 '(4)        
        With Sheets("Sheet2")
            n = .Cells(.Rows.Count, "C").End(xlUp).Row + 1                          '(5)
            .Range("A" & n).PasteSpecial Paste:=xlPasteValues                       '(6)
        End With
     End Sub

結局、ステップ実行すると

 (1)Sheet2のA列全体をクリアする
 (2)Sheet1のA1セルをコピーする【Range("A2").End(xlUp)はA1セル以外ありえません。】
 (3)Sheet2のA1セルに(2)を値貼付けする
 (4)Sheet1のB1セルをコピーする【Range("B2").End(xlUp)はB1セル以外ありえません。】
 (5)Sheet2の【C】列最終行の1行下の行番号を求める
 (6)Sheet2の【A】列かつ(5)で求めた行に(4)を値貼付けする

となっていることが分かると思います。
いくつか思い通りになってない部分がありませんか?

(もこな2 ) 2021/02/28(日) 12:34


追加で。
    Sub 本当はこんな感じかも()
        Dim n As Long, フラグ As Boolean

        Sheets("Sheet2").Columns("A:A").Clear

        'A列のコピペ
        n = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
        If n > 1 Then
            Sheets("Sheet1").Range("A2:A" & n).Copy
            Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteValues
            フラグ = True
        End If

        'B列のコピペ
        n = Sheets("Sheet1").Cells(Rows.Count, "B").End(xlUp).Row
        If n > 1 Then
            Sheets("Sheet1").Range("B2:B" & n).Copy
            If フラグ = True Then
                Sheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues
            Else
                Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteValues
            End If
        End If
    End Sub

また、表の項目行を除いて1列に組み替えたいというようにも思えるので、そうだとすればもっと単純にできるとおもいます。

    Sub 表を組み替え()
        Dim 表範囲 As Range, 出力セル As Range
        Dim 列 As Long

        Stop 'ブレークポイントの代わり

        With Worksheets("Sheet1").Range("A1").CurrentRegion
            Set 表範囲 = .Offset(1).Resize(.Rows.Count - 1)
        End With

        With Worksheets("Sheet2")
            Set 出力セル = .Range("A1")
            .Columns("A:A").Clear
        End With

        For 列 = 1 To 表範囲.Columns.Count
            出力セル.Resize(表範囲.Rows.Count).Value = 表範囲.Columns(列).Value
            Set 出力セル = 出力セル.Offset(表範囲.Rows.Count)
        Next 列

    End Sub

(もこな2 ) 2021/02/28(日) 13:12


大変網羅的な指摘をいただいていますが、私は一点だけ追記させていただきます。
 
Range("A2").End(xlUp)の意味は理解していますか?
 
ワークシート上の操作で言うと、
A2セルを選択した状態で、コントロールキーを押したまま↑矢印を押す、
ことと同じです。
まず、そのことから理解を始めたほうがよいのではないですか?
(γ) 2021/02/28(日) 13:42

もこな2様 
ありがとうございます。
Sub 表を組み替え()
で思った結果が出ました。
但し、Sheet1の値は数式の結果で得られたもので、最下行が数式の入っている最下行になってしまいました・

また、参考URLも感謝します。
参考にさせていただきます。

γ様
ありがとうございます。意味を理解していませんでした。
気付かせていただきありがとうございます。
(ふぅ) 2021/02/28(日) 15:22


頂いたコードなどを、内容を余り理解しないまま飲み込まないようにした方がいいですよ。
キチンと理解して、不明点は質問されるようにするのが、提供頂いた人に報いることになります。

(γ) 2021/02/28(日) 15:29


■7
>Sub 表を組み替え() で思った結果が出ました。
>但し、Sheet1の値は数式の結果で得られたもので、最下行が数式の入っている最下行になってしまいました・

既にコメント頂いていますが、私もステップ実行して何がどうなっているのかきちんと理解することを強くお勧めします。

■8
今回のケースでいえば、 数式が入っているのでCurrentRegion や Endプロパティでは正しいセル範囲や最終行を取得できないはずです。

なので、

 (1)項目行をしらべて【最終列】を取得する
 (2)1列目〜最終列を下から逆順で調べて【""じゃないセル】の行番号を取得する
 (3)A2セル〜(2)の行、(1)の列のセルを処理対象にする
 (4)組み替えを実行

とすればよいでしょう。

なお、逆順で調べて【""じゃないセル】を探す方法は、例えば↓が参考になると思います。
[[20200415114844]] 『VBAのマクロがうまく動かない』(ノブ)

(もこな2 ) 2021/02/28(日) 18:14


返信をいただいているのに、お礼が大変遅くなって申し訳ありません。

頂いた参考URLを見ながら、もう少しまともに質問が出来るように
勉強します。

今回はもこな2様のコードで結果を取り出すことは可能になりましたので
一旦、「解決」とさせていただきます。

何度も回答いただき、本当にありがとうございました。

(ふぅ) 2021/03/01(月) 16:17


コメント返信:

[ 一覧(最新更新順) ]


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