#author("2025-11-14T16:55:20+09:00","","")
#author("2025-11-14T17:01:05+09:00","","")
[[ソフトウェア開発>SoftwareEngineering]] / [[PowerShell>PowerShell]] / [[FolderStructureCreator>./]]

*FolderStructureCreator [#c00488d5]
#highlightjs([powershell])
 # ----------------------------------------------------------
 # インポート
 # ----------------------------------------------------------
 Add-Type -AssemblyName System.Drawing
 Add-Type -AssemblyName System.Windows.Forms
 
 
 . "${PSScriptRoot}\ExcelHelper.ps1"
 
 
 
 # ----------------------------------------------------------
 # 定数定義
 # ----------------------------------------------------------
 $EXCEL_BACKGROUND_COLOR_FIX_ROW = [Convert]::ToInt32("D9D9D9", 16)
 $EXCEL_BACKGROUND_COLOR_FOLDER  = [Convert]::ToInt32("CCFFFF", 16)
 
 $EXCEL_COLUMN_SPAN = 5
 
 
 
 # ----------------------------------------------------------
 # グローバル変数定義
 # ----------------------------------------------------------
 $entries = New-Object System.Collections.ArrayList
 
 
 
 # ----------------------------------------------------------
 # メイン画面
 # ----------------------------------------------------------
 $form = New-Object System.Windows.Forms.Form
 $form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
 $form.MaximizeBox = $false
 $form.StartPosition = 'CenterScreen'
 
 $form.Text = "フォルダー構成"
 $form.Width  = 640
 $form.Height = 120
 
 
 # ----------------------------------------------------------
 # 
 # ----------------------------------------------------------
 $bottomTableLayoutPanel = New-Object System.Windows.Forms.TableLayoutPanel
 $bottomTableLayoutPanel.Dock = [System.Windows.Forms.DockStyle]::Bottom
 $bottomTableLayoutPanel.Height = 50
 
 $bottomTableLayoutPanel.RowCount    = 1
 $bottomTableLayoutPanel.ColumnCount = 2
 
 $bottomTableLayoutPanel.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Percent, 100))) | Out-Null
 $bottomTableLayoutPanel.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::AutoSize))) | Out-Null
 
 $form.Controls.Add($bottomTableLayoutPanel)
 
 
 
 # ----------------------------------------------------------
 # 実行ボタン
 # ----------------------------------------------------------
 $executeButton = New-Object System.Windows.Forms.Button
 $executeButton.Width  = 80
 $executeButton.Height = 30
 $executeButton.Text   = '実行'
 
 $executeButton.Anchor = [System.Windows.Forms.AnchorStyles]::None
 $executeButton.Margin = New-Object System.Windows.Forms.Padding(10, 0, 10, 0)
 
 $bottomTableLayoutPanel.Controls.Add($executeButton, 1, 0)
 
 
 
 # ----------------------------------------------------------
 # 
 # ----------------------------------------------------------
 $fillTableLayoutPanel = New-Object System.Windows.Forms.TableLayoutPanel
 $fillTableLayoutPanel.Dock = [System.Windows.Forms.DockStyle]::Fill
 $fillTableLayoutPanel.Height = 50
 
 $fillTableLayoutPanel.RowCount    = 2
 $fillTableLayoutPanel.ColumnCount = 2
 
 $fillTableLayoutPanel.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Percent, 15))) | Out-Null
 $fillTableLayoutPanel.ColumnStyles.Add((New-Object System.Windows.Forms.ColumnStyle([System.Windows.Forms.SizeType]::Percent, 85))) | Out-Null
 
 $form.Controls.Add($fillTableLayoutPanel)
 
 
 
 # ----------------------------------------------------------
 # 
 # ----------------------------------------------------------
 $targetLabel = New-Object System.Windows.Forms.Label
 $targetLabel.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
 $targetLabel.Margin = New-Object System.Windows.Forms.Padding(5, 5, 5, 5)
 $targetLabel.AutoSize = $true
 $targetLabel.Text = 'パス'
 
 $fillTableLayoutPanel.Controls.Add($targetLabel, 0, 0)
 
 
 $targetTextBox = New-Object System.Windows.Forms.TextBox
 $targetTextBox.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
 $targetTextBox.Margin = New-Object System.Windows.Forms.Padding(5, 5, 5, 5)
 $targetTextBox.Width  = 515
 $targetTextBox.Text = ''
 $targetTextBox.AllowDrop = $true
 
 $fillTableLayoutPanel.Controls.Add($targetTextBox, 1, 0)
 
 
 $targetTextBox.Add_DragDrop({
     foreach ($filename in $_.Data.GetData([System.Windows.Forms.DataFormats]::FileDrop)) {
         $targetTextBox.Text = $filename
         break
     }
 })
 $targetTextBox.Add_DragOver({
     foreach ($filename in $_.Data.GetData([System.Windows.Forms.DataFormats]::FileDrop)) {
         $_.Effect = [System.Windows.Forms.DragDropEffects]::All
     }
 })
 
 
 
 # ----------------------------------------------------------
 # 
 # ----------------------------------------------------------
 $executeButton.Add_Click({
     Create-FolderStructure -RootFolderPath $targetTextBox.Text
 
     $form.TopMost = $true
     [System.Windows.Forms.MessageBox]::Show($form, 'たいへんよくできました', '通知', 'OK', 'Information')
     $form.TopMost = $false
 })
 
 
 
 # ----------------------------------------------------------
 # Excel にフォルダー構成を出力します。
 # ----------------------------------------------------------
 function Write-ExcelFolderStructure {
     $worksheet = Get-ExcelFirstWorksheet $workbook
     $worksheet.Name = 'フォルダー構成'
     $worksheet.Cells.ColumnWidth = 2
 
     $excel.ActiveWindow.DisplayGridlines = $false
 
     $maxIndentLevel = ($entries | ForEach-Object {$_.IndentLevel} | Measure-Object -Maximum).Maximum
     $endsColumnIndex = ($maxIndentLevel * $EXCEL_COLUMN_SPAN) + $EXCEL_COLUMN_SPAN
     $containerColumnIndex = $endsColumnIndex + 1
 
     $startsDetailRowIndex = 2
     $endsDetailRowIndex = $startsDetailRowIndex + $entries.Count - 1
 
 
     # ----------------------------------------------------------
     # ヘッダー
     # ----------------------------------------------------------
     $worksheet.Cells(1, 1).Value = 'ルート'
     $outerBorderRange = $worksheet.Range($worksheet.Cells(1, 1), $worksheet.Cells(1, 1 + $EXCEL_COLUMN_SPAN - 1))
     Draw-ExcelOuterBorder $outerBorderRange
 
     $backGroundColorRange = $worksheet.Range($worksheet.Cells(1, 1), $worksheet.Cells(1, 1 + $EXCEL_COLUMN_SPAN - 1))
     Set-ExcelCellBackgroundColor $backGroundColorRange $EXCEL_BACKGROUND_COLOR_FIX_ROW
 
     for ($indentLevel = $firstIndentLevel; $indentLevel -le $maxIndentLevel; $indentLevel++) {
         $columnIndex = 1 + ($indentLevel * $EXCEL_COLUMN_SPAN)
         $worksheet.Cells(1, $columnIndex).Value = "第 ${indentLevel} 階層"
 
         $outerBorderRange = $worksheet.Range($worksheet.Cells(1, $columnIndex), $worksheet.Cells(1, $columnIndex + $EXCEL_COLUMN_SPAN - 1))
         Draw-ExcelOuterBorder $outerBorderRange
 
         $backGroundColorRange = $worksheet.Range($worksheet.Cells(1, $columnIndex), $worksheet.Cells(1, $columnIndex + $EXCEL_COLUMN_SPAN - 1))
         Set-ExcelCellBackgroundColor $backGroundColorRange $EXCEL_BACKGROUND_COLOR_FIX_ROW
     }
 
 
     # ----------------------------------------------------------
     # 詳細
     # ----------------------------------------------------------
     $rowIndex = $startsDetailRowIndex
     foreach ($entry in $entries) {
         $columnIndex = 1 + ($entry.IndexLevel * $EXCEL_COLUMN_SPAN)
         $columnIndex = 1 + ($entry.IndentLevel * $EXCEL_COLUMN_SPAN)
         $topLeftRange = $worksheet.Cells($rowIndex, $columnIndex)
 
         $topLeftRange.Value = $entry.Name
 
         if ($entry.IsContainer) {
             $bottomRightRange = $worksheet.Cells($rowIndex + $entry.Count, $endsColumnIndex)
             $outerBorderRange = $worksheet.Range($topLeftRange, $bottomRightRange)
             Draw-ExcelOuterBorder $outerBorderRange
 
             $bottomRightRange = $worksheet.Cells($rowIndex + $entry.Count, $columnIndex + $EXCEL_COLUMN_SPAN - 1)
             $backGroundColorRange = $worksheet.Range($topLeftRange, $bottomRightRange)
             Set-ExcelCellBackgroundColor $backGroundColorRange $EXCEL_BACKGROUND_COLOR_FOLDER
 
             $bottomRightRange = $worksheet.Range($topLeftRange, $worksheet.Cells($rowIndex, $endsColumnIndex))
             $backGroundColorRange = $worksheet.Range($topLeftRange, $bottomRightRange)
             Set-ExcelCellBackgroundColor $backGroundColorRange $EXCEL_BACKGROUND_COLOR_FOLDER
         } else {
             $bottomRightRange = $worksheet.Range($topLeftRange, $worksheet.Cells($rowIndex, $endsColumnIndex))
             $outerBorderRange = $worksheet.Range($topLeftRange, $bottomRightRange)
             Draw-ExcelOuterBorder $outerBorderRange
         }
 
         $rowIndex++
     }
 
 
     # ----------------------------------------------------------
     # ウィンドウ枠を固定する
     # ----------------------------------------------------------
     $worksheet.Range('2:2').Select() | Out-Null
     $excel.ActiveWindow.FreezePanes = $true
 
     Release-ExcelComObjectSafely $worksheet
 }
 
 
 
 # ----------------------------------------------------------
 # フォルダー構成を作成するのに必要な情報を収集します。
 # ----------------------------------------------------------
 function Set-FolderStructure {
     param (
          [string]$Path
         ,[int]$indentLevel = 0
     )
 
     $items = Get-ChildItem -Path $Path | Sort-Object @{Expression={$_.PSIsContainer}}, @{Expression={$_.Name}}
 
     foreach ($item in $items) {
         $count = 1
         if ($item.PSIsContainer) {
             $count = Get-ItemCountRecursive $item.FullName
         }
 
         $entry = @{
             IndentLevel   = $indentLevel;
             FullName      = $item.FullName;
             Name          = $item.Name;
             LastWriteTime = $item.LastWriteTime;
             IsContainer   = $item.PSIsContainer;
             Count         = $count
         }
 
         $entries.Add($entry) | Out-Null
 
         if ($item.PSIsContainer) {
             Set-FolderStructure $item.FullName ($indentLevel + 1)
         }
     }
 
 }
 
 
 # ----------------------------------------------------------
 # サブフォルダーを含めたフォルダーとファイルの数を取得します。
 # ----------------------------------------------------------
 function Get-ItemCountRecursive {
     param (
         $Path
     )
 
     return (Get-ChildItem -Path $Path -Recurse).Count
 }
 
 
 # ----------------------------------------------------------
 # フォルダー構造を作成します。
 # ----------------------------------------------------------
 function Create-FolderStructure {
     param (
         $RootFolderPath
     )
 
     $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
 
     $rootFolder = Get-Item -Path $RootFolderPath
 
     $entries.Clear()
     $rootIndentLevel = 0
     $entry = @{
         IndentLevel   = $rootIndentLevel;
         FullName      = $rootFolder.FullName;
         Name          = $rootFolder.Name;
         LastWriteTime = $rootFolder.LastWriteTime;
         IsContainer   = $rootFolder.PSIsContainer;
         Count         = Get-ItemCountRecursive $rootFolder.FullName
     }
     $entries.Add($entry) | Out-Null
 
     $firstIndentLevel = 1
     Set-FolderStructure $rootFolder.FullName $firstIndentLevel
 
     try {
         $excel = New-ExcelApplication
         $excel.Visible = $true
 
         $workbook = Add-ExcelWorkbook $excel
 
         Write-ExcelFolderStructure
 
         Reset-ExcelViewState $workbook
     } finally {
         Release-ExcelComObjectSafely $workbook
         Release-ExcelComObjectSafely $excel
     }
 
     Write-Host "処理時間:[$($stopwatch.ElapsedMilliseconds)]ms"
 }
 
 
 
 # ----------------------------------------------------------
 # 画面表示
 # ----------------------------------------------------------
 $form.ShowDialog()

トップ   差分 履歴 リロード   一覧 検索 最終更新   ヘルプ   最終更新のRSS