Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : Excel 2021)
フィルターで該当データのみを別シートにコピーし元シートのデータは削除したい
投稿日時: 22/11/09 16:21:04
投稿者: yusukyo0123

VBA超初心者です。
エクセルのシート1にフィルターをかけて、該当行のみ別シートにコピーし、元シートのデータは削除するというコードを設定したいのですが、うまくいきません。
具体的にはシート1にある
4行目にタイトル、A-O列の表で、K4セルに設定したフィルター(TRUE/FALSE)のTRUEの該当行のみコピーし
シート2(シート1のタイトル列が1列目)の2行目(データがある行のすぐ下から)からタイトル抜きで貼り付け
シート1の元データは行ごと削除する
というコードを書きたいです。
マクロの記録からとネットで拾ったコードなので変だと思います。
ご教示いただけますと幸いです。
 
Sub 期限切れデータ移動()
'
'
    ActiveSheet.Range("$A$4:$O$600").AutoFilter Field:=11, Criteria1:="TRUE"
    Range("A4").Select
    Selection.End(xlDown).Select
    Range("A4").Select
    Range(Selection, Selection.End(xlDown)).Select
    Range(Selection, Selection.End(xlToRight)).Select
    Selection.Copy
    Selection.SpecialCells(xlCellTypeVisible).Select
    Application.CutCopyMode = False
    Selection.Copy
    Sheets("Sheet2").Select
    Range("A2").Select
    ActiveSheet.Paste
     
     'List_Shtをループして、期限切れデータと同じ値があったら行削除
     Sheets("sheet1").Select
    For i = 5 To UBound(SearchWord)
        '最終行からループ
        For j = LastRow To 5 Step -1
            If List_Sht.Cells(j, 1) & List_Sht.Cells(j, 2) = SearchWord(i) Then
                '行削除
                 List_Sht.Rows(j).Delete
            End If
        Next j
    Next i
     
    
End Sub

回答
投稿日時: 22/11/09 16:46:26
投稿者: WinArrow
投稿者のウェブサイトに移動

変数がていぎされていませんが・・・
  
  
変数:
i
j
LastRo
SearchWord
List_Sht
 
なお、
>シート1の元データは行ごと削除する
この元データとは、K列セル=Trueということですか?
 

回答
投稿日時: 22/11/09 17:33:29
投稿者: WinArrow
投稿者のウェブサイトに移動

コード添削(代案)

Sub 期限切れデータ移動()
'
Dim ws1 As Worksheet, ws2 As Worksheet
Dim i As Long
Const K列 As Long = 11

    Set ws1 = Sheets("Sheet1")
    Set ws2 = Sheets("Sheet2")
    With ws1
        With .Range("$A$4:$O$600")
            .AutoFilter Field:=K列, Criteria1:=True
        
            Intersect(.CurrentRegion, .CurrentRegion.Offset(1)).Copy _
                Destination:=ws2.Range("A2")
            .AutoFilter  'オートフィルタ解除
        End With
        
    'k列セル=trueの行を削除する
        For i = .Cells(.Rows.Count, "A").End(xlUp).Row To 5 Step -1
            If .Cells(i, K列).Value = True Then
                .Rows(i).Delete
            End If
        Next
    End With
End Sub

回答
投稿日時: 22/11/09 18:06:42
投稿者: WinArrow
投稿者のウェブサイトに移動

↑のコード
K列セル=TRUEと期限切れデータとの関連が説明されていないので、
勝手に同じものと推測してコードを記述しています。
   
最初、掲示のコードでは、
For 〜Next が2重になっているが、
K列セル=TRUEと期限切れデータ識別が異なっても、
当該行内のセルで期限切れが判断できるのであれば、
2重にする必要はないと思います。

投稿日時: 22/11/10 09:17:32
投稿者: yusukyo0123

 WinArrowさん
早々にありがとうございます!定義が無いから動かないのですね・・
 
>この元データとは、K列セル=Trueということですか?
ご理解の通りです。
コード提案ありがとうございます。
シート2にコピーする際、コピー元はシート1の5行目以降と指定したいのですが、どのようにすればよろしいでしょうか?
またシート2には2行目以降貼り付けたいのですが、期限切れデータを蓄積したいので、前データの続きから貼り付けできるようにできますでしょうか?

回答
投稿日時: 22/11/10 09:29:56
投稿者: WinArrow
投稿者のウェブサイトに移動

yusukyo0123 さんの引用:

シート2にコピーする際、コピー元はシート1の5行目以降と指定したいのですが、どのようにすればよろしいでしょうか?
またシート2には2行目以降貼り付けたいのですが、期限切れデータを蓄積したいので、前データの続きから貼り付けできるようにできますでしょうか?

