繰り返しの印刷処理を自動実行したいのですが

このQ&Aのポイント
  • 請求書データベースというシートがあります。毎月の売り上げが入りますが、同じ会社でも月に何回も注文があることがあります。そこで以下のマクロを作りました。
  • 売上日から該当月のフィルターをかけて、表示させ、そのシート全体を作業用シートにいったんコピーします。作業用シートから重複する会社コードを除く会社コードリストを今月処理件数というシートにコピーします。
  • 次に今月処理件数のシート上で、会社コードが請求書データベースにコピーされます。その後、請求書データベース上の会社コードを参照してフィルターがかかり、その会社の売り上げ一覧が表示され、そこから印刷できる状態です。毎月の処理件数は月平均50~60件くらい入ってきます。
回答を見る
  • ベストアンサー

繰り返しの印刷処理を自動実行したいのですが

請求書データベースというシートがあります。毎月の売り上げが入りますが、同じ会社でも月に何回も注文があることがあります。そこで以下のマクロを作りました。 ・売上日から該当月のフィルターをかけて、表示させ、そのシート全体を作業用シートにいったんコピーします。 ・作業用シートから重複する会社コードを除く会社コードリストを今月処理件数というシートにコピーします。 上記内容はマクロボタン一つで実行できるようにしてあります。 次に今月処理件数のシート上で、下記マクロ(kprint1)を実行すると、A2の会社コードが請求書データベースのAD1にコピーされます。 その後、請求書データベース上のAD1の会社コードを参照してA列(会社コード)にフィルターがかかり、その会社の売り上げ一覧が表示され、そこから印刷できる状態です。 毎月の処理件数は月平均50~60件くらい入ってきます。そのため単純にkprint1から余裕をもってkprint70くらいまで作っておけばよいかと考えました。 その後、下にある「自動実行1」を使って、印刷を自動実行させるボタンを作ればと考えてのですが、マクロ分があまりにも長く、処理も時間がかかりそうな気がしています。  おそらく do while や for nextを使えばもっと短くできると思うのですが、うまくいきません。 一番下の「自動処理2」を試行錯誤で作ったのですが、実行すると、なぜか「今月処理件数」シート上のA2にある最初の会社コードのみ実行され、連続してA3,A4と進みません。 何がいけないのでしょうか。 Sub kprint1() ThisWorkbook.Worksheets("請求書データベース").Unprotect ThisWorkbook.Worksheets("今月処理件数").Unprotect Worksheets("今月処理件数").Range("A2").Copy Worksheets("請求書データベーす").Range("AD1") 'AD1で会社コードを取得して、フィルター検索で該当会社のみ表示させる。 Range("D2").Value = "印刷済み"  '今月処理件数に印刷済みの文字を表示させる。 Call 条件フィルタ2 '請求書データベースのA列(会社コード)のフィルタ解除 Call 条件フィルタ1 '請求書データベースのAD1の会社コードからA列にフィルターをかけ、該当会社のみ表示 call 印刷 '請求書データベースから請求書を作成して印刷実行。 ThisWorkbook.Worksheets("今月処理件数").Protect ThisWorkbook.Worksheets("請求書データベース").Protect AllowFiltering:=True End Sub Sub 自動実行1() select case true case range("a2") = "" msgbox "印刷データがなし" case range("a3") = "" call kprint1 msgbox "印刷しました。" case range("a4") = "" call kprint1 call kprint2 msgbox "印刷しました。" End Select End sub Sub 自動実行2() ThisWorkbook.Worksheets("請求書データベース").Unprotect ThisWorkbook.Worksheets("今月処理件数").Unprotect Dim i As Long, LastRow As Long LastRow = Cells(Rows.Count, 2).End(xlUp).Row call 条件フィルタ2  'A列のフィルター解除のマクロ文です。 call 条件フィルタ1 ’AD1の会社コードを使ってA列にフィルターをかけるマクロ文です。  call 印刷 ’請求書を作成、印刷するマクロ文が記述してあります。 i = 2 Do Range("A" & i).Value = Sheets("請求書データベース").Range("AD1").Value Call 条件フィルタ1 i = i + 1 Loop Until i > LastRow ThisWorkbook.Worksheets("今月処理件数").Protect ThisWorkbook.Worksheets("請求書データベース").Protect AllowFiltering:=True End Sub ※下は条件フィルター1と条件フィルター2のマクロ文です。上記「自動実行2」で試しに、call印刷を外して、call 条件フィルタ2とcall条件フィルタ1だけにしても、やはり最初の会社コードで止まってしまいます。 Sub 条件フィルタ1() Worksheets("請求書データベース").Select ActiveSheet.Range("$A$1").AutoFilter Field:=1, Criteria1:=Range("AD1") End Sub Sub 条件フィルタ2() Worksheets("請求書データベース").Select ActiveSheet.Range("$A$1").AutoFilter Field:=1 End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • HohoPapa
  • ベストアンサー率65% (454/692)
