|
効率的では無いかも知れませんが、こんな物かな?
余りTestをしていないので上手く行くか?
ログのファイルと集計結果用のファイルが共にExcelのBookとします
マクロは、集計結果用のファイルに有る物とします
Dataは先頭行からデータで見だしは無い物とします
集計結果もA列にグループ名、B列に集計結果を書き込み、1列めが見出しとします
尚、ログのファイルがCSV、Textならまた別なやり方に成ります
標準モジュールに記述
Option Explicit
Public Sub AddUp()
Dim i As Long
Dim j As Long
Dim vntResult As Variant
Dim vntGroup As Variant
Dim lngGroupTop As Long
Dim lngGroupEnd As Long
Dim lngGroupCount As Long
Dim vntData As Variant
Dim lngDataCount As Long
'データの有るファイル名
Const strDataFile As String = "Data.xls"
'もしデータファイルが無い場合
If Dir(ThisWorkbook.Path & "\" & strDataFile) = "" Then
Beep
MsgBox "ファイルが有りません"
Exit Sub
End If
' Application.ScreenUpdating = False
'データファイルのOpen
Workbooks.Open ThisWorkbook.Path & "\" & strDataFile
'データファイルのSheet1
With Worksheets("Sheet1")
'データの取得
vntData = Range(.Cells(1, 1), _
.Cells(65536, 2).End(xlUp)).Value
End With
'データファイルのClose
Workbooks(strDataFile).Close SaveChanges:=False
'データの個数
lngDataCount = UBound(vntData, 1)
'データのソート
ShellSort vntData
'集計用シートのSheet1
With Worksheets("Sheet1")
'集計行の先頭
lngGroupTop = 2
'集計行の最終を取得
lngGroupEnd = .Cells(65536, 1).End(xlUp).Row
'集計Group名の取得
vntGroup = Range(.Cells(lngGroupTop, 1), _
.Cells(lngGroupEnd, 1)).Value
End With
'集計Group名の個数
lngGroupCount = UBound(vntGroup, 1)
'集計Group名配列の拡張
ReDim Preserve vntGroup(1 To lngGroupCount, 1 To 2)
'集計Group名配列に行位置を書き込み
For i = 1 To lngGroupCount
vntGroup(i, 2) = i + lngGroupTop - 1
Next i
'集計Group名配列のソート
ShellSort vntGroup
'集計結果配列の確保
ReDim vntResult(1 To lngGroupCount)
'集計
'データのカウンタの初期設定
j = 1
'集計Group名を1つづつ取り出す
For i = 1 To lngGroupCount
'データと比較
Do Until j > lngDataCount
'もし、データの中に取り出した集計Group名が有れば
If InStr(1, vntData(j, 1), _
vntGroup(i, 1), vbTextCompare) <> 0 Then
'結果用配列に加算
vntResult(i) = vntResult(i) + vntData(j, 2)
j = j + 1
Else
Exit Do
End If
Loop
Next i
'集計用シートのSheet1
With Worksheets("Sheet1")
'集計Group名の全てを書き込み
For i = 1 To lngGroupCount
.Cells(vntGroup(i, 2), 2).Value = vntResult(i)
Next i
End With
' Application.ScreenUpdating = True
End Sub
別な標準モジュールに記述
Option Explicit
Option Compare Text
Public Sub ShellSort(vntList As Variant)
Dim i As Long
Dim j As Long
Dim lngGap As Long
Dim vntTmp(1) As Variant
Dim lngTop As Long
Dim lngEnd As Long
lngTop = LBound(vntList, 1)
lngEnd = UBound(vntList, 1)
lngGap = 1
Do While lngGap < (lngEnd - lngTop + 1) \ 3
lngGap = 3 * lngGap + 1
Loop
Do Until lngGap <= 0
For i = lngGap + lngTop To lngEnd
vntTmp(0) = vntList(i, 1)
vntTmp(1) = vntList(i, 2)
For j = i To lngGap + lngTop Step -lngGap
If vntList(j - lngGap, 1) <= vntTmp(0) Then
Exit For
End If
vntList(j, 1) = vntList(j - lngGap, 1)
vntList(j, 2) = vntList(j - lngGap, 2)
Next j
vntList(j, 1) = vntTmp(0)
vntList(j, 2) = vntTmp(1)
Next i
lngGap = lngGap \ 3
Loop
End Sub
|
|