質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

4回答

6807閲覧

VBA 特定の行を別シートに切り取りしたい

abc-.-cba

総合スコア6

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/11/13 07:16

予定表を作成しております。
完了した予定ついて履歴を残したいので、ボタンをクリックするとシート1のU列に「完了」
と記入されている行をシート2の3行目~に転記(切り取り)されるものを作成したいです
シート2にはシート1の完了した予定がどんどん転記されるイメージです。

【シート1】
B列の8行目からAM列の307行(B8:AM307)を使用した予定表があります。
予定が完了した行についてはU列に「完了」と記入しています。

【シート2】
シート1のU列に完了と記入されている行をシート2のB列3行目~に転記したいです。

自分なりに調べてみたのですが下記のコードだと中途半端な行しか転記されません。
ご教授お願い致します。

Private Sub kanryou_Click()
Dim i, LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To LastRow
If Cells(i, 21) = "完了" Then
Rows(i).Cut Sheets("完了分").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
End If
Next i
End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

こちらになります。こちらでは簡単な確認しか行っていません。
特に各列の細かい確認(関数式の列とそうでない列の確認)はしていません。
あなたのほうで、詳細の確認をお願いします。

VBA

1Private Sub kanryou_Click() 2 Const endRow As Long = 307 3 Const startRow As Long = 8 4 Dim wrow As Long, LastRow As Long 5 Dim fromRow As Long 6 Dim toRow As Long 7 Dim sh1 As Worksheet 8 Dim sh2 As Worksheet 9 Dim dicT As Object '完了の行番号記憶 10 Dim ctr As Long '完了の件数 11 Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義 12 Set sh1 = Worksheets("予定表") 13 Set sh2 = Worksheets("完了分") 14 LastRow = sh2.Cells(Rows.Count, "B").End(xlUp).Row + 1 15 If LastRow < 3 Then LastRow = 3 16 ctr = 0 17 For wrow = startRow To endRow 18 If sh1.Cells(wrow, "U") = "完了" Then 19 sh1.Range("B" & wrow & ":AM" & wrow).Copy sh2.Range("B" & LastRow & ":AM" & LastRow) 20 sh1.Cells(wrow, "U") = "" 21 ctr = ctr + 1 22 If ctr = 1 Then 23 toRow = wrow 24 fromRow = wrow 25 End If 26 dicT(wrow) = True 27 LastRow = LastRow + 1 28 End If 29 Next wrow 30 If ctr = 0 Then 31 MsgBox ("完了行なし") 32 Exit Sub 33 End If 34 Do While (toRow < endRow) 35 fromRow = get_from_row(dicT, endRow, fromRow + 1) 36 If fromRow = -1 Then 37 Exit Do 38 End If 39 Call move_line(sh1, toRow, fromRow) 40 toRow = toRow + 1 41 Loop 42 For wrow = endRow - ctr + 1 To endRow 43 Call clear_line(sh1, wrow) 44 Next 45 MsgBox (ctr & "行 処理完了") 46End Sub 47 48Private Function get_from_row(ByVal dicT As Object, ByVal endRow As Long, ByVal fromRow As Long) As Long 49 get_from_row = -1 50 Do 51 If fromRow > endRow Then Exit Function 52 If dicT.Exists(fromRow) = False Then 53 get_from_row = fromRow 54 Exit Function 55 End If 56 fromRow = fromRow + 1 57 Loop 58End Function 59 60Private Sub move_line(ByVal ws As Worksheet, ByVal toRow As Long, ByVal fromRow As Long) 61 ws.Range("B" & toRow).Value = ws.Range("B" & fromRow).Value 62 ws.Range("C" & toRow).Value = ws.Range("C" & fromRow).Value 63 ws.Range("E" & toRow).Value = ws.Range("E" & fromRow).Value 64 ws.Range("G" & toRow & ":U" & toRow).Value = ws.Range("G" & fromRow & ":U" & fromRow).Value 65 ws.Range("AJ" & toRow).Value = ws.Range("AJ" & fromRow).Value 66 ws.Range("AL" & toRow).Value = ws.Range("AL" & fromRow).Value 67End Sub 68 69Private Sub clear_line(ByVal ws As Worksheet, ByVal toRow As Long) 70 ws.Range("B" & toRow).ClearContents 71 ws.Range("C" & toRow).ClearContents 72 ws.Range("E" & toRow).ClearContents 73 ws.Range("G" & toRow & ":U" & toRow).ClearContents 74 ws.Range("AJ" & toRow).ClearContents 75 ws.Range("AL" & toRow).ClearContents 76End Sub 77

