Excel2010を使っている者です。
指定した範囲の値で順番に表①の任意の列にソートをかけて印刷していくVBAを作りたいと思っております。
具体的には、A1からA20の各セルに値が入力してあるのですが、表①(セル範囲はA30からS500)のF列に順番にソートをかけて、順次、印刷したいと思っております。
なお、A1からA20についてですが、上から順番に必要がある場合のみ値を入れるようになっているため、全てのセルは使わない可能性が高いです。(A1からA8のみ値が入っている日もあれば、A1からA15まで値が入っている日もあれば、A1からA3までしか値が入ってないときもあればです)
私はネットで調べながら以下のようにVBAを作ってみたのですが、実行しようとすると「Nextに続くForがありません」というメッセージが出てしまいます。
どのような記述にすれば良いのか、ご教示願います。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Sub 印刷()
Dim i As Long
For i = 1 To 20
If Cells(i, 1) = "" Then
Exit Sub
Range("A30:S500").AutoFilter Field:=7, Criteria1:=Cells(i, 1).Value
Next i
ActiveSheet.PrintOut
End Sub
No.6ベストアンサー
- 回答日時:
こんばんは!
少しだけコードの説明を!
① For k = 31 To 500 ”31行から500行までKを使ってループを行う
本来であれば最終行を取得しそこまでのループにすればよいのですが、
必ず500行目まではデータがある!という前提のコードでした。
② If Rows(k).Hidden = False Then ”もし、K行が表示されていれば
myFlg = True ”myflgにはTrueを入れる。
Exit For ”ループをやめる?
End If ”?
Next k ”次の行の処理に移る?
フィルタを掛けるというコトは30行目は項目行でデータは31行以降にあると思い
31行目からその行が「表示」されているかどうか?を調べています。
>End If ”?
の部分は
>If Rows(k).Hidden = False Then
に対する「End If」です。
仮に「myFlg」が「FALSE」である場合は「TRUE」になるまで、もしくは500行目までループします。
「myFlg」はBoolean型で宣言していますので、「FALSE」(初期値)か「TRUE」のどちらかになります。
仮に31行目が表示されているというコトは少なくとも1つ以上の該当データがあるので
「myFlg」を「TRUE」とし、それ以降ループしても無意味なのでそこでループを抜けます。
ただ、該当データがない場合は500行目まで「FALSE」となり続けます。
最終的に「myFlg」が「TRUE」なのか?「FALSE」なのかを判定し
「TRUE」の場合 → 該当データが1つ以上はあるので印刷プレビューへ
「FALSE」の場合 → 該当データが存在しないのでメッセージボックスを表示!
といった流れにしています。
最後の
End If ”? (あ)
myFlg = False ”?(い)
End If "?(う)
Next i
(あ)は
If myFlg = False Then
に対する「If」の「End If」になる。
(い)は
次のループに入り前に「myFlg」を初期値の「FALSE」に戻します。
これを行わないと常に「TRUE」のままになりデータがない場合でも印刷プレビューが表示されてしまう。
(う)の「End If」は
>Next i
の前にあるので
>If Cells(i, j) <> "" Then
に対する「End If」になります。
※ こちらのVBE画面は↓のように記載し、「End If」はどこの「If・・・」にかかっているのか
タブ送りで判りやすく訂正しやすいようにしているのですが
それをそのままこの画面にコピー&ペーストすると
左寄せになってしまうので判りにくいですよね。m(_ _)m
No.5
- 回答日時:
あぁ~~~!そういうコトだったのですね。
↓のコードに変更してみてください。
Sub Sample3()
Dim i As Long, j As Long, myCol As Long
Dim k As Long, myFlg As Boolean
For j = 1 To 2 '←A~B列まで//
If j = 1 Then
myCol = 6 '←A列の場合はF列で//
Else
myCol = 7 '←B列の場合はG列で//
End If
For i = 1 To 20
If Cells(i, j) <> "" Then
Range("A30:S500").AutoFilter field:=myCol, Criteria1:=Cells(i, j)
For k = 31 To 500
If Rows(k).Hidden = False Then
myFlg = True
Exit For
End If
Next k
If myFlg = False Then
MsgBox "「" & Cells(i, j) & "」のデータなし"
Else
ActiveSheet.PrintPreview '←印刷プレビューでやめています。//
End If
myFlg = False
End If
Next i
ActiveSheet.AutoFilterMode = False
Next j
End Sub
今度はどうでしょうか?m(_ _)m
何度もお付き合いいただき、ありがとうございます。
完璧にうまくいき、大変助かりました。
ただ、コードで理解できない点があったのですが、教えたいただけないでしょうか。書いていただいた以下のコードについてですが、それによってどういった流れの処理になっているのかが理解できなかったのですが、私が「?」を付けた個所が理解できていないのだと思います。
For k = 31 To 500 ”31行から500行までKを使ってループを行う
If Rows(k).Hidden = False Then ”もし、K行が表示されていれば
myFlg = True ”myflgにはTrueを入れる。
Exit For ”ループをやめる?
End If ”?
Next k ”次の行の処理に移る?
If myFlg = False Then "もし、K行が非表示ならば
MsgBox "「" & Cells(i, j) & "」のデータなし" ”セル番号のデータなし”と表示させる。
Else ”もし、K行が表示されていれば
ActiveSheet.PrintPreview '←印刷プレビューでやめています。// ”プリントプレビュー
End If ”?
myFlg = False ”?
End If "?
Next i
ActiveSheet.AutoFilterMode = False ”行の非表示を解除する。
Next j
End Sub
No.4
- 回答日時:
何度もごめんなさい。
No.3を投稿後今一度タイトルが気になったので顔をだしました。
>順番にソートをかけて、指定した表を印刷していく・・・
「ソート=並び替え」 となりますが
要するに順にフィルタをかけて該当データがあれば印刷するという解釈でよいのでしょうか?
その場合は↓のコードにしてみてください。
Sub Sample2()
Dim i As Long, j As Long
Dim k As Long, myFlg As Boolean
For j = 1 To 2
For i = 1 To 20
If Cells(i, j) <> "" Then
Range("A30:S500").AutoFilter field:=6, Criteria1:=Cells(i, j)
For k = 31 To 500
If Rows(k).Hidden = False Then
myFlg = True
Exit For
End If
Next k
If myFlg = False Then
MsgBox "「" & Cells(i, j) & "」のデータなし"
Else
ActiveSheet.PrintPreview '←印刷プレビューでやめています。//
End If
myFlg = False
End If
Next i
Next j
End Sub
※ コードは「印刷プレビュー」でやめていますので、すぐに印刷を実行する場合は
>ActiveSheet.PrintPreview
を変更してください。m(_ _)m
毎度、誠にありがとうございます。
書いていただいたコードを使うと、見事に動きました。
しかし、大変申し訳ないのですが、私の説明不足がありまして、求めていたものをは少し違ったものになってしまいました。
おっしゃるとおり、順にF列にフィルタをかけて、データがあれば印刷プレビューに出したいと思っております。混乱させてしまって申し訳ありませんでした。
しかし、A列とB列には違う条件(A列の値でフィルタをかける場所はF列、B列の値のときはG列でフィルタをかけたいと思っております。つまり、表①で、A1~A20の値のときはその値でF列でフィルタをかけて其々にデータがあれば印刷プレビューにし、B1~B20の値のときはG列でフィルタを・・(以下同様)と思っております)
また、さらにフィルタをかけるためのC列を追加する可能性があるため、A列、B列を並列的に描くのではなく、直列的に上から書いていきたいと思まいます。
書いていただいたコードを以下のように変更してみたのですが、うまく動きませんでした。どのように書けば良いのかご教示いただけると幸いです。
For j = 1 To 2
For i = 1 To 20
If i = 1
If Cells(i, j) <> "" Then
Range("A30:S500").AutoFilter field:=6, Criteria1:=Cells(i, j)
Else
End If
AutoFilterMode = False
If i = 2
If Cells(i, j) <> "" Then
Range("A30:S500").AutoFilter field:=7, Criteria1:=Cells(i, j)
Else
End If
AutoFilterMode = False
For k = 31 To 500
If Rows(k).Hidden = False Then
myFlg = True
Exit For
End If
Next k
If myFlg = False Then
MsgBox "「" & Cells(i, j) & "」のデータなし"
Else
ActiveSheet.PrintPreview
End If
myFlg = False
End If
Next i
Next j
End Sub
No.3
- 回答日時:
続けてお邪魔します。
質問内容のコードをもう一度よく見てみると
一つずつフィルタをかけているのでその都度印刷プレビューを表示させるようにしていました。
あくまで憶測ですが・・・
A1~B20にオートフィルタの項目を入力し、複数の条件でフィルタを掛けたい!
というコトなのでしょうか?
↓の画像でいえばA1~B20セルに 「日・月・火・金」がありますので、
6列目(F列)が「日」か「月」か「火」か「金」をキーとしてフィルタを掛ける!
といったことがお望みであれば
今までのコードはお望みの動きにならないはずです。
結構面倒になります。
Excel2007以降で使える(Excel2003まではオートフィルタのキーは三つまでしか設定できない)コードにしてみました。
Sub Sample1()
Dim i As Long, c As Range, myFlg As Boolean
Dim myStr As String, myAry As Variant
For Each c In Range("A1:B20")
If c <> "" Then
myStr = myStr & c & ","
End If
Next c
If myStr <> "" Then
myAry = Array(Split(Left(myStr, Len(myStr) - 1), ","))
Range("A30:S500").AutoFilter field:=6, Criteria1:=myAry, Operator:=xlFilterValues
For i = 31 To 500
If Rows(i).Hidden = False Then
myFlg = True
Exit For
End If
Next i
If myFlg = False Then
MsgBox "該当データなし"
Else
ActiveSheet.PrintPreview
End If
End If
End Sub
これでF列が「日、月、火、金」の行が表示 → 印刷プレビュー
該当データがない場合のみメッセージボックスを表示させるようにしています。
的外れならごめんなさい。m(_ _)m
お礼が遅くなって申し訳ありません。
複数の条件でオートフィルタをかけたいとは思っているのですが、書かれていることが理解できませんでした。
次のご回答に、不明な点等は書かせていただきます。
No.2
- 回答日時:
No.1です。
>当初のとおり「For i = 1 To 20」にしておくと問題があるのでしょうか(?)
前回、余計なお世話で書いたのは
最終行を取得し、そこまでのループでやめるための方法でしたが
A30~S500までデータがあるようなので、この方法は使えません。
また、
>For i = 1 To Cells(Range("A1").End(xlDown).Row, "A")
は
>For i = 1 To Range("A1").End(xlDown).Row
の間違いでした。どうも失礼しました。
ただこれはA1セルから下へ見ていき、空白セルの前までの行番号取得方法ですが、
データが21行目以降も続いている場合はこちらもダメですね。
今回の質問に関しては20行だけのループなので
まったく問題ないと思います。
ただ、コードを拝見すると30行目が項目行になっているという前提で
Dim i As Long
For i = 1 To 20
If Cells(i, 1) = "" Then Exit Sub
Range("A30:S500").AutoFilter Field:=6, Criteria1:=Cells(i, 1).Value
If MsgBox("印刷プレビューを行って良いですか?", vbYesNo + vbExclamation, "確認") = vbYes Then
ActiveSheet.PrintPreview
End If
Next i
のように最後に「Next i」を持ってこないと
メッセージボックスも表示されないと思います。
※ 上記コードではA1セル以降も印刷プレビューに表示されますが、
印刷範囲は指定しなくてよいのですよね?m(_ _)m
毎度、ありがとうございます。
教えていただいたとおりに修正すると、うまく動きました。
しかし、実は抽出したい値はA1~A20のみでなく、B1~B20にも入っているのですが、どのようにつなげれば良いのか教えていただけないでしょうか。
そのまま以下のようにコードをつなげてもB1~B20の分が動きませんでした。
Dim i As Long
For i = 1 To 20
If Cells(i, 1) = "" Then Exit Sub
Range("A30:S500").AutoFilter Field:=6, Criteria1:=Cells(i, 1).Value
If MsgBox("印刷プレビューを行って良いですか?", vbYesNo + vbExclamation, "確認") = vbYes Then
ActiveSheet.PrintPreview
End If
Next i
For i = 1 To 20
If Cells(i, 2) = "" Then Exit Sub
Range("A30:S500").AutoFilter Field:=6, Criteria1:=Cells(i, 1).Value
If MsgBox("印刷プレビューを行って良いですか?", vbYesNo + vbExclamation, "確認") = vbYes Then
ActiveSheet.PrintPreview
End If
Next i
また、大変申し訳ないのですが、可能であれば、A1~A20,B1~B20の値では何も抽出できなかった場合は処理をしない(印刷プレビューを・・のメッセージが出ない)ようにする方法も教えていただけると幸いです。
No.1
- 回答日時:
こんばんは!
そのままのコードで使いたい場合は
>If Cells(i, 1) = "" Then
>Exit Sub
と2行になっているところを
>If Cells(i, 1) = "" Then Exit Sub
のように1行にしてみてはどうでしょうか?
おそらく2行にするとそのあとに
>End If
が必要になるはずです。
※ 私的には
>Exit Sub
ではなく
>Exit For
という使い方をします。
ただその後の処理がないので「Exit Sub」でも問題はないと思いますが・・・
余計なお世話かもしれませんが、
>For i = 1 To 20
を
>For i = 1 To Cells(Rows.Count, "A").End(xlUp).Row
もしA21セル以降にもデータがある場合は
>For i = 1 To Cells(Range("A1").End(xlDown).Row, "A")
とすれば
空白の場合の処理は不要だと思います。m(_ _)m
お返事ありがとうございます。
>>If Cells(i, 1) = "" Then Exit Sub
のように1行にしてみてはどうでしょうか?
修正いたしました。
>>For i = 1 To Cells(Range("A1").End(xlDown).Row, "A")
とすれば空白の場合の処理は不要だと思います。m(_ _)m
A列においては21行目以降にもデータがあるため(A30:S500に表があります)、書いていただいたようにしましたが、実行しようとすると、型が違うというエラーが出てしまいました。
当初のとおり「For i = 1 To 20」にしておくと問題があるのでしょうか(?)
なお、申し訳ないのですが、質問の際は実際に書こうとしているコードを少し省略してしまいました。
実際は以下のとおりなのですが、どこが問題なのかご教示いただけないでしょうか。
Dim i As Long
For i = 1 To 20
If Cells(i, 1) = "" Then Exit Sub
Range("A30:S500").AutoFilter Field:=6, Criteria1:=Cells(i, 1).Value
Next i
Dim intRet As Integer
intRet = MsgBox("印刷プレビューを行って良いですか?", vbYesNo + vbExclamation, "確認")
If intRet = vbNo Then
Exit Sub
End If
ActiveSheet.PrintPreview
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Excel(エクセル) Excel VBAプルダウンの値を変えながら2枚ずつ印刷する方法? 4 2022/05/27 13:04
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) 複数シート一括作成後に、特定範囲の数式は値で貼り付けしたい 3 2022/10/07 11:18
- Visual Basic(VBA) VBA横データを縦にしたいです 2 2023/08/08 19:38
- Visual Basic(VBA) Excelのマクロについて教えてください。 1 2023/03/12 12:16
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Excel(エクセル) 日付で矢印マクロ 4 2023/07/25 16:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
至急!尿検査前日にオナニーし...
-
首吊りどこ締めるの
-
尿検査の前日は自慰控えたほう...
-
尿検査前日に自慰行為した時の...
-
検便についてです。 便は取れた...
-
白血球が多いとどんな心配があ...
-
中出しをするとお腹が痛い・・・。
-
射精をして1週間以内に尿検査を...
-
彼女のことが好きすぎて彼女の...
-
腕を見たら黄色くなってる部分...
-
勃起する時って痛いんですか? ...
-
変な話しになります。尿検査で...
-
これって喉仏ですか? 私は女性...
-
EXCELで条件付き書式で空白セル...
-
男です。昨日の午後3時くらいに...
-
今朝、毎朝の習慣でオナニーし...
-
納豆食べた後の尿の納豆臭は何故?
-
1日前の検尿
-
値が入っているときだけ計算結...
-
精子が黄色?
おすすめ情報