[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『差し込み連続印刷VBAのエラーについて』(右近)
お尋ねします。
エクセル上で差し込み連続印刷ができるVBAを参照させていただき、以下のように設定して実行しようとしたところ、
「実行時エラー '13': 型が一致しません。」というエラーが表示されます。
デバッグすると「myNo = .Range("B" & i).Value」の行に問題が発生していました。
myNoにマウスカーソルを当てると、「myNo = 3」の値が表示されます。
実際にF13に入力している数値も「3」です。
どのようなコードの修正が必要かご教授いただきたく、お尋ねいたします。よろしくお願いいたします。
Sub 印刷()
Dim LastRow As Long Dim i As Long Dim myNo As Long
If vbNo = MsgBox("印刷を開始していいですか?", vbYesNo) Then Exit Sub
With Worksheets("Sheet3") LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
For i = 1 To LastRow
myNo = .Range("B" & i).Value
With Worksheets("Sheet3") .Range("F13").Value = myNo .PrintOut Copies:=1, Collate:=True End With Next i End With
MsgBox "印刷が終わりました"
End Sub
< 使用 Excel:Excel2019、使用 OS:Windows10 >
おはようございます 単純に型が違うだけでしょうから これを Dim myNo As Long ⬇これに変えてみたらどうでしょうか? Dim myNo (SoulMan) 2021/04/11(日) 10:31
それから、その他に後3箇所(セル)へも差込みする場合の修正も併せてご教授いただけないでしょうか。
よろしくお願いいたします。
(右近) 2021/04/11(日) 10:36
すみません。 状況が今一読み込めませんm(__)m >3つ以外のものまで差込み印刷してしまいます。
コードのどこかに IF myNo= 3 Then とかの条件分岐があるのなら分かりますけど、、 Dim myNo As Long ↓ Dim myNo に変えただけで、なぜ?そうなるのか???
それから >その他に後3箇所(セル)へも差込みする場合の修正 これはなんのことですか??? (SoulMan) 2021/04/11(日) 10:55
私も同様の疑問を持ちました。 その他、デバッグについての誤解がありそうなのでコメントしておきます。
> デバッグすると「myNo = .Range("B" & i).Value」の行に問題が発生していました。 > myNoにマウスカーソルを当てると、「myNo = 3」の値が表示されます。
黄色くハイライトされている行は、実行しようとして「実行できていない」行ですよ。 右辺にある .Range("B" & i).Valueが何かを調べる必要があります。 イミディエイトウインドウで ? Worksheets("Sheet3").Range("B" & i).Value として、内容を確認して下さい。(iを調べて、B列の該当セルを目視確認でもよいでしょう) それが、整数として不適格なものになっているはずです。
整数型で宣言していること自体がまちがいなら、Variant型に変更すればよいですが、 そのあたりもよく理解のうえ実行しましょう。 (γ) 2021/04/11(日) 11:04
といいつつも想像力をMaxにしてコードを書くと↓みたいな感じでしょうけど。。。 原型がないですよ(^^;
Option Explicit Sub 印刷() Dim LastRow As Long Dim i As Long Dim myNo As Variant 'Double If vbNo = MsgBox("印刷を開始していいですか?", vbYesNo) Then Exit Sub With Worksheets("Sheet3") LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row For i = 1 To LastRow myNo = .Range("B" & i).Value If myNo = 3 Then With Worksheets("Sheet3") .Range("F13").Value = myNo .PrintOut Copies:=1, Collate:=True End With End If Select Case i Case 3 With Worksheets("Sheet3") .Range("F14").Value = myNo .PrintOut Copies:=1, Collate:=True End With Case 4 With Worksheets("Sheet3") .Range("F15").Value = myNo .PrintOut Copies:=1, Collate:=True End With Case 5 With Worksheets("Sheet3") .Range("F16").Value = myNo .PrintOut Copies:=1, Collate:=True End With End Select Next i End With MsgBox "印刷が終わりました" End Sub (SoulMan) 2021/04/11(日) 11:08
(右近) 2021/04/11(日) 12:39
コードのどこかに IF myNo= 3 Then とかの条件分岐があるのなら分かりますけど、、 Dim myNo As Long ↓ Dim myNo に変えただけで、なぜ?そうなるのか??? .Range("F13").Value = myNo ←F13に数値を直接入力しています。それがこの場合は、「3」ということです。最大「10」まで入力できるようにしています。
領収書の宛名に名前を差し込んでいるのでが、3人分ということです。10人分まで差し込めるようにしているということです。
それから その他に後3箇所(セル)へも差込みする場合の修正 これはなんのことですか??? 上記宛名に加えて、例えば金額、日付なども差し込めるようにしたいということですが。
γさんへ
イミディエイトウインドウで、「myNo = .Range("B" & i).Value」を確認しました。
「myNo = 3」、「i = 5」と表示されます。
B列=IFERROR(IF($C2<>"",ROW()-1,""),"") このような関数をB11まで入れています。
C列にいわゆる宛名となる名前を入れています。
この場合、3名の名前となっているため、3件です。F13には手入力で3を入力しています。本当は、B列から関数で入るようにしていましたが、印刷を実行すると関数が消えてしまうのです。本当は手入力ではなくしたいのですが。
B列もF13の値も整数であると思います。
以上、回答いたします。
何とか差込み印刷できるように出来ればと思っております。よろしくお願いいたします。
(右近) 2021/04/11(日) 13:01
Sub 印刷_改() Dim i As Long
If MsgBox("印刷を開始していいですか?", vbYesNo) = vbNo Then Exit Sub
With Worksheets("Sheet3") For i = 1 To .Cells(.Rows.Count, "B").End(xlUp).Row .Range("F13").Value = .Cells(i, "B").Value .PrintOut Copies:=1, Collate:=True Next i End With
MsgBox "印刷が終わりました"
End Sub
F13セルに何が入っていようが関係ないのでは?
(マクロで、.Cells(i, "B")の値に書き換えられちゃうので)
(もこな2) 2021/04/11(日) 13:29
すみません。全然わかりません。私だけかもしれませんが、、、 >.Range("F13").Value = myNo ←F13に数値を直接入力しています。 >それがこの場合は、「3」ということです。
それはわります。 分からないのは、ここの数字を変えるだけでなぜ人数が増えるのですか? ちょっとご希望に添えそうもないのでもう一度質問を整理していただくか 分かるように説明してください。
レイアウトがあるといいです。
>上記宛名に加えて、例えば金額、日付なども差し込めるようにしたいということですが。 差し込むという表現がどういうものかわかりませんけど、、
右辺と左辺を書けばそうなりますよ?
例えば
Range("○○").Value=金額 Range("○○").Value=日付
などです。
また、当初のご質問は、型が違うエラーに対してです。 条件の限定とか項目の追加とか趣旨が全然違います。 お互い無駄のない様に効率よくいきましょう。。。。
もこな2 さんから回答がついてますのでそちらで進めてもらっても構いません。。。 (SoulMan) 2021/04/11(日) 14:00
>私の説明が下手くそで、きちんと伝わらず
説明云々以前に。。。 参考のHpには少なくともシートが二つあって マスターのA列の数だけ印刷するようになってます。
対してトピ主さんのコードはシートは一つですよね??? 分かってますか?
もう少しコードを理解してから応用するなり 質問するなりしないとこれでは、、はっきり言って 「迷惑」です。
少なくとも不特定多数の人に少なからず時間を割いていただいているのですから。。。。 もう少し精進してください。。。。
少しきつく聞こえるかもしれませんので補足です。
先ずこのような質問をする場合は、 1)最初に参考にしたURLを貼る 2)参考にしたサイトの内容を忠実に実現するところから始めるべきだと思います。 3)以上を踏まえたうえで今回の場合は、型違いでコードが進まないのでこのようなサイトで質問する
というような流れになると思います。 以上であれば、、コード理解出来ていない人でも出来る内容だと思うのです。
トピ主さんが理解していないコードを載せて要望だけ言われても何が何だかです。 で、実はここを参考にしました。。。 では、、はぁ????です。 (SoulMan) 2021/04/11(日) 20:26
リンク先を拝見しましたがお困りのところはよくわかりません。
強いて言えば、リンク先では【シートを分けて】考えているのに対し、提示されたコードでは【Sheet3のみ】しか出てきてないですが、そこは問題ないですか?
また、参考にされたサイトではインデントが付いてなくて読みづらいうえに冗長な気がするので私なりに整理してみました。
Option Explicit
Sub 印刷_改二() Dim i As Long Stop 'ブレークポイントの代わり
If MsgBox("印刷を開始していいですか?", vbYesNo) = vbYes Then With Worksheets("スタッフマスタ") For i = 1 To .Cells(.Rows.Count, "A").End(xlUp).Row Worksheets("印刷シート").Range("J4").Value = .Range("A" & i).Value Worksheets("印刷シート").PrintOut Copies:=1, Collate:=True Next i End With
MsgBox "印刷が終わりました" End If End Sub
↑をステップ実行して研究してみてはいかがでしょうか?
(もこな2) 2021/04/11(日) 20:28
>一つのシートでできるようにしたい
↑は可能です。
興味があれば、2021/04/11(日) 13:29に提示したコードをステップ実行してみてください。
2021/04/11(日) 20:28に提示したものは、リンク先のコードを整理しただけです。
いずれにせよ、Long型の「myNo」という変数はいらないなぁというのが私の感想です。
(もこな2) 2021/04/11(日) 21:33
(右近) 2021/04/12(月) 07:10
例えば、数式などが入っているために↓が想定外の行になってしまったとかありませんか?
.Cells(.Rows.Count, "B").End(xlUp).Row
また、印刷範囲は手動設定してるんですよね?
(じゃなきゃリスト部分まで印刷対象になりそうなので)
(もこな2) 2021/04/12(月) 07:54
例えば、数式などが入っているために↓が想定外の行になってしまったとかありませんか? もこな2さんのおっしゃるとおり、B列には48行目まで断続的(すべてではありません。)に数式等が入っています。
この差込みは、2行目から11行目までという指定をして、かつ、F13に1〜10までのいずれかの数字を入れたところまでを差込み印刷させたいのです。
F13=1ならば、B2のみ
F13=2ならば、B3のみ
・
・
F13=10ならば、B11までを差込み印刷できればと思います。
(右近) 2021/04/12(月) 14:50
B C 1 1 佐藤 2 2 鈴木 3 3 山下 4 5 6 7 8 9 10 11 (右近) 2021/04/12(月) 15:01
本当にステップ実行したなら、わかると思いますが↓は1行目から、【B列】最終行まで繰り返すという命令になっているわけですが理解できてますか?
For i = 1 To .Cells(.Rows.Count, "B").End(xlUp).Row 〜〜〜 Next i
■2
>以下が実際の書式になります。
たぶん"数式"の書き間違いですよね。
それはそれとして、【B列】は前述のとおり数式が入っているならEndプロパティで思った行番号が取得できないとおもうので、【C列】に変えたらいかがですか?
さらに↓は結局【C列】の名前を取り出しているわけですよね、
=IFERROR(VLOOKUP($F$13,$B$2:$F$11,2,FALSE),"")
■4
ということを踏まえると
Sub 印刷_改() Dim i As Long
Stop 'ブレークポイントの代わり
If MsgBox("印刷を開始していいですか?", vbYesNo) = vbNo Then Exit Sub
With Worksheets("Sheet3") For i = 2 To .Cells(.Rows.Count, "C").End(xlUp).Row '★C列最終行まで繰り返す If .Cells(i, "C").Value <> "" Then '★C列の値が空白じゃないときだけ処理する .Range("F13").Value = .Cells(i, "B").Value '★B列の数字?をそのまま入れる .Range("○○").Value = .Cells(i, "C").Value '★C列の名前をそのまま入れる .PrintOut Copies:=1, Collate:=True End If Next i End With
MsgBox "印刷が終わりました" End Sub
このように、
(1)C列を基準にするよう改造 (2)C列が空欄だったらスキップして次の行に進むように改造
ということを考えるべきじゃないでしょうか?
(もこな2 ) 2021/04/12(月) 17:08
こんばんは! もこな2 さんのコードをお借りして。。。。 最初からおかしいとは思っていましたが、、 F13の値までループしたいのですね???
Option Explicit Sub 印刷_改() Dim i As Long Stop 'ブレークポイントの代わり If MsgBox("印刷を開始していいですか?", vbYesNo) = vbNo Then Exit Sub With Worksheets("Sheet3") For i = 2 To .Range("F13").Value + 1 '★C列最終行まで繰り返す If .Cells(i, "C").Value <> "" Then '★C列の値が空白じゃないときだけ処理する .Range("F13").Value = .Cells(i, "B").Value '★B列の数字?をそのまま入れる .Range("○○").Value = .Cells(i, "C").Value '★C列の名前をそのまま入れる .PrintOut Copies:=1, Collate:=True End If Next i End With MsgBox "印刷が終わりました" End Sub (SoulMan) 2021/04/12(月) 19:52
なお、差込印刷する際には、当初の固定範囲を印刷範囲に再設定する処理が
必要になりますよ。それをお忘れ無く。
ネットに掲載されているコードを訳も分からず(失礼)使うのではなく、
VBAの基本をきちんと学習することをお薦めします。
薄い本でよいので、全体を読み通すことが重要です。
(γ) 2021/04/13(火) 11:50
(γ) 2021/04/13(火) 20:06
'
Range("C72:M81").Select ActiveSheet.PageSetup.PrintArea = "$C$72:$M$81" ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True, _ IgnorePrintAreas:=False End Sub
2.はい、その予定です。
(右近) 2021/04/13(火) 20:39
私が申し上げたのは、"$C$72:$M$81"を印刷したあとで、
また別の差込印刷すると、"$C$72:$M$81"を覚えていますから、
それ以降はずっと"$C$72:$M$81"を対象にして印刷を
何件もしますよ、という意味でした。
そうでなければ、再設定は不要です。
(γ) 2021/04/13(火) 20:48
1差込み印刷範囲$C$15:$Z$69
↓
2$C$72:$M$81
1の差込み印刷後に2を1枚だけ印刷させたいという思いです。
(右近) 2021/04/13(火) 21:06
■5
↓ということなので、RangeオブジェクトのほうのPrintoutメソッドでいいんじゃないですかね。(通常の操作でいうと「選択部分を印刷」に相当)
>差込み印刷が終了した後に、別の範囲(C72:M81)を1枚だけ印刷
すなわち、こんな感じ
Sub 印刷_改() Dim i As Long Stop 'ブレークポイントの代わり
If MsgBox("印刷を開始していいですか?", vbYesNo) = vbNo Then Exit Sub With Worksheets("Sheet3") For i = 2 To .Cells(.Rows.Count, "C").End(xlUp).Row If .Cells(i, "C").Value <> "" Then .Range("○○").Value = .Cells(i, "C").Value .PrintOut Copies:=1, Collate:=True '★WorksheetのPrintOut End If Next i .Range("C72:M81").PrintOut Copies:=1, Collate:=True '★RangeのPrintOut End With MsgBox "印刷が終わりました" End Sub
■6
>↓この部分を再設定する必要があるのでしょうか。
>.PrintOut Copies:=1, Collate:=True
なぜ、↑のように考えたのですか?
既に、同種のコメントがありますが、ネットで見かけたのを理解せずにただコピペしてる感が否めません。
ちゃんと、ステップ実行して、どのような命令をしているのか研究したうえで、それでもわからない場合は質問するなりしてきちんと理解しておいたほうが良いとおもいます。
■7
上記に関連しますが、当初の問題は【何がマズかったのか】理解できたのですか?
一応、こういうことですよね。
(1) For i = 1 To .Cells(.Rows.Count, "B").End(xlUp).Row となっていて数式が設定されている【B列】の最終行としたために、1〜48 まで繰り返すという命令になっていた。
(2) Dim myNo As Long となっていて【IFERROR(IF($C2<>"",ROW()-1,""),"")】で返ってきた""をLong型に入れようとしたために 「型が合わない」というエラーが、4ループ目で発生した
これは、エラーが発生しているときに「i」の中身が何であるか確認すれば、3行目まででよいはずなのになぜか4行目の処理に進んでしまっているということで(1)のミスに気づけたと思いますし、「Range("B" & 4).Value」がなんであるかをちゃんと確認すれば、「myNo = ""」となっていて、Long型に文字列を入れようとしたから(2)のように型が合わないというエラーが発生したのが理解できたのではないかと思います。
■8
誤解されてはいけないので補足で。
If .Cells(i, "C").Value <> "" Then
↑を組み込んだのは、「B列には48行目まで断続的(すべてではありません。)」と仰っているので、歯抜け行があるのではないかと思ったからです。
2021/04/12(月) 15:01に提示されたように、C列が上からきっちり詰まっているのが前提ならいらないです。
(もこな2) 2021/04/14(水) 05:13
γさん、SoulManさんも誠にありがとうございました。
(右近) 2021/04/14(水) 07:26
?@N2セルにデータの入力規則でリストを設定して、「領収書」を選択した場合にのみ以下をすべて実行
?A「領収書」以外を選択した場合は、
・差込印刷は実行するが、.Range("○○").Value = .Cells(i, "C").Valueの転記はしない。
・Range("C72:M81")の印刷は実行しない。
Sub 印刷_改() Dim i As Long Stop 'ブレークポイントの代わり If MsgBox("印刷を開始していいですか?", vbYesNo) = vbNo Then Exit Sub With Worksheets("Sheet3") For i = 2 To .Cells(.Rows.Count, "C").End(xlUp).Row If .Cells(i, "C").Value <> "" Then .Range("○○").Value = .Cells(i, "C").Value .PrintOut Copies:=1, Collate:=True '★WorksheetのPrintOut End If Next i .Range("C72:M81").PrintOut Copies:=1, Collate:=True '★RangeのPrintOut End With MsgBox "印刷が終わりました" End Sub (右近) 2021/04/19(月) 21:10
(もこな2 ) 2021/04/19(月) 22:03
セルの値で条件分岐する方法は、↓のトピックで既に提示されていますから、さかのぼって学んでみてはどうですか?
[[20210120163414]] 『書込みのマクロに条件を追加する』(右近)
(もこな2) 2021/04/19(月) 23:48
If Worksheets("Sheet3").Range("C13").Value <> 領収書 Then Exit Sub
これをWith Worksheets("Sheet3")の後に追加でよいでしょうか?
度々ですみません。どうぞよろしくお願いいたします。
(右近) 2021/04/20(火) 07:16
「領収書」という変数の宣言と、変数への値の代入が 見当たりませんが、そこは大丈夫ですか?
もこな2さんが既に指摘されてますが、。 (通りすがり) 2021/04/20(火) 08:22
>〜でしょうか?
安易に聞くより、ご自身で試したほうが理解できると思いますよ。
ちなみに、それだと「Sheet3」シートのC13(N2?)セルの値が、「領収書」という変数の中身と一致しなければ、そこで終了という意味になってますよ。
それは【正しい】のですか?
(もこな2 ) 2021/04/20(火) 08:32
ちなみに、2021/04/19(月) 21:10のお話からすれば↓のようになるとおもいますよ。
処理開始 2行目〜C列最終行までくりかえし もしも、【N2セル】の値が"領収書"という【文字列】だったら .Range("○○").Value = .Cells(i, "C").Value をする。 もしもの話はおしまい
【シート】をプリントアウトする
C列最終行まで処理したらくりかえしはおしまい
もしも、【N2セル】の値が"領収書"という【文字列】だったら 【セル範囲】をプリントアウトする もしもの話はおしまい 処理終了
(もこな2 ) 2021/04/20(火) 12:09
>If Worksheets("Sheet3").Range("C13").Value <> 領収書 Then Exit Sub
>これをWith Worksheets("Sheet3")の後に追加でよいでしょうか?
こちらとしては「2021/04/20(火) 12:09」に提示したような流れじゃないかなと思っていますので、思い通りの結果にならないのではないかと思いますが、いずれにせよ【自分で検証】して納得(理解)してから次を考えたほうがよいですよ。
(他のトピックでも再三指摘されているので耳タコでしょうが・・・・)
(もこな2 ) 2021/04/20(火) 13:02
Sub 印刷_改()
Dim i As Long If MsgBox("差込印刷を開始します。", vbYesNo) = vbNo Then Exit Sub With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If Worksheets("領収書").Range("C13").Value <> 領収書 Then If .Cells(i, "B").Value <> "" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value .PrintOut Copies:=1, Collate:=True '★WorksheetのPrintOut End If Next i .Range("C72:M81").PrintOut Copies:=1, Collate:=True '★RangeのPrintOut End With MsgBox "差込印刷を終了しました。" End Sub (右近) 2021/04/20(火) 13:22
If Worksheets("領収書").Range("C13").Value <> 領収書 Then
ちなみに↓のようにThen節が1行しかなければ
If Worksheets("Sheet3").Range("C13").Value <> 領収書 Then Exit Sub End IF
「2021/04/20(火) 07:16」に提示された↓のように記述することが可能です(この場合は「End If」を書いてはだめです)
If Worksheets("Sheet3").Range("C13").Value <> 領収書 Then Exit Sub
(もこな2 ) 2021/04/20(火) 13:43
Sub 印刷_改()
Dim i As Long If MsgBox("差込印刷を開始します。", vbYesNo) = vbNo Then Exit Sub With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If Worksheets("領収書").Range("C13").Value <> 領収書 Then Exit Sub If .Cells(i, "B").Value <> "" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value .PrintOut Copies:=1, Collate:=True '★WorksheetのPrintOut End If Next i .Range("C72:M81").PrintOut Copies:=1, Collate:=True '★RangeのPrintOut End With MsgBox "差込印刷を終了しました。" End Sub
(右近) 2021/04/20(火) 14:06
そもそも領収書という変数はどこで宣言して、どこで値を入れているのだろうか? また、VBエディタのツール-オプションで変数の宣言を強制するにチェックは入っているだろうか? (ねむねむ) 2021/04/20(火) 14:25
ちなみに、ちゃんと【ステップ実行】して検証してますか?
もし、ステップ実行して検証しているなら
(1) 変数の宣言が強制されてないから、エクセル君が変数「請求書」を勝手に設定(初期値は"") (2) ↑により If Worksheets("領収書").Range("C13").Value <> "" then Exit Subということになり (3) ↑は「領収書」シートのC13セルの値が「""」でなければ Exit Sub しなさい という命令になっているから (4) よって、実質的な処理はなにもされない
ということになっているのが、観察できたとおもいますが【理解できましたか?】
(もこな2 ) 2021/04/20(火) 14:38
そもそも領収書という変数には何を入れるのだろうか? 話が戻るがWorksheets("Sheet3").Range("C13").Valueに"領収書"という文字があればいいということは無いだろうか? (もこな2さんからの問いかけに対して領収書という変数に入っている文字の場合、と右近さんは答えていたが) (ねむねむ) 2021/04/20(火) 14:51
"領収書"という文字があればいいということは無いだろうか? はい、そのとおりです。
変数ということを理解しておらず、そのような不確かな答えをしていました。申し訳ありません。
C13セルには、「領収書」「預か書」「返納書」の3つをデータの入力規則でリスト化しています。
(右近) 2021/04/20(火) 15:00
>変数の設定が必要ということでしょうか?
既に皆さんから突っ込まれてますけど、結局↓だとおもいますよ。(つまり、「領収書」が変数になってること自体が間違い)
もしも、【N2セル】の値が"領収書"という【文字列】だったら
(もこな2 ) 2021/04/20(火) 16:18
(2) If MsgBox("差込印刷を開始します。", vbYesNo) = vbNo Then
(3) ※「はい」をクリック
(4) With Worksheets("領収書")
(5) For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row
(6) If Worksheets("領収書").Range("C13").Value <> 領収書 Then
(7) Exit Sub
の順番でハイライトされた(3は除く)とおもいますが、それぞれどのような処理だとおもいましたか?
(もこな2 ) 2021/04/20(火) 17:50
(右近) 2021/04/20(火) 19:34
まずは「2021/04/20(火) 17:50」の問いかけに答えてください。
(もこな2 ) 2021/04/20(火) 20:21
(1) Sub 印刷_改() 差し込み印刷 (2) If MsgBox("差込印刷を開始します。", vbYesNo) = vbNo Then 開始のメッセージ (4) With Worksheets("領収書") この領収書のシート (5) For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row B列に入力済みのデータすべて (6) If Worksheets("領収書").Range("C13").Value <> 領収書 Then C13が領収書でなければ実行しない (7) Exit Sub 終了 (右近) 2021/04/20(火) 20:53
(1) Sub 印刷_改() 「印刷_改」というマクロの処理を開始
(2) If MsgBox("差込印刷を開始します。", vbYesNo) = vbNo Then メッセージボックスで、ユーザーに実行するか照会して、 「いいえ」が押されたら真と判定
(3) ※「はい」をクリック これにより、(2)が偽と判定されるので「Exit Sub」の処理に進まない
(4) With Worksheets("領収書") 以下で、「.〜〜」と記述した場合、 「Worksheets("領収書").〜〜」とみなすこととする
(5) For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row 2〜「領収書」シートのB列最終行まで 1ずつカウントアップしながら繰り返し
(6) If Worksheets("領収書").Range("C13").Value <> 領収書 Then もしも、「領収書」シートのC13セルの値が「領収書」という変数の中身と一致しなければ 真と見なしてThen節に進む
(7) Exit Sub 処理を中止する
です。
(スマホで手打ちしたので誤字は御容赦を)
(もこな2 ) 2021/04/20(火) 21:37
(もこな2 ) 2021/04/20(火) 21:41
【ステップ実行】 https://www.239-programing.com/excel-vba/basic/basic023.html http://plus1excel.web.fc2.com/learning/l301/t405.html
ついでに↓も覚えてしまいましょう。
【イミディエイトウィンドウ】 https://www.239-programing.com/excel-vba/basic/basic024.html https://excel-ubara.com/excelvba1/EXCELVBA486.html
【ローカルウィンドウ】 https://excel-ubara.com/excelvba4/EXCEL266.html http://excelvba.pc-users.net/fol8/8_2.html
■10
>確認したところ、チェックが入っていなかったので、入れました。
そこにチェックを入れると、【次に挿入した】モジュールから、自動的に「Option Explicit」が挿入される仕組みなので、【今のモジュール】はそのままです。
変数については、↓を読んでみることをお勧めします。
http://officetanaka.net/excel/vba/beginner/11.htm
http://officetanaka.net/excel/vba/beginner/06.htm
■11
>流れが少し理解できたように思います。
流れも大切ですが、それぞれの命令が理解できてるのかというところが確認したかったのですが・・・
まぁ次のステップに進みます。
さて、すでに皆さんからもツッコまれているのでわかったかと思いますが。「領収書」という変数ができてしまってるのが問題ですね。
まず、ここを直しましょう。
VBAの世界では、""で括ることで【文字列】を示します。
したがって、「領収書」となっているところを「"領収書"」のように修正すればよいです。
■12
上記を踏まえて、【新しい標準モジュールを追加して】下記みたいになるようにのコードを記述してください。
また、「領収書」シートのN2セルに「預か書」と入力してから、【ステップ実行】してどのような処理になったか答えてください。
Option Explicit Sub 修正1() Dim i As Long
With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If Worksheets("領収書").Range("N2").Value <> "領収書" Then Exit Sub If .Cells(i, "B").Value <> "" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value .PrintPreview End If Next i .Range("C72:M81").PrintPreview End With
End Sub
※テストするのに邪魔くさいのでMsgboxはどかしました。 ※「C13ではなくN2でした。」とのことなので直しておきました。 ※いちいち印刷すると紙がもったいないのでプリントプレビューにしておきました
(もこな2) 2021/04/21(水) 07:42
■番外1
>それはそうなんですが
↑そうとも限らないので撤回します。
----以下は、■12を取り組んでから読み進めてください----
■13
さて、「■12」をステップ実行すると、正常に Exit Sub することが観察できたはずです。
ここまでの理屈は理解できてますか?
(勘違いしたまま先に進むとマズいので確認しています)
■14
ここで改めて処理内容を確認してみましょう。
>C13セルには、「領収書」「預か書」「返納書」の3つをデータの入力規則でリスト化しています。
>C13ではなくN2でした。
>N2セル〜「領収書」を選択した場合にのみすべて実行 > 「領収書」以外を選択した場合は、 > ・差込印刷は実行するが、.Range("○○").Value = .Cells(i, "C").Valueの転記はしない。 > ・Range("C72:M81")の印刷は実行しない。
ですから↓のようになりまよね。
【N2セルの値が「請求書」のとき】
・繰り返し処理のなかで Worksheets("Sheet3").Range("AD2").Value = .Cells(i, "B").Value を実行 Worksheets("Sheet3").Range("AE2").Value = .Cells(i, "H").Value を実行 Worksheets("Sheet3").PrintOut を実行
・1回だけ Worksheets("Sheet3").Range("C72:M81").PrintOut を実行
【N2セルの値が「請求書」以外のとき】
・繰り返し処理のなかで Worksheets("Sheet3").PrintOut を実行
■15
次に↓をコードに反映させてみましょう。(C13セルになっているのと、「領収書」という変数になっているのは修正してください。)
>If Worksheets("Sheet3").Range("C13").Value <> 領収書 Then Exit Sub
>これをWith Worksheets("Sheet3")の後に追加でよいでしょうか?
Sub 修正2() Dim i As Long With Worksheets("領収書") .Range("N2").Value <> "領収書" Then Exit Sub '←★
For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "B").Value <> "" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value .PrintPreview End If Next i .Range("C72:M81").PrintPreview End With End Sub
↑のようになりますよね?
では、もう一度確認します。
★の部分は「「領収書」シートのN2セルの値が、「領収書」という文字列でなければ、そこで終了」という処理ですが、このような処理で「■14」は達成できるのでしょうか?できないのでしょうか?
【Yes】or【No】で答えて(考えて)ください。
もし、Noであれば何故ダメだとおもったのか答えてください。
(もこな2 ) 2021/04/21(水) 10:30
★の部分は「「領収書」シートのN2セルの値が、「領収書」という文字列でなければ、そこで終了」という処理ですが、このような処理で「■14」は達成できるのでしょうか?できないのでしょうか? 【Yes】or【No】で答えて(考えて)ください。
答えは、【No】だと思います。Exit Subとなってしまい、印刷を実行する前に、処理を中止してしまうからです。ではないでしょうか。
(右近) 2021/04/21(水) 12:22
誤 .Range("N2").Value <> "領収書" Then Exit Sub '←★ 正 If .Range("N2").Value <> "領収書" Then Exit Sub '←★
■16
>答えは、【No】だと思います。
>Exit Subとなってしまい、印刷を実行する前に、処理を中止してしまうからです
まぁ・・・違いではないですかね。
一応こちらで考えた答えは、「領収書」シートのN2セルの値が「領収書」という文字列意外だった場合【何もせず中止】になってしまう。
でした。
ようやく、「2021/04/20(火) 08:32」まで戻れました。
当初のお答えは【YES】だったわけですが、それではマズかったということが理解(納得)出来ましたか?
■17
さて、「■14」を踏まえると
Sub 修正3() Dim i As Long With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "B").Value <> "" Then ★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value ★もしもの話はおしまい .PrintPreview End If Next i ★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("C72:M81").PrintPreview ★もしもの話はおしまい End With End Sub
ということになろうかとおもいますが、ここまではよろしいですか?
(しつこいようですが、勘違いしたまま進むとよろしくないので確認しています)
■18
では、条件分岐はどうするかというと「2021/04/19(月) 23:48」でアドバイスしたとおり、過去トピックでも出てきたIfステートメントによる条件分岐をしてみましょう
ちょっとおおざっぱですが、Ifステートメントの基本形はこんな感じです
IF 条件式 Then <真のときの処理> Eles <偽のときの処理> End IF
なお、Else節は何も無ければ省略して構いません。
これを、当てはめるとこんな感じです。
もしも、 「領収書」シートのN2セルの値 が "領収書" だったら ~~↓~~~ ~~~~~~~~~~~↓~~~~~~~~~~~~~~ ~↓~ ~~↓~~~ ~~~↓~~~~~ If Worksheets("領収書").Range("N2").Value = "領収書" Then
↑のようなるわけですから、
★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value ★もしもの話はおしまい
↓
If Worksheets("領収書").Range("N2").Value = "領収書" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value End If
のようにすればよいです。ここまではOKですか?
■19
「■18」が理解できたらの★のところを改造してみましょう。
(出来たら見せて(提示して)ください。)
Sub 修正4() Dim i As Long With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "B").Value <> "" Then ★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value ★もしもの話はおしまい .PrintPreview End If Next i ★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("C72:M81").PrintPreview ★もしもの話はおしまい End With End Sub
(もこな2 ) 2021/04/21(水) 15:07
Sub 修正4()
Dim i As Long With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "B").Value <> "" Then If Worksheets("領収書").Range("N2").Value = "領収書" Then ←★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value End If ←★もしもの話はおしまい .PrintPreview ←後ほど .PrintOut Copies:=1, Collate:=True に変更 End If Next i If Worksheets("領収書").Range("N2").Value = "領収書" Then ←★もしも、「領収書」シートのN2セルの値が"領収書"だったら .Range("C72:M81").PrintPreview ←後ほど .PrintOut Copies:=1, Collate:=True に変更 End If ←★もしもの話はおしまい End With End Sub (右近) 2021/04/21(水) 16:43
また、インデント(字下げ)が適当になっているとおもいます。
VBAでは、インデントにプログラム上の意味がないので、ユーザーが好きなように設定できます。
したがって、インデントをうまく使うことでコードを見やすく整理することができ、「2021/04/20(火) 13:22」のようなミスを未然に防ぐことができるようになります。
(今回のケースでは、うっかり「End IF」を忘れたのではなく、そもそもIFステートメントを理解していなかったということに起因してますが)
ついでに言うと、IFステートメントについては、説明をだいぶ端折りました。
↓などを読んでみてください。
http://officetanaka.net/excel/vba/error/compilation_error/error_13.htm
このほか、特に説明してませんでしたが、「Withステートメント」というものを使っています
With Worksheets("領収書") ←この部分
こちらも、詳しく説明されているサイトがいくらでもありますから、学んでおいたほうがよいとおもいます。
http://officetanaka.net/excel/vba/beginner/16.htm
■21
上記を踏まえて、私なりに一例を示すならこんな感じでしょうか。
Sub さんぷる() Dim i As Long
With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "B").Value <> "" Then If .Range("N2").Value = "領収書" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value End If .PrintPreview End If Next i
If .Range("N2").Value = "領収書" Then .Range("C72:M81").PrintPreview End With End Sub
※Msgboxによる確認やPrintOutへ戻すのは、もうご自身でできると思うのであえて提示しません。
■22
>これを完成させることができましたら、なにかお礼をさせてください!
特にそういった気遣いはいりませんが、せっかくなので何点か好き勝手にコメントします。
このトピックで分かったように、ネットで見つけたコードを何も考えずにそのままコピペしてうまくいくことは稀で、大抵の場合はご自身の環境に合わせてカスタマイズが必要になります。
そして、そのカスタマイズをするのはご自身の仕事です。誰かに丸投げしてよいものではありません。
(本当に業者に外注するというなら話は別ですが)
なので、今後は、うまくいかないな〜とおもったら
(1)ステップ実行して、何が想定どおり動いてないのか【自分で】研究してみる (2)こうかな?とおもったことがあったら【自分で】試してみる (3)また、見たことがない命令があったら【自分で】調べてみる
というプロセスを経たうえで、分からないことがあれば具体的に、○○が××になるようにしたくて、赫赫云々というコードを書いたが、何処何処で△△というエラーになってしまうというように具体的に聞くと皆さん丁寧に対応してくださると思います。
■23
以下は本当に蛇足です。(特にお返事は要りません)
・B列には数式が入っているため、最終行が正しく取得できないのではありませんでしたか? それゆえに、C列の最終行を採るようにしていたはずですが、いつのまにかB列に戻ってますが 大丈夫ですか?
・結局、C列(B列になったんですかね?)は歯抜け行があるんですか? 「■8」でコメントしたとおりのことが気になります。
・「■7」は理解できましたか?
(もこな2) 2021/04/22(木) 04:12
■20
21でお示しいただいたものにMsgboxによる確認やPrintOutを追加しました。
Sub さんぷる()
Dim i As Long If MsgBox("差込印刷を開始します。", vbYesNo) = vbNo Then Exit Sub With Worksheets("領収書") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "B").Value <> "" Then If .Range("N2").Value = "領収書" Then .Range("AD2").Value = .Cells(i, "B").Value .Range("AE2").Value = .Cells(i, "H").Value End If .PrintOut Copies:=1, Collate:=True End If Next i If .Range("N2").Value = "領収書" Then .Range("C72:M81").PrintOut Copies:=1, Collate:=True End With MsgBox "差込印刷を終了しました。" End Sub
■21
20で教えていただいたように、インデントにも意味があることを知り、もこな2さんの示していただいたものは、とてもきれいだなと感じます。
内容だけではなく、見た目もその一部なんだと感じました。
■22
まさにおっしゃるとおりで、今回のご指導で得ることができた、自分で考え、取り組む喜びと楽しさを忘れずに(1)〜(3)にまずは取り組んでいきます。
■23
・C列に最大10件まで入力して試してみましたが、B列の最終行まで取得できていますので、大丈夫かと思います。
・もこな2さんのご指摘を受けて、元々断続的だったB列を1行追加して、上から詰まったものに修正しましたので、これも大丈夫かと思います。
・はい、理解できました。
(右近) 2021/04/22(木) 07:14
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.