반응형
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.keys 로 for을 진행
원하는 항목 검사 InStr(1, aa, "빼내고자 하는 항목명") 해서
액티브 시트에 찍기
음...나중에도 쓸만하겠지?
반응형