[[20200319220557]] 『VBA 最終行に追加コピー』(文2号) ページの最後に飛ぶ

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

 

『VBA 最終行に追加コピー』(文2号)

Sub hoge()

        Sheets("hoge").Select
        Columns("A:A").Select
        Selection.Copy

        Sheets("hoge1").Select
        Range("D1").Select
        ActiveSheet.Paste
End sub

A列に別シートhoge1のD列をコピーするのですが
A列には既にデータがあります。
既存データの次の行にコピーするにはどう書けばよいでしょうか
宜しくお願い致します。

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


 >A列に別シートhoge1のD列をコピーするのですが
 >A列には既にデータがあります。
 コードはそうではなく、
 hogeシートのA列を、hoge1シートのD列にコピーペイストしていますが?

 以下は、行継続文字を使っているのですが、本来、一行のコードです。
 内容は、
 「hogeシートのA1:A10を hoge1シートのD列の最終行の次行にコピーペイストする」ものです。
 参考にしてください。

 Sub test()
     Sheets("hoge").Range("A1:A10").Copy _
         Sheets("hoge1").Cells(Rows.Count, "D").End(xlUp).Offset(1)
 End Sub

(γ) 2020/03/19(木) 22:37


ありがとうございます。
「hogeシートのA1:A10を」
A1:A10と固定ではなく日々、流動的な場合はどう書けばいいでしょうか
宜しくお願い致します。
(文2号) 2020/03/19(木) 22:41

最終行の次行というのが質問でしたよね。
そこは理解されました?
コピー元は焦点じゃなかったはず。

流動的だというならその都度指定させることです。
Application.Inputbox(そのうちType:=8)を
調べて下さい。
(γ) 2020/03/20(金) 01:01


ありがとうございます。
やはりその都度指定するのですね。

できれば、コピー元の最終行を自動判定して、そこの最終行にコピー先からデータコピペしたかったのですが、、、
言葉足らずですみません。
(文2号) 2020/03/20(金) 06:31


横からですが
>言葉足らずですみません。
【コピー元】の最終行に【コピー先】"から"データコピペ っていってるように思うんですが・・・

さらに、γさんが指摘済みですが
>A列に別シートhoge1のD列をコピーするのですが
とのことですが、コードを見ると、

 「hoge」シートのA列全体をコピー
         ↓
 「hoge1」シートのD1セル(D列全体)に貼付

ってなってます。

いずれも逆に思えるので、もう一度シート名を「元データ」「貼付先」みたいに変えて説明してみてはどうでしょうか?

ちなみに、

 【元データ】のA1〜A列最終行 をコピーして【貼付先】のD列最終行の1行下に貼付

ということは可能です。

(もこな2) 2020/03/20(金) 07:16


既に回答した最終行の求め方が理解されていれば、同様にできるはずですが。
Range("A1", A列の最終行セル)というようにして。

セル範囲の指定方法については、下記が参考になります。
一度まとめて整理しておかれることをお薦めします。
[セル範囲の指定方法]
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_cell.html

なお、内容からすると、下記の質問者さんと同一の方ですよね。
[[20200318200803]] 『VBAデータ追加』
きちんと返事をされたほうがいいですよ。

こちらに別の質問をしていなければ、
あちらのほうには当然返事がついているはずなのに、
あちらが放置されているのは、同じ方という証拠でしょう。

(γ) 2020/03/20(金) 07:30


たぶん↓も同じ方ですね・・・(2号っていってるし)
[[20200319172036]] 『vbaタイトルを消したい』(文ちゃん)

この掲示板のルール上、禁止はしていないようですが、ニックネームをコロコロ変えるのはお勧めしません。
同じ説明を何度もされてもウザったいでしょうし、説明する方もめんどくさいです。
別人を装うことで得することはあまり無いとおもいますから、ニックネームは固定することをおすすめします。

(もこな2) 2020/03/20(金) 07:47


ご指摘、お叱り
ありがとうございます。
(文2号) 2020/03/20(金) 08:03