回答No.2

自動実行2のコード群で繰り返される部分は Do~Loopの間です。 この繰り返しの中に印刷命令がありません。 コードの一部しか記載されていないこと シートのレイアウトが未詳なことから 提示のコードを詳しく追いかけることができませんが、 おそらく、次のようなコードになるものと思います。 Sub 自動実行2()  ThisWorkbook.Worksheets("請求書データベース").Unprotect  ThisWorkbook.Worksheets("今月処理件数").Unprotect  Dim i As Long, LastRow As Long  LastRow = Cells(Rows.Count, 2).End(xlUp).Row  i = 2 '<== 正しくは1かも????  Do   Range("A" & i).Value = _    Sheets("請求書データベース").Range("AD1").Value   call 条件フィルタ2    call 条件フィルタ1     call 印刷    i = i + 1  Loop Until i > LastRow  ThisWorkbook.Worksheets("今月処理件数").Protect  ThisWorkbook.Worksheets("請求書データベース").Protect AllowFiltering:=True End Sub むしろコードではなく ThisWorkbook.Worksheets("今月処理件数") ThisWorkbook.Worksheets("請求書データベース") のレイアウトとやりたいことを掲示しなおしたほうが 識者の方から より見やすいコードを提示してもらえるんじゃないかと思います。 レイアウト次第では、SQL文を使うことで AutoFilter を使わずに済むんじゃないかと思います。

shibushijuko
質問者

お礼

ご回答ありがとございました。 今一度、整理してから再質問させていただきます。

その他の回答 (1)

  • chayamati
  • ベストアンサー率41% (254/607)
回答No.1

お早うございます、すごい馬力ですね <call 印刷 ’請求書を作成、印刷するマクロ文が記述してあります。  肝心の「印刷」のマクロ文がありませんが?

shibushijuko
質問者

お礼

ご回答ありがとございました。 今一度、整理してから再質問させていただきます。

