忍者ブログ

アパッチのWEBアクセスログの集計③

2020年01月14日
アパッチのWEBアクセスログをエクセルVBAで集計したい。
step1.フォルダ内の全ファイルを対象としたループを作る
step2.各ファイル内のデータを日付別にシート出力
step3.各シートで、ログデータを区切る
step4.区切られたデータを集計

前回step3を力技でやったけど、納得いかなかったので作り直した。


元々スペースで区切られたデータがあって、""や[]で挟まれたデータ内では
スペースで区切りたくないというのがやりたいこと。

検索するとこんなページなどはあるんだけど・・・。
https://tonari-it.com/vba-csv-double-quotation/

置換!!!

引用符の中のスペースは別の文字(〓とか)に置換しておいて、
区切った後に戻せばいいのか。

ってことで作ったソースがこちら。


Sub アパッチログのスプリットFixed()
Dim tictoc As Double
tictoc = Timer
Dim Gyo As Long, GyoEnd As Long, i As Long
GyoEnd = Cells(Rows.Count, 1).End(xlUp).Row
Dim oiArr() As String ' "split出力用
Dim tmpArr() As String
Application.StatusBar = "配列作成中"
tmpArr = Text2tmpArr2(Cells(2, 1))   '列数確認のために2行目を処理(見易さ優先)
Dim oArr() As String    'セル出力用
ReDim oArr(GyoEnd - 1, UBound(tmpArr))
Gyo = 1  'タイトル行
    oArr(Gyo - 1, 0) = "IP"
    oArr(Gyo - 1, 1) = "--"
    oArr(Gyo - 1, 2) = "--"
    oArr(Gyo - 1, 3) = "[t]"
    oArr(Gyo - 1, 4) = "Method"
    oArr(Gyo - 1, 5) = "URL"
    oArr(Gyo - 1, 6) = "プロトコル"
    oArr(Gyo - 1, 7) = "ステータス"
    oArr(Gyo - 1, 8) = "その他"
    oArr(Gyo - 1, 9) = "訪問"
    oArr(Gyo - 1, 10) = "UA"
For Gyo = 2 To GyoEnd
'関数呼び出しでtmpArr
    tmpArr = Text2tmpArr2(Cells(Gyo, 1))  '  速度が遅いけど、保守性を重視
    For i = 0 To UBound(tmpArr)
        tmpArr(i) = Replace(tmpArr(i), "〓", " ")
        oArr(Gyo - 1, i) = tmpArr(i)    '出力配列に格納
    Next i
Next Gyo
    Application.StatusBar = "配列出力中"
    Cells(1, 3).Resize(GyoEnd, UBound(tmpArr) + 1).Value = oArr
    Application.StatusBar = ""
Debug.Print "[" & Now & "] "; Format(GyoEnd - 1, "#,##0行を") & Format(Timer - tictoc, "0.00秒")
End Sub

Function Text2tmpArr2(TextLine As String)
    Dim oiArr() As String
    Dim tmpArr() As String
    Dim i As Long
    ''[t]を"t"に置換
    ''"splitでOI配列を作る
    oiArr = Split(Replace(Replace(TextLine, "[", """"), "]", """"), """")
    ''Iに対して、SPを〓に置換
    For i = 1 To UBound(oiArr) Step 2
        If i <> 3 Then  'oiArr(3)は区切るので例外(method URL Protcol)
            oiArr(i) = Replace(oiArr(i), " ", "〓")
        End If
    Next i
    ''OI配列を1行データに戻す
    ''SP splitで配列に
    tmpArr = Split(Join(oiArr, ""), " ")
    Text2tmpArr2 = tmpArr
End Function


ソースに関するコメント
  1. []を""と同様に処理するために置換
  2. 「"」でsplit。 要素数が奇数(0から始まるので)なら"の内側
  3. 内側のスペースを「〓」に置換
  4. 配列を1行のデータに戻す
  5. 本命のスペースでsplit
  6. 「〓」をスペースに戻す
  7. 出力配列に格納
  8. 1~5をText2tmpArr2 関数で処理
  9. 出力配列のサイズがわからないので、1つ目のログを処理してから決定

結果
[2020/01/13 23:37:25] 100,000行を10.21秒
  • 汎用性を持たせた結果、遅くなったw
  • 各行での処理を関数にまとめて見やすくなったが、25%くらい遅くなった
(これを作っていたときは、比較対象のモジュールに不要なDoEventsが残っていたのでこちらのほうが速かった。)

    PR
    Comment
      Vodafone絵文字 i-mode絵文字 Ezweb絵文字