====== Excel에서 Syntax Highlighting SQL ====== {{tag>blog Excel 엑셀 매크로 vba sql 개발}} 인공지능, 머신러닝 등을 수행하기 위해선 Python, R 등 특화된 도구를 사용해야 하지만 그 전에 데이터 추출, 정리, 보고를 위해서 실제 현업에서는 엑셀을 많이 사용할 수 밖에 없습니다.\\ 엑셀, PPT를 이용해서 보고서를 작성하고, 자료를 정리하는 경우가 많아서 SQL 쿼리를 엑셀에 정리를 하고 있습니다. \\ \\ 다른 IDE에서는 지원하는 Syntax Highlighting 기능이 없어, 실제 쓰기 위해서 간단히 만들어 보았습니다. \\ {{blog:pasted:vba_sql_gif.gif}} \\ \\ ==== 글자 색 바꾸기 ==== [[https://www.extendoffice.com/documents/excel/3775-excel-highlight-part-of-text-in-cell.html|참고]] 를 기반으로 수정 Sub HighlightStrings(aFnd As Variant, color As Integer) Application.ScreenUpdating = False Dim Rng As Range Dim cFnd As String Dim xTmp As String Dim x As Long Dim m As Long Dim y As Long For i = LBound(aFnd) To UBound(aFnd) cFnd = aFnd(i) y = Len(cFnd) For Each Rng In Selection With Rng m = UBound(Split(Rng.Value, cFnd, -1, vbTextCompare)) If m > 0 Then xTmp = "" For x = 0 To m - 1 xTmp = xTmp & Split(Rng.Value, cFnd, -1, vbTextCompare)(x) With .Characters(Start:=Len(xTmp) + 1, Length:=y) .Font.ColorIndex = color .Font.FontStyle = "bold" End With xTmp = xTmp & cFnd Next End If End With Next Rng Next i Application.ScreenUpdating = True End Sub 현재 선택된 엑셀 범위에 대해서, 색, 모양을 바꾸기 위한 글자를 cFnd 라고 하고, 셀 내용을 cFnd 를 기준으로 split 한 다음, 그 위치를 기준으로 cFnd의 글자 개수만큼 글자 형태를 바꿔주는 함수입니다. 여기서 Split 함수를 한번 살펴보면 Split ( Expression, [Delimiter], [Limit], [Compare] ) VBA에서 Split 함수는 기본적으로 대소문자를 구분기 때문에 Compare 파라미터에 vbTextCompare 를 전달해서 대소문자 구분없이 사용할 수 있도록 했습니다. Split(Rng.Value, cFnd, -1, vbTextCompare) 현재는 bold체에 색깔만 함수를 통해서 전달받는 것으로 했는데, [[https://docs.microsoft.com/en-us/office/vba/api/excel.font(object)|Range.Characters.Font]] 에 대한 설명을 보시고 수정하실 수 있습니다. 색깔에 RGB(00,00,00) 을 넣으면 RGB를 통해서도 색깔을 지정할 수 있습니다. \\ \\ ==== Highlight 할 문자들 ==== Sub highlight_sql() aFnd = Array("select", "from", "where", _ "left outer join", "left join", " on", " in", "not in", "inner join", "union", _ "(", ")", "=", "group by", "order by", "insert ", "update ", _ "truncate table", "drop table", "if exists", "create table", "having") HighlightStrings aFnd, 5 aFnd = Array("sum(", "count(", ".", "'", _ " like", " and", " or", " between", "),", _ "rank()", " over", "partition by", " asc", " desc", _ "min(", "max(", "distinct", "cast(", "to_char(") HighlightStrings aFnd, 13 End Sub Array를 통해서 SQL에서 자주 쓰는 명령어들을 앞서 설정한 함수에 전달하였습니다. 평소에 많이 쓰는 명령어들만 넣어놔서, 필요하신 명령어들을 추가하면 될 것입니다. SQL말고 다른 언어에도 충분히 활용 가능할 것 같습니다. 필드명 등에 in, sum, or, and 등이 들어갈 수 있기 때문에 앞이나 뒤에 공백을 넣었습니다. \\ \\ ==== 문자열, 주석 등 처리하기 ==== 앞에서 만든 함수는 간단히 String을 찾아서 형태만 치환해 주는 형태인데요,\\ RegExp을 쓰기에 VBA는 번거로운 점이 많아서\\ ' 이나 " 으로 묶여있는 문자열 등의 색깔을 구분하고 싶어서 아래처럼 수정해 보았습니다.\\ Sub HighlightStrings_between(cFnd As String, color As Integer, Optional endFnd As String = "") Application.ScreenUpdating = False Dim Rng As Range Dim xTmp As String Dim x As Long Dim m As Long Dim y As Long isEnd = 0 For Each Rng In Selection With Rng m = UBound(Split(Rng.Value, cFnd, -1, vbTextCompare)) If m > 0 Then xTmp = "" For x = 0 To m - 1 xTmp = xTmp & Split(Rng.Value, cFnd, -1, vbTextCompare)(x) If endFnd = "" Then If isEnd = 0 Then y = Len(Split(Rng.Value, cFnd, -1, vbTextCompare)(x + 1)) + 1 'MsgBox Split(Rng.Value, cFnd)(x + 1) isEnd = 1 Else y = Len(cFnd) isEnd = 0 End If Else If Len(Split(Rng.Value, cFnd, -1, vbTextCompare)(x + 1)) = 0 Then y = Len(cFnd) Else y = Len(Split(Split(Rng.Value, cFnd, -1, vbTextCompare)(x + 1), endFnd, -1, vbTextCompare)(0)) + Len(cFnd) End If 'MsgBox Split(Split(Rng.Value, cFnd)(x + 1), endFnd)(0) End If With .Characters(Start:=Len(xTmp) + 1, Length:=y) .Font.ColorIndex = color '.Font.FontStyle = "bold" End With xTmp = xTmp & cFnd Next End If End With Next Rng Application.ScreenUpdating = True End Sub endFnd 를 Option으로 받아서 endFnd가 존재하면 cFnd에서 endFnd까지 문자형태를 바꾸고, 없으면 cFnd 사이를 바꿔주도록 했습니다. 간단히 isEnd 라는 변수를 사용해서 처음인지, 끝인지 구분하도록 했습니다. 여기에 쓰일 문자열들은 하나씩 설정해줘야 하니까, 파라미터에서 Array 도 제외했습니다. 아래와 같이 사용하면 됩니다. HighlightStrings_between "--", 10, Chr(10) HighlightStrings_between "as", 3, Chr(10) HighlightStrings_between "'", 10 HighlightStrings_between """", 10 Chr(10)은 라인끝을 볼 수 있는 문자열이니까, 주석이나 as 같은 경우는 라인끝까지 형태를 바꿔주게 됩니다. \\ \\ ==== 활용 ==== 아래와 같이 Contol 버튼이나 Shape에 Macro를 연결하여 사용하실 수 있습니다. {{blog:pasted:20200215-130327.png?300}} .xla 로 저장하여 리본메뉴를 통해서 실행하는 방법도 있습니다. [[blog:excel_vba_ribbon_menu|Excel에서 리본 메뉴 만들기]] 참고하세요 \\ \\ ==== Add-in 다운 ==== \\ {{blog:vba_add-in_example.zip|다운로드}} \\ \\ ~~DISCUSSION~~