VBA表作成で次の行の作成を自動化したい

このQ&Aのポイント
  • VBAでExcel2003の表作成を行っています。最下行に内容を入力した場合、自動で次の行の作成を行いたいです。しかし、ループが起こってしまいうまく動作しません。どのように修正すれば良いでしょうか?
  • VBAでExcel2003の表作成を行っています。最下行に内容を入力した場合、自動で次の行の作成を行いたいです。しかし、ループが起こってしまいうまく動作しません。修正方法を教えてください。
  • VBAでExcel2003の表作成を行っています。最下行に内容を入力した場合、自動で次の行の作成を行いたいですが、ループが起こってしまいうまくいきません。どのように修正すれば良いでしょうか?
回答を見る
  • ベストアンサー

 VBA 表作成で内容を最下行で入力した場合 自動で次の行の作成を行いたい。

VBAで質問です。  Excel2003 最下行を検索し、そこの内容部分を入力された場合、1行あたらしく 式、罫線をコピーしたいのですがずっとループを起こしてしまいます。 直し方を教えていただきたいです。 ソース Private Sub Worksheet_Change(ByVal Target As Range) '------------------------------------ '変数の宣言 '------------------------------------ Dim naiyou As Object Dim bikou As Object Dim xline As Integer Dim yline As Integer Dim count As Integer Dim startrow As Integer Dim maxcolumn As Integer '------------------------------------ '内容=D4の列検索 '------------------------------------ Set naiyou = ActiveSheet.Cells.Find("内容") xline = naiyou.Column '------------------------------------ '表示している最終行の検索 '------------------------------------ startrow = 4 count = Cells(startrow, xline).End(xlDown).Row '------------------------------------ '備考の=I4列検索 '------------------------------------ Set bikou = ActiveSheet.Cells.Find("備考") yline = bikou.Column '------------------------------------ 'コピペ処理 '------------------------------------ If ActiveSheet.Cells(count, 4) <> "" Then Range(Cells(count + 1, 1), Cells(count + 1, yline)).Select Selection.Copy Range(Cells(count + 2, 1), Cells(count + 2, yline)).Select ActiveSheet.Paste Application.CutCopyMode = False Exit Sub Else: End If End Sub

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

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.6

#5です。 キーイベントが生きたままファイルを閉じるとやっかいなので、 標準モジュールに Sub Auto_Close() resetEnterEvent End Sub を入れておいて下さい。

その他の回答 (5)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.5

>その場合、variantで宣言してどうすればよろしいでしょうか? 意味不明ですが、Enterキー割り込みに作り替えてみました。数値が変わらずとも、空でもEnterを押せば動作します。(矢印キーとかで移動しても無効です)解説はいたしかねます。元のコードを生かしたので冗長です。他のシートから、目的のシートに移らないと、イベントが有効になりません。また、Sheet4が対象のコードになっています。 <シートモジュール> Public Sub Enter_keyin(ByVal target As Range) Dim myRange As Range, headerRange As Range Dim lastRow As Long Const CheckColumn As String = "D" Set headerRange = Range("A4:I4") '見出し行の範囲 If target.Cells.Count <> 1 Then Exit Sub If target.Column <> Range(CheckColumn & "1").Column Then Exit Sub If target.Row <= headerRange.Row Then Exit Sub lastRow = ActiveCell.Row Set myRange = headerRange.Offset(lastRow - headerRange.Row) ’次の行が空でなければ抜ける If emptyCheck(myRange.Offset(1, 0)) Then myRange.Copy myRange.Offset(1, 0) '定数削除 On Error Resume Next myRange.Offset(1, 0).SpecialCells(xlCellTypeConstants, 23).ClearContents On Error GoTo 0 myRange.Offset(1, 0).Cells(1).Activate End If Set myRange = Nothing End Sub '選択範囲がすべて空かチェックする、ワークシート関数のCountA等でも良い Private Function emptyCheck(target As Range) As Boolean Dim myCell As Range Dim emptyFlag As Boolean emptyFlag = True For Each myCell In target.Cells If myCell.Value <> "" Then emptyFlag = False Next myCell emptyCheck = emptyFlag End Function 'ワークシートがアクティブになったとき、Enterキー割り込みを有効化 Private Sub Worksheet_Activate() Call setEnterEvent End Sub '無効化 Private Sub Worksheet_Deactivate() Call resetEnterEvent End Sub <標準モジュール> Sub ENTER_Key() Dim myCell As Range Set myCell = ActiveCell Sheets("Sheet4").Enter_keyin myCell ’Sheet4が対象 End Sub Sub setEnterEvent() Application.OnKey "{RETURN}", "ENTER_Key" Application.OnKey "{ENTER}", "ENTER_Key" 'テンキー End Sub Sub resetEnterEvent() Application.OnKey "{RETURN}" Application.OnKey "{ENTER}" End Sub

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

