[[20261002104950]] 『別シートからメインシートへコピー&挿入までのマメx(Bulls) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) |

| 全文検索 | 過去ログ ]

 

『別シートからメインシートへコピー&挿入までのマクロについて』(Bulls)

確認表シートの2〜4行、B〜J列、JI〜JX列を削除
Templateシートの1〜3行を確認表シートに挿入
確認表シートF列に「入場」文字があることとG列に空欄でなければ、TemplateシートにあるA5〜JW18をコピー&挿入する命令文を作りました。

別々でやると最後までできますが、1つにまとめると必ずフリーズしてしまいます。どこか間違っているのか教えていただけますでしょうか。

よろしくお願いいたします。

/*---------------------------------------------------------*?

Sub MainProcess()

    Dim ws As Worksheet
    Dim wsTemplate As Worksheet
    Dim LastRow As Long
    Dim i As Long
    Dim InsertRow As Long

    Set ws = Sheets("確認表")
    Set wsTemplate = Sheets("Template")

    Application.ScreenUpdating = False

    '不要行削除
    ws.Rows("2:4").Delete

    '不要列削除
    ws.Columns("JI:JX").Delete
    ws.Columns("B:J").Delete

    'Templateの1〜3行を先頭へコピー
    wsTemplate.Rows("1:3").Copy
    ws.Rows("1").Insert Shift:=xlDown

    Application.CutCopyMode = False

    'テンプレート挿入処理
    LastRow = ws.Cells(ws.Rows.Count, "F").End(xlUp).Row

    For i = LastRow To 1 Step -1

        If Trim(ws.Cells(i, "F").Value) = "入場" And _
           ws.Cells(i, "G").Value <> "" Then

            InsertRow = i + 4

            '14行挿入
            ws.Rows(InsertRow & ":" & InsertRow + 13).Insert

            'TemplateシートのA5:JW18を貼付
            wsTemplate.Range("A5:JW18").Copy
            ws.Range("A" & InsertRow).PasteSpecial xlPasteAll

        End If

    Next i

    Application.CutCopyMode = False
    Application.ScreenUpdating = True

    MsgBox "完了しました"

End Sub

< 使用 Excel:unknown、使用 OS:unknown >


< 使用 Excel:unknown、使用 OS:unknown >

バージョンによって回答が異なるので必ずバージョンを書いた方がいいですよ。
(?) 2026/10/02(金) 11:20:44


適当なところに
doevevs
でも入れておけばいいんじゃいですかね?
因みにスペル忘れていますので
その辺は調べてください
(痴呆) 2026/10/02(金) 11:31:45

F5で1行ずつ実行しながら動きを見てはどうでしょうか。

また、「1つにまとめると必ずフリーズしてしまいます」は間違えています。
「永久(無限)ループ処理に忙しすぎて、応答する暇がありません」です。

それを解消するために、
For文や、Do〜Loopの間に、「DoEvents」をいれて、
「処理を一旦OSに渡す」という事をします。

例えば、繰り返し処理中に、Breakボタンが押されたとき、
OSに処理を渡すことで、Breakボタンが押されたかどうか判定できます。
しかし、繰り返し処理中にOSに処理を渡さないと、
Breakボタンが押されたかどうかの判断ができません。
(VBAのコード上でBreakボタンが押されたかを判断するコードがない)
従って、よく言われる「フリーズ」しているように見えているだけです。

(匿名) 2026/10/02(金) 12:21:08


↑間違えました、
F5ではなく、F8でした。すみません。
(匿名) 2026/10/02(金) 12:21:40

文章通りのマクロになっていません。
(?) 2026/10/02(金) 15:37:48

 まず、自動再計算をオフにして試して見てください。

 疑問
   InsertRow = i + 4
 はこれでいいですか?
   InsertRow = i + 1
 にしないとだめじゃないですかね?  

 最初に
    ws.Rows("2:4").Delete
 して、3行上にずれているの、計算にいれてますか?
(´・ω・`) 2026/10/02(金) 16:01:04

(匿名)さん

アドバイスありがとうございます。
一度、For文にDoEventsを入れましたが、改善は見られませんでした。
Loopつかってないからか…。

実は9月下旬にマクロやり始めた(15年ぶりに…)ので、思い出しながら作っています。
ど素人レベルなので…愚問でしたらすみません。
(Bulls) 2026/10/02(金) 16:14:30


(´・ω・`)さん

確認表シートの2~4行目を削除して、templateシートの1~3行目をコピー&挿入しているので間違いないと思っています。

(Bulls) 2026/10/02(金) 16:20:18


文章通りのマクロになっていません。
(?) 2026/10/02(金) 16:26:41

 当方でワークシートが見えるわけではないので、
    InsertRow = i + 4
 で正しいというならそれでよいです。
 自動再計算をOFFにして実行した結果をおしららせください。

 ? さん
 >文章通りのマクロになっていません。
 どのあたりのことですか? 具体的に書いてもらうと助かります。
 私は説明どおりだと思いました。
(´・ω・`) 2026/10/02(金) 16:38:06

 (発言を取り下げます。)
(xyz) 2026/10/02(金) 17:34:02

>どのあたりのことですか?

>確認表シートの2〜4行、B〜J列、JI〜JX列を削除
「確認表シートF列に「入場」文字があることとG列」は削除範囲にあること。

ws.Columns("B:J").Delete

If Trim(ws.Cells(i, "F").Value) = "入場" And _

   ws.Cells(i, "G").Value <> "" Then

列を対称にしているのでこれで正しく動作しますか。

違っていたらすみません。

(?) 2026/10/02(金) 18:33:13


 元データのシートに削除や挿入するのはどうなのかと思いますけど

 > 別々でやると最後までできます。
 っていうのは それぞれの処理objに分けて実行 ステップ実行 コメントアウトで実行 などのどれでしょう

 > 1つにまとめると必ずフリーズしてしまいます。
 フリーズであっていますか excelを閉じるとき応答してません と出るか
 電源落として再起動する必要が出てきますか。

 もしマウスは動いてexcelの表示が変わらないだけであれば 
   Application.ScreenUpdating = False
 が聞いているだけなので ループで挿入しているから重いだけの可能性が高いです。
 コメントアウトすれば動いているか確認できるので確かめてください。

 高速化するなら
 一度配列として取り込んで最後にシートに書き込んでください。

 確認表シートに数式入ってるなら
 (´・ω・`)さんの
 > 自動再計算をオフにして試して見てください。

 が最も影響あると思います。。

(ちくわ) 2026/10/02(金) 19:12:04


私も横からですが何点か。

■1
既に指摘があるところですが、例えばLOOKUP系の参照が大量にあって行の削除や挿入(貼付けを含む)のたびに再計算が走っていてべらぼうに時間がかかっているとかはないでしょうか?

■2
大差はないとおもいますが、IF分岐のところは入れ子にした方が理屈上は早いということになると思います。

 If Trim(ws.Cells(i, "F").Value) = "入場" And ws.Cells(i, "G").Value <> "" Then
   〜〜〜処理〜〜〜
 End If

 If Trim(ws.Cells(i, "F").Value) = "入場" Then
     If ws.Cells(i, "G").Value <> "" Then
   〜〜〜処理〜〜〜
     End If
 End If

前者は、1つ目の条件が偽になるときでも2つ目の条件の評価を行いますが、後者は1つ目の条件が偽になるときは2つ目の評価はそもそも行いません。

■3
表のレイアウトがわからないので何ともいえないのですが、以下はそれぞれ上書き貼付けや、セル範囲の挿入で対応できないのかな?と疑問に思いました。

    ws.Rows("2:4").Delete
    wsTemplate.Rows("1:3").Copy
    ws.Rows("1").Insert Shift:=xlDown

    ws.Rows(InsertRow & ":" & InsertRow + 13).Insert
    wsTemplate.Range("A5:JW18").Copy
    ws.Range("A" & InsertRow).PasteSpecial xlPasteAll

■4
以下は、工夫すればまとめられます。

 ws.Columns("JI:JX").Delete
 ws.Columns("B:J").Delete

■5
ということをふまえて、↓のようにするのも手かなとおもいました。

    Sub 整理()
        Dim wsTemplate As Worksheet
        Dim LastRow As Long
        Dim i As Long

        Set wsTemplate = Sheets("Template")

        Application.Calculation = xlCalculationManual '再計算を止める

        With Sheets("確認表")
            '不要列の削除
            .Range("B:J,JI:JX").Delete

            'Templateの1〜3行を確認表の2〜4行に(上書き)貼り付け先頭へコピー
            wsTemplate.Rows("1:3").Copy .Rows(2)

            '最終行取得
            LastRow = .Cells(.Rows.Count, "F").End(xlUp).Row

            For i = LastRow To 1 Step -1

                If Trim(.Cells(i, "F").Value) = "入場" Then
                    If .Cells(i, "G").Value <> "" Then

                        'TemplateシートのA5:JW18を確認表の該当箇所に挿入(して下にシフトさせる)
                        wsTemplate.Range("A5:JW18").Copy
                        .Cells(i, "A").Insert Shift:=xlDown
                    End If
                End If

            Next i
        End With

        Stop  'ブレークポイントの代わり
        Application.Calculation = xlCalculationAutomatic '自動計算にもどす
    End Sub

(もこな2) 2026/10/02(金) 19:36:44


F、G列を削除しているので、F、G列の値を見つけられないため無限ループになっているのではないでしょうか。

(自分思考) 2026/10/03(土) 09:34:04


 自分思考さん、こんにちは。
 For i = LastRow To 1 Step -1 という固定の行のループですので、無限ループにはならないと思います。
 仮に、「その行のF列が"入場"で、G列になんらかのものが入力されている」の条件を満たすものが
 何も無ければ、瞬時にプロシージャは終了すると思います。

 質問者さんへ。(すでに(ちくわ)さんから指摘されていることですが、あえて書きます)
 画面更新を抑止することと、フリーズすることは全く別のことですが、そこは理解されていますね?

 条件にあう行はどのくらいあるのですか?(概算で結構です。)
 もし数百程度であれば、少し待てば処理は終了するのではないですか?
 数式を多用しているシートであれば、手動計算にして処理実行、終了してから自動計算に戻すと
 処理時間を短縮できると思います。

(xyz) 2026/10/03(土) 14:36:47


>条件を満たすものが何も無ければ、瞬時にプロシージャは終了すると思います。
なるほどそういうことですね。理解しました。
(xyz)さん補足有難う。

(自分思考) 2026/10/03(土) 14:46:30


  ? さん
 回答ありがとうございます。
 B〜J列を削除後のF列、G列のことだと思ってましたので、矛盾が無いように思ってました。
 質問に明記されていないので、どっちかわからないですね
(´・ω・`) 2026/10/05(月) 08:28:18


軽々しく編集しすぎなのではないですかね?
(ちょっと) 2026/10/05(月) 20:19:54

AIに聞いてみた。

□ChatGPT

Sub 確認表更新()

    Dim wsC As Worksheet
    Dim wsT As Worksheet
    Dim lastRow As Long
    Dim r As Long

    Set wsC = Worksheets("確認表")
    Set wsT = Worksheets("Template")

    Application.ScreenUpdating = False
    Application.EnableEvents = False

    On Error GoTo ErrHandler

    '--------------------------------
    '?@ 確認表の2〜4行のB:J、JI:JXを削除
    '--------------------------------
    wsC.Range("B2:J4").ClearContents
    wsC.Range("JI2:JX4").ClearContents

    '--------------------------------
    '?A Templateの1〜3行を確認表へ挿入
    '--------------------------------
    wsT.Rows("1:3").Copy
    wsC.Rows("1:3").Insert Shift:=xlDown

    Application.CutCopyMode = False

    '--------------------------------
    '?B F列が「入場」かつG列が空欄でない行を検索
    '--------------------------------
    lastRow = wsC.Cells(wsC.Rows.Count, "F").End(xlUp).Row

    r = 1

    Do While r <= lastRow

        If InStr(1, CStr(wsC.Cells(r, "F").Value), "入場", vbTextCompare) > 0 _
           And wsC.Cells(r, "G").Value <> "" Then

            'Template A5:JW18 は14行
            wsC.Rows(r & ":" & r + 13).Insert Shift:=xlDown

            'Template A5:JW18をコピー
            wsT.Range("A5:JW18").Copy
            wsC.Range("A" & r).PasteSpecial Paste:=xlPasteAll

            Application.CutCopyMode = False

            '挿入した14行分を飛ばす
            r = r + 14
            lastRow = lastRow + 14

        End If

        r = r + 1

    Loop

    Application.ScreenUpdating = True
    Application.EnableEvents = True

    MsgBox "確認表の更新が完了しました。", vbInformation

    Exit Sub

ErrHandler:

    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.CutCopyMode = False

    MsgBox "エラーが発生しました。" & vbCrLf & _
           "エラー番号:" & Err.Number & vbCrLf & _
           "内容:" & Err.Description, vbExclamation

End Sub

□Copilot

Sub 確認表処理()

    Dim wsK As Worksheet   '確認表シート
    Dim wsT As Worksheet   'Templateシート
    Dim lastRow As Long
    Dim i As Long

    Set wsK = Worksheets("確認表")
    Set wsT = Worksheets("Template")

    '-----------------------------------------
    '?@ 確認表シートの 2〜4行、B〜J列、JI〜JX列を削除
    '-----------------------------------------
    wsK.Range("B2:J4").ClearContents
    wsK.Range("JI2:JX4").ClearContents

    '-----------------------------------------
    '?A Templateシートの 1〜3行を確認表シートに挿入
    '-----------------------------------------
    wsT.Rows("1:3").Copy
    wsK.Rows("1:3").Insert Shift:=xlDown

    '-----------------------------------------
    '?B F列が「入場」かつ G列が空欄でない行に対して
    '  Templateシート A5〜JW18 をコピーして挿入
    '-----------------------------------------
    lastRow = wsK.Cells(wsK.Rows.Count, "F").End(xlUp).Row

    For i = 1 To lastRow
        If wsK.Cells(i, "F").Value = "入場" _
           And wsK.Cells(i, "G").Value <> "" Then

            wsT.Range("A5:JW18").Copy
            wsK.Rows(i + 1).Insert Shift:=xlDown
        End If
    Next i

    MsgBox "処理が完了しました。"

End Sub

(オアソビ) 2026/10/05(月) 22:05:58


(´・ω・`)
ありがとうございます。
自動計算をOFFにしてみます。

(Bulls) 2026/10/07(水) 14:26:32


(ちくわ)さんありがとうございます。

一度配列として取り込んで最後にシートに書き込んでください。
試してみます。

久々にマクロで作成したので、かなり苦しいですが挑戦します。

(Bulls) 2026/10/07(水) 14:28:45


(もこな2)さん

作って頂いたマクロを解読しながら進めています。
大変勉強になります。

(Bulls) 2026/10/07(水) 14:30:50


(オアソビ) さん
ありがとうございます。
Copilot先生にも聞いてみました。
気まぐれなのか…私が作成したコードと違うコードが返ってきました…。

(Bulls) 2026/10/07(水) 14:33:17


 せっかく回答するなら
(?) 2026/10/02(金) 18:33:13 さん
(´・ω・`) 2026/10/05(月) 08:28:18 さん
 とかに回答すると多分誰かがvbaを書いてくれます。(たぶん)

 私はvba嫌いなので関数ですが、
 座標計算めんどくなったので9割方geminiです。

 sheetnnn!A1 :=LET(
    _wsSrc, TRIMRANGE(確認表!A1:ZZ1000,2,2),
    _wsTemplate, template!A1:JW18,

    __1,"不要行の削除 2:4行目を削除 = 1行目 と 5行目以降を結合 ",
    _delRow, VSTACK(TAKE(_wsSrc, 1), DROP(_wsSrc, 4)),

    __2,"不要列の削除 {B:J列(2〜10列目)とJI:JX列(243〜258列目)を除外}",
    _colMax, COLUMNS(_wsSrc),
    _c1, CHOOSECOLS(_delRow, 1),
    _c2, IF(_colMax>=11, CHOOSECOLS(_delRow, SEQUENCE(1, MIN(232, _colMax-10), 11)), ""),
    _c3, IF(_colMax>=259, CHOOSECOLS(_delRow, SEQUENCE(1, _colMax-258, 259)), ""),
    _delCol, IF(ISERR(_c2), _c1, IF(ISERR(_c3), HSTACK(_c1, _c2), HSTACK(_c1, _c2, _c3))),

    __3, "Templateの1〜3行目を先頭 1行目 へ挿入",
    _tempTop, TAKE(_wsTemplate, 3),
    _baseData, VSTACK(_tempTop, _delCol),

    __4, "テンプレートの挿入データを準備 A5:JW18の14行分",
    _tempBody, DROP(_wsTemplate, 4),

    __5, "ループ処理 REDUCEで1行ずつチェックしながら14行のテンプレートを差し込む",
    _startIdx, 4,
    _header, TAKE(_baseData, _startIdx),
    _body, DROP(_baseData, _startIdx),

    _result, REDUCE(_header, SEQUENCE(ROWS(_body)),
        LAMBDA(_v,_idx,
            LET(
                _currentRow, CHOOSEROWS(_body, _idx),

                __B,"J列の削除によって左に9列ズレるため、列間引き後のF列・G列=元のO列・P列を正しく参照",
                _f_val, TRIM(INDEX(_currentRow, 1, 6)),
                _g_val, INDEX(_currentRow, 1, 7),

                IF(AND(_f_val="入場", _g_val<>""),
                    VSTACK(_v, _currentRow, _tempBody),
                    VSTACK(_v, _currentRow)
                )
            )
        )
    ),
    _result
 )
(ちくわ) 2026/10/07(水) 16:28:53

 質問者さんへ
 あなたの質問の根幹は、↓ここだと思います。
 > 別々でやると最後までできますが、1つにまとめると必ずフリーズしてしまいます。どこか間違っているのか教えていただけますでしょうか。
 その問題に関しては、現状どのようにお考えなんですか?  焦点を絞って議論を進めて下さい。

 (ちくわ)さんの、以下の確認質問(2026/10/02(金) 19:12:04)をスルーする理由がわかりません。
 問題解決に向け重要な事項かと思います。回答をしてもらえませんか?

 | > 別々でやると最後までできます。
 |  っていうのは それぞれの処理objに分けて実行 ステップ実行 コメントアウトで実行 などのどれでしょう
 | 
 |  > 1つにまとめると必ずフリーズしてしまいます。
 |  フリーズであっていますか excelを閉じるとき応答してません と出るか
 |  電源落として再起動する必要が出てきますか。
 | 
 |  もしマウスは動いてexcelの表示が変わらないだけであれば 
 |    Application.ScreenUpdating = False
 |  が聞いているだけなので ループで挿入しているから重いだけの可能性が高いです。
 |  コメントアウトすれば動いているか確認できるので確かめてください。

 ついでに、私の確認質問(2026/10/03(土) 14:36:47)にも回答してください。
 > 条件にあう行はどのくらいあるのですか?(概算で結構です。)

 もしも、コードの改善を希望しているのであれば、
 シートの概要(レイアウト)や、作業の目的などをもう少し説明してください。
 例:"B:J"列の削除と、F:G列の状況に応じた行挿入の関係が不明ですし、
     同じタイミングで行う必要があるのか戸惑います。

 コードが正しい保証もないので、そういう基本的な説明は必要だと思います。

 ==========
 オアソビさん、AIの回答をそのままこちらに転送するのはやめて頂きたいです。
 少なくとも、あなたがコードを確認したうえで、正常に動作すると思われるものを投稿してもらえませんか?
 Copilotの回答は、今後の処理すべきセル範囲に挿入してしまうという、初歩的な誤りです。
 海外のQ&Aサイトでは、こうした投稿が続出したために、AIの回答をそのまま投稿することは
 大抵のところで禁止されています。

 ただし、ご自身で実際に動作確認したうえ、AI回答を加工したと断り、ご自身が説明責任を負うつもりで
 投稿されるのであれば問題ないのではないかと、私は考えています。

(xyz) 2026/10/07(水) 22:45:38


オアソビさん、AIの回答をそのままこちらに転送するのはやめて頂きたいです。

拒否します。

( オアソビ) 2026/10/08(木) 09:55:02


いろんな投稿があるのでお腹いっぱいかもしれませんが、トピ主のレスポンスがあったので追加でコメントします。

■6
結局のところ、フリーズと表現されている事象は、再計算に時間がかかっていただけではないかと私を含めて複数人からコメントがありましたが、どうだったのでしょうか?
そちらが的を外しているのであれば↓では解決しないことになります。

 Application.Calculation = xlCalculationManual '再計算を止める

■7
何らかの理由で再計算を止めたくないのですということであれば、元データは構わずに別に出力用のシートを用意し、そちらに値と書式を貼りつけるといった処理も一考の価値があるかと思います。

■8
配列に取り込んでから一気に出力するプランについて、高速化の手段としては有効だとおもいますが、セルの書式といった情報はコピーされません。
私見になりますが、まずは、現状の問題を解決されてからトライされたほうがいいのではないかと思います。

■9
>Copilot先生にも聞いてみました。
>気まぐれなのか…私が作成したコードと違うコードが返ってきました…。

余談になりますが、それでよいのではないかと思います。
正解は一つではありませんし、一番肝心なことは目的が達成できるかどうかでしょう。
さらにいうと、データが手元にない他者が代行してAIに聞いたものより、表のレイアウトなどが分かっているご自身がAIに聞いたものの方が確かである可能性すらあるとおもいます。
また、疑問に思ったところをAIに突っ込んで聞くことで確度が高められることも期待できます。

(もこな2) 2026/10/08(木) 21:01:32


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.