投稿2020/11/17 06:21

tatsu99

総合スコア5470

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abc-.-cba

2020/11/17 06:51

ありがとうございます。想像していた通りの予定表になりました。 頂いたコードを元により良いものを作成したいと思います。 長期に渡りありがとうございました。 大変助かりました。
guest

0

>可能であればシート1の空白になっている行を上に繰り上げできれば嬉しいです。
①②のどちらのケースでしょうか。
これが、切り取り前の状態です。
イメージ説明

これが切り取り直後です。11行と14行が空白になります。
イメージ説明

①空白行を上に移動します。(こちらがあなたが提示した内容)
イメージ説明

②空白行を下に移動します。(念のため、こちらではないことの確認)
イメージ説明

投稿2020/11/17 02:56

tatsu99

総合スコア5470

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abc-.-cba

2020/11/17 02:59

わかりやすくご説明ありがとうございます。 ②を想定していました。言葉足らずで申し訳ございません。
guest

0

オートフィルターで抽出して、
コピペしたら、ループをVBAで書く必要がなくなります。
ただし、表にタイトル行が必要になります。

この方法でやるなら、マクロの記録をしてみるところから始めます。
また、サンプルがネット上にありそうな気がします。

また、フィルターオプションの機能で抽出すれば、
VBAのコードがさらに少なるかもしれません。
シート上を汚すことにはなりますが。。。。

あ、コピペじゃなくて、移動なんですかね。
なら、オートフィルターですね。

投稿2020/11/13 10:03

編集2020/11/13 10:05
mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

これでどうでしょうか。

VBA

1Private Sub kanryou_Click() 2 Dim wrow As Long, LastRow As Long 3 Dim sh1 As Worksheet 4 Dim sh2 As Worksheet 5 Set sh1 = Worksheets("Sheet1") 6 Set sh2 = Worksheets("完了分") 7 LastRow = sh2.Cells(Rows.Count, "B").End(xlUp).Row + 1 8 If LastRow < 3 Then LastRow = 3 9 For wrow = 8 To 307 10 If sh1.Cells(wrow, 21) = "完了" Then 11 sh1.Range("B" & wrow & ":AM" & wrow).Cut sh2.Range("B" & LastRow & ":AM" & LastRow) 12 LastRow = LastRow + 1 13 End If 14 Next wrow 15End Sub 16

投稿2020/11/13 09:48

tatsu99

総合スコア5470

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abc-.-cba

2020/11/13 09:59

tatsu99さん ご回答ありがとうございます!! せっかくご回答頂いたのですがPCが週明けにしか触れない為、週明けに教えて頂いたコードを使用させて頂こうと思います。
abc-.-cba

2020/11/16 02:15

tatsu99さん 遅くなり申し訳ございません。ご教授頂きましたコードで上手く動作しました。 ありがとうございました。 ちなみにお手数でなければ2点ほど教えて頂きたいことがあります。 ・切り取りする列の範囲をC~D、H~Qに指定したい時はどのように変更すれば宜しいでしょうか。 ・シート1の切り取りを「値のみ」の切り取りにすることは可能でしょうか。 お手数おかけしますがご教授頂けると幸いです。
tatsu99

2020/11/17 00:06 編集

切り取ったデータの貼り付け先もC~D、H~Qで良いのでしょうか。 対象がU列がないので完了の文字が残りますがよいのですか。 又、現在完了分のシートの最終行判断をB列でやっていますが、それをC列にする必要があります。 前のマクロとの関連はどうなりますか。 シート1の切り取りを「値のみ」にするということは、そこに関数式があり関数式を残したいということでしょうか? 書式設定を残すことは可能ですが、関数式は残りません。 従って、見た目を空白にして、関数式を残すことはできません。
tatsu99

