[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『フォルダパスをツリー化表示させる方法がわかりません』(たか)
オンラインストレージのフォルダパスをツリー化して管理したいです。
オンラインストレージのフォルダパスは以下の形式(Excel)で抽出したのですが、ツリー化が出来なくて困っています。
やり方がわかる方がいらっしゃいましたらご教示ください。
オンラインストレージのフォルダパス
A/a/01/TEST1
A/a/01/TEST2
A/a/01/TEST3
A/a/02/TEST1
A/a/02/TEST2
Excelで表示させたいツリー構造
A━a┳01┰TEST1
┃ ┣TEST2
┃ ┗TEST3
┃
┗02┰TEST1
┗TEST2
なお、ExcelのSmartArtより階層構造を試しましたが、上記パスをコピペする全てのパスが選択されてしまいツリー構造になりませんでした。
< 使用 Excel:Microsoft365、使用 OS:Windows10 >
以前、xyzさんに教えていただきました。 https://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_080.html (マナ) 2023/09/28(木) 16:57:13
当方、VBAに疎いですがリンク先を参照させていただきました。
その中で質問ですが、今回のケースではオンラインストレージ上のファイル一覧の取得は行わず、
手元にあるExcelのデータ(フォルダパス)をツリー構造に変更することが目的となります。
ご共有いただいた内容は、上記目的と合致しているという理解で合っておりますでしょうか。
(たか) 2023/09/28(木) 17:20:36
失礼しました。そういう使い方はできません。 (マナ) 2023/09/28(木) 17:52:22
SmartArtの階層構造でいいなら、一度ピボットでデータを整理してからやったらどうでしょう?
データタブの区切り位置機能を使って/でセルごとに分け、タイトル行を追加する。
例) A B C D 1 第1階層 第2階層 第3階層 第4階層 2 A a 01 TEST1 3 A a 01 TEST2 4 A a 01 TEST3 5 A a 02 TEST1 6 A a 02 TEST2
ピボットを作る。タイトル行込みで全データを選択し、挿入タブからピボットテーブルを選択。 全データを「行」の位置に入れる。 ピボットの表内のセルをどこでもいいので選択。タブにデザインと言うのが出るので、そこを開く。 以下を設定 小計:小計を表示しない 総計:行と列の集計を行わない レポートのレイアウト:アウトライン形式で表示
あとは以下のURLのやり方参照で出来るかと思います。 https://extan.jp/?p=9697
(Q田) 2023/09/29(金) 14:22:28
こんにちは。
> その中で質問ですが、今回のケースではオンラインストレージ上のファイル一覧の取得は行わず、 > 手元にあるExcelのデータ(フォルダパス)をツリー構造に変更することが目的となります。 ご紹介のありました井上さんのサイトを探せば、フォルダ一覧をツリー表示できるものがあると思います。 抽出も含めて対応できる既存の"枯れた"(つまり、多くの方の使用に耐えた)ツールがあるのですから、 こうしたものを援用したほうがよいと思います。
さはさりながら、お題の、テキストデータを元にして、ツリーを表示するものを参考までに示します。
Windows標準のTreeコマンドと同様の出力形式によるものを作成してみました。 (こちらが一般的な形式だと思います。) 提示された形式とやや違いますが、参考にしてください。
ちゃちゃっと作れる感じはしません。少なくとも面倒なものではあるでしょう。 修正事項があるとしても、明らかなバグ対応以外は時間を費やす積りはありませんので、 予め申し上げておきます。
<<データと作成例>>
A列(元データ) C列(結果)
A/a/01/TEST1 A
A/a/01/TEST2 ┣ a
A/a/01/TEST3 ┃ ┣ 01
A/a/02/TEST1 ┃ ┃ ┣ TEST1
A/a/02/TEST2 ┃ ┃ ┣ TEST2
A/b/01/TEST1 ┃ ┃ ┗ TEST3
A/b/01/TEST2 ┃ ┗ 02
A/b/01/TEST3 ┃ ┣ TEST1
A/b/02/TEST1 ┃ ┗ TEST2
A/b/02/TEST2 ┣ b
A/c/01/TEST1 ┃ ┣ 01
B/a/01/test ┃ ┃ ┣ TEST1
B/b/01/test ┃ ┃ ┣ TEST2
┃ ┃ ┗ TEST3
┃ ┗ 02
┃ ┣ TEST1
┃ ┗ TEST2
┗ c
┗ 01
┗ TEST1
B
┣ a
┃ ┗ 01
┃ ┗ test
┗ b
┗ 01
┗ test
<<参考コード>> Option Explicit
Const letter1$ = "┣ " Const letter2$ = "┗ " Const letterC$ = "┃ " Const letterD$ = " "
Dim foldrs As Object Dim subfolders As Object
Dim line_continuous(1 To 10) As Boolean '接続線を書くか否か。なお、階層は上限10とした。(適宜修正のこと) Dim pos As Long '結果の書き込み位置
Sub main()
Set foldrs = CreateObject("Scripting.Dictionary")
Set subfolders = CreateObject("Scripting.Dictionary")
Call set_foldrs 'foldrs: すべてのフォルダをkeyとする辞書(itemはEmpty)を作成
Call set_subfolders '辞書 subfolders を作成
'key : 各folder
'item: その直下のサブフォルダからなる辞書
Columns("C").ClearContents '書き出す列(C)を初期化
pos = 0 '結果の書き出し行の初期化
Dim root As Variant
Dim roots As Object
Set roots = get_roots '最上位のフォルダを得る
'Tree図をC列に書き出す
For Each root In roots
pos = pos + 1: Cells(pos, "C") = root
Call recursion(root, 1)
Next
End Sub
Function set_foldrs()
Dim s$, ary, t$
Dim k&, j&
For k = 1 To Cells(Rows.Count, "A").End(xlUp).Row
s = Cells(k, "A")
ary = Split(s, "/")
For j = 0 To UBound(ary)
If j = 0 Then t = ary(j) Else t = t & "/" & ary(j)
foldrs(t) = Empty
Next
Next
End Function
Function set_subfolders()
Dim re As Object
Dim dic As Object
Dim fldr, fldr2
Dim k&
Set re = CreateObject("VBScript.RegExp")
For Each fldr In foldrs
re.Pattern = "^" & fldr & "\/" & "[^/]+$"
For Each fldr2 In foldrs
If re.test(fldr2) Then
If dic Is Nothing Then
Set dic = CreateObject("Scripting.Dictionary")
End If
dic(fldr2) = Empty
End If
Next
Set subfolders(fldr) = dic
Set dic = Nothing
Next
End Function
Function get_roots() As Object
Dim dic As Object
Dim k&, s$
Set dic = CreateObject("Scripting.Dictionary")
For k = 1 To Cells(Rows.Count, "A").End(xlUp).Row
s = Cells(k, "A")
dic(Split(s, "/")(0)) = Empty
Next
Set get_roots = dic
End Function
Function recursion(folder As Variant, depth As Long)
Dim a As Object
Dim c2&
Dim i&, k&
Dim elem
Dim elem2
Dim ary
Dim s$
If Not subfolders(folder) Is Nothing Then
Set a = subfolders(folder)
c2 = a.Count
line_continuous(depth) = True
i = 0
For Each elem In a.keys
ary = Split(elem, "/")
elem2 = ary(UBound(ary))
i = i + 1
s = "" '接続線
For k = 1 To depth - 1
If line_continuous(k) = True Then
s = s & letterC ' "┃ "
Else
s = s & letterD ' " "
End If
Next
If i = c2 Then
pos = pos + 1: Cells(pos, "C") = s & letter2 & elem2
Else
pos = pos + 1: Cells(pos, "C") = s & letter1 & elem2
End If
'最後のフォルダについては、接続線は不要
If i = c2 Then line_continuous(depth) = False
Call recursion(elem, depth + 1)
Next
End If
End Function
(xyz) 2023/09/29(金) 14:47:26
(マナ) 2023/09/28(木) 16:57:13
https://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_080.html
ページ下部にこうあります
Copyright(C) 2003,2023 井上 治,All Rights Reserved.
(ねじねじ) 2023/09/29(金) 15:46:59
●一番手っ取り早いのは、
コマンドプロンプトで Treeコマンド を使うことです。
具体的には、
Tree 対象とするルートフォルダのパス
とすれば、その配下のフォルダのTree図が表示されます。
●また、
Tree 対象とするルートフォルダのパス > tree図.txt
などと、テキストファイルにリダイレクトすれば、
テキストファイルに結果を書き込めます。
http://office-qa.com/win/win186.htm を参照。(何か結果図がおかしい気もします。)
# ちなみに、提示したコードは、 # 以前に同種の質問があった際の私の回答をもとに、今回新たに作成したものです。 # 今後、同様の質問があった場合に、閲覧されている方に活かしていただければと思います。 (xyz) 2023/09/29(金) 22:48:26
> Tree 対象とするルートフォルダのパス > tree図.txt > などと、テキストファイルにリダイレクトすれば、 > テキストファイルに結果を書き込めます。
マクロにしてみました。 念のため、空フォルダに、マクロブックを保存してください。 A列に、パスが列挙されている前提です。
Sub test()
Dim r As Range, e
Dim p As String, bat As String
Set r = Range("a1", Cells(Rows.Count, 1).End(xlUp))
p = ThisWorkbook.Path & "\"
bat = p & "tree.bat"
Open bat For Output As #1
For Each e In r.Value
Print #1, "md ""tmp\" & Replace(e, "/", "\") & """"
Next
Print #1, "tree tmp > """ & p & "tree図.txt"""
Print #1, "rd /s/q tmp"
Close #1
CreateObject("wscript.shell").Run """" & bat & """", 0, True
Kill bat
End Sub (マナ) 2023/10/02(月) 08:52:02
興味があったので作ってみました 参考出品 イミディエイトウインドウに書き出しますがごそこは勘弁ください
'-------- 標準モジュール ----------------------
Sub sample()
Dim tree As clsTree, aCell As Range
Set tree = New clsTree
tree.Delimiter = "/"
For Each aCell In Range("A2", Cells(Rows.Count, "A").End(xlUp))
tree.AddTree aCell.Value
Next
tree.PrintTree
End Sub
'-------- クラスモジュール clsTree ------------
Public Name As String
Public SubTrees As Collection
Public Items As Collection
Public Delimiter As String
Private Sub Class_Initialize()
Set SubTrees = New Collection
Set Items = New Collection
Name = "Root"
Delimiter = "\"
End Sub
Public Sub AddTree(newName As String)
Dim path() As String, tree As clsTree
path = Split(newName, Delimiter)
Set tree = Me
If UBound(path) = 0 Then
tree.Items.Add path(0), path(0)
Else
On Error GoTo AddNew
Set tree = SubTrees(path(0))
On Error GoTo 0
tree.AddTree Mid(newName, Len(path(0)) + 2)
End If
Exit Sub
AddNew:
tree.SubTrees.Add New clsTree, path(0)
tree.SubTrees(path(0)).Name = path(0)
tree.SubTrees(path(0)).Delimiter = Delimiter
Resume
End Sub
Public Sub PrintTree(Optional ByVal pre As String = "")
Dim tree As clsTree
Dim i As Long, nSubTree As Long, nItem As Long
nSubTree = SubTrees.Count: nItem = Items.Count
For i = 1 To nSubTree
Debug.Print pre & IIf(i = nSubTree And nItem = 0, "┗■", "┣■") & SubTrees(i).Name
SubTrees(i).PrintTree pre & IIf(i = nSubTree And nItem = 0, " ", "┃")
Next
For i = 1 To nItem
Debug.Print pre & IIf(i = nItem, "┗□", "┣□") & Items(i)
Next
End Sub
xyzさん 2023/09/29(金) 14:47:26 のサンプルデータで実行するとこうなります ┣■A ┃┣■a ┃┃┣■01 ┃┃┃┣□TEST1 ┃┃┃┣□TEST2 ┃┃┃┗□TEST3 ┃┃┗■02 ┃┃ ┣□TEST1 ┃┃ ┗□TEST2 ┃┣■b ┃┃┣■01 ┃┃┃┣□TEST1 ┃┃┃┣□TEST2 ┃┃┃┗□TEST3 ┃┃┗■02 ┃┃ ┣□TEST1 ┃┃ ┗□TEST2 ┃┗■c ┃ ┗■01 ┃ ┗□TEST1 ┗■B ┣■a ┃┗■01 ┃ ┗□test ┗■b ┗■01 ┗□test (´・ω・`) 2023/10/02(月) 12:14:01
もう一点質問となります。
初歩的な質問で恐縮ですが、batファイルを生成しない/叩かないで変換する方法はあるのでしょうか?
可能であれば、マクロが有効となったExcel上で動作が完結できればなと思っております。
Sub test()
Dim r As Range, e
Dim p As String, bat As String
Set r = Range("a1", Cells(Rows.Count, 1).End(xlUp))
p = ThisWorkbook.Path & "\"
bat = p & "tree.bat"
Open bat For Output As #1
For Each e In r.Value
Print #1, "md ""tmp\" & Replace(e, "/", "\") & """"
Next
Print #1, "tree tmp > """ & p & "tree図.txt"""
Print #1, "rd /s/q tmp"
Close #1
CreateObject("wscript.shell").Run """" & bat & """", 0, True
Kill bat
End Sub
(マナ) 2023/10/02(月) 08:52:02
(たか) 2023/10/12(木) 11:54:14
> batファイルを生成しない/叩かないで変換する方法はあるのでしょうか?
xyzさん、(´・ω・`)さんから提示されていますが… (マナ) 2023/10/12(木) 18:14:43
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.