[[20210215145121]] 『最終行を取得、セルに関数を入れて最終セルまでフ』(sato) ページの最後に飛ぶ

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

 

『最終行を取得、セルに関数を入れて最終セルまでフィルダウン』(sato)

VBA初心者です。

最終行を取得、C2セルとD2セルににvlookup関数を入れて最終セルまで
フィルダウンする以下構文を作成しましたが、
検索結果が一行しかない場合、
関数が入力されず、タイトル行のタイトル(C1セルとD1セル)が
C2とD2にコピーされてしまいます。
いろいろ試しましたがわからず、修正点をご教示頂けると助かります。

++++++++++++++++++++++++++++++
Sub 関数挿入()

 Dim i As Long
        i = Range("A" & Rows.Count).End(xlUp).Row

        Workbooks("aaa.xlsx").Worksheets("bbb").Select

'vlookup関数挿入

        Range("c2") = "=VLOOKUP(B2,ccc!$F$3:$I$100,2,FALSE)"
        Range("d2") = "=VLOOKUP(B2,ccc!$F$3:$I$100,4,FALSE)"

        Range("c2:c" & i).FillDown
        Range("d2:d" & i).FillDown

End Sub
++++++++++++++++++++++++++++++

よろしくお願い致します。

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


iが1ならそうなるように書いてありますね。
If i > 2 Then

End If
のようなものを挟むと良いかもしれません。
(ダミー人形) 2021/02/15(月) 15:40


かぶっている内容もありますが、投稿しておきます。

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

■2
「標準モジュール」でシートの指定を省略した場合、ActiveSheetが指定されたものと見なされます。
したがって、「■1」のこととも併せて、ブックやシートはきちんと明示することをお勧めします。

■3
プロパティが必要なところで記述を省略すると、Valueプロパティが省略されているものとして見なされます。
今回は、Excel君が忖度してくれているので問題にはなりませんが、数式を設定するのであれば「Formula」プロパティを使用されたほうが適切であろうとおもいます。

■4
「FillDown」を使ったアプローチを試されていますが、今回のケースであれば一括入力が可能とおもわれますので検討してみるとよいと思います。

■5
以上を踏まえると、↓みたいな感じにすればよいのではないでしょうか?

    Sub 関数挿入_改()
        Dim i As Long

        With Workbooks("aaa.xlsx").Worksheets("bbb")
            i = .Range("A" & .Rows.Count).End(xlUp).Row

            If i < 2 Then Exit Sub

            'vlookup関数挿入
            Range("C2:C" & i).Formula = "=VLOOKUP(B2,ccc!$F$3:$I$100,2,FALSE)"
            Range("D2:D" & i).Formula = "=VLOOKUP(B2,ccc!$F$3:$I$100,4,FALSE)"
        End With

    End Sub

(もこな2) 2021/02/15(月) 16:00


ダミー人形様
もこな2様
ご教示ありがとうございます。

If i < 2 Then Exit Subを入れることで、
1行だけの抽出でも、正しく作成できました!

>もこな2様
ご丁寧にありがとうございました!
重複していたり、不足していたりで
まだまだ正しく構文が作れず、、、
時々こちらを覗いて勉強したいと思います。
(sato) 2021/02/16(火) 12:04


一応コメントしておきます。

■6
>If i < 2 Then Exit Subを入れることで、
>1行だけの抽出でも、正しく作成できました!

「■2」で示したように【標準モジュール】でシートを省略した場合、ActiveSheetが指定されたものと見なされるルールです。
したがって↓の順番だと「i」には、ActiveSheetのA列最終行の行番号が格納されることになります。

 i = Range("A" & Rows.Count).End(xlUp).Row
 Workbooks("aaa.xlsx").Worksheets("bbb").Select

また、アクティブでないブックのシートをいきなり選択はできないので、どうしても選択したいのであれば↓のようにすべきです。
(設計上、「aaa.xlsx」がアクティブの時にしかマクロを実行しないことになっているなら、別にいいですが・・・)

 Workbooks("aaa.xlsx").Activate
 Workbooks("aaa.xlsx").Worksheets("bbb").Select

なので、↓のように対象シートをアクティブにするんじゃなくて、ちゃんとブックとシートを指定した方がいいですよと伝えた次第です。

 i = Workbooks("aaa.xlsx").Worksheets("bbb").Range("A" & Workbooks("aaa.xlsx").Worksheets("bbb").Rows.Count).End(xlUp).Row

 ※提示では↑のように書くのがめんどくさかったので、Withステートメントを使用して記述しています。
   【Withステートメント】については↓をご覧ください。
   http://officetanaka.net/excel/vba/beginner/16.htm

(もこな2) 2021/02/16(火) 21:50


>もこな2様

ご教示頂きありがとうございます。
ちゃんと理解できておらず恐縮です・・
ネットで、しかもあちこちで調べた構文を理解しないままコピペしていたので、
順番もあまり考えていませんでしたが、そもそも変数の宣言をする順番も間違えていたんですね。
説明が分かりやすく、理解できました。

1点教えて頂きたいのですが、
今回「If i < 2 Then Exit Sub」を入れることで解決できましたが、
この構文を入れないと、なぜ1行しか抽出結果がなかった時(タイトル行の下に抽出結果が1行)
タイトルがコピーされてしまうのかがわかりません、、、
1行しかなかった抽出結果の行(2行目)が最終行になって、C2とD2に関数が入るのかなと思うんですが、、、

たぶんすごく低次元な質問をしていると思いますが、ご教示頂けると嬉しいです。

よろしくお願い致します。

(sato) 2021/02/19(金) 17:18


Range("c2:c" & i).FillDown
Range("d2:d" & i).FillDown
この式は、iが1のときは範囲がC1:C2とD1:D2になって
C1とD1の値をC2とD2にフィルコピーします。
iが1のときにC2とD2をC3とD3にフィルコピーする意図ならば
Range("C2").Resize(i+1).FillDown
Range("D2").Resize(i+1).FillDown
です。
(ダミー人形) 2021/02/19(金) 21:57

>ダミー人形様
返信が遅れて申し訳ありません。

書き出して頂いたのを拝見したら、
簡単に理解することができました・・
”Resize(i+1)”の説明も分かりやすかったです。

ありがとうございました。
(sato) 2021/03/02(火) 14:19


コメント返信:

[ 一覧(最新更新順) ]


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