(VBA) 同名フォルダーの存在をチェック

このQ&Aのポイント
  • VBAで同名フォルダーの存在をチェックする方法はありますか?
  • フォルダー名の変更時に同名ファイルがある場合にエラーが発生する問題があります。
  • どのように判定して、同名がある場合はフォルダー名の末尾に(1)、(2)を付加することができますか?
回答を見る
  • ベストアンサー

(VBA) 同名フォルダーの存在をチェック

以下のコード(Sub ⑤フォルダー名の変更())でフォルダー名の変更を行っています。 変名時に同名ファイルがある場合エラーが以下のコードでエラーがでます。   .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text エラー無く処理したいので  同名があるばあいは、フォルダー名の末尾に(1)、(2)を付加したいのですが  同名があるかどうかは?どのように判定しますか ? Sub ⑤フォルダー名の変更() Dim i As Long Dim LastColumn As Single Dim LastColumn_ABC As String Dim MSG As String LastColumn = Cells(5, "B").End(xlToRight).Column LastColumn_ABC = Split(Cells(1, LastColumn).Address, "$")(1) MSG = MsgBox("B列フォルダー名が" & LastColumn_ABC & "列フォルダー名に変更されます!" & vbCrLf _ & "B," & LastColumn_ABC & "列に値がなければ、処理は行いません。", 257, "フォルダー名変更") If MSG = vbCancel Then Exit Sub i = 5 'subフォルダ名取得が5行目からフォルダー名を表示するため。 Do While Range("b" & i).Text <> "" If Cells(i, LastColumn).Text <> "" Then ' 新フォルダー名がある場合のみ、名前変更を行う。 With CreateObject("Scripting.FileSystemObject") .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text End With End If i = i + 1 Loop MsgBox "変名処理が終了しました。" End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率65% (1615/2454)
回答No.3

> さすがに同じフォルダー名で()の中の数字も同じフォルダー名が >  すでに存在することは無いような気がします。 無ければそれでいいと思います。ただ、「(1)、(2)を付加したい」と質問にあったので、ある事を想定してるのかなと思いました。 > イミディエイトウィンドウへの出力結果で >    ¥1と表示されていますが1個の重複があるとの意味でしょうか ? 「新フォルダー名がある場合のみ、名前変更を行う」のところだけの変更コードでしたのでテスト時に LastColumn = 3 i = 2 と適当な値で設定してますのでC2に何もなければそうなると思います。本来はフォルダー名1になります。 実際のデータの適切な指定に変更してください。 >  又、重複していないフォルダーの変名処理が行われていないように思います。 Else .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text の部分で行われると思いますが…C2に何もなければ行われないと思います。 また、重複フォルダーでの操作でイミディエイトにて正しいパスが生成できるようでしたら、変名処理を行っていただければと思っています。 一例として .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Replace(newfolderName, Range("A2").Value, "") という方法でもいけると思います。 > 一部コードを以下のように修正しました。 > .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text & "(" & (i - 4) & ")" 準じて以下の部分を変更してください。 Function Fcheck(ByRef fso As Object, ByVal folderPath As String, ByRef fNo As Long) As String With fso If .FolderExists(folderPath & "(" & fNo & ")") Then fNo = fNo + 1 Call Fcheck(fso, folderPath, fNo) End If End With Fcheck = folderPath & "(" & fNo & ")" End Function

NuboChan
質問者

補足

うっかりミスが多くてお世話をおかけしています。 >LastColumn = 3 >i = 2 >と適当な値で設定してますのでC2に何もなければそうなると思います。 コードの下の方ばかりを見ていたので  LastColumnとiの設定が実際と違っているのに気が付きませんでした。 実際にマッチした設定で試してみます。 旨く行かなかったら又書き込みしますので少し時間をください。 (うまく処理できたら、解決としたいです。)

その他の回答 (2)

  • kkkkkm
  • ベストアンサー率65% (1615/2454)
回答No.2

