Excel (VBA)

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

 
(Windows 11 Home : Microsoft 365)
条件を満たしたファイルを一覧に転記し、別のフォルダーに移動したい。
投稿日時: 23/01/13 00:35:00
投稿者: miyuukate

いつもお世話になっています。
 
フォルダー(加工用)→複数のファイル(テスト)→シート(計算)のD列E列の両方に〇がある場合、その行をフォルダー(加工用)→ファイル(一覧)に転記するマクロを作成しています。
 
・ファイル(テスト)は1行のものもあれば複数行の場合もあります。
 入力されてる行の全てのD列E列に〇がある場合、ファイル(テスト)をフォルダー(済)に移動させたい。
 
もしD列〇E列が〇ならばファイル(テスト)をフォルダ(済)に移動する…のコード自体かコードを入れる位置が悪いのかずっと試行錯誤してますが、D列E列両方に〇がない行があるファイルもフォルダー(済)に移動してしまうか全く動かないかエラーになります。
お忙しいところ恐れ入りますが、アドバイスお願いいたします。
 
ファイル(テスト)
    A   B   C   D   E   F
1 あ  い    〇  〇      →の場合、ファイル(一覧)に転記
2 う    え     〇      →の場合、D列に〇がないので転記しない
このファイル(テスト)の場合は2行目が条件を満たしていないのでフォルダー(済)には移動しない。
 
  A   B   C   D   E   F
1 お    か  〇  〇      →の場合、ファイル(一覧)に転記したフォルダー(済)に移動
 

