質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

745閲覧

VBA 33行目までしか動かない理由

Mkasai

総合スコア19

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/03/02 02:52

以下のコードなのですが、
契約情報シートの33行目までの情報は、作成情報シートへ抽出されるのですが、
34行目以下の情報は抽出されません。
使用するデータから考えて300行くらいまでは使えるようにしたいのですがどこを変更したらいいのかわかりません。
お力お貸しください。

Sub

1 2 If ActiveSheet.FilterMode Then 3 '絞り込まれていたら 4 5 ActiveSheet.ShowAllData 6 7 End If 8 9 Dim twb, cwb As Workbook 10 Dim curPath, Sakusei As String 11 Dim ws1, ws2 As Worksheet 12 Dim StartRow, EndRow, tmpRow As Integer 13 Dim wb As Workbook, flag As Boolean 14 15 Set twb = ThisWorkbook 16 curPath = twb.Path 17 18 'ブックが既に開いているかどうかチェック 19 For Each wb In Workbooks 20 If wb.Name = "書類作成.xlsm" Then 21 flag = True 22 Exit For 23 End If 24 Next wb 25 '既に開いている場合 26 If flag = True Then 27 'オブジェクトにセット 28 Set cwb = Workbooks("書類作成.xlsm") 29 cwb.Activate 30 Else 31 '新規で開いてオブジェクトにセット 32 Workbooks.Open Filename:=curPath & "書類作成.xlsm" 33 Set cwb = ActiveWorkbook 34 End If 35 36 'シート名を変えている場合は適宜変更 37 Set ws1 = twb.Worksheets("契約情報") 38 Set ws2 = cwb.Worksheets("作成情報") 39 40 41 ws2.Range("2:11").ClearContents 42 43 '作成シートに指定されている抽出条件 44 Sakusei = ws2.Cells(1, "A") 45 46 StartRow = 2 47 EndRow = ws1.Cells(Rows.Count, "C").End(xlUp).Row 48 tmpRow = 2 49 50 For i = StartRow To EndRow 51 If (ws1.Cells(i, "A") = Sakusei) Then 52 ws2.Cells(tmpRow, "A") = Sakusei 53 '範囲コピー 54 ws2.Range(ws2.Cells(tmpRow, "C"), ws2.Cells(tmpRow, "K")).Value = ws1.Range(ws1.Cells(i, "C"), ws1.Cells(i, "K")).Value 55 tmpRow = tmpRow + 1 56 End If 57 Next 58 59End Sub 60 61コード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sinzou

2020/03/02 03:13