#3です。 イベントの条件は、 a.複数セルでないこと(行、列全体選択でイベントが起こる事の防止) b.指定列であること c.最後に指定行であること を3段階で見ています。最後に使っているIntersectは、この様なケースでよく使われるので無理矢理使ってみただけで、今回の事例では、 If Target.row = lastRow Then で十分です。逆にIntersectを使っていれば、bは無くても動きます。 他には珍奇な関数は使っていませんし、ayamine0さんはオブジェクト変数も活用されているので、ご理解いただけるのではないかと思います。ただ、 Dim naiyou As Object は、 Dim naiyou as Range とされた方が、インテリセンスが効いて良いと思います。参考URLは検索してみつけました、ご参考まで。 http://shadowslasheizan.blog114.fc2.com/blog-entry-93.html

ayamine0
質問者

お礼

ありがとうございます! 出来ました。自分なりのプログラムで完成できました。 問題が出来まして、 内容入力をnullのまま次の行にした場合、改行されないのですが、 その場合、variantで宣言してどうすればよろしいでしょうか?

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

直接の回答ではありません。現金出納簿の行を増やすのに類似のニーズがあり、試しに作ってみました。イベントの条件判定や、Selectしない複写のご参考にはなるかもしれません。 ayamine0さんのコードを完全には読解していませんので、意図と異なるところがあるかもしれませんが、悪しからず。 Private Sub Worksheet_Change(ByVal Target As Range) Dim myRange As Range, headerRange As Range Dim lastRow As Long Const CheckColumn As String = "D" Set headerRange = Range("A4:I4") '見出し行の範囲 If Target.Cells.Count <> 1 Then Exit Sub If Target.Column <> Range(CheckColumn & "1").Column Then Exit Sub Application.EnableEvents = False lastRow = Range(CheckColumn & ActiveSheet.Rows.Count).End(xlUp).Row Set myRange = headerRange.Offset(lastRow - headerRange.Row) If Not Intersect(Target, Range(CheckColumn & lastRow)) Is Nothing Then myRange.Copy myRange.Offset(1, 0) '定数削除 myRange.Offset(1, 0).SpecialCells(xlCellTypeConstants, 23).ClearContents myRange.Offset(1, 0).Cells(1).Activate End If Set myRange = Nothing Application.EnableEvents = True End Sub

ayamine0
質問者

補足

難しいですね。 イベントの判定条件、セレクトしない複写している部分など コメントいれてもらえないでしょうか・・・ 今自分なりに理解はしようとしてるのですが、自分のつかっていない 関数が多いもので。すいません。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

#1のお礼の部分 Application.EnableEvents=False と Application.EnableEvents=True はイベントプロシの入り口直ぐと 出口直前で入れるもの。後者は大丈夫ですか それにApplication.EnableEvents=False はその後の途中でエラーを起すと、再度Changeイベントが発生するべきときに、前のが残っておって、働かない。防止するエラー処理をちゃんとやればこんな話にならないが。 もし起こったら 別途 Sub test01() Application.EnableEvents = True End Sub を標準モジュールに作って1回実行すべきだ。参考までに。 ーー ChangeイベントはVBAで相当経験をつまないと難しいよ(どういう場合に使うべきかの場合も含めて)。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

