[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『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 >
なんかうまくリンクできない。 (BJ) 2021/03/12(金) 18:11
↑ 質問者が消したと思われ、なくなってた。 (BJ) 2021/03/12(金) 18:21
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
(もこな2) 2021/03/12(金) 19:25
■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
■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.