以下のコードですと、取込み元のデータの2行目以下のデータがない場合、項目行の1行目と2行目(空行)が取りこまれます。
データがない場合は取込みせず、次のファイルでデータがあった場合は前々回(データあり)取り込んだ行の下にデータ表示をしたいのですが、どのように変更すればよろしいでしょうか。
ご教授お願いします。
Sub データ取り込み()
Dim buf As String, i As Long
Dim j
Dim r As Long
buf = Dir(Sheets("book保存場所").Range("A1").Value & "\*.xls")
Do While buf <> ""
Workbooks.Open Worksheets("book保存場所").Range("A1").Value & "\" & buf
For r = Sheets("DB").Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
If Sheets("DB").Cells(r, 1).Text <> "" Then Exit For
Next
Sheets("DB").Range("A2:I" & r).Copy
ThisWorkbook.Activate
ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues
Workbooks(buf).Activate
Application.CutCopyMode = False
Workbooks(buf).Close SaveChanges:=False
buf = Dir()
Loop
End Sub
No.2ベストアンサー
- 回答日時:
こんにちは
コードだけからではちょっとデータの状態が読み取れないのですが・・・
>Sheets("DB").Cells(Rows.Count, 1).End(xlUp).Row
通常、この処理では、A列の空白でない最大行の行数が取得できます。
(A列の最終行のセル(1048756行など)が空白の場合に限りますが、まぁ大抵は空白ですので…)
1行目は必ずタイトルが記されていると仮定でき、さらに、A列に値があるかないかだけで判断して良いのなら、上記の行数が2以上ならコピー、1ならばタイトル行のみと判断してコピーしないなどでよさそうな気がします。
もしも、A列のデータが飛び飛びで(途中に空白行が混ざっている)データのある行だけを詰めてコピーしたいという意図の場合は、途中の空白行を除く処理が必要になりそうです。
さて、ご提示のコードでは
>For r = Sheets("DB").Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
>If Sheets("DB").Cells(r, 1).Text <> "" Then Exit For
>Next
となっていますが、この処理をよく追いかけてみてください。
最終行から2行目までのループで、A列の値が空白でなければループを抜ける(rにその行が保持される)
ということですが、いろいろと問題がありそうです。
1)そもそもになってしまいますが、End(xlUp).Rowで取得した行は「値がある最大行」のはずなので、このループでどのような処理を期待しているのかがよくわかりません。(普通は、1回目で抜けるので何もしないのと同じ)
2)仮に条件判定でループが続くとして(このケースはないと思いますが)、2行目までに非空白行が見つかれば、その行がrに保持されますが、見つからなった場合はどうなりますか?
(変数rに1が保持されてループを抜けてきます)
3)もともと最終行を取得しているので、最終行が1の場合(=タイトル行しかない場合)には、ループの処理は行われないので、rの値はループの初期値(=1)となって抜けてきます。(Forの条件判定と実行については後述)
想像するところ、2)や3)のr=1の際には、コピー処理をスキップしたいのではないかと思いますが、ご提示のコードではr=1の値を保持しているので、A2:I1の範囲がコピーされるようになっています。
この結果、
>取込み元のデータの2行目以下のデータがない場合、
>項目行の1行目と2行目(空行)が取りこまれます。
のような処理になっているものと考えられます。
・・・で、どうすればよいかと言えば、最終行を取得してそれが2以上ならコピー、それ以外はスキップとすれば良さそうに思えますが、そういうことではないのでしょうか?
r = Sheets("DB").Cells(Rows.Count, 1).End(xlUp).Row
If r>1 Then
'
'ここにコピーの処理を入れる
'
End If
(前述のような途中の空白行を除きたいという場合は、別に処理が必要となります)
<おまけ>
ご提示のコードでは、暗黙の指定(ActiveWorkbookやActiveSheet)を利用した書き方となっていますが、単一ブックや単一シートでの作業では問題ありませんが、ご提示の処理のように、複数のブックやシートを扱う場合は、なるべくブックやシートを明示する記述方法にしておく方が、勘違いや間違いの原因を減らすことにつながると思います。
例えばセルを指定する典型的な記述方法として
Workbook.Worksheet.Range("~~")
といった具合です。
繰り返し利用する値は、一旦変数に保持しておくとコードが簡潔になり、見やすくなることが多いです。
例えばフォルダアドレスを変数に入れておけば、文字列連結処理を複数回させなくても済みます。
あるいは、コピー先の最終行を毎回取得する処理を行っていますが、Rangeオブジェクトとして保持しておいて、記入する毎にその行数を進めるような処理を行うようにする(記入先のポインタとする)などで、コピーの処理の記述も単純化できると思います。
Rangeオブジェクトではなく、「次に記入する行」を変数に入れておいても良いかも。
オブジェクトでの記述例として
Worksheets("DB").Range("A2:I" & r).Copy
destRange.PasteSpecial Paste:=xlPasteValues
Set destRange = destRange.Offset(r)
のような感じです。
変数を活用することで、ActivateやSelect、Selectionといった記述を無くしたコードにすることが可能です。
そうすることによって、処理速度の向上や画面のチラつき等を防ぐことに役立ちます。
(コードの簡明化も図れると思います)
他の方の回答で、Forループは必ず1回実行されるとありますが、Doループ等の場合はそのようなループを作成できますが、Forループでは条件が合わない場合は実行されません。
例えば
r = 5
For r = 8 To 10 Step -1
MsgBox r
Next
を実行してみると、(条件に合わないので)ループ内の処理が実行されることはありませんが、変数rの値はループの初期値の8に変わります。
詳しく教えていただきましてありがとうございました。
体調を崩しましてお返事とお礼が遅くなり申し訳ございません。
少し復活しましたので内容を熟読したいと思います。
またわからないことが出ましたら教えていただけますと幸いです。
No.1
- 回答日時:
for分は実行した後にloop変数をカウント・評価するので、1回は実行されてしまいます。
この点の注意が要ります。
if Sheets("DB").Cells(Rows.Count, 1).End(xlUp).Row>1 then ←追加
For r = Sheets("DB").Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
If Sheets("DB").Cells(r, 1).Text <> "" Then Exit For
Next
endif←追加
早速お返事ありがとうございます。
この後体調を崩しましてお返事とお礼が遅くまり申し訳ございませんでした。
上記のコードを実際に試してみたいと思います。
またわからないことが出ましたら教えていただけますと幸いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
都道府県穴埋めゲーム
都道府県の名前を1人1つずつ投稿してください。全ての都道府県が出たら締め切ります!
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
excelのマクロで該当処理できなければ飛ばして進むにはどうすればよいのでしょうか
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
首吊りどこ締めるの
-
彼女のことが好きすぎて彼女の...
-
白血球が多いとどんな心配があ...
-
EXCELで条件付き書式で空白セル...
-
勃起する時って痛いんですか? ...
-
小数点以下を繰り上げたものを...
-
2つの数値のうち、数値が小さい...
-
イタリアから帰国する際、肉製...
-
エクセル指定した範囲からラン...
-
検便についてです。 便は取れた...
-
エクセルのラベルの値(文字列...
-
Excel 0目標に対して数字があ...
-
エクセルで数式の答えを数値と...
-
甲状腺が腫れているが血液検査...
-
風俗店へ行く前のご飯
-
excelのIF関数 A,Bの大きいほ...
-
テスターで断線を調べる方法教...
-
EXCELの条件付き書式で数式を空...
-
VLOOKUP関数を使用時、検索する...
-
ワードのページ番号をもっと下...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
首吊りどこ締めるの
-
彼女のことが好きすぎて彼女の...
-
白血球が多いとどんな心配があ...
-
勃起する時って痛いんですか? ...
-
精子が黄色?
-
検便についてです。 便は取れた...
-
これって喉仏ですか? 私は女性...
-
小数点以下を繰り上げたものを...
-
甲状腺が腫れているが血液検査...
-
精液の落とし方を教えてください
-
エクセル指定した範囲からラン...
-
EXCELで条件付き書式で空白セル...
-
2つの数値のうち、数値が小さい...
-
精子に血が・・・
-
エクセルのラベルの値(文字列...
-
イタリアから帰国する際、肉製...
-
ある範囲のセルから任意の値を...
-
リンク先のファイルを開かなく...
-
中出しをするとお腹が痛い・・・。
-
MIN関数で空白セルを無視したい...
おすすめ情報