엑셀(Excel) 파일을 JSON 형식이나 CSV 형식으로 저장하는 방법

엑셀 파일을 게임에서 사용할 때 제일 좋은 방법은 엑셀 파일을 게임에서 바로 읽어 들이는 것이지만, 그렇게 하기 어려울 때가 많습니다. 그 다음으로 좋은 방법은 엑셀 파일 저장 시 텍스트 형식으로도 자동 저장되게 하는 것인데, 엑셀 VBA의 BeforeSave 이벤트를 사용하면 가능합니다.

엑셀 파일 저장 시 JSON 형식으로 자동 저장되게 하려면 엑셀 VBA 소스 코드를 아래처럼 작성해서 엑셀 문서의 ThisWorkbook 개체에 포함시키고, 엑셀 시트의 첫 번째 행엔 자료형을 정의하고 두 번째 행엔 항목 이름을 정의하고 첫 열엔 식별자를 정의하면 됩니다. 참고로 아래 소스 코드는 엑셀 시트의 각 행을 JSON의 배열이 아니라 JSON의 객체로 저장합니다. 이렇게 하는 이유는 식별자로 검색할 때 배열보다 연관 컨테이너에 담아 두는 게 더 편하기 때문입니다.

Private Sub Workbook_BeforeSave(ByVal save_as_ui As Boolean, cancel As Boolean)
    ' BOM이 있는 UTF-8로 저장하려고 ADODB.Stream을 사용합니다.
    Set ado_stream = CreateObject("ADODB.Stream")
    ado_stream.Charset = "utf-8"
    ado_stream.Open
    
    ado_stream.WriteText "{" & vbCrLf
    Const export_start_row_number = 2
    last_row_number = Range("A1").End(xlDown).Row
    last_column_number = Range("A1").End(xlToRight).Column
    Dim cell_value As String
    For row_number = export_start_row_number + 1 To last_row_number
        For column_number = 1 To last_column_number
            cell_value = Cells(row_number, column_number).Value
            If IsNull(cell_value) Then
                cell_value = ""
            End If
            cell_value = replace_character_that_should_be_escaped(cell_value)
            If column_number = 1 Then
                ado_stream.WriteText vbTab & """" & cell_value & """:" & vbCrLf & vbTab & "{ " & vbCrLf
            Else
                column_name = replace_character_that_should_be_escaped(Cells(export_start_row_number, column_number).Value)
                ado_stream.WriteText vbTab & vbTab & """" & column_name & """: "
                If Cells(1, column_number).Value = "number" Then
                    ado_stream.WriteText cell_value
                Else
                    ado_stream.WriteText """" & cell_value & """"
                End If
                If column_number < last_column_number Then
                    ado_stream.WriteText ","
                End If
                ado_stream.WriteText vbCrLf
            End If
        Next column_number
        ado_stream.WriteText vbTab & "}"
        If row_number < last_row_number Then
            ado_stream.WriteText ","
        End If
        ado_stream.WriteText vbCrLf
    Next row_number
    ado_stream.WriteText "}"
    
    file_name_without_extension = Replace(ThisWorkbook.FullName, ".xlsm", "")
    Const adSaveCreateOverWrite = 2
    ado_stream.SaveToFile file_name_without_extension & ".json", adSaveCreateOverWrite
    ado_stream.Close
    Set ado_stream = Nothing
End Sub

Private Function replace_character_that_should_be_escaped(input_string As String) As String
    replace_character_that_should_be_escaped = Replace(input_string, """", "\""")
    replace_character_that_should_be_escaped = Replace(replace_character_that_should_be_escaped, "\", "\\")
End Function

엑셀 파일 저장 시 모든 워크시트를 CSV 형식으로 자동 저장되게 하려면 엑셀 VBA 소스 코드를 아래처럼 작성한 후에 엑셀 문서의 ThisWorkbook 개체에 포함시키면 됩니다.

Option Explicit

Private Sub Workbook_BeforeSave(ByVal save_as_ui As Boolean, cancel As Boolean)
    Dim current_sheet As Worksheet
    Dim file_number As Integer
    Dim last_row_index As Long
    Dim last_column_index As Long
    Dim row_index As Long
    Const header_row_index As Integer = 1
    Dim row_string As String
    Dim column_index As Long
    Dim cell_value As String
    
    For Each current_sheet In ActiveWorkbook.Worksheets
        file_number = FreeFile()
        Open ActiveWorkbook.Path & current_sheet.Name & ".csv" For Output Access Write As #file_number
        
        last_row_index = current_sheet.Cells(Rows.Count, 1).End(xlUp).Row
        last_column_index = current_sheet.Cells(header_row_index, Columns.Count).End(xlToLeft).Column
        
        For row_index = header_row_index + 1 To last_row_index
            row_string = ""
            For column_index = 1 To last_column_index
                cell_value = Replace(current_sheet.Cells(row_index, column_index).Value, """", """""")
                If InStr(cell_value, ",") > 0 Or InStr(cell_value, """") > 0 Then
                    cell_value = """" & cell_value & """"
                End If
                row_string = row_string & cell_value
                If column_index < last_column_index Then
                    row_string = row_string & ","
                End If
            Next column_index
            Print #file_number, row_string
        Next row_index
        
        Close #file_number
    Next
End Sub

참고:

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중