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

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

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

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

1回答

9203閲覧

EXCEL VBAでデータをAutoFilterとSortでフィルターとソートをしたいが、AutoFilterメソッドが失敗しましたとなる。エラーを解決したい。

kotatsu2

総合スコア16

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2021/05/20 06:03

編集2021/05/20 10:34

3日前に仕事で急にVBAを使ってデータの処理をしなければならなくなり、Webでいろいろ調べてデータをフィルターし、ソートをするマクロを作ったのですが、エラーが解決できなくて困っています。
お力を貸してほしいです。(VBA初心者です)

やりたいこと

マクロを設定したボタンを押すと[予定表]シートに設定してある日付でフィルターをかけ、
結果を「抽出」シートに張り付け、時間列で昇順にソートをかける。
その後、「抽出」のデータを[予定表]に時間毎にわけて表示する。

困っていること

現在、困っていることは2つ。

1.AutoFilterを記述しているSchedule1マクロを開始すると、1度目は必ずエラーになる。

エラー内容:番号1004 詳細:RangeクラスのAutoFilterメソッドが失敗しました。 関数:Schedule1

5/20追記
上記のエラーが発生している箇所がわかりました。
以下のコードを実行したところでエラーが発生します。

'セットされた日付でオートフィルをかける Range("A1").AutoFilter field:=13, Criteria1:=Format(second, "m月d日") コード

2.しかし、再度Schedule1マクロを実行すると正常に最後まで処理が終了するが、正常に処理が終了後、再度エラーメッセージが表示される。

エラー内容;番号:0 詳細: 関数FirstDaySort

教えてほしいこと

1.エラーの原因と解決方法を教えてほしい。
2.データ件数が現在2700件ほどあり、処理時間が10秒ほどかかる。これから毎日300件ずつ増える予定なので、少しでも処理時間を短くしたい。短くするにはどうすればよいか。
3.ソートのマクロをソートする列が違っても共有して使えるようにしたいが、どうすれば実現できるか。

ファイルの環境

シート3つ:[予定表][データ一覧][抽出]

Option Explicit Sub Schedule1() 'データを日付でフィルターし、時間列で昇順にソートをかける On Error GoTo Catch Dim day1 As Date, first As String Application.ScreenUpdating = False '画面の表示を止める Sheets("抽出").Select Cells.Clear Sheets("予定表").Select day1 = Range("L2").Value first = CStr(day1) 'Date型を文字列に変更(5/1⇒5月1日でフィルターをかけるため) ' Sheets("データ一覧").Select Range(Range("A2"), Cells(Rows.Count, 1).End(xlDown)).AutoFilter '上から最終行を検索 'セットされた日付でオートフィルをかける(〇月〇日) Range("A1").AutoFilter field:=9, Criteria1:=Format(first, "m月d日") 'オートフィルの結果をコピーする Range("A1", Range("W1").End(xlDown)).SpecialCells(xlCellTypeVisible).Copy '書式と共にコピーする Sheets("抽出").Range("A1").PasteSpecial Paste:=xlPasteAll '予約時間①でソートをかける Sheets("抽出").Select Call FirstDaySort Worksheets("データ一覧").AutoFilterMode = False '念のためフィルタを解除 Application.ScreenUpdating = True '画面を再表示する MsgBox "処理が終了しました" Exit Sub Catch: Call LogErrorMessage("Schedule1") End Sub Sub FirstDaySort() On Error GoTo Catch Range("A1").CurrentRegion.Sort key1:=Range("J1"), Order1:=xlAscending, Header:=xlYes Catch: Call LogErrorMessage("FirstDaySort") End Sub Public Sub LogErrorMessage(ByVal funcName As String) Dim err_mess As String err_mess = err_mess & "番号: " & Err.Number err_mess = err_mess & " 詳細: " & Err.Description err_mess = err_mess & " 関数: " & funcName 'ログやメッセージを出力する Debug.Print (err_mess) Dim r As VbMsgBoxResult r = MsgBox(err_mess, vbOKOnly Or vbCritical) End Sub

以上、ご指導いただけませんか。よろしくお願いします。

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

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

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

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

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

jinoji

2021/05/20 08:59

とりあえず、困っていることの2つ目は、 Catch:の前にExit Sub を書いていないからでしょう。
jinoji

2021/05/20 09:11

この処理が動くとき、Sheets("データ一覧")のAutoFilerはどういう状態だという想定なのでしょうか。 そこが不確定だと、処理が思ったように動かないことにつながります。 処理の中で、一度AutoFilterを解除して改めて設定しなおす、とかやった方が確実かも。
jinoji

2021/05/20 09:17

特に複数のシートを扱う場合は、 Sheets("抽出").Select Cells.Clear のように事前にSelectする書き方よりは、 Sheets("抽出").Cells.Clear のように直で書く、もしくはWithを使って With Sheets("データ一覧") .Range(.Range("A2"), .Cells(Rows.Count, 1).End(xlDown)).AutoFilter End With のように書くことをお勧めします。
kotatsu2

2021/05/20 09:24 編集

jinojiさん、ありがとうございます。 Catch:の前にExit Subの記載で、Sortの処理が終了後のエラーメッセージは解決できました。ただ、「RangeクラスのAutoFilterメソッドが失敗しました」のエラーはこれでは消えませんでした。 [データ一覧]のデータをAutoFilerを使って日付列に入っている特定の日付[予定表で設定する]で絞り込んだ状態と想定しています。その結果を「抽出」シートにそのままコピーしたいと思っています。 書き方も大切なんですね。勉強になります。これからもいろいろ覚えていこうと思います。 ありがとうございました。助かりました。
jinoji

