[[20220330175945]] 『VBA 値貼り付け』(ぽぽぽん) ページの最後に飛ぶ

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

 

『VBA 値貼り付け』(ぽぽぽん)

値貼り付けをしたいのですが、エラーになってしまいます。
下記の一番下の行でActivesheet.Pastespecial paste:=xlpastevaluesとするとエラーになってしまいます。
どこを直せば値貼り付けになるかご教示お願いします。

sub ()
Activeworkbook.activate
Range(Activecell,”T”&cells(rows.count,”B”).End(xllup).Row).copy

Thisworkbook.activate
Range(“A”&cells(Rows.count,”A”).End(xlup).Row +1).select
Activesheet.paste

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


Pastespecialは Rangeオブジェクトのメソッドですよ。
(γ) 2022/03/30(水) 18:16

そうすると、
下から2行目のselect のところをpastespecial paste:=xlpastevaluesとすればできるのでしょうか?
マクロ始めたばかりなのでご容赦ください。
(ぽぽぽん) 2022/03/30(水) 18:19

まあ、やってみてください。
# 爆発する恐れはないので。
(γ) 2022/03/30(水) 18:26

■1
>マクロ始めたばかりなのでご容赦ください。
まずは、ご自身のコードの意味を解釈するところから手を付けてみましょう。

そもそもおかしな部分がいくつかあります。

 (1)
 Activeworkbook.activate
 ↑アクティブなブックだから、Activebookです。
 わざわざアクティブにする意味がありません。

 (2)
 End(xllup) ←正しくは「xlUp」です。

 (3)
 セル範囲の書き方も間違っているわけではありませんが少々気になります。

■2
助言のあった「Pastespecial」と、お使いになられた「Paste」は別の命令です。
Pasteメソッドでよければ「■1」で指摘した箇所を直せば動作します・・・が、Pasteは【シート】に対する命令です。
↓で自ブックのActiveSheetがアクティブになっているので問題はありませんが、意味合い的にはきちんとシートを指定したほうがよいです。
ThisWorkbook.Activate

■3
「■2」関連して、VBAの世界では基本的にブックやシート(オブジェクトといいます)をきちんと指定すれば、いちいちアクティブにしたり選択したりする必要はありません。

■4
Pasteメソッドと同じ動きでよいのであれば、Copyメソッドの引数に貼り付け先を指定してあげることで代用ができます。

■5
以上を踏まえて、例えば(アクティブブックの)アクティブシートの情報を、マクロブックの1番目のシートのA列最終行の1行下に貼付するといったことなら、↓のように実質1行で書くこともできます。

    Sub 名前も終わりもないマクロ()
        Range(ActiveCell, "T" & Cells(Rows.Count, "B").End(xlUp).Row).Copy _
        ThisWorkbook.Worksheets(1).Cells(Rows.Count, "A").End(xlUp).Offset(1)
    End Sub

(もこな2 ) 2022/03/30(水) 18:52


値貼り付けをしたい、と読んだのですけど。

(γ) 2022/03/30(水) 19:06


>値貼り付けをしたい、と読んだのですけど。
気づいて、書きためている間に指摘頂きましたがそのまま。

■6
タイトルや冒頭にあるように【値】を張り付けたいのであれば、Pasteメソッドでは問題があります。
既に答えが提示されているところではありますが、御自身でも【マクロの記録】で調べるてみると理解しやすいのではないかと思います。

    Sub 名前も終わりもないマクロ2()
        Range(ActiveCell, "T" & Cells(Rows.Count, "B").End(xlUp).Row).Copy
        ThisWorkbook.Worksheets(1).Cells(Rows.Count, "A").End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues
    End Sub

■7
別のアプローチとして↓のような方法もあります。

    Sub 別案()
        With Range(ActiveCell, "T" & Cells(Rows.Count, "B").End(xlUp).Row)
            ThisWorkbook.Worksheets(1).Cells(Rows.Count, "A").End(xlUp).Offset(1).Resize(.Rows.Count, .Columns.Count).Value = .Value
        End With
    End Sub

興味があれば読み解いてみてください。

