プロが教える店舗&オフィスのセキュリティ対策術

VBAで親フォルダから最終ファイルまでの一覧を自動で出力するコードを組みたいです。
今は下のコードを使用しており、少ないフォルダ数であれば問題なく出力してくれるのですが、
何万ものファイルが入っているフォルダを指定し出力しようとするとネットワークエラーと出て固まるor途中までしか出力されません。
エラーにならない方法などはありますでしょうか。
また、より簡潔な別のコードがなどがあれば教えて頂きたいです!

Public ParentFolder As String
Public fpl As Object
Public buf As String
Public l As Folder
Public e As File
Public fso As FileSystemObject
Public pathbuf(20) As String
Public i As Long
Public level As Long
Public num As Long

Sub getfilename()
Dim n As Date
n = Now
Cells(3, 4) = n

ParentFolder = Range("B3").Value
Set fso = New FileSystemObject
Dim s As Folder
level = 0
num = 7
Cells(num, level + 2) = ParentFolder
Set fl = fso.GetFolder(ParentFolder)
Call getsubfolder(fl)

Set fso = Nothing
End Sub

Function getsubfolder(fp) As Object
Dim folderName As String
folderName = fp.Name ' フォルダ名を取得

For Each l In fp.SubFolders
level = level + 1
Debug.Print (l.Name)
Cells(num, level + 2) = l.Name
pathbuf(level) = l.Name
Set fpl = fso.GetFolder(fp + "\" + l.Name)
Call getsubfolder(fpl)
Next

Dim finalFile As String
finalFile = ""

For Each e In fpl.Files
Debug.Print (e.Name)
finalFile = e.Name
num = num + 1

' 該当するフォルダ名をセル全体に出力
For i = 7 To num - 1
Cells(i, 6).Value = folderName
Next i

' 最終ファイルに該当するフォルダ名をセル全体に出力
Cells(num, 6).Value = folderName
num = num + 1 ' 空行を挿入
Next

i = Len(pathbuf(level))
fps = Left(CStr(fp), Len(fp) - i)
level = level - 1
Set fpl = fso.GetFolder(fps)
End Function

Sub test()
Rows("7:" & Cells.Rows.Count).Delete
End Sub

よろしくお願いします。

質問者からの補足コメント

  • ご回答ありがとうございます。
    言葉足らずで申し訳ございません。

    最終的にはエクセル内でファイル名を検索したいので、最終ファイルを6列目に出力させています。
    (VBAの知識がないのでコードの作成にはAIを使用しました。)

    >少ないフォルダ数であれば問題なく出力してくれるのですが、
    「フォルダ名のみのリスト作成」ということでしょうか?
    ファイル名も取得しているもののシートには出力していないようなので、どちらにしろ意味不明になっています。

    >>親フォルダから最終ファイル(ExcelやWordなどの作業ファイル)までをツリー構造で出してくれるコードを組みたいです。
    ファイル名に関しては、現状のコードで6列目に出力されています。

    (以下補足になりますが、
    ファイル名の出力に関して、現在は6列目に指定していますが、同じ列に最終ファイルが出力されるのであればどの列でもいいです。)

    No.1の回答に寄せられた補足コメントです。 補足日時:2023/06/21 08:21
  • >何万ものファイルが入っているフォルダを指定し出力しようとすると
    >ネットワークエラーと出て固まるor途中までしか出力されません。
    数が少ない場合には、ご希望の結果ということでしょうか?
    もしもそうなら、不必要な処理が多すぎる気がしますけれど。

    >>数千程のファイルであれば希望通りに出力されますが、何万…となってくると固まってしまいます。。。
    不必要な処理を省いたものを教えていただくことは可能でしょうか?

    その他3点のご回答、リンクのご提示もありがとうございます。確認します。
    補足で意図は伝わりましたでしょうか?
    お手数お掛けしますがご検討よろしくお願いいたします。

      補足日時:2023/06/21 08:27

A 回答 (2件)

>ツリー構造で出してくれるコードを組みたい


コマンドプロンプトに、tree コマンドっていうのがあるのですが、これを Shellで実行して、標準出力を取得するだけで、ほぼほぼ、出来ちゃうような気がします。
詳細は、AIに聞いてください。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
treeコマンドについて調べてみます。
ご協力ありがとうございました!

お礼日時:2023/06/28 07:38

こんばんは



回答がつかないようですので・・・

>少ないフォルダ数であれば問題なく出力してくれるのですが、
「フォルダ名のみのリスト作成」ということでしょうか?
それにしては意味不明な処理が多いし、ファイル名も取得しているもののシートには出力していないようなので、どちらにしろ意味不明になっています。

>何万ものファイルが入っているフォルダを指定し出力しようとすると
>ネットワークエラーと出て固まるor途中までしか出力されません。
数が少ない場合には、ご希望の結果ということでしょうか?
もしもそうなら、不必要な処理が多すぎる気がしますけれど。

数が多くてエラーになる可能性があるのは、
 1)ネストが深くて、配列がオーバーフロー
 2)シート範囲に収まらない数のファイル数でオーバーフロー
 3)ネストによるメモリ不足
などですが、1)以外は現実的にはあまり発生しそうにないですね。
(ファイル数が超膨大であれば、2)の可能性はありますが)

1)は、pathbuf(20)と宣言しているので、これを超えるサブフォルダの階層があればオーバーフローするでしょうということです。
一方で、ファイル名(?:実際には、出力していないので不明)の表示列を6列目に固定しているようなので、階層が4を超えれば、シートの表示の方が干渉して何だか分からなくなります。
とは言え、ご提示のコードでは6列目に何度も上書きしているので、そもそも何をなさりたいのかよくわからないですけれど。

どのような出力を予定しているのか不明ですが、通常のツリー構造で表示するなら、同じ階層のフォルダーとファイルは同列に表示するのが一般的なような気がします。
(混在するので区別にくいというのなら、フォルダ名は黒、ファイル名は青などとしておけば視認性は良くなると思います。)
ファイル名を全て同じ列に揃えたいのなら、階層構造に影響されない最初の列に記入するとか。
どうしても最終列にしたければ、処理の最後に一番深い階層の次の列に列全体を移動するなどでしょうか。
(処理前には階層の深さがわかりませんので)

2)はファイル数が多くてシートの行数が不足する場合ですが、余程のことがない限り発生しないと想像しますし、仮に発生したとしてもシートを見れば一目瞭然でしょう。

3)はメモリがもともと不足していて、再帰のスタックによってオーバーフローするケースですが、スタックの量がさほどとも思えないので、これが原因でオーバーフローが起きるようなら、通常使用の状態でも非常に重かったり、落ちたりが発生する状態だと想像します。

ですので、2)、3)はほぼ発生することはないのではと推測します。


>より簡潔な別のコードがなどがあれば教えて頂きたいです
『VBA ファイル一覧 再帰』あたりで検索すれば、いくらでもサンプルが見つかると思います。
出力部分をお好みの形式になるようにすれば、ほぼそのまま利用できるものが多いと思います。

処理の構造がわかりやすいのは、以下あたりでしょうか。
https://vba-labo.rs-techdev.com/archives/30
※ 上記はシートへの入・出力はしていないようなので、その部分は追加・変更する必要がありますが。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!