もこな2様 すみません
荷物がきて途中になってしまいました
文ちゃんと文2号は私で同じです
(2号っていってるし)
はい、わざと分かるようにニックネームを書いて
自分の中で質問の関連性を後でまとめるつもりでした
1度に複数の質問と私も含めて混乱するかと思ったからです
お礼もまとめてするつもりでした

ウザったいことして
本当に申し訳御座いませんでした
(文2号) 2020/03/20(金) 08:55


大事なことを申し上げますが、
AをコピーしてBに貼り付けるとき、
A が コピー元、
B が コピー先ですよ。
あなたは、反対に使っています。
どうしてそういう回路に迷い込んだのか不明ですが。
(γ) 2020/03/20(金) 09:53

Y様
申し訳御座いませんでした。

どうしてそういう回路に迷い込んだのか不明ですが 私が初心者過ぎるという理由以外ありません。

(文2号) 2020/03/20(金) 10:46


 Sub test2()
    Dim 最終セル As Range
    Dim コピー元 As Range
    Dim 貼付先 As Range

    Set 最終セル = Sheets("hoge").Cells(Rows.Count, "A").End(xlUp)
    Set コピー元 = Sheets("hoge").Range("A1", 最終セル)
    Set 貼付先 = Sheets("hoge1").Cells(Rows.Count, "D").End(xlUp).Offset(1)

     コピー元.Copy 貼付先

 End Sub

(マナ) 2020/03/20(金) 11:32


[[20200319172036]]をみると、A1は見出しでコピーしたくないなら
 >Set コピー元 = Sheets("hoge").Range("A1", 最終セル)
                                       ↓
  Set コピー元 = Sheets("hoge").Range("A2", 最終セル)

(マナ) 2020/03/20(金) 11:41


[[20200318200803]]をみると、コピー元のシート名が固定でないなら
 Sub test3()
    Dim 最終セル As Range
    Dim コピー元 As Range
    Dim 貼付先 As Range

    With ActiveSheet
        Set 最終セル = .Cells(Rows.Count, "A").End(xlUp)
        Set コピー元 = .Range("A2", 最終セル)
    End With
    Set 貼付先 = Sheets("hoge1").Cells(Rows.Count, "D").End(xlUp).Offset(1)

     コピー元.Copy 貼付先

 End Sub

(マナ) 2020/03/20(金) 11:55


ん〜
もこな2さん、あなた様もどうかと。
「説明する方もめんどくさいです」⇒それであればもこな2さんは説明しなくてもよいではないでしょうか。
それにまるで某掲示板みたいに犯人探しみたいなことして楽しいですか?
そういう行為自体が客観的にウザったいと感じました。(というより同調してイジメに似てるかな〜と)
別人でも同人でもExcelの質問をしているわけですし、それに答えるのも答えないのも相手の自由のはずですよ。
あなた様がこのサイトの運営者なのか知りませんが、
せかっくの良いサイトが台無しになるのが残念に思えますよ。
少なくともあなた様の07:47の返答は質問者様の質問や意向に関係なく、あなたの想いだけになってます。
ここのルールを誇張されていましたが
このサイトの「初めての方へ」の「マルチポストについて」で
「マルチポストで何であれ、自由に質問して、自由に答えて、みんなで学んで解決してゆこう」 という考え方です」とあるように、
ここは、とても寛大で自由な方針のサイトです。
もなこ2さんの想いと逆のように思われます。

Yさんの「どうしてそういう回路に迷い込んだのか不明」の発言も嫌味っぽく嫌悪感でしかありません。
Yさん自身がケアレスミスを把握した上で返答しているのであればそれでよいではないでしょうか。
助言であれば、もっと人に対し思いやりのある言葉選びはできませんか。

いろんな質問者の方が委縮するような流れに違和感を感じました。
※私への返答は不要です。

(次郎と菜々子) 2020/03/20(金) 12:07


お叱りをいただいたようです。
言い訳ですが、
「参照元」と「参照先」というのがありますね。
これは相互に関連していて、
参照する方向とデータを取得する方向が違うので、
時々混乱することがあります。
これに比べて、「コピーする」というのは、
方向はかなり明確なものと考えていたので、
どうしてコピーに関して混乱が生ずるのか不思議だな、
という気持ちがあったわけです。