EndRow = ws1.Cells(Rows.Count, "C").End(xlUp).Row なので C列の最終行は? (ws1.Cells(i, "A") = Sakusei A列の文字列とSakuseiとイコールでないから? 空白、-と-  とかないですか?
Mkasai

2020/03/02 03:28

C列の最終行は301行です。 後は何を確認したらよろしいのでしょうか。
sinzou

2020/03/02 03:46

再度確認ですが1物件のみ転記ですか? 関連物件 -02 や -03 も含めるのですか?
Mkasai

2020/03/02 03:53

動きました。 Cセルに何もデータが入っていないと他のセルに情報が入っていても動かないようです。 この部分は改善できるのでしょうか。
sinzou

2020/03/02 03:59

EndRow = ws1.Cells(Rows.Count, "C").End(xlUp).Row はC列の最終行なので EndRow = ws1.Cells(Rows.Count, "A").End(xlUp).Row A列の最終行でおこなえば?
yureighost

2020/03/02 04:02

ws1.Cells(Rows.Count, "C").End(xlUp).Rowの動作をExcelの操作で説明すると、 「C列の最終行からCtrl+↑を実行した」という物でC列の最後のデータが入っている行に移動します。 そのため処理を実行したい行までデータが入っている列を対象としないといけません。 抽出検索条件が入っているA列とかは空白のデータが入っていない行とかあるのでしょうか。
Mkasai

2020/03/02 04:42

A列としたら問題なく動きました。 ありがとうございました。
guest

回答3

0

vba

1EndRow = ws1.Cells(Rows.Count, "C").End(xlUp).Row

が処理最終行を指してそうです。

Rows.Countの部分が開いているシート内容によって不定になるので
⇢ 不定というのは誤りでした。失礼しました。常に最終行になるので、65535 or 1048576になります。

vba

1EndRow = 300

の様に固定値にしてしまうか、「契約情報」シートのC列の最後、という意図で書かれているなら

vba

1EndRow = ws1.Cells(65536, "C").End(xlUp).Row

のように適当に大きな数値からxlUpを試してみるのはどうでしょうか。

投稿2020/03/02 03:14

編集2020/03/02 04:07
Eggpan

総合スコア2799

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2020/03/02 03:45

Rows.Count はシートに関係なく一定ですよ。 Excelのバージョンに依存しますが。 Office2003以前は65536、Office2007以降は1048576。
Mkasai

2020/03/02 03:46

大きい数値で試してみたのですが、変わりません。 他が間違っているのでしょうか。
Mkasai

2020/03/02 03:53

動きました。 Cセルに何もデータが入っていないと他のセルに情報が入っていても動かないようです。 この部分は改善できるのでしょうか。
Eggpan

2020/03/02 04:02

>hatena19さん 勘違いしていたようです。回答修正します。失礼しました。 >Mkasaiさん Cセルを上にたどっていっているコードなので、そのようになります。
mattuwan

2020/03/02 04:58

>Cセルに何もデータが入っていないと他のセルに情報が入っていても動かないようです。 >この部分は改善できるのでしょうか。 C列で最終データのセルを探しているから、C列の最終行番号が返ってきてるので、 A列とかB列とか、「最終のデータ」が入っている列で探せばいいのでは?
guest

0

自己解決

sinzouさんよりA列の最終行で行うというアドバイスいただきまして、そのように変更しました。

EndRow = ws1.Cells(Rows.Count, "C").End(xlUp).Row

EndRow = ws1.Cells(Rows.Count, "A").End(xlUp).Row
としました。
C列にこだわらなければいけない理由は特にないので、このように変更しました。

投稿2020/03/02 07:04

Mkasai

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ExcelVBA

1Option Explicit 2 3Sub test() 4 '絞り込まれていたら 5 If ActiveSheet.FilterMode Then ActiveSheet.ShowAllData 6 7 Dim curPath As String, Sakusei As String 8 Dim ws1 As Worksheet, ws2 As Worksheet 9 Dim StartRow As Integer, EndRow As Integer, tmpRow As Integer 10 Dim wb As Workbook, flag As Boolean 11 12 curPath = ThisWorkbook.Path 13 14 'ブックが既に開いているかどうかチェック 15 For Each wb In Workbooks 16 If wb.Name = "書類作成.xlsm" Then Exit For 17 Next 18 'ループを最後まで回ったらwbはNothingになるので、無かったと判定 19 If wb Is Nothing Then 20 Set wb = Workbooks.Open(Filename:=curPath & "\書類作成.xlsm") 21 End If 22 23 'シート名を変えている場合は適宜変更 24 Set ws1 = ThisWorkbook.Worksheets("契約情報") 25 Set ws2 = wb.Worksheets("作成情報") 26 27 28 ws2.Range("2:11").ClearContents 29 30 '作成シートに指定されている抽出条件 31 Sakusei = ws2.Cells(1, "A").Value 32 33 StartRow = 2 34 EndRow = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row 35 tmpRow = 2 36 37 For i = StartRow To EndRow 38 If ws1.Cells(i, "A").Value = Sakusei Then 39 ws2.Cells(tmpRow, "A").Value = Sakusei 40 '範囲コピー 41 ws2.Range(ws2.Cells(tmpRow, "C"), ws2.Cells(tmpRow, "K")).Value = ws1.Range(ws1.Cells(i, "C"), ws1.Cells(i, "K")).Value 42 tmpRow = tmpRow + 1 43 End If 44 Next 45End Sub

多分こんな感じだと思いますが、
動かしてみてないのでバグがあるかもです。

プロパティ、メソッドの探り方 マクロ記録とF1のHelpを使う
記事が古いけど、参考になれば。。。
上手く行かない時はステップ実行をしながら、ローカルウィンドウやウォッチ式、イミディエイトウィンドウ等で変数の中身が意図通りになっているか確認してみてください。
(解らない用語はまずは検索して調べてみてください。)

あと、オートフィルターを使えばループを自分で書かなくていいけど、
それは、とりあえずおいておいて、自分でVBAを組み立てる練習ということですかね?
もひとつ、操作するのは結局セル範囲(Rangeオブジェクト)なので、
操作対象のセル範囲を変数を用意して保持していった方が組み立て方も、
後で読む方も簡単になると思いました。

投稿2020/03/02 05:25

mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問