- ベストアンサー
Excelマクロプログラム解りません。*初心者です
初めまして。 私は某発注担当です。 そこで発注したものの履歴を残せないかと思っています。 以下プログラムを印刷マクロに組み込んで、印刷と同時に内容を 発注履歴シートにコピー&ペーストしたいと思っております。 具体的な内容は以下のとおりです。 ・現行ではNextに対するForがないと言われる ・発注書出力に打ち込んだ商品に対する個数をコピペしたい。 (商品名と個数) その際、個数を打ち込んだものだけをコピペしたい。 何分、初心者でインターネットのページを見ながら作っており、 至らない点、不明点はご了承ください。 質問にあたり、不足事項ありましたら、ご指摘ください Sub Macro1() Worksheets("発注書出力").Activate For i = 24 To 43 If Cells(5, i) = xlPasteValues Then Range(Cells(4, i), Cells(5, i)).Select Selection.Copy Sheets("発注履歴").Select 貼付行 = Range("C65536").End(xlUp).Row + 1 Range(Cells(4, 貼付行), Cells(5, 貼付行)).Select Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False ActiveSheet.Paste Application.CutCopyMode = False Worksheets("発注書出力").Select Range("A1").Select ElseIf Cells(5, i) = "" Then Next End Sub
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
本職ではありませんが、時々excelのvbaやるんで、よくマクロ記録して書き直します。 で、プログラム見て、「マクロ記録したんだなー、それを書き直して繰り返してるんだなー」って思ってます。 でも、動かない時って、直せば直すほど泥沼に入っていくんですよね。 で、さっきまで文句を言わなかったのに突然、Forが無いなんて「Forあるじゃん」と言いたくなるんですよね。 勝手な想像で、違ったらすみません。 >・現行ではNextに対するForがないと言われる if文がendifで終わってないため、Nextが ElseIf Cells(5, i) = "" Thenブロック内で突然出てきたので、forが無いと言われた。 もちろん全部のエラーを出せば、forに対するnextも無いし、ifに対するendifも無いと思われている。 全部エラー出してくれれば気づくのに・・・って思いませんか。 それと、どうせ入力が無いときは何もしないのなら、ElseIf文いらないので、そこをendifにする。 >・発注書出力に打ち込んだ商品に対する個数をコピペしたい。 ちなみに、xlPasteValuesは、形式を選択して貼り付け(PasteSpecial)の、値のみ貼り付ける時の定数ですので、ただの-4163と言う数値です。 と言うわけで、 If Cells(5, i) = xlPasteValues Then の方を If Cells(5, i)<>"" Then にする。 以上で、 For i = 24 To 43 If Cells(5, i) <>"" Then [発注履歴シートにコピー&ペースト処理] End If Next の形になれば、まずひと段落。 で、多分マクロを記録してfor、nextを付けたからだろうけど、 Worksheets("発注書出力").Activate For i = 24 To 43 [処理1] Sheets("発注履歴").Select [処理2] Worksheets("発注書出力").Select Next の形になってますが、対象シートの選択は各処理の前で指定した方が良いと思います。 逆に、貼付行は、最初に取得すれば、1行づづしか増やさないので、forの前に設定しておけば、あとは+1でいいと思います。 それと、.Activateは、シート自体を表示するため、場合によっては画面がちらつくので、必要なければ.selectの方がいいと思います。 貼付行=初期値 For i = 24 To 43 sheets("発注書出力").Select [処理1] Sheets("発注履歴").Select [処理2] 貼付行=貼付行+1 Next の形がいいと思います。 以上はエラーが出るのと、マクロを記録して直してるんで、気になった点です。 で、致命的な事なんですが、Cells(??, 貼付行)とありますが、cells(行,列)で指定する物なので、すべて逆です。 で、致命的な事2なんですが、貼付行 = Range("C65536").End(xlUp).Row + 1は、C列の最後から探して・・・なので、5番目の列(E)を基準にしないと、いつも上書きされてしまいます。 貼付行 = Range("E65536").End(xlUp).Row + 1です。 以上気になった点と致命的な点です。 で、正しく書き換える・・・んじゃなく、記録したマクロを直すより、以下の方が良いんじゃないかと思います。 Sub Macro1() Dim 貼付行 As Integer Dim i As Integer 貼付行 = Sheets("発注履歴").Range("E65536").End(xlUp).Row + 1 For i = 24 To 43 If Sheets("発注書出力").Cells(i, 5) <> "" Then Sheets("発注履歴").Cells(貼付行, 4) = Sheets("発注書出力").Cells(i, 4) Sheets("発注履歴").Cells(貼付行, 5) = Sheets("発注書出力").Cells(i, 5) 貼付行 = 貼付行 + 1 End If Next End Sub こんなのでどうでしょう。
その他の回答 (1)
Sub Macro1() Worksheets("発注書出力").Activate For i = 24 To 43 If Cells(5, i) = xlPasteValues Then ~(中略)~ ElseIf Cells(5, i) = "" Then Next End Sub 発注書出力のプログラムは、 よく見てませんが、 プログラム構文として、 If~ElseIf 文の最後に、「 endif 」 が欠けているように見えます。 Nextの前後に挿入して試してみると良いのでは?
お礼
御回答有難う御座いました。 >If~ElseIf 文の最後に、「endif」が欠けているように見えます。 基本的な間違いのようですね・・・。 sub が end sub で終わるように、感覚的に納得です。
お礼
御回答有難う御座いました。 >「マクロ記録したんだなー、それを書き直して繰り返してるんだなー」って思ってます。 ・おっしゃる通りです。Excelのマクロ機能に魅せられて、記録し使える文をコピペしていました。だから面倒な文に成ってるのかも知れません。 >突然、Forが無いなんて「Forあるじゃん」と言いたくなるんですよね。 ・そうなんです。さすが機械です。「なんで?ここにあるじゃん」と画面を指差す感じです・・・・。 >致命的な事なんですが、Cells(??, 貼付行)とありますが、cells(行,列)で指定する物なので、すべて逆です。 ・致命的ですね。セルを指す場合”A5”なので、1番目の5番目なんて思い、そのまま書いてました。 >.Activateは、シート自体を表示するため、場合によっては画面がちらつくので、必要なければ.selectの方がいいと思います。 ・これは私的にウロコです。他の動くマクロもパラパラ画面が切り替わり、その分遅くなっていました。マクロ記録のためですね。 現在の構文をfumufumu_2006さんの指摘通りに書き直しを試みましたが、改めて書いて頂いた構文の美しさ、解りやすさに、そちらを使わせて頂きたいと思います。 Dim とか Integer とか解らない文字も次第に覚えていきたいと思います。有難う御座いました。 ちなみにもう少しVBAレベルを上げていきたいのですが、どのような方法が効果的でしょうか?参考になる書籍等御座いましたら、ご紹介下さい。宜しくお願いします。