> If CreateObject("Scripting.FileSystemObject").FolderExists(range)"A2") & cells(i,LastColumn)) Then > With CreateObject("Scripting.FileSystemObject") > .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text & (i-4) 多分これだとCells(i, LastColumn).Text & (i-4)と同じフォルダが既にあった場合エラーになるような気がします。 変更しようとするフォルダがある場合、再帰呼び出しで再度チェックするようにしたらいかがでしょう。 Debug.Print NewfolderName で新しいフォルダ名をイミディエイトに出していますので確認してください。 Sub Test() Dim fso As Object Dim folderPath As String, newfolderName As String Dim i As Long, LastColumn As Long, fNo As Long LastColumn = 3 i = 2 Set fso = CreateObject("Scripting.FileSystemObject") fNo = 1 With fso If .FolderExists(Range("A2") & Cells(i, LastColumn)) Then newfolderName = Fcheck(fso, Range("A2") & Cells(i, LastColumn).Text, fNo) Debug.Print newfolderName Else .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text End If End With End Sub Function Fcheck(ByRef fso As Object, ByVal folderPath As String, ByRef fNo As Long) As String With fso If .FolderExists(folderPath & fNo) Then fNo = fNo + 1 Call Fcheck(fso, folderPath, fNo) End If End With Fcheck = folderPath & fNo End Function

NuboChan
質問者

お礼

コードの訂正ありがとうございます。 >多分これだとCells(i, LastColumn).Text & (i-4)と同じフォルダが既にあった場合エラーになるような気がします。 さすがに同じフォルダー名で()の中の数字も同じフォルダー名が  すでに存在することは無いような気がします。 一部コードを以下のように修正しました。 .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text & "(" & (i - 4) & ")" 「再帰呼び出し」と言うマクロ素人には思い付かない方法で  転ばぬ先の杖的エラー回避を教えていただいたので  コードをそのまま利用させていただき確認してみました。  イミディエイトウィンドウへの出力結果で    ¥1と表示されていますが1個の重複があるとの意味でしょうか ?  又、重複していないフォルダーの変名処理が行われていないように思います。  (test()実施前後のフォルダーの名前に変化がありません。) ---------------------------- 私のコード(Sub ⑤フォルダー名の変更_改())を行うと  元フォルダーが変名後に添付画像のようになり  一応うまく処理できているように思えます。 添付画像(参考画像)  https://imgur.com/Zscju6b

  • kkkkkm
  • ベストアンサー率65% (1615/2454)
回答No.1

VBAでフォルダ存在チェック https://vbabeginner.net/folder-existence-check/ こちらを参照してください。

NuboChan
質問者

お礼

urlの紹介ありがとうございます。 紹介いただいたURLと違うのですが下記のURLが参考になりそうです。 https://tonari-it.com/excel-vba-exists-folder-create/ つまり、ラフなコードとして以下のように考えましたが  修正箇所の指摘をお願いします。 Sub ⑤フォルダー名の変更() Dim i As Long Dim LastColumn As Single Dim LastColumn_ABC As String Dim MSG As String LastColumn = Cells(5, "B").End(xlToRight).Column LastColumn_ABC = Split(Cells(1, LastColumn).Address, "$")(1) MSG = MsgBox("B列フォルダー名が" & LastColumn_ABC & "列フォルダー名に変更されます!" & vbCrLf _ & "B," & LastColumn_ABC & "列に値がなければ、処理は行いません。", 257, "フォルダー名変更") If MSG = vbCancel Then Exit Sub i = 5 'subフォルダ名取得が5行目からフォルダー名を表示するため。 Do While Range("b" & i).Text <> "" If Cells(i, LastColumn).Text <> "" Then ' 新フォルダー名がある場合のみ、名前変更を行う。 If CreateObject("Scripting.FileSystemObject").FolderExists(range)"A2") & cells(i,LastColumn)) Then With CreateObject("Scripting.FileSystemObject") .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text & (i-4) end with else With CreateObject("Scripting.FileSystemObject") .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text end wit elnd if End If i = i + 1 Loop MsgBox "変名処理が終了しました。" End Sub Sub フォルダの存在確認をしてなければ作成する() Dim objFso As Object Set objFso = CreateObject("Scripting.FileSystemObject") Dim strFolderPath As String MsgBox "フォルダpdfは存在しています" Else strFolderPath = objFso.CreateFolder(ThisWorkbook.Path & "\pdf") MsgBox "フォルダpdfは存在しなかったので作成しました" & vbNewLine & strFolderPath End If Set objFso = Nothing End Sub

NuboChan
質問者

補足