2020/11/16 04:29

もし、前のマクロを一切使わないということであれば、U列の完了の扱い及び最終行の決定の問題は解決します。もし、前のマクロを使うのなら、どのように前のマクロとこれから作るマクロ(C~D、H~Q対応版) を使い分けるのか提示てください。 シート1の切り取りを「値のみ」にする件ですが、特定の列のみ関数式であれば、以下の条件が成立すれば対応可能です。 例としてC列、D列のみ関数式が埋め込まれているとします。 C列、D列はカットではなく転記先へコピーします。 H~Qは転記先へコピーし、その後、その内容をクリアします。 C列、D列の関数式はH~Qのどれかの列が空白なら、空白を表示するようにします。(関数式の修正が必要になる可能性あり)
tatsu99

2020/11/17 00:08

>・シート1の切り取りを「値のみ」の切り取りにすることは可能でしょうか。 具体的にどのようにされたいのでしょうか。現状でどのように不都合なのでしょうか。そのあたりを具体的に説明していただけると良い回答が得られやすくなるかと思います。
abc-.-cba

2020/11/17 01:20

シート2の名前を「完了分」としました。 お忙しい中、ご回答ありがとうございます。 ・切り取りする列の範囲をC~D、H~Qに指定したい時はどのように変更すれば宜しいでしょうか。 >こちらに関してはご教授頂いたコードをコピーに変えてみました。 特定の列のみコピーするのではなく、転記先のシート2の不要な行を非表示にするという形にしました。 Private Sub kanryou_Click() Dim wrow As Long, LastRow As Long Dim sh1 As Worksheet Dim sh2 As Worksheet Set sh1 = Worksheets("予定表") Set sh2 = Worksheets("完了分") LastRow = sh2.Cells(Rows.Count, "B").End(xlUp).Row + 1 If LastRow < 3 Then LastRow = 3 For wrow = 8 To 307 If sh1.Cells(wrow, 21) = "完了" Then sh1.Range("B" & wrow & ":AM" & wrow).Copy sh2.Range("B" & LastRow & ":AM" & LastRow) LastRow = LastRow + 1 End If Next wrow End Sub
abc-.-cba

2020/11/17 01:27

ご認識の通り関数式を残したいと思っております。 関数式はD,F,V~AI,AK,AM列に入っています。 転記された行には新しい予定を入れたいと思っていますので シート1のD,F,V~AI,AK,AM列に入っている関数式を残したいです。
abc-.-cba

2020/11/17 01:33

シート2へのコピーに関してはシート2の不要な列を非表示にするという形を取りましたので全てコピーのままで問題ありません。可能であればシート1の空白になっている行を上に繰り上げできれば嬉しいです。
tatsu99

2020/11/17 02:48

シート1は切り取らないので、コピーした行の各セルを空白にします。 但し、関数式のあるD,F,V~AI,AK,AM列を除きます。 関数式のあるD,F,V~AI,AK,AM列は、他の列が空白になったとき、自動的に自身の列も空白になる関数が 埋め込んであるという前提で良いですか。
tatsu99

2020/11/17 02:50

>可能であればシート1の空白になっている行を上に繰り上げできれば嬉しいです。 こちらは、図で確認したいので回答欄に書きました。①②のどちらのケースを望んでますか。
abc-.-cba

2020/11/17 05:37

わかりやすくご説明ありがとうございます。 ②を想定していました。言葉足らずで申し訳ございません。
abc-.-cba

2020/11/17 05:38

シート1は切り取らないので、コピーした行の各セルを空白にします。 但し、関数式のあるD,F,V~AI,AK,AM列を除きます。 関数式のあるD,F,V~AI,AK,AM列は、他の列が空白になったとき、自動的に自身の列も空白になる関数が 埋め込んであるという前提で良いですか。 >はい。関数に関してはこちらで作成しますのでその前提でお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問