Sub Macro2() For aa = 1 To Selection.Count ee = Selection(aa).Row bb = Cells(ee, Columns.Count).End(xlToLeft).Column For d = 1 To Rows.Count f = 1 cc = 0 For e = 1 To bb If Sheets("Sheet3").Cells(d, e) = "" Then cc = cc + 1 If Cells(ee, e) <> Sheets("Sheet3").Cells(d, e) Then f = 2 End If Next e If f = 1 Then Exit For If cc = bb Then Exit For Next d If f = 2 Then For h = 1 To bb Sheets("Sheet3").Cells(d, h) = Cells(ee, h) Next h End If Next aa End Sub
▽2
●
a-kuma3 ●1000ポイント ベストアンサー |
こんな感じで、どうでしょう。標準モジュールに貼り付けて、サブルーチン Append1To3 をボタンに登録してください。
Public Sub Append1To3() On Error GoTo ErrorHandler ' 画面のちらつきを抑える Application.ScreenUpdating = False Set s = Selection ' 選択されたセルの数が多すぎるときは、処理を中断 If s.Count > 50 Then Exit Sub ' 書き込み行を決定 Set last_b = Sheets("Sheet3").Cells(Rows.Count, 2).End(xlUp) If IsEmpty(last_b) Then to_i = 1 Else to_i = last_b.Row + 1 End If For Each c In s If Sheets("Sheet3").Range("B:B").Find(What:=c.EntireRow.Cells(1, 2).Value, LookAt:=xlWhole) Is Nothing Then ' 値と書式を複写 Sheets("Sheet1").Rows(c.Row).Copy Sheets("Sheet3").Rows(to_i).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False Sheets("Sheet3").Rows(to_i).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False to_i = to_i + 1 End If Next ' 最終行を、左下に表示 Sheets("sheet3").Activate last_row = to_i - ActiveWindow.VisibleRange.Rows.Count + 1 If last_row < 0 Then last_row = 1 End If ActiveWindow.ScrollRow = last_row ActiveWindow.ScrollColumn = 1 FINAL: Application.ScreenUpdating = True Exit Sub ErrorHandler: GoTo FINAL End Sub
質問で書かれていなかったことを、ひとつ前提にしています。
Sheet1 の B列には、空白のセルが無いことを前提にしました。
Sheet3 の書き込む先の行を決める際に、B列で何か値が入っているセルの次の行を書き込み行としています。
後、Sheet1 を全選択したときに泣きそうになると思うので、複写するセルの数に上限を設けてます。
適宜、増やしてください。
●セル選択だけでなく、
【Sheet1】で行番号を選択した場合でも(行番号を複数選択した場合でも)、
【Sheet3】に貼り付ける仕様を追加していただけないでしょうか。
行を指定しちゃうと、選択したセル数が 50 まで、というチェックで処理を止めちゃうんですね。
Selection.Areas というコレクションがあったので、これを使って処理を変えてみました。
Public Sub Append1To3() On Error GoTo ErrorHandler ' 画面のちらつきを抑える Application.ScreenUpdating = False Set s = Selection ' 選択された列数が多すぎるときは、処理を中断 n_rows = 0 For Each a In s.Areas n_rows = n_rows + a.Rows.Count Next If n_rows > 20 Then MsgBox "Too much cells ! " & n_rows Exit Sub End If ' 書き込み行を決定 Set last_b = Sheets("Sheet3").Cells(Rows.Count, 2).End(xlUp) If IsEmpty(last_b) Then to_i = 1 Else to_i = last_b.Row + 1 End If For Each a In s.Areas For Each r In a.Rows If Sheets("Sheet3").Range("B:B").Find(What:=r.EntireRow.Cells(1, 2).Value, LookAt:=xlWhole) Is Nothing Then ' 値と書式を複写 Sheets("Sheet1").Rows(r.Row).Copy Sheets("Sheet3").Rows(to_i).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False Sheets("Sheet3").Rows(to_i).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False to_i = to_i + 1 End If Next Next ' 最終行を、左下に表示 Sheets("sheet3").Activate last_row = to_i - ActiveWindow.VisibleRange.Rows.Count + 1 If last_row < 0 Then last_row = 1 End If ActiveWindow.ScrollRow = last_row ActiveWindow.ScrollColumn = 1 FINAL: Application.ScreenUpdating = True Exit Sub ErrorHandler: GoTo FINAL End Sub
結構、遅かったので、選択した行の上限を 20 に変えました。
上限を超えたときには、音なしで終了するのではなく、MsgBox でメッセージを表示します。
Sub Macro3() Application.ScreenUpdating = False For aa = 1 To Selection.Count ee = Selection(aa).Row For d = 1 To Rows.Count f = 1 cc = 0 If Cells(ee, 2) <> Sheets("Sheet3").Cells(d, 2) Then f = 2 Else Exit For If Sheets("Sheet3").Cells(d, 2) = "" Then f = 2: Exit For Next d If f = 2 Then Rows(ee).Copy Sheets("Sheet3").Rows(d).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _ SkipBlanks:=False, Transpose:=False Sheets("Sheet3").Rows(d).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False End If Next aa Sheets("Sheet3").Select ActiveCell.SpecialCells(xlLastCell).Select Application.ScreenUpdating = True End Sub
書式もコピーするようにしました。