반응형

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, "빼내고자 하는 항목명") 해서

액티브 시트에 찍기

 

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

반응형
반응형

와....xml 을 했더니 이제는 텍스트가 날 괴롭히네...


일반 적인 형식으로 읽으면 문자가 다 깨져서 objStream 으로 읽어야 한다..


Private Sub Read()


filename = "c:\text.txt"

Dim objStream As Object '읽어올 objStream 을 만들고

Set objStream = CreateObject("ADODB.Stream") 'objStream 을 ADODB.Stream으로 생성

objStream.Open ' 열고

objStream.Type = 2 'adTypeText '텍스트 타입

objStream.Charset = "UTF-8" '캐릭터셋을 utf-8로

objStream.LoadFromFile filename '오브젝트 스트림에 파일을 로드

Do Until objStream.EOS '오브젝트 스트림이 종료시까지 반복

strLine = objStream.ReadText(-2)  ' strLine에 한줄씩 넣기

Loop


End Sub


별거 아닌데 은근 꽤 찾아야 나오더라는..;;

반응형
반응형

xml로 열심히 작업해놨는데
운영툴 제작으로 인하여 엑셀에서 직접 DB 로 데이터 넣는 작업을 하게 되었음...

아...귀찮아

다시 구글링~~

vba 메뉴에서 도구-참조 에서 위에꺼 다 설정 //예전에 한거라 뭐였는지 기억이 안남..-_-

Dim a() '필드명 넣을넘
Dim b() '데이터 넣을넘
Dim DbCon As New ADODB.Connection '커넥션 관련 지정
strConnect = "Provider=SQLOLEDB.1; Persist Security Info=True; User ID=아이디; Password=패스워드; Initial Catalog=데이터베이스이름; Data Source=아이피" '연결 명령어를 스트링으로 저장
DbCon.Open strConnect '디비랑 연결~~
strSQL = "DELETE from 테이블명 '기존에 있던 테이블 데이터 지우기
DbCon.Execute strSQL '실행

'strSQL = "INSERT INTO 테이블명" & Filename & " values(" & k2 & ")"
'DbCon.Execute strSQL
'DbCon.Close             ' 디비닫기
'Set DbCon = Nothing     ' 개체반환


'여기서부터는 뭐 참고로 생각하시면됨
nRow = WorksheetFunction.CountA(Worksheets(strSheetName).Rows(1))
cn = 0
For j = 1 To nRow '서버에 올릴 필드 개수 체크
If Worksheets(strSheetName).Cells(1, j).Font.ColorIndex = 2 Then
    cn = cn + 1
End If
Next j
ReDim a(cn - 1)
ReDim b(cn - 1)
fl = -1
For j = 1 To nRow '필드명을 배열에 저장
If Worksheets(strSheetName).Cells(1, j).Font.ColorIndex = 2 Then
   fl = fl + 1
    a(fl) = Worksheets(strSheetName).Cells(1, j).Value
End If
Next j
For j = 0 To fl '배열에 저장된 필드명을 k3에 나열
    If j = fl Then
        k3 = k3 & "," & a(j)
    ElseIf j = 0 Then
    k3 = k3 & a(j)
    Else: k3 = k3 & "," & a(j)
    End If
Next j
nCol = WorksheetFunction.CountA(Worksheets(strSheetName).Columns(1))  ' 열의 갯수 체크

For k = 2 To nCol
ii = -1
    For j = 1 To nRow
        If Worksheets(strSheetName).Cells(1, j).Font.ColorIndex = 2 Then
                ii = ii + 1
                b(ii) = Worksheets(strSheetName).Cells(k, j)
        End If
    Next j
    For jj = 0 To fl '배열에 저장된 값을 k2에 나열
        If jj = fl Then
            k2 = k2 & ",'" & b(jj) & "'"
        ElseIf jj = 0 Then
        k2 = k2 & "'" & b(jj) & "'"
        Else: k2 = k2 & ",'" & b(jj) & "'"
        End If
    Next jj
strSQL = "INSERT INTO 테이블명" & Filename & " values(" & k2 & ")"
DbCon.Execute strSQL
Er_Rtn:
      If Err <> 0 Then
          MsgBox Err.Description & vbCrLf & strSheetName & " 시트의" & k & "행 값을 확인하세요"
          Exit Sub
      End If
k2 = ""
Next k
DbCon.Close             ' 디비닫기
Set DbCon = Nothing     ' 개체반환

반응형
반응형

해외버전 작업시 UTF-8로 스트링 파일을 저장해야 하는 문제가 발생

기존의 파일 쓰기 방식으로는 파일 생성시 캐릭터 셋이 ansi 로 되기 때문에 구글링~~~

vba 도구 참조에서 

오브젝트 라이브러리 관련된거 체크 해줘야 됨

Dim objStream As Object '오브젝트를 선언
Set objStream = CreateObject("ADODB.Stream") '오브젝트 생성
objStream.Open '열기!!
objStream.Position = 0 '쓰기 위치
objStream.Charset = "UTF-8" '캐릭터셋 설정
objStream.WriteText "<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & vbCrLf
'쓰기 vbCrLf 는 줄바꿈 명령어
objStream.SaveToFile strPathName, 2 'strPathName 에 파일 위치와 파일명이 있어야함
objStream.Close '닫기
Set objStream = Nothing '사라져!!






반응형

+ Recent posts