(γ) 2020/03/20(金) 13:26


マナ様
うわぁぁあ
私の未熟な質問の仕方に対しご親切にお答え頂き
ありがとうございます。
私がしたかったことを見事にクリアになっております。
感謝致します!
(文2号) 2020/03/20(金) 17:30

Yさん
あなたが言い訳したいのは自分で言ってる下記ではないの。
あなたの尺度で明確と思っている事項でも貴方と質問者はちがうのです。
他の質問者へも攻撃的な返答が見受けられますね。
ネットでなく実際の職場であなたのような発言する人がいたら、あなたに質問したくないし答えてほしくもありません。
クロスポジションで相手の状況や気持ちを取り入れることができていません。と指摘したのです。
※もうこれ以上のやりとりは不快なので返信しません。

[[20200318045110]]
# どうも最近、ミスリードする回答をしてしまうことが多い。
# 自分のことなら気合いも入るが、所詮他人事なので、
# 自分の知識の範囲で適当に答えてしまう「らしい」。
# 上手くいかなかったら直せばいいだけと開き直っているせいもあって、
# 迷惑この上ないかもしれない。
(γ) 2020/03/19(木) 19:52

(次郎と菜々子) 2020/03/20(金) 18:15


>私がしたかったことを見事にクリアになっております。

できれば、コードの意味を1行ずつ理解して欲しいです。
わたしは、他の回答をただ組み合わせただけです。

こんなこと書くと、わたしも叱られるのかな。
文句言ってないで、自分で回答すればよいのに…

(マナ) 2020/03/20(金) 18:46


余計なことわざわざ言うとこが上の誰かと似てる
(読んだーZ) 2020/03/20(金) 18:53

"できれば、コードの意味を1行ずつ理解して欲しいです。"

マナさんが上の回答者と同一人物かどうかなんてどうでもいいけど、
ここで質問してる人は掲示板を利用してまで勉強しようとしてる前向きな人なので
コードを理解しようとしている人が多いと思うよ。
お礼を先行したいだけかと思うけど。
どうしてそのお礼を謙虚に素直に受け入れないのかと。。。

もう質問者さんが満足して完了されているので終わりにしましょうよ。

(ねむねむ) 2020/03/20(金) 20:02


細心の注意を払って100%正しい回答だけするなんてできない、
たまには注意不足で前提を読み飛ばすこともありますよ、
という気持ちを自嘲的に書いたら、随分クローズアップされました。

私を批判なさっている方は、どのくらい回答されているんですか?
回答してみないと見えてこない世界もあるんですよ。
もしあなたが常連回答者であるなら、こうした発言にはならないと思いますよ。
論争する気もありませんがね。
(γ) 2020/03/20(金) 21:38


執拗だね。
誰もγさんを指名して回答を懇願してるわけでないしょうよ。
はいはい終わり終わり。
見苦しい。
(ねむねむ) 2020/03/20(金) 21:45

休日や外出自粛で暇な人が多いのかしょーもないコメントで荒れていて、質問者さんはもう見てないかもですけど、私も暇なんでいくつか補足説明すると・・
 ==========================================================
【1】
おそらく標準モジュールに書いているのだと思いますが、その場合
 Range("A1").Copy
      ↓
 ActiveSheet.Range("A1").Copy

上記のように、対象シートを書かないと"省略した"とみなされ「アクティブシート」を指定しているものとして扱われます。

 ==========================================================

【2】
Pasteメソッドについて調べて頂ければわかると思いますが、Destinationを省略すると、選択されているセルに貼り付けるという仕組みになっています。

 ==========================================================

【3】
マクロの記録で得られたコードなどをみると「Active〇〇」や「Selection.××」という記述になっているとおもいますが、基本的に対象となるオブジェクト(ブックやシート、セルなど)を明示すれば、わざわざアクティブにしたり選択したりする必要はありません。

 ==========================================================

