使い捨てマクロ
Option Explicit
#Const DEBUG_ = False
Public Sub Main()
#If DEBUG_ Then
Dim wshShell As IWshRuntimeLibrary.wshShell
Dim wshScriptExec As IWshRuntimeLibrary.wshExec
#Else
Dim wshShell As Object
Dim wshScriptExec As Object
#End If
Set wshShell = VBA.Interaction.CreateObject("WScript.Shell")
Set wshScriptExec = wshShell.Exec("PowerShell -Command -")
With wshScriptExec.stdIn
.WriteLine "using namespace System.Collections.Generic"
.WriteLine "Set-StrictMode -Version Latest"
.WriteLine "Add-Type -AssemblyName Microsoft.VisualBasic"
.WriteLine "1 / 0"
.WriteLine "Write-Error 'non-terminating error' -ErrorAction Continue"
.WriteLine "$ErrorActionPreference = 'Stop'"
.WriteLine "$Cmp = Add-Type -PassThru -Language CSharp -TypeDefinition @'"
.WriteLine "namespace MyNS {"
.WriteLine " using Microsoft.PowerShell.Commands; using System.Collections.Generic; using System.Management.Automation; using System.Runtime.InteropServices;"
.WriteLine " public class CmpStrCmpLogicalW : IComparer<GroupInfo>, IComparer<PSObject> {"
.WriteLine " private string propName;"
.WriteLine " public CmpStrCmpLogicalW(string propertyName = ""Name"") { this.propName = propertyName; }"
.WriteLine " public int Compare(GroupInfo x, GroupInfo y) { return StrCmpLogicalW(x.Name, y.Name); }"
.WriteLine " public int Compare(PSObject x, PSObject y) { return StrCmpLogicalW(x.Properties[propName].Value.ToString(), y.Properties[propName].Value.ToString()); }"
.WriteLine " [DllImport(""Shlwapi.dll"", CharSet = CharSet.Unicode)]"
.WriteLine " private static extern int StrCmpLogicalW([MarshalAs(UnmanagedType.LPWStr)] string psz1, [MarshalAs(UnmanagedType.LPWStr)] string psz2);"
.WriteLine " }"
.WriteLine "}"
.WriteLine "'@ -ReferencedAssemblies Microsoft.PowerShell.Commands.Utility"
.WriteLine ""
.WriteLine "try {"
.WriteLine " $strPath = [Microsoft.VisualBasic.Interaction]::InputBox('パス', $Host.Name, ""$HOME\Desktop"", -1, -1)"
.WriteLine " $grDirName = Get-ChildItem -LiteralPath $strPath -Force -Recurse -Depth 1 | "
.WriteLine " Select-Object -Property Attributes, Length, Mode, BaseName, Extension, Name, @{ Name='DirName'; Expression={ Convert-Path -LiteralPath $_.PSParentPath } }, FullName, CreationTime, LastWriteTime | "
.WriteLine " Group-Object -Property DirName"
.WriteLine " if ($null -eq $grDirName) { return } "
.WriteLine " $psObjList = [List[PSObject]]::new()"
.WriteLine " $grDirNameList = [List[Microsoft.PowerShell.Commands.GroupInfo]]$grDirName"
.WriteLine " $grDirNameList.Sort($Cmp::new())"
.WriteLine " $grDirNameList | ForEach-Object {"
.WriteLine " # Splatting"
.WriteLine " $params = @{ Property = @('Mode', 'Length', 'BaseName', 'Extension', 'DirName', 'FullName', 'CreationTime', 'LastWriteTime') }"
.WriteLine " # ディレクトリ"
.WriteLine " $list = [List[PSObject]]($_.Group | Where-Object { $_.Attributes -band [IO.FileAttributes]::Directory })"
.WriteLine " if ($null -ne $list) { $list.Sort($Cmp::new()); $psObjList.AddRange([List[PSObject]]($list | Select-Object @params)) }"
.WriteLine " # ファイル"
.WriteLine " $list = [List[PSObject]]($_.Group | Where-Object { -not ($_.Attributes -band [IO.FileAttributes]::Directory) })"
.WriteLine " if ($null -ne $list) { $list.Sort($Cmp::new()); $psObjList.AddRange([List[PSObject]]($list | Select-Object @params)) }"
.WriteLine " }"
.WriteLine ""
.WriteLine " $psObjList | ConvertTo-Csv -NoTypeInformation"
.WriteLine "} catch { throw $_ }"
.WriteLine ""
.Close
End With
Dim strExecOutputs As New VBA.Collection
Dim strExecErrors As New VBA.Collection
With wshScriptExec.stdOut
Do While .AtEndOfStream <> True
strExecOutputs.Add .ReadLine()
Loop
End With
With wshScriptExec.stdErr
Do While .AtEndOfStream <> True
strExecErrors.Add .ReadLine()
Loop
End With
Set wshScriptExec = Nothing
Set wshShell = Nothing
Dim xlWorkbook As Excel.Workbook
Dim xlWorksheet As Excel.Worksheet
Dim xlRange As Excel.Range
Dim str2dArr() As String
Dim i As Long, N As Long
Set xlWorkbook = Excel.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet)
Set xlWorksheet = xlWorkbook.Worksheets.Item(1)
xlWorksheet.Name = "StdOut"
N = strExecOutputs.Count
If N <> 0 Then
ReDim str2dArr(1 To N, 1 To 1)
For i = 1 To N Step 1
str2dArr(i, 1) = strExecOutputs(i)
Next i
Set xlRange = xlWorksheet.Range(xlWorksheet.Cells.Item(1, 1), xlWorksheet.Cells.Item(N, 1))
xlRange.Value2 = str2dArr
xlRange.TextToColumns _
Destination:=xlWorksheet.Range("A1"), _
DataType:=Excel.XlTextParsingType.xlDelimited, _
TextQualifier:=Excel.Constants.xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=False, Semicolon:=False, Comma:=True, Space:=False, Other:=False, OtherChar:="", _
FieldInfo:=Array( _
Array(1, Excel.XlColumnDataType.xlTextFormat), _
Array(2, Excel.XlColumnDataType.xlGeneralFormat), _
Array(3, Excel.XlColumnDataType.xlTextFormat), _
Array(4, Excel.XlColumnDataType.xlTextFormat), _
Array(5, Excel.XlColumnDataType.xlTextFormat), _
Array(6, Excel.XlColumnDataType.xlTextFormat), _
Array(7, Excel.XlColumnDataType.xlYMDFormat), _
Array(8, Excel.XlColumnDataType.xlYMDFormat) _
), _
DecimalSeparator:=".", _
ThousandsSeparator:=",", _
TrailingMinusNumbers:=True
End If
N = strExecErrors.Count
If N <> 0 Then
Set xlWorksheet = xlWorkbook.Worksheets.Add(after:=xlWorkbook.Worksheets.Item(1))
xlWorksheet.Name = "StdErr"
ReDim str2dArr(1 To N, 1 To 1)
For i = 1 To N Step 1
str2dArr(i, 1) = strExecErrors(i)
Next i
Set xlRange = xlWorksheet.Range(xlWorksheet.Cells.Item(1, 1), xlWorksheet.Cells.Item(N, 1))
xlRange.Value2 = str2dArr
End If
Set xlWorksheet = xlWorkbook.Worksheets.Item(1)
xlWorksheet.Activate
End Sub