すいません。  最初に書いたコードの修正版です。 Sub ⑤フォルダー名の変更_改() Dim i As Long Dim LastColumn As Single Dim LastColumn_ABC As String Dim MSG As String LastColumn = Cells(5, "B").End(xlToRight).Column LastColumn_ABC = Split(Cells(1, LastColumn).Address, "$")(1) MSG = MsgBox("B列フォルダー名が" & LastColumn_ABC & "列フォルダー名に変更されます!" & vbCrLf _ & "B," & LastColumn_ABC & "列に値がなければ、処理は行いません。", 257, "フォルダー名変更") If MSG = vbCancel Then Exit Sub i = 5 'subフォルダ名取得が5行目からフォルダー名を表示するため。 Do While Range("b" & i).Text <> "" If Cells(i, LastColumn).Text <> "" Then ' 新フォルダー名がある場合のみ、名前変更を行う。 If CreateObject("Scripting.FileSystemObject").FolderExists(Range("A2") & Cells(i, LastColumn)) Then With CreateObject("Scripting.FileSystemObject") .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text & (i - 4) End With Else With CreateObject("Scripting.FileSystemObject") .GetFolder(Range("A2").Text & Range("B" & i).Text).Name = Cells(i, LastColumn).Text End With End If End If i = i + 1 Loop MsgBox "変名処理が終了しました。" End Sub