【4】
以上を踏まえて、このトピックの最初のコードを(シート名を変更して)整理すると

    Sub 整理1()
        Sheets("コピー元").Columns("A:A").Copy
        Sheets("貼付先").Paste Destination:=Sheets("貼付先").Range("D1")
    End Sub

というように書くことができます。

 ==========================================================

【5】
一方で、↓は失敗します。

    Sub 整理1()
        Sheets("コピー元").Columns("A:A").Copy
        Sheets("貼付先").Paste Destination:=Sheets("貼付先").Range("D2")
    End Sub

これは、エラーメッセージで気が付かれるかもしれませんが、【列全体(つまり、1行目〜最大行)】を【2行目以降】に貼り付けようとしているため1行はみ出てしまうためです。
したがって、

 【A列全体】をコピー
   ↓
 【A1〜A列の最大行-1まで】をコピー

とすれば、理屈上は問題ないです。
ただ、何もないセルをわざわざコピーする必要もないわけで、普通は【A列のうちデータが入っている部分】をコピーするようにすると思います。

 ==========================================================

【6】
では、【A列のうちデータが入っている部分】を指定するには・・・と考えてみましょう。
まず、セル範囲を指定するには Range("A1:D2") のようにセル番地を文字列で書く方法があります。
これはマクロの記録で得られたコードにも出てくると思いますので、見たことあるのではないかと思います。

実は、このような書き方のほかに、Range(Range("A1"),Range("D2"))のように、左上のセルと右下のセルをそれぞれ指定する方法もあります。
さらに、この方法の場合 Range("A1","D2")のように書いても大丈夫です。

    Sub 実験01()
        Range("A1:B2").Select
        MsgBox Selection.Address(False, False)

        Range(Range("B3"), Range("C5")).Select
        MsgBox Selection.Address(False, False)

        Range("C5", "D8").Select
        MsgBox Selection.Address(False, False)

        Range("C7", Range("D6")).Select
        MsgBox Selection.Address(False, False)

    End Sub

ただし、それぞれのセルが別のシートにある場合は辻褄が合わないのでエラーとなります。

    Sub 実験02()
        Dim WS1 As Worksheet
        Dim Ws2 As Worksheet

        Set WS1 = Worksheets(1)
        Set Ws2 = Worksheets(2)

        Stop

        WS1.Activate
        '成功する
        Range(WS1.Range("A1"), Range("B2")).Select
        WS1.Range("A1", Range("B1")).Select

        Ws2.Activate
        '失敗する
        Range(WS1.Range("A1"), Range("B2")).Select
        WS1.Range("A1", Range("B1")).Select

    End Sub

 ==========================================================

【7】
このほか、セルを表現するにはRangeプロパティのほかに、Cellsプロパティというものも使えます。
両者の違いはざっくりとこんな感じ。

 Range・・・・列文字と行番号の組み合わせを【文字列】で表現
              単独でセル範囲も対応できる

 Cells・・・・行番号、列番号をそれぞれ【数値】で表現
              (例外的に列のほうは"文字"で書いても、Excel君の忖度により処理される)
              単独でセル範囲は指定できない

これを踏まえると、例えば「Sheet1」のA1〜D5セルを"選択"するという場合だけでも

 Worksheets("Sheet1").Range("A1:D5").Select
 Worksheets("Sheet1").Range(Worksheets("Sheet1").Range("A1"),Worksheets("Sheet1").Range("D5")).Select
 Worksheets("Sheet1").Range("A1",Worksheets("Sheet1").Range("D5")).Select
 Worksheets("Sheet1").Range("A1",Worksheets("Sheet1").Cells(5,4)).Select
 Worksheets("Sheet1").Range("A1",Worksheets("Sheet1").Cells(5,"D")).Select

等々、いろんな書き方が可能です。

 ==========================================================

【8】
これらを踏まえると、【コピー元】のセルは
Range(A1〜A列最終行)と表現すればよいことになります。