関連するQ&A

  • 長いマクロ文をdo whileで簡潔にするには

    お得意先ごとに月末に一括で請求書を自動作成・保存・印刷するマクロを作りました。しかし、あまりにもマクロ文が長いので短くしたいと考えています。 現状、シート名「今月処理件数」上のマクロ”請求書一括印刷”を押すと該当月の一社ごとの売上が保存され、請求書作成、印刷まで実行されます。このシートのA列A2からその下に該当月に取引のあった会社コードが入ります。A71を最終行としています。A2がkprint1~A71がkprint70までのマクロ文を作っています。 「今月処理件数」上のマクロ”請求書一括印刷”及び"kprint1~kprint70"のマクロ文を do while か for next文で書き換えて短くする方法はありますでしょうか。 ※シート名「作業データ1」及び「作業データ3」は一時作業シートです。他のシートは請求書保存、会社ごとの売掛情報保存に必要なシートです。 Sub 請求書一括印刷() '実際にはkprint1~kprint70までありますが、kprint3までで割愛しています。 Select Case True Case Range("a2") = "" MsgBox "印刷データがありません。" Case Range("a3") = "" Call kprint1 MsgBox "印刷しました。" Case Range("a4") = "" Call kprint1 Call kprint2 MsgBox "印刷しました。" Case Range("a5") = "" Call kprint1 Call kprint2 Call kprint3 MsgBox "印刷しました。" End Select End Sub kprint1からkprint70まで作成しています。kprint1は「今月処理件数」のA2の会社コードの処理です。kprint2はA3の会社コードの処理、それ以降、A71までの会社コートを想定してkprint70まで作っています。 Sub kprint1() Application.ScreenUpdating = False ThisWorkbook.Worksheets("請求書データベース").Unprotect ThisWorkbook.Worksheets("今月処理件数").Unprotect Worksheets("今月処理件数").Range("A2").Copy Worksheets("請求書データベース").Range("AD1") Range("D2").Value = "印刷済み" Call 条件フィルタ2 '請求書データベースA列(会社コード)を解除する Call 条件フィルタ1 '請求書データベースAD1に入力された会社コードを使ってA列(会社コード)からAD1の会社コードを取得する ThisWorkbook.Worksheets("今月処理件数").Protect ThisWorkbook.Worksheets("請求書データベース").Protect AllowFiltering:=True ThisWorkbook.Worksheets("請求書データベース").Unprotect Range("A1").Select Selection.CurrentRegion.Select 'アクティブシートの切り替え ActiveWorkbook.Worksheets("作業データ1").Activate 'アクティブシートの図形・画像を全て削除 ActiveSheet.DrawingObjects.Delete 'アクティブシートの内容を全て削除 ActiveSheet.Cells.Clear 'アクティブシートのコメントを全て削除 ActiveSheet.Cells.ClearComments Sheets("請求書データベース").Select Selection.Copy Sheets("作業データ1").Activate Range("A1").Select ActiveSheet.Paste Call 売上一覧入力  '請求書データベースのフィルタ検索結果の可視行をすべて作業データ1に貼り付ける Call 売上集計保存2  '一時作業シート「作業シート3」の内容を「売上集計」に貼り付ける  Sheets("請求書データベース").Select ActiveSheet.Protect AllowFiltering:=True Sheets("請求書3").Visible = True Sheets("請求書3").Select Call print_nohin1 Sheets("請求書3").Visible = False Sheets("今月処理件数").Select Application.ScreenUpdating = True End Sub 上記"kprint1"に出てくる、callステートメントのマクロの内容は以下の通りです。 Sub 条件フィルタ1() Worksheets("請求書データベース").Select ActiveSheet.Range("$A$1").AutoFilter Field:=1, Criteria1:=Range("AD1") 'AD1の値でA列の会社コードにフィルターをかける End Sub Sub 条件フィルタ2() Worksheets("請求書データベース").Select ActiveSheet.Range("$A$1").AutoFilter Field:=1 'A列の会社コードのフィルター解除 End Sub Sub 売上一覧入力() ' 売上一覧入力 Macro' ActiveWorkbook.Worksheets("作業データ1").Activate GYOU = Sheets("売上一覧表").Range("B65536").End(xlUp).Offset(1, 0).Row '「売上一覧表」には会社コード、会社名、売上金額、入金情報がコピーされる。 Sheets("売上一覧表").Cells(GYOU, 1).Value = Range("X2").Value Sheets("売上一覧表").Cells(GYOU, 2).Value = Range("P2").Value Sheets("売上一覧表").Cells(GYOU, 3).Value = Range("C2").Value Sheets("売上一覧表").Cells(GYOU, 4).Value = Range("Q2").Value Sheets("売上一覧表").Cells(GYOU, 5).Value = Range("R1").Value Sheets("売上一覧表").Cells(GYOU, 6).Value = Range("S1").Value Sheets("売上一覧表").Cells(GYOU, 7).Value = Range("T1").Value Sheets("売上一覧表").Cells(GYOU, 8).Value = Range("U1").Value Sheets("売上一覧表").Cells(GYOU, 9).Value = Range("V1").Value Sheets("売上一覧表").Cells(GYOU, 10).Value = Range("W1").Value Sheets("売上一覧表").Cells(GYOU, 11).Value = Range("Y2").Value End Sub Sub 売上集計保存2() '変数の宣言 Dim LstRow1 As Long Dim LstRow2 As Long '最終行の取得 Worksheets("作業データ3").Activate '作業データ1の2行目から80行目までの内容をすべて、作業データ3の2行目に取得する。 LstRow1 = Worksheets("作業データ3").Cells(Rows.Count, 1).End(xlUp).Row LstRow2 = Worksheets("売上集計").Cells(Rows.Count, 1).End(xlUp).Row 'タイトル行を除き、売上集計へコピー、貼り付け Worksheets("作業データ3").Range("A2:ZM2").Copy Worksheets("売上集計").Select Worksheets("売上集計").Range("A" & LstRow2).Offset(1, 0).PasteSpecial xlPasteValues Worksheets("今月処理件数").Select End Sub Sub print_nohin1() ActiveWindow.SelectedSheets.PrintOut From:=1, To:=1, Copies:=1, Collate _ :=True, IgnorePrintAreas:=False '請求書は繰越額や請求金額の数字だけなので、1ページのみの印刷 End Sub

  • VBAのエラーについて

    いつも識者の皆様にはお世話になっております。 Excel VBAのことで質問させてください。 Range("i23").Value = Application.VLookup(ThisWorkbook.Worksheets("aaa").Range("b5"), ThisWorkbook.Worksheets("data").Range("a2:b7"), 2, 0) というコードは通るのですが、 Range("i23").Value = Application.Left(VLookup(ThisWorkbook.Worksheets("aaa").Range("b5"), ThisWorkbook.Worksheets("data").Range("a2:b7"), 2, 0), 2) というleft関数を追加したコードだと「sub または function が定義されていません」というエラーになってしまいます。 VBAを始めたばかりなのですが、何か根本的な勘違いをしていますでしょうか? ちなみに Range("i23").Value = Application.Left(Application.VLookup(ThisWorkbook.Worksheets("aaa").Range("b5"), ThisWorkbook.Worksheets("data").Range("a2:b7"), 2, 0), 2) というコードも通りませんでした。 ご回答よろしくお願いいたします。

  • 除外シートの連続印刷をしたい

    Vista SP1 Excel2000でマクロを作成中の超初心者です。 マクロコードの修正でエラー続出。四苦八苦しています。どうぞお助けください。 ---------------------------------------------------------------------------- イ)現在使用しているマクロを次のように修正したい。 (1)表紙.xls に次のコードを追加する。     Public Const EXCEPT_NAME = "一覧表, 印刷1, データ集, 請求見本" (2)表紙.xls の次のコードを削除する。    '開始   mySh = Array("A会社", "B会社", "C会社", "D会社",・・・ZZ会社") (3)代わりに、次のコードを使用する。  For Each SheetName In ActiveWorkbook.Worksheets 'すべての会社シートをアクティブにする  If InStr(EXCEPT_NAME, SheetName.Name) = 0 Then  Sheets(SheetName.Name).Activate ------------------------------ ア)現在の状況   デスクトップにAAフォルダがあります。その中身は     1)表紙.xls------コード記述用(シート名は「表紙」1枚のみ)     2)BBフォルダ       請求書.xls-----             シート名(1)A会社, B会社, C会社, D会社,・・・ZZ会社                (2)一覧表, 印刷1, データ集, 請求見本-----このシートは印刷しない。 イ)現在使用しているマクロ Sub 請求書連続印刷()  Application.ScreenUpdating = False  ChDrive ThisWorkbook.Path  ChDir ThisWorkbook.Path Workbooks.Open (ThisWorkbook.Path & "\BBフォルダ\請求書.xls") Worksheets("印刷1").Activate Dim mySh As Variant Dim i As Long '請求印刷面のデータの削除 Worksheets("印刷1").UsedRange.Clear '開始 mySh = Array("A会社", "B会社", "C会社", "D会社",・・・ZZ会社") For i = LBound(mySh) To UBound(mySh) Worksheets(mySh(i)).Unprotect 'プロテクトを外す Call 印刷時削除項目 Worksheets(mySh(i)).Range("A1:Q44").Copy _ Worksheets("印刷1").Cells((i + 1) + 43 * i, 1) Worksheets(mySh(i)).Protect 'プロテクトを掛ける Next Application.CutCopyMode = False Worksheets("印刷1").PrintPreview Application.CutCopyMode = False ActiveWorkbook.Close False

  • 「オブジェクトが必要です。」エラーになります。

    次のコードで2.は動くのですが、1.が動きません。「オブジェクトが必要です。」エラーになります。 何が違うんでしょうか? 教えてください。よろしくお願いします。 Function hoge(aa As Range) aa.Value = "Hello!!" End Function Sub Worksheet_Activate() Dim a As Range Set a = ThisWorkbook.Worksheets("Sheet1").Range("G10") hoge (a) ' ←1.これだとエラーになる ' hoge (ThisWorkbook.Worksheets("Sheet1").Range("G10")) ' 2.こちらはOK End Sub

  • 印刷後のVBAの実行 (2)

    Private Sub Workbook_BeforePrint(Cancel As Boolean)   If ActiveSheet.Name = "Sheet1" Then     If Range("D6").Value = "" Then       Cancel = True       MsgBox ("名前を入力してください")       Range("D6").Select       Exit Sub     End If   Else     If ActiveSheet.Name = "Sheet2" Then       If Range("C11").Value = "" Then         Cancel = True         MsgBox ("受付時間を入力してください")         Range("C11").Select         Exit Sub       End If     Else              Exit Sub     End If   End If   ActiveSheet.Range("A70:Y70").Copy   If Worksheets("Sheet3").Range("A1").Value = "" Then     Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues   Else     Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _       Paste:=xlPasteValues   End If   Application.CutCopyMode = False   ActiveSheet.Range("A1").Select End Sub 先日、上記のコードを回答者の方から教えてもらい、とても助かっていますが sheet1のD5に「不要」という文字が入っていた場合、 sheet3への貼り付け(23~30行目の作業)をキャンセルして、最後にsheet1のA1を選択するようにはどの様にしたらいいでしょうか?

  • Setステートメントをまとめて記述する方法 (エクセル2000VBA)

    お世話になります。 Setステートメントで以下のように書いて、シート名を省略して使っています。  Set a = ThisWorkbook.Worksheets("い")  Set b = ThisWorkbook.Worksheets("ろ")  Set c = ThisWorkbook.Worksheets("は") これをプロシージャ毎に書くとコードが長くなるので、先頭かどこかに1回書くだけで、全てのプロシージャで使えるようにしたいのですがどうしたら良いでしょうか? このようなプロシージャを実行したいのですが、 Private Sub CommandButton1_Click()  a.Range("A2").Value = "データ1"  b.Range("B4").Value = "データ2"  c.Range("C9").Value = "データ3" End Sub (他にもコマンドボタンやチェックボックス用のプロシージャがあります) Setステートメントだけを先頭に書くと、 「プロシージャの外では無効です」というエラーが出ましたので、 Public Sub hensuu()  Set a = ThisWorkbook.Worksheets("い")  Set b = ThisWorkbook.Worksheets("ろ")  Set c = ThisWorkbook.Worksheets("は") End Sub のようにしたら、「実行時エラー"424":オブジェクトが必要です」というエラーが出てしまいました。 どのようにしたらエラーが出ず正しく動くようになりますでしょうか?よろしくお願いします。

  • 印刷後のVBAの実行(4)

    Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name = "顧客データー1" Then If Range("D1").Value = "" Then Cancel = True MsgBox ("名前を入力してください") Range("D1").Select Exit Sub End If Else Exit Sub End If End If If Worksheets("顧客データー1").Range("D6") = "不可" Or _ Worksheets("顧客データー2").Range("D6") = "不可" Then GoTo P1 ActiveSheet.Range("F650:O650").Copy If Worksheets("日報").Range("F5").Value = "" Then Worksheets("日報").Range("F5").PasteSpecial Paste:=xlPasteValues Else Worksheets("日報").Range("F65536").End(xlUp).Offset(1, 0).PasteSpecial _ Paste:=xlPasteValues End If Application.CutCopyMode = False P1: ActiveSheet.Range("A1").Select End Sub 現在上記コードを使っていますが、ワークシート日報への値のみ貼り付けの部分で少し変更したいのですが、印刷するシートのセルM1の値が1ならそのシートのRangeF650:O650をコピーしてワークシート日報のF5に値のみで貼り付け、M1の値が2ならF6に、M1の値が3ならF7に・・・という感じでM1の数字の値によってワークシート日報へ貼り付け先を変えていくようしたいのですが、どのようにコードを変更したらいいでしょうか?

  • 配列に使うArry関数について

    winXP Excel2003でマクロ作成している初心者です。 1)指定した4個のシート以外を選択するコードを教えていただきました。  これを利用して list = Array("AAA会社", "BBB会社", "CCC会社", "DDD会社", "EEE会社", ・・以下略") の 部分を手修正でなく、追加削除にも対応できるように指定シート以外を選択したいのですがうまくいきません。 どうかお助けください。 ーーーーーーーーーーーーーーーーーーーーーーーーーーー 教えていただいたコード Sub 請求書入力()   ' // 処理を除外するシート名リスト   Const EXCEPT_NAME = "集計用 印刷用 リンク用 会社見本"   Dim sh As Worksheet   For Each sh In ThisWorkbook.Worksheets     If InStr(EXCEPT_NAME, sh.Name) = 0 Then       sh.Activate       Call 請求書作成用部品     End If   Next End Sub ーーーーーーーーーーーーーーーーーーーーーーーーーー 現在のマクロコード Sub 請求一覧表作成() Application.ScreenUpdating = False ChDrive ThisWorkbook.Path ChDir ThisWorkbook.Path Call BookOpen("請求書入力.xls") Dim list, SheetName Sheets("請求一覧表").Select Range("A4:U15").Select Selection.ClearContents Range("A4").Select list = Array("AAA会社", "BBB会社", "CCC会社", "DDD会社", "EEE会社", ・・以下略") ↑この部分はシートの追加・削除の度に手修正している。 For Each SheetName In list Sheets(SheetName).Activate Call 配列 Next Worksheets("請求一覧表").Activate ActiveSheet.Protect End Sub ーーーーーーーーーーーーーーーーーーーーーーー Sub 配列() With ActiveSheet ' 配列に格納 -- Dim i As Integer Dim LastRow As Long Dim SaleAry As Variant ' 配列に格納 -- SaleAry = Array(.Range("C8"), .Range("D13"), .ange("T30")・・・以下略)) End With ' 転記 --- With Worksheets("請求一覧表") LastRow = .Range("A65536").End(xlUp).Row For i = 0 To UBound(SaleAry) .Cells(LastRow + 1, i + 1).Value = SaleAry(i) Next i End With Set SaleAry = Nothing End Sub

  • 印刷後のVBAの実行 (3)

    Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name = "Sheet1" Then If Range("D6").Value = "" Then Cancel = True MsgBox ("名前を入力してください") Range("D6").Select Exit Sub End If Else If ActiveSheet.Name = "Sheet2" Then If Range("C11").Value = "" Then Cancel = True MsgBox ("受付時間を入力してください") Range("C11").Select Exit Sub End If Else Exit Sub End If End If If Worksheets("Sheet1").Range("D5") = "不要" Then GoTo P1 ActiveSheet.Range("A70:Y70").Copy If Worksheets("Sheet3").Range("A1").Value = "" Then Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues Else Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _ Paste:=xlPasteValues End If Application.CutCopyMode = False P1: ActiveSheet.Range("A1").Select End Sub sheet1のD5に「不要」と入っていたら 24~33行目の作業がキャンセルになりますが sheet2のD5にも「不要」と入っていたら、同じ様にキャンセルできる様に出来ますでしょうか? ご回答お願いします

  • セルの入力後の常時自動処理

    どちらかのA1の値を入力しEnterキーを押したあとに下記の処理を自動実行するには どうしたら良いでしょうか? お教え願えませんでしょうか。 Windows7・SP1 Office2010 Option Explicit(標準モジュールに書いてあります。) Private Flg As Boolean Sub 処理() If Flg Then Exit Sub Application.OnTime Now + TimeValue("00:00:05"), "処理" If Flg Then Exit Sub If Worksheets("メイン・1").Range("A1") <> Worksheets("祝祭日").Range("A1") Then MsgBox ("祝祭日の日付を反映させるために年度を同じにしてください。") Else: Exit Sub End If(中断モードで実行することはできません。)ここで止まります。 End Sub Sub ストップ() Flg = True End Sub

専門家に質問してみよう