提示したコードでは、
Sheet1の5行目以降を
Sheet2の2行目以降に
複写するようになってるはずです。
お確かめください。

投稿日時: 22/11/10 09:49:37
投稿者: yusukyo0123

 WinArrowさん
ご教示ありがとうございます。
やってみたのですが、Sheet1の2行目(注意書きや他の入力欄あり)からsheet2の2行目へコピーされてしまいました。
また次のデータを入れて再度実行したところ、同様にSheet1の2行目からコピーされ、Sheet2の2行目から上書きされてしまいました。
何か変な操作をしてしまっているのかもしれません。。すみません。

回答
投稿日時: 22/11/10 09:56:04
投稿者: WinArrow
投稿者のウェブサイトに移動

アドバイス
 
> With .Range("$A$4:$O$600")
と記述すると、For ループの際、常にデータの入っていないセルもアクセスすることになります。
 
これを、データが入っている行までにするには、
 With .Range("A4").Resize(.Range("A" & .Rows.Count).End(xlUp).Row - 4, .Columns("O").Column)
と記述するとよいです。但し、横方向は固定にしてあります。
 

回答
投稿日時: 22/11/10 09:58:38
投稿者: WinArrow
投稿者のウェブサイトに移動

yusukyo0123 さんの引用:
WinArrowさん
ご教示ありがとうございます。
やってみたのですが、Sheet1の2行目(注意書きや他の入力欄あり)からsheet2の2行目へコピーされてしまいました。
また次のデータを入れて再度実行したところ、同様にSheet1の2行目からコピーされ、Sheet2の2行目から上書きされてしまいました。
何か変な操作をしてしまっているのかもしれません。。すみません。

 
実際のコードを掲示して貰えますか?

回答
投稿日時: 22/11/10 10:10:30
投稿者: WinArrow
投稿者のウェブサイトに移動

原因が分かりました。
 
> Intersect(.CurrentRegion, .CurrentRegion.Offset(1)).Copy _

 Intersect(.Cells, .Cells.Offset(1)).Copy _
 
に修正してください。

投稿日時: 22/11/10 11:09:34
投稿者: yusukyo0123

WinArrowさん
早々にありがとうございます!コピー成功しました。
ただ、追加データを試したらシート2の2行目から上書きされてしまったのですが、データのある行の下から貼り付けすることは可能でしょうか?色々お願いしてすみません。

回答
投稿日時: 22/11/10 12:58:03
投稿者: WinArrow
投稿者のウェブサイトに移動

複写先セルを固定ではなく、可変に変更します。
 
固定:Rrange("A2")
可変:データの入っている最終セルの一つ下のセル
 
> Destination:=ws2.Range("A2")

              Destination:=ws2.Range("A" & ws2.Rows.Count).End(xlUp).Offset(1)
解説
ws2.Range("A" & ws2.Rows.Count) は、シートのA列の最終セル
End(xlUp)は、[Ctrl]+[↑] という操作 ・・・これでデータが入っている最終セルが取得できます。
offset(1)は、そのセルの1つ下のセル
 
 

投稿日時: 22/11/10 15:32:33
投稿者: yusukyo0123

 WinArrowさん
ご親切にありがとうございます。うまく動かすことができました。
業務改善できそうです。大変お世話になりました。本当にありがとうございました。 :D

回答
投稿日時: 22/11/10 16:21:20
投稿者: simple

変数は必ず宣言することを推奨します。
http://officetanaka.net/excel/vba/beginner/06.htm
を参照してください。
変数の入力ミスを防止したり、色々とメリットはあります。
  
Option Explicit
をモジュールの一行目に挿入するようにして下さい。
そうすれば、未宣言の変数には警告が出て、 しかも場所を特定してくれます。
  
また、Option Explicitを自動設定するようにしておくとよいでしょう。
上記のサイトにやりかたが書いてありますので、是非。

回答
投稿日時: 22/11/10 17:34:46
投稿者: WinArrow
投稿者のウェブサイトに移動

yusukyo0123 さんの引用:
WinArrowさん
ご親切にありがとうございます。うまく動かすことができました。
業務改善できそうです。大変お世話になりました。本当にありがとうございました。 :D

 
回答で得られたコードで解決したことだけで「終わり」とせず、
そのコードの一行一行の意味を理解するようお願いします。
丸写しは、カンニングと同じです。
 

投稿日時: 22/11/11 09:02:13
投稿者: yusukyo0123

 simpleさん、WinArrowさん
ご教示ありがとうございます。
VBAの本も購入しました。コードの意味を理解するように努めます。
参考サイトご案内もありがとうございました。