[[20210312173218]] 『VBA 1行のみ選択の際にエラーがでてしまう。』(とも) ページの最後に飛ぶ

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

 

『VBA 1行のみ選択の際にエラーがでてしまう。』(とも)

納品書のデータ内訳を別のシートにコピペするVBAを作成しましたが、
内訳の内容が1行しかなかった場合、1行目から以下全行選択してしまうために
エラーがでてしまいます。

ネットから検索してつなぎ合わせて作ったVBAのために解消方法がよくわかりません。
分かる方ご教授願えないでしょうか。
ちなみに納品書の行数が2行以上あるときはエラーが出ません。

納品書は
11行目にタイトル行があり、そこに常にオートフィルタを
かけています。12行目から31行目まで項目が入力できるように
しておりますが、日によって行数が変動します。

VBAは下記の通り作成しました。
何卒よろしくお願い致します。

'タイトル行を除き、納品書集計へコピペ(↓納品書で1行しかない時に全行を選択してしまいここでエラーとなる)

    Worksheets("月間集計用 (納品書)").Range("A" & LstRow2).Offset(1, 0).PasteSpecial Paste:=xlPasteValues

'納品書集計へ移動し最終行のセルを選択

    Sheets("月間集計用 (納品書)").Select

    Range("A1").End(xlDown).Select

'納品書データへ移動しソートを解除し全セル選択もA12を選択

    Sheets("関西").Select

    ActiveSheet.ShowAllData '→全行選択したままソートを解除し不可視行も表示する。

    Range("A12").Select

    MsgBox "終了"

End Sub

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


[[20141126103633]]?『可視セルの一番上(タイトル行除く)から一番下までを取得するコード』(りぼん)

 なんかうまくリンクできない。
(BJ) 2021/03/12(金) 18:11

 ↑
 質問者が消したと思われ、なくなってた。
(BJ) 2021/03/12(金) 18:21

xldownを使ってるからだと思いますが、
これで上手くいきませんか?

Sub test()
Dim refsh, wrksh As Worksheet
Dim LstRow, LstRow2, LstCol As Long

Set refsh = ThisWorkbook.Worksheets("関西")
Set wrksh = ThisWorkbook.Worksheets("月間集計用(納品書)")

LstRow = refsh.Cells(Rows.Count, 1).End(xlUp).Row
LstCol = refsh.Cells(11, Columns.Count).End(xlToLeft).Column
LstRow2 = wrksh.Cells(Rows.Count, 1).End(xlUp).Row

refsh.Range(refsh.Cells(12, 1), refsh.Cells(LstRow, LstCol)).Copy
wrksh.Cells(LstRow2 + 1, 1).PasteSpecial Paste:=xlPasteValues

Application.CutCopyMode = False
refsh.Activate

End Sub
(yu) 2021/03/12(金) 18:48


スマホでポチポチ打ってたら編集かぶりましたがそのまま。

端的に言えば
>11行目にタイトル行があり、
ですから、

 Range("A12").End(xlDown)
      ↓
 Range("A11").End(xlDown)

とすればとりあえずの解決はするでしょう

ただ、抽出データが0件のときに問題になるから、A列最大行からEnd(xlUp)したときの行が、12行目以下のときに、項目行を除くフィルタ範囲をコピーと考えてみてはどうでしょうか?

(もこな2) 2021/03/12(金) 18:53


 なんでオートフィルタをかけた後に表示されている最後の次の行なんですかね?
 空白であるかどうかの確認とかしないんですかね?
 ま、あまり考えなしのような気がします。
(BJ) 2021/03/12(金) 19:08

>12行目から31行目まで項目が入力できるようにしておりますが、日によって行数が変動します。
なので、12行目から詰めてデータが入ってる想定なんでしょう。たぶん

(もこな2) 2021/03/12(金) 19:25


PCの前に戻りましたので何点か。

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

■2
「標準モジュール」で「Range("A12")」のような書き方をした場合、「ActiveSheet.Range("A12")」のようにアクティブシートを指定したものとして扱われます。
したがって、想定外のシートを対象にしないためにも、1と併せて対象のブックやシートは明示したほうがよいとおもいます。

■3
>そこに常にオートフィルタをかけています。
実はオートフィルタがかかっている範囲は↓のようにすれば簡単に取得できます。

 シートオブジェクト.AutoFilter.Range

さらに、オートフィルタがかかっている範囲の1行目が項目行なので、取得した範囲を1行ずらせば項目行を除くことができます。
(1行ずらすと、空っぽの行が最後に含まれることになります。コピペするだけなら問題はないとおもいますが、空っぽの行が含まれると困る場合はintersectメソッドを使うとよいです)

■4

 LstRow2 = Worksheets("月間集計用 (納品書)").Cells(Rows.Count, 1).End(xlUp).Row
 Worksheets("月間集計用 (納品書)").Range("A" & LstRow2).Offset(1, 0).PasteSpecial Paste:=xlPasteValues

↑についてダメではないですが、A列最終行の行番号をもとめてから、A列の求めた行の1行下に貼り付けろって書いてありますよね。
つまり、A列の行番号を一旦もとめてから、同じA列の行番号を指定してるわけです。
すごい回りくどいですよね。

■5
上記のことを踏まえて提示のコードを整理するとこんな感じになります。
必要のない選択を省くと構造がシンプルになり、メンテしやすくなると思いますので興味があれば研究してみてください。

    Sub 整理1()
        Stop '←ブレークポイントの代わり

        With Sheets("関西").AutoFilter.Range
            .AutoFilter Field:=5, Criteria1:="<>"
            .Offset(1).Copy
            Worksheets("月間集計用 (納品書)").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
            .Parent.ShowAllData
        End With

        MsgBox "終了"
    End Sub

(もこな2 ) 2021/03/12(金) 21:27


 あれ、質問者の最初の質問文にオートフィルタのコードが書いてあったような気がしたけど。
 勘違いなら、話が違うので私の上の返信は無視してください。
(BJ) 2021/03/12(金) 22:32

皆様ご教授ありがとうございます。
もこな2さんの書き直しコードで問題なく実現できました。
こんなにシンプルな構文にできるのですね。目から鱗です。
どうもありがとうございました。
(とも) 2021/03/14(日) 08:55

BJさんがコメントされているように、なんか当初の質問内容が書き換わっちゃってますよね。

■6
既に気づいたから消したのかもしれませんが、↓のような記述だとA列の状況如何では思った範囲が取得できないかもしれませんね。(Endプロパティにセル範囲を渡しても左上セルしか参照しないので)

 Range("A12").Select
 Range(Selection, Selection.End(xlToRight)).Select
 Range(Selection, Selection.End(xlDown)).Select

また、入力欄だとおっしゃるので実は【最終列】は決まってませんか?
本当に「End(xlToRight)」で求める必要があるのかちょっと疑問です。

■7
書き換わる前の質問だと、5列目で空白以外を抽出していたかとおもいますが、想像したように上から詰めて書いているならば、そもそもオートフィルタはいらないかもしれません。

■8
「■6」「■7」を踏まえると↓のようのな感じでもよいかもしれません。
(最終列は適当に決めました。)

    Sub 整理2()
        Dim 最終行 As Long
        Stop '←ブレークポイントの代わり

        最終行 = Sheets("関西").Cells(Rows.Count, 5).End(xlUp).Row
        If 最終行 > 11 Then
            Sheets("関西").Range("A12:D" & 最終行).Copy
            Worksheets("月間集計用 (納品書)").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
        End If
    End Sub

(もこな2 ) 2021/03/14(日) 13:46


コメント返信:

[ 一覧(最新更新順) ]


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