2021/05/20 09:33

Range("A1", Range("W1").End(xlDown)).SpecialCells(xlCellTypeVisible).Copy でコピーする際に、範囲が意図通りになっているか気になります。 というのは、 End(xlDown)で最下行まで行ってしまい、 意図せず広大な範囲をコピーしているがために遅くなっているのでは、と考えたからです。 Debug.Print Range("A1", Range("W1").End(xlDown)).SpecialCells(xlCellTypeVisible).Address とかで確かめてみてはどうでしょうか。
kotatsu2

2021/05/20 09:42 編集

Jinojiさん、ありがとうございます。早速調べてみました。 結果:$A$1:$W$2,$A$5:$W$16,$A$2697:$W$1048576 この結果が何を意味しているのか、わからないのですが。すみません。 実際にコピーしたいデータがあるのはA1:W16だけです。 ここ[A1:W16]だけコピーしているつもりでしたが、間違っていたのでしょうか。 確かに時間がかかっていたのは、この部分でした。 どのように修正すれば実際にデータのある部分だけコピーペーストできるのでしょうか。
jinoji

2021/05/20 09:46

Filterの結果、W列が全て空白の行だけが表示されている状態と思われます。 その状態で Range("W1").End(xlDown) とやると、シート全体の最下行であるRange("$W$1048576")が選ばれることになります。 実際のシートのフォーマットがわからないのではっきりしたことは言いづらいですが、 Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).Copy とかがよいような気がします。
kotatsu2

2021/05/20 10:00

jinojiさん、ありがとうございます。 早速書き換えてみました。 Debug.Printを設定して結果を見ると「True」と変わりました。そして、処理速度が劇的に速くなりました。 ただ、「RangeクラスのAutoFilterメソッドが失敗しました」のエラーメッセージは相変わらず消えません。 フォーマットというのは、どういう意味でしょうか?データの入力状態でしょうか? [データ一覧]には、A列にはデータが必ず入力されており、A列がキーになっています。 他の列には、データがあったり、なかったりします。予約で日付が決まったものだけを日付列と時間列に入力し、特定の日付を指定してデータを絞り込んで抽出し、時間でソートをかけたいです。
jinoji

2021/05/20 10:08

Range(Range("A2"), Cells(Rows.Count, 1).End(xlDown)).AutoFilter の行を消したらエラーが消える気がきます。 フォーマットといったのは、 シートの1行目が見出し行で2行目以降がデータ行、という形なのか、それとも見出し行はなくて1行目からデータ行なのか、とか もし見出し行がある場合、コピーの際に見出し行も含めてコピーしたいのか、選択されたデータ行だけをコピーしたいのか、といったことです。
kotatsu2

2021/05/20 10:19

jinojiさん、ありがとうございます。 その記載の部分は教えていただいた通り、 With Sheets("データ一覧") .Range(.Range("A2"), .Cells(Rows.Count, 1).End(xlDown)).AutoFilter End With に変更しています。 それでもまだ毎回ではなく、2回に1回は「RangeクラスのAutoFilterメソッドが失敗しました」のエラーが発生します。 フォーマットの解説ありがとうございます。 データ一覧のフォーマットは、シートの1行目が見出し行で2行目以降がデータ行になっております。 そして、コピー先には見出しも含めて「抽出」シートにコピーしたいです。
guest

回答1

0

ベストアンサー

多分こんな感じ。

VBA

1 Sheets("抽出").Cells.Clear 2 day1 = Sheets("予定表").Range("L2").Value 3 4 With Sheets("データ一覧") 5 '一旦フィルタを解除 6 .AutoFilterMode = False 7 'セットされた日付でオートフィルをかける(〇月〇日) 8 .Range("A1").AutoFilter field:=9, Criteria1:=Format(day1, "m月d日") 9 'オートフィルの結果をコピーする 10 .Range("W1", .Range("A1").End(xlDown)).SpecialCells(xlCellTypeVisible).Copy Sheets("抽出").Range("A1") 11 End With 12 13 14 '予約時間①でソートをかける 15 With Sheets("抽出") 16 .Range("A1").CurrentRegion.Sort key1:=.Range("J1"), Order1:=xlAscending, Header:=xlYes 17 End With 18

投稿2021/05/20 10:32

jinoji

総合スコア4592

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

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

kotatsu2

2021/05/20 10:47

jinojiさん、ありがとうございます。 無事にエラーがなくなり、処理もとても速くなりました。 オートフィルの記述がよくなかったみたいですね。助かりました。もっとVBAのことを勉強していきます。 助かりました。ありがとうございました。
jinoji

2021/05/20 10:52

解決してよかったです。 エラーが2回に1回起きるからくりですが、 元のコードの Range(Range("A2"), Cells(Rows.Count, 1).End(xlDown)).AutoFilter Range("A1").AutoFilter field:=9, Criteria1:=Format(first, "m月d日") が、 <1回目> A2を見出しとしたフィルターを作る  → (すでにフィルターがあるのに)A1を見出しとしたフィルターを作ろうとする →エラー <2回目> A2を見出しとしたフィルターを解除する  → A1を見出しとしたフィルターを作ろうとする → OK ということだと思います。
kotatsu2

2021/05/20 11:15

jinojiさん、詳しい説明ありがとうございます。なぜエラーが出ていたのかよくわかりました。 VBAをさわって4日目なので、WEBにあるコードをコピーして使用していました。 たくさん勉強しなければいけないですね。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問