(もこな2 ) 2022/03/30(水) 19:21


 コピーして貼り付け、というのはExcelVBAの一丁目一番地であり、
 しかも使用頻度も高いです。この際、しっかり身に着けてください。

 すでに解説もいただいていますが、私なりのまとめをしてみた。
 例文を作りながら、確認してみてください。

 (1)全貼り付けの場合(形式を選択して貼り付けではない場合)

    ●私は、以下の書き方を推奨します。

        コピー元範囲.Copy  コピー先範囲(のトップセル(*))

       ・一行でコンパクトに書ける
       ・シートを選択したりという手間がかからない

    ●一方で、Worksheetオブジェクトの Pasteメソッドは殆ど使わない。
       ・貼り付けそのものは、シート.Paste と書けば済むのだが、
       ・対象先のセル範囲(のトップセル)を"選択"(Select)しておかなければならない。
       ・それには、シートを選択して、次にセルを選択する必要がある。
       ・結果として、何行も書かなければならないし、
         シートやセルの選択は避けるべきというルール(中級者以上は守るべき黄金則)に抵触する。

 (2)形式を選択して貼り付け

     ●RangeオブジェクトのPasteSpecialの使用

          コピー元範囲.Copy
          コピー先範囲.PasteSpecial オプション

        ・2行に渡って書く必要はあるものの、
        ・ワークシートのセルは直接指定でき、選択の必要がないのは、大きなメリット。
        ・コピー先のトップセルだけの指定でよい。
        ・オプションが多彩(全要素の貼り付けも可能)

     ●コピー先範囲.Value = コピー元範囲.Value
       と、セル範囲のValueプロパティの値を直接操作する方法もある。
       この場合は、コピー先範囲のトップセルだけでよい、というわけにいかず、
       コピー元と同じ大きさをセル範囲を指定する必要がある。(面倒と言えば面倒)
     ●いったん、全貼り付けをしたあとで、
           コピー先範囲.Value  = コピー先範囲.Value 
       として値だけにする(式ではなくする)という方法もあります。

  (*)トップセル(公式な用語ではありません)とは、
      A1:B3なら、A1セルというように、セル範囲内の最左、最上のセルを言います。  
(γ) 2022/03/30(水) 21:46

たくさん返信ありがとうございます。

Rangeのオブジェクトの助言とのことでそちらで解決できました。ありがとうございます。

1行目の
Activebook.activateの件だけ補足させてください。
そちらは別ブックからのコピーをしたかったのでThisworkbookではなくそちらで合っているのです。
無駄に書いたわけじゃないです。
(もしかしたらもっと指定でいい方法があるのかもしれませんがいまのわたしのレベルではこちらで限界です)

みなさんの助言をもとに勉強も引き続きしてまいります。
ありがとうございます。
(ぽぽぽん) 2022/03/31(木) 08:08


 >そちらは別ブックからのコピーをしたかったのでThisworkbookではなくそちらで合っているのです。
 >無駄に書いたわけじゃないです。

 アクティブなのものをアクティブにするのは無意味です。
 誰もそんなコードは書きません。

(半平太) 2022/03/31(木) 08:30


老婆心ながらいろいろ勘違いされていないか心配です。

■8
>Rangeのオブジェクトの助言
【形式を選択して(値)を貼り付ける】命令は、「Pastespecialメソッド」です。
提示されたコードで使っていた「Pasteメソッド」とは別の命令です。

よって"値貼り付け"で解決を目指すなら、「Pasteメソッド」ではなく「Pastespecialメソッド」を使う必要があります

そのうえで、Pasteメソッドは【シート】を対象にする命令ですが、Pastespecialメソッドは【セル(範囲)】を対象にする命令という違いがありますから、それ相応の書き方があるという話でした。

この辺は繰り返しになりますが"マクロの記録"でどのような書き方になるか確認されると理解しやすいとおもいます。

■9
>そちらは別ブックからのコピーをしたかったのでThisworkbookではなくそちらで合っているのです。
「■1(1)」でコメントしましたし、他の方からもコメントがありますが、アクティブなものをアクティブにしても意味がありません。(だってもともとアクティブですから・・・・・)

したがって、たとえば、↓のようにアクティブブックではなく、【対象のブック】をアクティブにするということであったなら意味はあります。

    Sub Macro1()    '
        Windows("データ.xlsx").Activate
        Sheets("aaa").Select
        Range("A1:F10").Select
        Selection.Copy

        Windows("貼付先.xlsm").Activate
        Sheets("bbb").Select
        Range("A2").Select
        Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
    End Sub

ですが、「■3」でも述べたように↑は↓のように整理が可能です。

    Sub Macro2()
        Workbooks("データ.xlsx").Sheets("aaa").Range("A1:F10").Copy
        Workbooks("貼付先.xlsm").Sheets("bbb").Range("A2").PasteSpecial Paste:=xlPasteValues
    End Sub

上記のように書いた場合はどのブックやどのシートがアクティブだろうと関係なく処理が可能です。
ただ、今回はコピーしたいセル範囲の特定に「ActiveCell」が絡んでますので、(対象ブックの)対象シートをアクティブにする必要が出てきます。

したがって、処理順としては

 (1)(対象ブックをアクティブにして)対象シートをアクティブにする。
 (2)ActiveCellを基準にコピーするセル範囲を特定してコピーする
 (3)PasteSpecialメソッドを使って値のみ貼り付けする

といった流れにすれば目的は達成できるとおもいます。

 無論、ActiveCellに依存しないようにすれば、先に示したとおり
 アクティブシートは関係なくなるのでそちらのほうがおすすめです。

(もこな2 ) 2022/03/31(木) 20:26


↑について誤字等がありましたので、修正しました。

(もこな2) 2022/04/01(金) 06:43


コメント返信:

[ 一覧(最新更新順) ]


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