반응형

C# (유니티?) 엔진 및 이펙트, 타격타이밍 등을 json 으로 저장하게 되면서

json 파일 정보를 엑셀에서 정리해야 되는 경우가 발생

+ json 파일이 줄바꿈되어 있지 않은 경우

+ 추가기능을 추가 하지 않고 파싱하여 가져와 보자

 

원본 json데이터 : "c:\eff.json"

 


{"target": [{"stateName": "ShortAttack","effectName": "vfx_hit_01_yellow","effectBulletName": "","boneName": "Bip001 Pelvis","startboneName": "","ftime": 0.25699999928474429,"fAngle": [],"isMelee": true,"fAngleX": [],"bulletCount": 0,"selectStartBoneidx": 0,"selectBoneidx": 3,"selectidx": 1,"objEffect": {"instanceID": 71280},"objBulletEffect": {"instanceID": 0}},{"stateName": "LongAttack","effectName": "fx_hit_laser_01_green","effectBulletName": "fx_laser_01_green","boneName": "Bip001 Pelvis","startboneName": "dummy_attack_long_01","ftime": 0.38999998569488528,"fAngle": [0.0],"isMelee": false,"fAngleX": [0.0],"bulletCount": 1,"selectStartBoneidx": 79,"selectBoneidx": 3,"selectidx": 2,"objEffect": {"instanceID": 67170},"objBulletEffect": {"instanceID": 58998}},{"stateName": "Smash","effectName": "vfx_hit_01_yellow","effectBulletName": "","boneName": "Bip001 Pelvis","startboneName": "","ftime": 0.5569999814033508,"fAngle": [],"isMelee": true,"fAngleX": [],"bulletCount": 0,"selectStartBoneidx": 0,"selectBoneidx": 3,"selectidx": 10,"objEffect": {"instanceID": 71280},"objBulletEffect": {"instanceID": 0}}]}

 

 

보는것과 같이 한줄로 주욱....되어 있는 경우가 대부분이다.

이걸 json 뷰어등으로 파싱하면..

{
  "target": [
    {
      "stateName": "ShortAttack",
      "effectName": "vfx_hit_01_yellow",
      "effectBulletName": "",
      "boneName": "Bip001 Pelvis",
      "startboneName": "",
      "ftime": 0.25699999928474429,
      "fAngle": [
        
      ],
      "isMelee": true,
      "fAngleX": [
        
      ],
      "bulletCount": 0,
      "selectStartBoneidx": 0,
      "selectBoneidx": 3,
      "selectidx": 1,
      "objEffect": {
        "instanceID": 71280
      },
      "objBulletEffect": {
        "instanceID": 0
      }
    },
    {
      "stateName": "LongAttack",
      "effectName": "fx_hit_laser_01_green",
      "effectBulletName": "fx_laser_01_green",
      "boneName": "Bip001 Pelvis",
      "startboneName": "dummy_attack_long_01",
      "ftime": 0.38999998569488528,
      "fAngle": [
        0.0
      ],
      "isMelee": false,
      "fAngleX": [
        0.0
      ],
      "bulletCount": 1,
      "selectStartBoneidx": 79,
      "selectBoneidx": 3,
      "selectidx": 2,
      "objEffect": {
        "instanceID": 67170
      },
      "objBulletEffect": {
        "instanceID": 58998
      }
    },
    {
      "stateName": "Smash",
      "effectName": "vfx_hit_01_yellow",
      "effectBulletName": "",
      "boneName": "Bip001 Pelvis",
      "startboneName": "",
      "ftime": 0.5569999814033508,
      "fAngle": [
        
      ],
      "isMelee": true,
      "fAngleX": [
        
      ],
      "bulletCount": 0,
      "selectStartBoneidx": 0,
      "selectBoneidx": 3,
      "selectidx": 10,
      "objEffect": {
        "instanceID": 71280
      },
      "objBulletEffect": {
        "instanceID": 0
      }
    }
  ]
}

이런 모양이 된다.

 

표로 보자면

 

target/stateName target/effectName target/effectBulletName target/boneName target/startboneName target/ftime target/isMelee target/bulletCount target/selectStartBoneidx target/selectBoneidx target/selectidx target/objEffect/instanceID target/objBulletEffect/instanceID target/fAngle/0 target/fAngleX/0
ShortAttack vfx_hit_01_yellow   Bip001 Pelvis   0.25699999928474426 true 0 0 3 1 71280 0    
LongAttack fx_hit_laser_01_green fx_laser_01_green Bip001 Pelvis dummy_attack_long_01 0.38999998569488525 false 1 79 3 2 67170 58998 0 0
Smash vfx_hit_01_yellow   Bip001 Pelvis   0.5569999814033508 true 0 0 3 10 71280 0    

 

