質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Windows 11

Windows 11は、Windows 10の後継バージョン。それまでのMetroデザインを廃止し、Fluentデザインを導入しています。スタートメニューの構成やウィンドウのデザインの変更の他、Androidアプリをネイティブに実行できます。

Q&A

解決済

1回答

727閲覧

フルパスが300文字程度のフォルダの中をVBAでアクセスしたい

sugoidaizu

総合スコア5

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Windows 11

Windows 11は、Windows 10の後継バージョン。それまでのMetroデザインを廃止し、Fluentデザインを導入しています。スタートメニューの構成やウィンドウのデザインの変更の他、Androidアプリをネイティブに実行できます。

0グッド

0クリップ

投稿2024/03/11 08:30

編集2024/03/11 08:41

実現したいこと

Windowsのフルパスの制限が2百数十文字であることはネットで見かけていますが、その制限を超えた長いフルパスについても、excel-VBAで、フォルダのツリー構造を再帰的に辿って、中のファイルを削除したり、個数をカウントしたり、したい。

発生している問題・分からないこと

上の目的のため、フォルダのツリー構造を再帰的に辿ってみたところ、フォルダやファイルのフルパスが、2百何十文字かを超えると、不具合がありました。

具体的には、
(a)folder_.subfolders.Count だと、フォルダ数が取得できたけど、
(b)For Each subfolder_ In folder_.subfolders だと、見つからないフォルダがあった。
つまり、(b)だと、フルパスが長すぎるフォルダが見つかりません。

フルパスが300文字を超える場合でも、VBAで、再帰的に全てのサブフォルダをたどりたいです。
どのようなコードを書けば可能でしょうか?

※紛らわしくてすみません。再帰的プログラムの質問でなく、フルパス300文字のファルダやファイルをVBAでアクセスる方法の質問でした。
taratail投稿用にプログラムを改変した際に、再帰的プログラムではなくなりましたが、再帰的かどうかは質問の趣旨ではありません。

該当のソースコード

Sub 調査() Set fso = CreateObject("Scripting.FileSystemObject") Set folder_ = fso.getfolder("{省略}") ' {省略}部分は、フォルダのパス、300文字くらい cnt1 = folder_.subfolders.Count cnt2 = 0 For Each subfolder_ In folder_.subfolders cnt2 = cnt2 + 1 Next Debug.Print cnt1, cnt2 End Sub ’ 結果→「 1 0 」

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

解決案が見つかっていません。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

案1:その制限を無くしておく
ググればやり方がヒットすると思いますが、レジストリの修正もしくはグループポリシーエディターで設定。
⇒ これが正道。

案2: 途中にドライブレターを付けておく
D:\aaa\bbb\ccc\中略\yyy\zzz\file.txtが長すぎるとして、
subst Z: D:\aaa\bbb\ccc\中略\yyyをあらかじめコマンドプロンプトやPowerShellで実行しておくと、その場所がZドライブのルートになるので、Z:\zzz\file.txtでアクセス出来るはず。
空いているドライブレターは人により違うかも知れないので、「部内どのPCでも実行できる」ためには部内でドライブレター割り当てのルールが要りそうですね。

また、設定するディレクトリ自体が長すぎるともしかすると出来ないので、途中フォルダーをどこまでsubstしてどこからファイルと一緒に指定するかは工夫要かも。

案3:事前準備無しでやるには、Chdir で下に降りていって、そこからの相対パスで指定する。
上記例だと、VBAスクリプトの中で、ChDir "D:\aaa\bbb\ccc\中略\yyy" : ChDrive "D" すると、zzz\file.txtでアクセスできるはず。これもどこまで指定するかは工夫要かも。
また、カレントディレクトリーを移動してしまうと、全てのファイル指定に影響するので、ファイルやフォルダーを扱っている部分を全部チェック要。

300文字程度あればたぶんどれでもいいはず。
ただし、案2相当はやったことありますが、案3は多分やったこと無いので「多分出来る」くらいでお願いします。

案2の変形として、あらかじめsubstコマンドを実行しておくのでなく、VBAスクリプトの中で
・空いているドライブレターを探す
・そのドライブレターに対してsubstコマンドを実行する
・後でドライブレターを削除しておく
ということにすれば、組織内のどのPCでも実行できるようにするのも可能です。それぞれのやり方が分からない場合はググれば情報があると思います。

投稿2024/03/11 08:55

編集2024/03/11 09:41
otn

総合スコア84566

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2024/03/11 09:05 編集

一般論的に書きましたが、 再帰処理しているなら、再帰の都度、そのターゲットに Chdir して、再帰からリターンしたら、`ChDir ".."`するのが良いかもしれません。
sugoidaizu

2024/03/11 09:21

大変、ありがとうございます。 後日になりますが、先ずは、「案1:その制限を無くしておく⇒ これが正道」を試してみます。
otn

2024/03/11 09:40 編集

実行するのが自分の自由になるPCだけでとか、組織内で実行する可能性のあるPCを全部そのように変更できるなら、それが一番ですね。
sugoidaizu

2024/03/12 00:44 編集

色々とありがとうございます。「案1」を試した結果は残念変わらず、下の理由かも知れません。次は「案3」を試します。助かります。 https://answers.microsoft.com/ja-jp/msoffice/forum/all/microsoft-excel/b5105bf0-2886-41e9-bcff-dce4757d7df3 >Office アプリ自体が取り扱えるパス長の制限を持っているので、Windows 側で MAX_PATH の制限を緩和しても Office で長いパスを扱えるようになるわけでは無いようです。
otn

2024/03/12 15:07 編集

レジストリエディターでLongPathsEnabledを有効にして、ExcelVBAで長いパス名を扱ったことはありますが、私がやったのは多分PDFファイルの浅い階層から深い階層へのコピーです。(ファイル名がExcelに入っている) Officeファイルを開くとか、テキストファイルを読み書きとかは、深い階層ではやったことないかも。 お書きのコードだとScripting.FileSystemObject のメソッドの機能なので、Officeの外側の機能の呼び出しですね。何がネックか分からないので、案3も駄目かも知れません。全体書き直す前に短いテストプログラムを実行してみるのが良いと思います。 最後は案2ですね。
sugoidaizu

2024/03/13 06:31 編集

案1:レジストリLongPathsEnabled修正 →For Each subfolder_ In folder_.subfolders にて長いパスの対象が(エラーなく)スキップされたので、利用見送りました。  folder_.subfolders.Count と、ループの数が不一致でした。 案2:途中にドライブレターを付けておく →テストプログラムでは成功したので、この方法を目的のマクロに適応しようと考えています。 Shell "subst M: /d" Shell "subst M: """ & 長いpath_ & """" Set folder_ = fso.getfolder("M:\") cnt1 = folder_.subfolders.Count cnt2 = 0 For Each subfolder_ In folder_.subfolders cnt2 = cnt2 + 1 Next Debug.Print cnt1, cnt2 案3:Chdir で下に降りていって、そこからの相対パスで指定する。 →ChDir は、(稀に存在する)中国語のフォルダ名がエラーになったため、利用見送りました。 以上、ご丁寧に、大変、ありがとうございました。
otn

2024/03/13 13:29

> →ChDir は、(稀に存在する)中国語のフォルダ名がエラーになったため、利用見送りました。 どうも、VBAは、UTF-8のファイル名に対応していないみたいですね。SJIS専用か。OSのロケールを中国語に切り替えれば出来そうな気がしますが、そうすると日本語が駄目。 ググってもノイズばかりで情報が見つかりませんが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問