関連するQ&A

  • vba 四捨五入 について教えてください。

    VBA初心者です。お世話になりますがよろしくお願いします。 vbaでRound関数を使って四捨五入したいと考えております。 以下のコードで実行するとエラー(プロシージャの呼び出し,または引数が不正です。)が出ます。 何がなんだかわからずに困っております。 どうかご教授よろしくお願いします。 Sub 計算() Worksheets("abc").Activate Dim LastRow As Long Dim i As Integer LastRow = Worksheets("abc").Range("K65536").End(xlUp).Row For i = 6 To LastRow If Cells(i, 11) = 0 Then Cells(i, 12) = "" Else Cells(i, 12) = Round(Cells(i, 9) / Cells(i, 11),-2) End If Next End Sub

  • VBA エクセル 列の並び替え

    左から右にA、B、Cと値が入っています。 ABC以外の文字が列に入っていたら、削除するというマクロを組みましたが、範囲を設定するところでエラーが出てしまいました。 なぜでしょうか? 教えて下さい。 Sub arrange() Dim rg As Range Dim i As Long i = 1 Do rg = Cells(i, 1) If rg <> "A" And rg <> "B" And rg <> "C" Then Range(i & ":" & i).Delete End If i = i + 1 Loop Until (i & "1") = "" End Sub

  • EXCEL_VBAのコードのコード修正

    EXCEL_VBAのコードのコード修正での質問です。 現在以下のコードを利用しています。 (ほぼネットからの入手したコードで    私は、マクロに関しては初心者レベル以下です。) 変更したいのは、名前変更対象の列を現在E列固定なのを  名前変更対象列をマクロ途中で指定できるようにしたいのです。  つまり、イメージとしては    処理途中でダイアログが表示されて処理対象列を指定して    処理を開始するような。。。        現在、E,F,G列が候補となりますが将来増加する予定です。 どのようなにコードを追加すれば良いでしょうか ?    --------------------------------------- Sub フォルダー名の変更() ' Name "C:\Users\tmp.txt" As "C:\Users\tmp\tmp.txt"  ←移動となる。 ' B列現在のフォルダー名 C列=新しいフォルダー名(入力要) ' OKキャンセルボタンとデフォルトアクティブボタンの設定は数値の加算で行う。 '   1              第2ボタン256 = 1+256 = 257 Dim i As Long Dim atai As String   '処理列選択コード挿入予定 ------- ? atai = MsgBox("B列フォルダー名E列フォルダー名に変更されます!" & vbCrLf _ & "B,E列に値がなければ、処理は行いません。", 257, "フォルダー名変更") If atai = vbCancel Then Exit Sub i = 4 'subフォルダ名取得が4行目からフォルダー名を表示するため。 Do While Range("b" & i).Text <> "" If Range("E" & i).Text <> "" Then ' 新ファイル名がある場合のみ、名前変更を行う。 Name Range("a2").Text & Range("b" & i).Text As Range("a2").Text & Range("E" & i).Text End If i = i + 1 Loop End Sub

  • VBA のコードについて

    すみません、以前にも同じようなご質問をさせて頂いたのですが、どうしても以下のマクロがうまく機能しません。 新しいブックは作成されるのですが、End If以降の検索結果が反映(コビー)されません。 コードに問題があるかアドバイス頂けますと幸いです。 どうぞ宜しくお願いいたします。 Sub sort() Dim i As Long Dim grp As String Dim newBookName As String Dim newBookPath As String Dim newBook As Workbook For i = 2 To 4 LOB = Workbooks("test").Worksheets("grpリスト").Cells(i, 2) newBookName = Workbooks("test").Worksheets("grpリスト").Cells(i, 2) & ".xlsx" newBookPath = ThisWorkbook.Path & "\" & newBookName '指定したパスにファイルが作成済でないかを確認。 If Dir(newBookPath) = "" Then '新しいファイルを作成 Set newBook = Workbooks.Add '新しいファイルをVBAを実行したファイルと同じフォルダ保存 newBook.SaveAs newBookPath Else '既に同名のファイルが存在する場合はメッセージを表示 MsgBox "既に" & newBookName & "というファイルは存在します。" End If With Workbooks("test").Worksheets("マスタ0701").AutoFilterMode = False With .Range(Cells(3, "B"), Cells(Rows.Count, "CK").End(xlUp)) .AutoFilter Field:=13, Criteria1:=grp '.CurrentRegion.Select Range(Cells(3, "B"), Cells(Rows.Count, "CK").End(xlUp)).SpecialCells(xlVisible).copy Workbooks(grp).Worksheets("Sheet1").Range("A1") '.AutoFilter End With End With Next i End Sub

  • VBAでの質問

    お世話になります。 下記の記述で、「←」の矢印の記述で、 Cells.(5,2)がブランクでなければ、 「→」から進めたいのですが、 どの様に記述すれば宜しいでしょうか ご教示お願いします。 Sub 表記入() Dim Data As Range Dim i As Integer Dim j As Integer Dim k As Integer Set Data = Sheets("集計").Range("A2").CurrentRegion j = 16 k = 0 With Sheets("表") For i = 3 To Data.Rows.Count If Data.Cells(i, 51) <> "" Then .Cells(5, 2) = Data.Cells(i, 3)  ← .Cells(5, 7) = Data.Cells(i, 4) → .Cells(j, 2) = Data.Cells(i, 10) .Cells(j, 6) = Data.Cells(i, 11) & Data.Cells(i, 12) .Cells(j, 14) = Data.Cells(i, 51) Else End If k = k + 1 If k = 10 Then j = j + 18 k = 0 Else j = j + 1 End If End If Next i End With End Sub

  • excel2000vba コントロールの値チェック

    写真のように、ユーザーフォームの、各テキストボックスに数字を入れるようにしています。 そして、それぞれの、テキストボックスには、数字の下限値と上限値が設けられており、それに満たない数字が入力された場合、登録ボタンを押したときに、メッセージでそのテキストボックス名称を表示させるようにしようとしたいです。 また、値の下限値、コントロール名称、値の上限値は、workwheet1 のA列、B列、C列にそれぞれ入力されています。 下記プロシージャで異常な値のテキストボックスだけを、メッセージに表示させようと狙っていましたが、いつも、worksheet1の最下行のコントロールだけが、異常ですというメッセージが出てしまいます。 記述をどのように修正すれば、また、もっといい記述があれば、なども併せてアドバイスいただけないでしょうか。よろしくお願いします。 Private Sub CommandButton1_Click() Dim myctl As Object Dim endrow As Long Dim i As Long Dim myMSG As String endrow = Worksheets(1).Range("A" & Rows.Count).End(xlUp).Row For Each myctl In Controls For i = 2 To endrow If InStr(1, myctl.Name, Range("B" & i).Text) < Range("A" & i) Or InStr(1, myctl.Name, Range("B" & i).Text) > Range("C" & i) Then myMSG = Range("B" & i).Text & vbCrLf End If Next Next MsgBox myMSG & vbCrLf & "が異常です。" End Sub

  • VBAの操作

    ↓の事を行いていのでうまくいきません。 アドバイスをお願いできませんか? 変更前(Sheet1); (A列) (B列) 1 ABC010 Data_010 2 ABC020 (同上) 'B1-B2は結合セル 3 ABC030 Data_020 4 ABC040 (同上) 'B3-B4は結合セル . . 変更後(Sheet2); (A列) (B列) 1 ABC010 "OK" 2 ABC020 "OK" 3 Data_010 "Comp" '追加行 4 ABC030 "OK" 5 ABC040 "OK" 6 Data_020 "Comp" '追加行 . . Sheet1(B列)に値があれば、 Sheet2(A列)に結合セルの単位で値をコピーする。 Sheet2(B列)には"OK"コメント その都度、必ず最後に行追加して結合セルの値、"Comp"コメントをコピーする. 現象は毎行、追加行が挿入されてしまいます。 Sub testVBA() Dim i Worksheets("Sheet1").Range("A:B").Copy With Worksheets("Sheet2") .Range("A1").PasteSpecial For i = 1 To 1000 If .Cells(i, 2) <> "" Then .Cells(i + 1, 1) = .Cells(i, 2) .Cells(i + 1, 2) = "Comp"   .Cells(i, 2) = "OK" End If Next i End With End Sub

  • VBAのコードについて

    VBA初心者でございます。 以下のコードの後半(End If以降)でエラーがでてしまいます。 非常に乱暴な質問で大変恐れ入りますが、コードで気になる点などございますでしょうか? もしございましたら、ご教示頂けますと幸いです。 どうぞ宜しくお願いいたします。 Sub 絞り込み() Dim i As Long Dim grp As String Dim newBookName As String Dim newBookPath As String Dim newBook As Workbook For i = 2 To 4 grp = Workbooks("test_master").Worksheets("grpリスト").Cells(i, 2) newBookName = Workbooks("test_master").Worksheets("grpリスト").Cells(i, 2) & ".xlsx" newBookPath = ThisWorkbook.Path & "\" & newBookName '指定したパスにファイルが作成済でないかを確認。 If Dir(newBookPath) = "" Then '新しいファイルを作成 Set newBook = Workbooks.Add '新しいファイルをVBAを実行したファイルと同じフォルダ保存 newBook.SaveAs newBookPath Else '既に同名のファイルが存在する場合はメッセージを表示 MsgBox "既に" & newBookName & "というファイルは存在します。" End If Workbooks("test_master").Worksheets("マスタ0701").AutoFilterMode = False With Workbooks("test_master").Worksheets("マスタ0701").Range(Cells(3, "B"), Cells(Rows.Count, "CK").End(xlUp)) .AutoFilter Field:=13, Criteria1:=grp '.CurrentRegion.Select Range(Cells(3, "B"), Cells(Rows.Count, "CK").End(xlUp)).SpecialCells(xlVisible).copy Workbooks(grp).Worksheets("Sheet1").Range("A1") '.AutoFilter End With Next i End Sub

  • EXCEL2010エラーVBA

    下記を実行するとエラーになりEXCEL2010が終了してしまいます。 fDebug:0 offset00009391 がエラーメッセージです。 何が原因でしょうか。 Private Sub Worksheet_Change(ByVal Target As Range) Dim ws As Worksheet Dim rg As Range Dim r As Variant Dim c As Long Dim hanni1 As Range Dim atai As Range Set ws = Worksheets("あああ") Set rg = Worksheets("コード").Range("A1:B10") r = ws.Cells(Rows.Count, 1).End(xlUp).Row Set hanni1 = ws.Range(Cells(2, 2), Cells(r, 3)) Set atai = ws.Range(Cells(2, 3), Cells(r, 3)) atai = Application.VLookup(hanni1, rg, 2, False) End Sub

  • ExcelにおけるVBAで、データの振り分けをしたい

    Sub a() Dim i As Long Dim s As Long Dim b As Worksheet Dim c As Worksheet Dim maxi As Long Dim maxs As Long Application.ScreenUpdating = False With ThisWorkbook Set b = .Worksheets("bbb") Set c = .Worksheets("ccc") End With maxi = b.Range("A1").CurrentRegion.Rows.Count maxs = c.Range("A1").CurrentRegion.Rows.Count For i = maxi To 2 Step -1 For s = maxs To 2 Step -1 If c.Cells(s, 1) = b.Cells(i, 1) And c.Cells(s, 2) = b.Cells(i, 2) Then c.Cells(s, 14) = b.Cells(i, 3) End If Next s Next i Application.ScreenUpdating = True End Sub ワークシートcとワークシートbの1列目と2列目が一致したときにだけ、cの14列目にbの3列目のデータを代入したく思い、以上のようなコードを書きましたが、重くて終わる様子がありません。 ・そもそもあっているのか、あっていないならどこを修正すればよいか ・早く終わるようにするにはどうしたらいいか アドバイスをよろしくお願いします。

専門家に質問してみよう