여기서 내가 필요한것은

각 "stateName" 별 이벤트 발생시간 "ftime" 값이다.

 

Private p&, token, dic

Sub jsonDataRead()
	Set Arry = CreateObject("Scripting.Dictionary")
    Dim bb As Integer
	filename = "c:\eff.json"
	Open filename For Input As #1
        Do Until EOF(1)
			Line Input #1, textline
			Total = Total & vbNewLine & textline
		Loop
	Close #1
    If InStr(1, Total, vbCrLf) >= 1 Then 	'줄바꿈 되어 있는 데이터를 한줄로
    	Total = Replace(Total, vbCrLf, vbLf)
    End If
    Set Arry = ParseJSON(Total)
    For Each aa In Arry.keys '키기준으로 돌리자
    	If InStr(1, aa, "stateName") Then
          Fileline = Application.CountA(range("a:a")) 'a열 숫자 카운트 해서 다음에 넣자
          ActiveWorkbook.Activeworksheets.Cells(Fileline + 1, 1).Value = Arry.Items()(bb) 'aa
    	ElseIf InStr(1, aa, "ftime") Then
    		ActiveWorkbook.Activeworksheets.Cells(Fileline + 1, 2).Value = Arry.Items()(bb) 'aa
    	End If
    	bb = bb + 1
    Next
End Sub
'---------------------------------------------------------------------------
' VBA JSON Parser 도구 참조 추가 하지 않는  파서 Dictionary 형식으로 반환
'---------------------------------------------------------------------------

Function ParseJSON(json$, Optional key$ = "obj") As Object
    p = 1
    token = Tokenize(json)
    Set dic = CreateObject("Scripting.Dictionary")
    If token(p) = "{" Then ParseObj key Else ParseArr key
    Set ParseJSON = dic
End Function

Function ParseObj(key$)  '키 분해
    Do: p = p + 1
        Select Case token(p)
            Case "]"
            Case "[":  ParseArr key
            Case "{":  ParseObj key
            Case "}":  key = ReducePath(key): Exit Do
            Case ":":  key = key & "." & token(p - 1)
            Case ",":  key = ReducePath(key)
            Case Else: If token(p + 1) <> ":" Then dic.Add key, token(p)
        End Select
    Loop
End Function

Function ParseArr(key$) '키 배열
    Dim e&
    Do: p = p + 1
        Select Case token(p)
            Case "}"
            Case "{":  ParseObj key & ArrayID(e)
            Case "[":  ParseArr key
            Case "]":  Exit Do
            Case ":":  key = key & ArrayID(e)
            Case ",":  e = e + 1
            Case Else: dic.Add key & ArrayID(e), token(p)
        End Select
    Loop
End Function

'-------------------------------------------------------------------
' Support Functions
'-------------------------------------------------------------------
Function Tokenize(s$) '값 토큰화
    Const Pattern = """(([^""\\]|\\.)*)""|[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?|\w+|[^\s""']+?"
    Tokenize = RExtract(s, Pattern, True)
End Function

Function RExtract(s$, Pattern, Optional bGroup1Bias As Boolean, Optional bGlobal As Boolean = True) '값 추출
  Dim c&, m, n, v
  With CreateObject("vbscript.regexp")
    .Global = bGlobal
    .MultiLine = False
    .IgnoreCase = True
    .Pattern = Pattern
    If .test(s) Then
      Set m = .Execute(s)
      ReDim v(1 To m.Count)
      For Each n In m
        c = c + 1
        v(c) = n.Value
        If bGroup1Bias Then If Len(n.submatches(0)) Or n.Value = """""" Then v(c) = n.submatches(0)
      Next
    End If
  End With
  RExtract = v
End Function

Function ArrayID$(e) '값 배열
    ArrayID = "(" & e & ")"
End Function

Function ReducePath$(key$) '값패스 정리
    If InStr(key, ".") Then ReducePath = Left(key, InStrRev(key, ".") - 1)
End Function



 

Arry Dictionary 의 구조

변수 Arry에  Dictionary로 저장후 Arry.keys 로 for을 진행

 

Arry keys

원하는 항목 검사 InStr(1, aa, "빼내고자 하는 항목명") 해서

액티브 시트에 찍기

 

음...나중에도 쓸만하겠지?

반응형

+ Recent posts