Sub 一覧作成()
    
    Dim swb As Workbook
    Dim dwb As Workbook
    Dim sws As Worksheet
    Dim dws As Worksheet
    Dim strFolderPath As String
    Dim strFileName As String
    Dim sLastRow As Long
    Dim dLastRow As Long
           
    strFolderPath = "C:\Users\加工用\"
    strFileName = Dir(strFolderPath & "*テスト.xlsx")
    
    If strFileName = "" Then
        MsgBox strFolderPath & "ファイルありません", vbExclamation, "ファイルなし"
        Exit Sub
    End If
    
    Set dwb = ThisWorkbook
    Set dws = dwb.Worksheets("一覧")
    
    Dim i As Long
    i = 1
    
    Dim FSO As New Scripting.FileSystemObject
    Dim sourceFile As String
    Dim destinationFile As String
    
    sourceFile = "C:\Users\加工用\*テスト.xlsx"
    destinationFile = "C:\Users\処理済\"
        
    Do Until strFileName = ""
        Set swb = Workbooks.Open(strFolderPath & strFileName, , True)
        Set sws = swb.Worksheets("計算")
        
        dLastRow = dws.Cells(dws.Rows.Count, 1).End(xlUp).Row
        With sws
           sLastRow = .Cells(sws.Rows.Count, 1).End(xlUp).Row
        
           If sLastRow > 1 Then
              For i = 1 To sLastRow
                 If .Cells(i, 4) = "〇" And .Cells(i, 5) = "〇" Then
                  .Range(.Cells(i, 1), .Cells(i, 5)).Copy
                  dws.Cells(dLastRow + 1, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
                  dLastRow = dLastRow + 1
                  FSO.MoveFile sourceFile, destinationFile
                 End If
                 
               Next i
           End If
                                      
        End With
                                         
        strFileName = Dir()
         swb.Close False
     Loop
        
    Set FSO = Nothing
    Set sws = Nothing
    Set swb = Nothing
        
 End Sub

[/code]

回答
投稿日時: 23/01/13 08:53:17
投稿者: simple

詳細に見ていませんが、

   FSO.MoveFile sourceFile, destinationFile
は、一行ごと実行されることになっていますが、
それは意図したことなんですか?
そのあたりをよく検討されてはいかがですか?
 
(1).Cells(i, 4) = "〇" And .Cells(i, 5) = "〇"がFalseになったとき、
   転記不要のフラッグを立て、
(2)全行終了後に、フラッグが立っていなければ、
   ファイルを閉じたあとで転記する、としたらどうですか?
(3)その際、ファイルパスも、strFileNameを反映したものにする必要があるのではないですか?

投稿日時: 23/01/13 21:16:04
投稿者: miyuukate

simple さんの引用:
詳細に見ていませんが、
   FSO.MoveFile sourceFile, destinationFile
は、一行ごと実行されることになっていますが、
それは意図したことなんですか?
そのあたりをよく検討されてはいかがですか?
 
(1).Cells(i, 4) = "〇" And .Cells(i, 5) = "〇"がFalseになったとき、
   転記不要のフラッグを立て、
(2)全行終了後に、フラッグが立っていなければ、
   ファイルを閉じたあとで転記する、としたらどうですか?
(3)その際、ファイルパスも、strFileNameを反映したものにする必要があるのではないですか?

 
アドバイスありがとうございます。
条件を満たしてるかどうかのフラグを立てて最後に実行する方法思いつきませんでした。
VBA初心者で本やネットで検索しながら勉強中のため、アドバイスいただいた点も理解できていない部分があるのでご教授願います。
 
(1)の部分をIf .Cells(i, 4) = "〇" And .Cells(i, 5) = "〇" Then〜
  の中にFlag = Falseというようにして
(2)でファイルを閉じてLOOPの後に
   If Flag = False Then
            FSO.MoveFile sourceFile, destinationFile
       End Ifとしました。
(3)ですがsourceFIleの部分にstrFilenameに置き換えるとプロシージャの呼び出し〜引数が不正ですのエラーがでます。sourceFileだとエラーは出ませんが全てのファイル(テスト)が済フォルダに移動してしまいます。
お手数ですがよろしくお願いいたします。
 
Sub 一覧作成()
    Dim swb As Workbook
    Dim dwb As Workbook
    Dim sws As Worksheet
    Dim dws As Worksheet
    Dim strFolderPath As String
    Dim strFileName As String
    Dim sLastRow As Long
    Dim dLastRow As Long
            
    strFolderPath = "C:\Users\作成\"
    strFileName = Dir(strFolderPath & "*テスト.xlsx")
     
    If strFileName = "" Then
        MsgBox strFolderPath & "ファイルありません", vbExclamation, "ファイルなし"
        Exit Sub
    End If
     
    Set dwb = ThisWorkbook
    Set dws = dwb.Worksheets("一覧")
     
    Dim i As Long
    i = 1
    Dim Flag As Boolean
    Dim FSO As New Scripting.FileSystemObject
    Dim sourceFile As String
    Dim destinationFile As String
     
    sourceFile = "C:\Users\作成\*テスト.xlsx"
    destinationFile = "C:\Users\処理済\"
         
    Do Until strFileName = ""
        Set swb = Workbooks.Open(strFolderPath & strFileName, , True)
        Set sws = swb.Worksheets("計算")
         
        dLastRow = dws.Cells(dws.Rows.Count, 1).End(xlUp).Row
        With sws
           sLastRow = .Cells(sws.Rows.Count, 2).End(xlUp).Row
           If sLastRow > 1 Then
              For i = 1 To sLastRow
                 If .Cells(i, 4) = "〇" And .Cells(i, 5) = "〇" Then
                  .Range(.Cells(i, 1), .Cells(i, 5)).Copy
                  dws.Cells(dLastRow + 1, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
                  dLastRow = dLastRow + 1
                 Flag = False
                 End If
              Next i
           End If
         End With
                                          
        strFileName = Dir()
         swb.Close False
    Loop
       
       If Flag = False Then
            FSO.MoveFile sourceFile, destinationFile
       End If
               
    Set FSO = Nothing
    Set sws = Nothing
    Set swb = Nothing
       
End Sub
 

回答
投稿日時: 23/01/13 22:03:03
投稿者: simple

FSO.MoveFile sourceFile, destinationFile
を実行する際に、
sourceFile = "C:\Users\作成\*テスト.xlsx"
とワイルドカードを使っているので、対象ファイルをすべて、
〇の有無にかかわらず、Moveしてしまっているからでしょう。
 
概略、こんなことになるのではないですか?
 

Sub 一覧作成()
    'Microsoft Scripting Runtimeに参照設定のこと
    
    Dim swb As Workbook
    Dim dwb As Workbook
    Dim sws As Worksheet
    Dim dws As Worksheet
    Dim strFolderPath As String
    Dim strFileName As String
    Dim sLastRow As Long
    Dim dLastRow As Long
    Dim noNeedToMove As Boolean
   
    Set dwb = ThisWorkbook
    Set dws = dwb.Worksheets("一覧")

    Dim i As Long
    Dim FSO As New Scripting.FileSystemObject

    Dim destinationFolder As String

    destinationFolder = "C:\Users\処理済\"
    
    strFolderPath = "C:\Users\加工用\"
    
    strFileName = Dir(strFolderPath & "*テスト.xlsx")
    If strFileName = "" Then
        MsgBox strFolderPath & "ファイルありません", vbExclamation, "ファイルなし"
        Exit Sub
    End If
    
    Do Until strFileName = ""
        Set swb = Workbooks.Open(strFolderPath & strFileName, , True)
        Set sws = swb.Worksheets("計算")
        
        noNeedToMove = False
        dLastRow = dws.Cells(dws.Rows.Count, 1).End(xlUp).Row
        With sws
            sLastRow = .Cells(sws.Rows.Count, 1).End(xlUp).Row
            'If sLastRow > 1 Then   'データが一行目から始まっているなら不要?
                For i = 1 To sLastRow
                    If .Cells(i, 4) = "〇" And .Cells(i, 5) = "〇" Then
                        .Range(.Cells(i, 1), .Cells(i, 5)).Copy
                        dws.Cells(dLastRow + 1, 1).PasteSpecial _
                                                Paste:=xlPasteValuesAndNumberFormats
                        dLastRow = dLastRow + 1
                    Else
                        noNeedToMove = True 'ファイルの移動は不要
                    End If
                Next i
            'End If
        End With
        
        swb.Close False
        If noNeedToMove = False Then        'ファイルの移動が必要なら
            FSO.MoveFile strFolderPath & strFileName, destinationFolder
        End If
        strFileName = Dir()
    Loop

    Set FSO = Nothing
    Set sws = Nothing
    Set swb = Nothing
End Sub

私の環境で、簡単なテストは実行し、確認しています。
それを、元のファイル名などに戻す修正をしているので、
そこでミスが入っている可能性はあります。
ステップ実行して確認してください。

投稿日時: 23/01/13 23:00:08
投稿者: miyuukate

simpleさま
 
条件を満たしている場合のみ、ファイルを済フォルダーに移動することができました。
(1)のところで移動するかどうかの分岐はIf〜Thenの中に含めなくてもElseのところで移動しないと入れるのですね〜!
(3)のStrFileNameの使い方もどのように記述するのかわかり、これからも使う機会が多いと思うので勉強になりました。
これからこちらのコードを参考に勉強していきます。
考えが同じところでグルグル回って他の方法なども思い浮かばず困っていました。
大変勉強になりました。ありがとうございます。