A列最終行の取得方法は、同じ人かはわかりませんが、↓で紹介されているリンク先を読めばわかると思いますので説明省略。
[[20200318200803]] 『VBAデータ追加』(コロナに勝つ)

コード化してみるとこんな感じ

 Worksheets("コピー元").Range("A1",Cells(Rows.Count,"A").End(xlUp)).Copy

貼付先も同じ考え方で"貼付先シート"のD列最終行の"セル"を取得して、その1行下に貼り付ければよいから

 Sheets("貼付先").Paste Destination:=Sheets("貼付先").Cells(Rows.Count,"D").End(xlUp).Offset(1,0)

というようにそれぞれ記述することができます。

さらに、既に示されているように【コピー元】の開始位置(行)が項目行で要らなければ、開始位置(行)をずらせばよいですね。

 ==========================================================

【9】
これらをまとめると

    Sub 実験03()
        Dim srcSH As Worksheet: Set srcSH = Worksheets("コピー元")
        Dim dstSH As Worksheet: Set dstSH = Worksheets("貼付先")

        srcSH.Range("A2", srcSH.Cells(srcSH.Rows.Count, "A").End(xlUp)).Copy
        dstSH.Paste Destination:=dstSH.Cells(dstSH.Rows.Count, "D").End(xlUp).Offset(1, 0)
    End Sub

みたいな感じになり、「3」のとおり、シートをアクティブにしたり、セル(範囲)を選択したりする必要はありません。

さらに、変数部分は別にして、
1行目は【Rangeオブジェクト】を【コピー】しています
2行めは【Worksheetオブジェクト】に【セルを指定】して【貼付け】しています。

この、「コピー」や「貼付け」のことを"メソッド"といいますが、1行目の【Rangeオブジェクト】の【COPYメソッド】には便利なテクニックがあります。
http://officetanaka.net/excel/vba/cell/cell09.htm

↑のように、【Rangeオブジェクト】の【COPYメソッド】の引数(Destination)に貼付先のセルを指定すると【Pasteメソッド】の代わりができるのです。

 ==========================================================

【10】
したがって、

    Sub 実験04()
        Dim srcSH As Worksheet: Set srcSH = Worksheets("コピー元")
        Dim dstSH As Worksheet: Set dstSH = Worksheets("貼付先")

        srcSH.Range("A2", srcSH.Cells(srcSH.Rows.Count, "A").End(xlUp)).Copy _
        Destination:=dstSH.Cells(dstSH.Rows.Count, "D").End(xlUp).Offset(1, 0)
    End Sub

のようにしても問題ないですし、【Withステートメント】を使って

    Sub 実験05()
        With Worksheets("コピー元")
            .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)).Copy Worksheets("貼付先").Cells(.Rows.Count, "D").End(xlUp).Offset(1, 0)
        End With
    End Sub

のように記述することも可能です。

 ==========================================================

【11】
さらに、オートフィルタで抽出している時など項目行はわかっているが、データの始まり位置が特定できない場合、項目行の分だけコピー範囲をずらすというテクニックも有効だと思います。

    Sub 実験06()
        With Worksheets("コピー元")
            .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)).Offset(1).Copy _
            Worksheets("貼付先").Cells(.Rows.Count, "D").End(xlUp).Offset(1, 0)
        End With
    End Sub

 ==========================================================

【おわり】
とまぁ色々書きましたが、このトピックで言えば

 1) どのセル(シート)にコピーしたいデータがあるのか
 2) どのセル(シート)に貼付すればいいのか

が理解できる情報があれば、すんなり答えは出ただろうなぁなんて思います。

また、もう過ぎたことを言ってもしょうがないですが、
>わざと分かるようにニックネームを書いて
とおっしゃるなら、尚更”同じニックネーム”でいいんじゃないですか?と言いたくなります。
(たぶん、同じニックネームで投稿した場合、トピック分ける必要は無いとの指摘が入ったと思いますが)