Changeイベント http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_event.html#change コピペする事でイベントが発生し続けてしまい、無限ループになるのでしょう。 コピペ処理のIf文を Application.EnableEvents = False '~コピペ Application.EnableEvents = True で挟んであげる。

ayamine0
質問者

補足

ありがとうございます。 しかし、 ループは終了できましたが、セルをほかのとこに移動しようとするとまた かってにコピペが処理がはじまってしまい。結局 作業ができなくなってしまいます。 変更後 '------------------------------------ 'コピペ処理 '------------------------------------ If ActiveSheet.Cells(count, 4) <> "" Then Application.EnableEvents = False Range(Cells(count + 1, 1), Cells(count + 1, yline)).Select Selection.Copy Range(Cells(count + 2, 1), Cells(count + 2, yline)).Select ActiveSheet.Paste Application.CutCopyMode = False Application.EnableEvents = True Else: End If Exit Sub

関連するQ&A

  • 複数行コピー、貼り付け実行時エラー1004

    ユーザー側が任意の場所を選択コピー し(2行毎) また 任意の位置に貼り付ける動作ですが 1回目のコピー、貼り付けは正常動作しますが 再度 コピー(任意の場所),貼り付け時に1004実行エラーが発生します。 下記はコードです。 どうかご教授お願いいたします。 Dim StartRow As Long, LastRow As Long, SRC As Long Sub コピー() If ActiveCell.Row < 76 Then Exit Sub StartRow = ActiveCell.Row: SRC = Selection.Rows.Count If (ActiveCell.Row Mod 2) = 0 Then StartRow = ActiveCell.Row If (Selection.Rows.Count Mod 2) = 0 Then LastRow = StartRow + Selection.Rows.Count - 1 Else LastRow = StartRow + Selection.Rows.Count End If Else StartRow = ActiveCell.Row - 1 If (Selection.Rows.Count Mod 2) = 0 Then LastRow = StartRow + Selection.Rows.Count + 1 Else LastRow = StartRow + Selection.Rows.Count End If End If ActiveSheet.Range(ActiveSheet.Cells(StartRow, 1), ActiveSheet.Cells(LastRow, 19)).Copy End Sub Sub 貼付け() If ActiveCell.Row >= 76 Or Application.ClipboardFormats(1) <> -1 Then ActiveSheet.Unprotect If (ActiveCell.Row Mod 2) = 0 Then StartRow = ActiveCell.Row Else StartRow = ActiveCell.Row - 1 End If ActiveSheet.Paste Destination:=Cells(StartRow, 1): Application.CutCopyMode = False ActiveSheet.Protect End If End Sub

  • マクロ FIND 検索方向の変更

    いつも回答ありがとうございます。 FINDを使用した検索方向の変更についての質問です。以下のFINDの記述方法で、上から一発目に捉えられたキーワードではなく、下から一発目に捉えられたキーワードに変更するにはどうしたらよろしいでしょうか?それとも、FINDの記述方法を大幅に変えなければいけないのでしょうか?御指導の程宜しくお願い致します。 Sub TEST() Dim d As Integer Dim e As Integer Worksheets("一覧").Activate d = 3 e = 3 Do While Worksheets("一覧").Cells(d, 2).Value <> "" Dim c As Variant Dim R As Range Dim s As Range With Worksheets(Worksheets("一覧").Cells(d, 2).Value) Set c = .Columns("H").Find("増", , xlValues, 1) If Not c Is Nothing Then Set R = .Range(c.Offset(1, -4), .Cells(Rows.Count, "D").End(xlUp)) Set s = c.Offset(, -5) With Worksheets("編集用一覧") .Range(.Cells(e, 4), .Cells(e, 5)).ClearContents .Cells(e, 4).Value = s .Cells(e, 5).Value = Application.Sum(R) End With End If End With d = d + 1 e = e + 4 Loop End Sub

  • VBA コード番号がない場合は、次の行へ進む

    OSはXPPro、 Excelは2003を使用しています。 入金データの「支店データ」シートのコード番号がマスタの表にある時、新シート(test)にコピーするマクロを作ろうと悪戦苦闘しています。 下記までは組んだのですが、「インデックスが有効範囲にありません」とエラーになってしまいます。 マスタにないコードだからだと思っているのですが、そういう場合は次の行のコード番号に進めるステートメントをどう組めば良いか分かりません。 どなたかご教示頂けると有り難いです。 よろしくお願い致します。 Sub test() Dim wb As Workbook Dim ws As Worksheet Dim mypath As String Dim fname As String Dim maxgyo As Long 'マスタの最終行 Dim intRow As Long 'マスタの行 Dim strMasCode As Long   'マスタのコード番号 Dim maxgyo2 As Long '入金データの最終行 Dim intRow2 As Long '入金データの行 Dim strSrhCode As Long '入金データのコード番号 Dim shingyo As Long '新シートの書き込み行 Worksheets.Add After:=ActiveSheet, Count:=1 '新しいワークシートを作成 ActiveSheet.Name = "test"            'そのシートの名前は[test] mypath = "C:\Documents and Settings\XXX\My Documents\XXX\" fname = "マスタ.xls" Set wb = Workbooks.Open(mypath & fname) '上記で指定したブックを開く Set ws = wb.Worksheets("担当マスタ")     '[担当マスタ]シートを指定 Workbooks("入金データ").Activate maxgyo = Sheets("支店データ").Cells(Rows.Count, 1).End(xlUp).Row '支店データの最終行 For intRow = 2 To maxgyo strSrhCode = Worksheets("支店データ").Cells(intRow, 6) shingyo = 1 shingyo = singyo + 1 Workbooks("マスタ").Activate maxgyo2 = Sheets("マスタ").Cells(Rows.Count, 2).End(xlUp).Row 'マスタの最終行 For intRow2 = 2 To maxgyo2 strMasCode = Sheets("マスタ").Cells(intRow2, 2) 'マスタのコード番号を代入 If strSrhCode = strMasCode Then 'マスタと支店データのコード番号が一致したら With Workbooks("入金データ").Worksheets("test") .Cells(shingyo, 1) = Worksheets("支店データ").Cells(intRow, 1) .Cells(shingyo, 2) = Worksheets("支店データ").Cells(intRow, 2) End With End If Next intRow2 Next intRow End Sub

  • VBA表作成 再

    頭がこんがらがってしまい途中でしめさせていただきました。改めて整理がついたので質問をしたいと思います。 VBAを使い表を作成しています。 まず入力フォームというブックがあり、そこに入力した日付より1ヶ月分のデータを日付、曜日などを別ブックにある予めできている表に貼り付けていきます。表には31日分の表(罫線あり)が出来ています。 ☆一つ目 Datediff("d",wSh1.Range("C6"),Dateadd("m",1,wSh1range("C6"))) を使いその月の日数を求め表からいらない分の表を削除。 例えば)2/1を入力した際に31日分もいらないため2つ削除。 削除したら入力した日付から1ヶ月間の日付と曜日を貼り付ける。 表は   L ・・・ 4 日付・・・ 5 曜日・・・ ・ ・ ・ のようになっています。 ここまでにいく前に次のような処理をしましたのでソースを載せます。 Private Sub CommandButton1_Click() Dim wStr As String Dim wDate As String Dim wDate2 As String Dim Exitflg As Boolean Dim i As Integer Dim wVal As Variant Dim wSh1 As Worksheet Dim wSh2 As Worksheet Dim iStartRow As Long Dim iEndRow As Long Dim wDay As Long Set wSh1 = Workbooks("入力フォーム.xls").Worksheets("日付セット") If wSh1.Range("C6") = "" Then '値が入っているか MsgBox "日付を入力してください!" Exit Sub End If wDate = Replace(wSh1.Cells(6, "C"), "西暦", "") wDate = Format(wSh1.Cells(6, "C"), "yyyy/mm/dd") If Date < wDate Then MsgBox "未来の日付入力はできません!" Exit Sub End If If DateAdd("yyyy", -1, Date) > wDate Then MsgBox "日付を今日から1年以内で設定してください!" Exit Sub End If わかりづらいかもしれませんがよろしくお願いします。

  • やはり図形のクリアで実行時エラー1004

     図形を二行三列で一枡とし図形を貼り付けていますが、どうしても実行時エラー 「1004」が出て図形のクリアができません。(尚、四角形は枠線上にあります。) 対処法がありましたらお願いします。 Windows7・SP1 Office2010 Sub 図形の貼付け() Dim i As Integer Dim j As Integer For i = 10 To 43 Step 2 For j = 9 To 99 Step 3 Select Case Cells(i, j).Value Case 1: ActiveSheet.Shapes("四角形1").Select Selection.Copy Cells(i + 1, j + 1).Select ActiveSheet.Paste Case 2: ActiveSheet.Shapes("四角形2").Select Selection.Copy Cells(i + 1, j).Select ActiveSheet.Paste Case 4: ActiveSheet.Shapes("四角形3").Select Selection.Copy Cells(i + 1, j + 1).Select ActiveSheet.Paste Case 5: ActiveSheet.Shapes("四角形3").Select Selection.Copy Cells(i + 1, j + 2).Select ActiveSheet.Paste Case 6: ActiveSheet.Shapes("円1").Select Selection.Copy Cells(i, j).Select ActiveSheet.Paste End Select Next Next End Select End Sub Sub 図形のクリア() Dim myRng As Range Set myRng = Range("I10:CW43") Dim n As Integer, sp As Variant For n = ActiveSheet.Shapes.Count To 1 Step -1 Set sp = ActiveSheet.Shapes(n) If Not Intersect(Range(sp.TopLeftCell, sp.BottomRightCell), myRng) Is Nothing  (ここで実行時エラー1004になります。) Then sp.Delete End If Next Set myRng = Nothing End Sub

  • EXCEL VBAでHPageBreaks

    いつもお世話様です。 こちらで教えていただいたマクロでフッダーの前に自動で罫線を引こうとしています。 前の質問は→http://okweb.jp/kotaeru.php3?q=1310420 下記のマクロを動かすと、1ページだけの時はちゃんとフッダーの上に罫線が引けますが、2ページ目になると「インデックスが有効範囲にありません」という実行時エラーが出てしまいます。 どこがいけないのでしょうか? Sub 自動罫線TEST() Dim BreakSu As Integer Dim BreakSu2 As Integer Dim B As Integer Dim Rw As Long Dim LastRow As Long For N = 1 To 3 With Cells .ClearContents .Borders(xlEdgeTop).LineStyle = xlNone .Borders(xlEdgeBottom).LineStyle = xlNone .Borders(xlInsideHorizontal).LineStyle = xlNone End With Range("A1:D" & N * 30) = N & N & N 'TESTデータ挿入 LastRow = Range("A65536").End(xlUp).Row '最終行取得 BreakSu = ActiveSheet.HPageBreaks.Count '改ページ数取得 Range(Cells(LastRow + 1, "A"), Cells(LastRow + 100, "A")) = "ABC" '改ページ数を増やすダミー BreakSu2 = ActiveSheet.HPageBreaks.Count '増えた改ページ数取得 For B = 1 To BreakSu + 1 ' MsgBox B & "-" & BreakSu + 1 & "-" & BreakSu2 Rw = ActiveSheet.HPageBreaks(B).Location.Row - 1 '改ページ前行取得(ここでエラー!) With Range(Cells(Rw, "A"), Cells(Rw, "D")).Borders(xlEdgeBottom) '改ページ前罫線挿入 .LineStyle = xlContinuous End With Next B Range(Cells(LastRow + 1, "A"), Cells(LastRow + 100, "A")) = ClearContents 'ダミー消去 ActiveSheet.PrintPreview Next End Sub

  • ExcelVBAで、選択範囲内で同じ値が入力されたセルを調べる

    選択範囲内(縦一列)で同じ値が入力されたセルの色を黄色にするプログラムを作りました。 Sub 選択範囲内で同じ値が入力されたセルを調べる_縦() Dim startrow As Byte Dim lasrow As Byte Dim i As Long Dim j As Byte Dim atai If TypeName(Selection) <> "Range" Then Exit Sub startrow = ActiveCell.Row '最初のセルの列番号を取得 lasrow = Selection.Rows(Selection.Rows.Count).Row '最終列番号を取得 '同じ値が入力されているセルを黄色にする For i = startrow To lasrow - 1 If ActiveSheet.Cells(i, ActiveCell.Column).Interior.ColorIndex = xlNone Then atai = ActiveSheet.Cells(i, ActiveCell.Column).Value For j = i + 1 To lasrow If atai = ActiveSheet.Cells(j, ActiveCell.Column).Value Then ActiveSheet.Cells(i, ActiveCell.Column).Interior.ColorIndex = 6 ActiveSheet.Cells(j, ActiveCell.Column).Interior.ColorIndex = 6 End If Next End If Next End Sub 但し、上記のプログラムでは選択範囲内に結合セルがあるとエラーになってしまいます。 どなたか、解決方法をご教授頂けませんでしょうか? 宜しくお願い致しますm(._.)m

  • マクロでのActiveSheet.Pasteでのデバック

    関数の入ったセルを切取りで貼付けたいのですが、ActiveSheet.Pasteのところで"WorksheetクラスのPasteメソッドが失敗しました.”のデバッグになってしまいます。対応を教えていただけないでしょうかお願い致します。 Sub susiki() Columns("A:J").Select Selection.AutoFilter Selection.AutoFilter Field:=6, Criteria1:="AG" Dim kirix As Integer, kiriy As Integer Dim kiriz As Long kiriy = Range("A:A").Column kiriz = Range("F1").End(xlDown).Row For kirix = 1 To kiriy Range(Cells(kiriz, kirix), Cells(kiriz, kirix)).Select Selection.CurrentRegion.Select Selection.Cut Next kirix Selection.AutoFilter Field:=6, Criteria1:="DB" Dim harix As Integer, hariy As Integer Dim hariz As Long hariy = Range("A:A").Column hariz = Range("F1").End(xlDown).Row For harix = 1 To kiriy Range(Cells(hariz, harix), Cells(hariz, harix)).Select ActiveSheet.Paste Next harix Selection.AutoFilter End Sub

  • マクロで文字の移動

    Dim x As Integer x = ActiveSheet.UsedRange.Columns.Count + 1 Cells(1, x) = Cells(2, 1).Value Cells(2, 1).ClearContents End Sub 一部しか載せてないので変かもしれませんが、このようなマクロを作ってA2の文字列を移動したいのですが消えてしまいます。 A2の文字は消しつつ移動先では表示させるにはどうしたらよいですか?

  • マクロが実行しない

     二行三列を一枡として月の勤務割表を作成しています。マクロで同じ事を しているのにMacro1の方が実行しません。お教え願えませんでしょうか。 (尚、図形を枠線上にコピペしています。) Sub Macro1()実行しません。 Dim i As Integer Dim j As Integer For i = 10 To 43 Step 2 For j = 10 To 103 Step 3 Select Case Cells(i, j).Value Case 1: ActiveSheet.Shapes("四角形1").Select Selection.Copy Cells(i + 1, j + 1).Select ActiveSheet.Paste End Select Next Next End Sub Sub Macro2()実行します。 ActiveSheet.Shapes.Range(Array("四角形1")).Select Selection.Copy Range("J11:K11").Select ActiveSheet.Paste End Sub

専門家に質問してみよう