このほか、この掲示板に限らず回答者さんは、理解してほしいなぁとおもって回答している人が多いと思います。(少なくとも私はそうです)
ですので、コードをもらって「わーい うごいたぁ」で話が終わるとがっかりなのです。
なので、時間と労力に余裕があるなら提示されたコードを【ステップ実行】して、どの命令が何をしているか研究してみることをおすすめします。
研究を踏まえて、「××というコードを実行したら、〇〇になるとおもっていたのに、□□になった理由が知りたいです。」のように質問してみると皆さん喜んで回答してくださるとおもいます。

なお、【おわり】部分へのレスは不要です。(と書いていても反応しちゃう人いるんだろうなぁ・・・)

(もこな2) 2020/03/21(土) 11:17


もこな2様 補足ありがとうございます。

しかしながら、
もなこ2様は言うような「暇な人が多いのかしょーもないコメント」
など一つもないです。

みなさん私の質問をキーに討論していただいて、結果このサイトが今後、質問者の使いやすい
サイトになれば、それはそれは良い事ではないでしょうか。
これを否定するなら、私のネームは文をキーに使いますので
私が今後、もし質問に使わせて頂いても、もこな2様からの回答を拒否させてもらいます。。。

(文2号) 2020/03/21(土) 17:42


もなこ2さん

(私もたまに質問者の立場で使用させて頂くので質問者側の立場で言わせてもらいます。

その時の回答者への方へは今でも感謝しております。)

なんというかその長〜い補足必要?
質問者さんが既に完了宣言してるわけですよ。
自分で暇と言ってるけど自己満足の域なだけじゃなの?

「この掲示板に限らず回答者さんは、理解してほしいなぁとおもって回答している人が多いと思います。(少なくとも私はそうです)」
質問者の方もそれなりに理解しようと努力してると思いますよ。
でもそれを押し付けるような回答の仕方はありがた迷惑この上ない事もあるのですよ!

他トピでも質問者の方の質問内容がおかしい箇所があるなら、もう少し優しく丁寧に誘導さしあげてはいかがでしょうか。
もし、ここが有料サイトでもなこ2さんのような回答者は苦情対象となっていると思います。
質問者の中にはいろんな状況や環境や立場に置いて質問しているのを理解していますか?
別にExcelVBAを完璧に覚えて使いこなそうなんて人いなく、会社の業務においての
ある一部分において知りたいから知ってる人おしえて〜くらいで利用してる人も多いと思いますよ。
他にもExcel以外のちがう業務を沢山抱えている人もいっぱいいるのです。暇じゃないのです。貴方とちがって。
それが何か問題でもありますか?

他トピでも質問者が萎縮するような上から目線の態度を平気で取る回答者がいて一部の方が回答者へ指摘しています。
ここはサイト名にあるようにExcel学校なので生徒(質問者)ファーストで丁度いいのではないでしょうか。
なぜ、ニックニームにしつこく拘るのかも理解不能で、上のほうで「説明する方もめんどくさいです」と言いながら
結局、不必要にダラダラ長く自分から説明を押し付けてるではありませんか。
これを自分本位というのです。

別に無理に回答しなくてもいいのではないですか。「(少なくとも私はそうです)」と見返りを求めるなら。
質問者が萎縮や迷惑に感じる行為をする方はフェードアウトしてほしいです。
すべてがもなこ2さんの思い通りになるわけではないです。

(なんちゃん) 2020/03/21(土) 19:05


 学校、ということなら、学校は学習意欲がある人が
 くるところです。

 やさしさを求めるなら、それこそ有料のサービスを利用
 すべきです。

 ※以前ここにもいらっしゃいました。回答者の振りして少し
 やさしい回答をしては自分の有料サービスへ誘導される方が。
(OK) 2020/03/21(土) 19:33

学習意欲はみんなあるのではないですか。
だから掲示板利用しているわけですから。
その意欲の環境が人それぞれってことでは。
私も優しくなくても優しくてもどちらでもと思うけど
質問者が不快になる行為はダメってことでしょ。
上の書き込みみてると補足と言いながら余計な文句言ってる回答者が
いるからね。

(ねむねむ) 2020/03/21(土) 19:45


コメント返信:

[ 一覧(最新更新順) ]


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