EXCEL - VBA

두 문장의 같은 단어 비교(4) - 어미, 조사 등 제거 도전

별동산 2023. 5. 11. 08:11
반응형

 

https://lsw3210.tistory.com/entry/%EB%91%90-%EB%AC%B8%EC%9E%A5%EC%9D%98-%EA%B0%99%EC%9D%80-%EB%8B%A8%EC%96%B4-%EB%B9%84%EA%B5%90

 

두 문장의 같은 단어 비교(1) - 매크로 작성

위와 같이 A1셀과 A2셀의 문장 2개를 비교해서 같은 단어일 경우는 글자 색을 빨간색으로 표시하는 것을 해보겠습니다. 1. 논리 A1셀과 A2셀을 각각 빈칸을 기준으로 문장을 나눈 다음 배열에 넣고,

lsw3210.tistory.com

 

위 글을 쓸 때만 해도 어미 또는 조사 등을 제거하는 것이 어렵다고 생각하고 포기했는데,

 

간단하게라도 만들어 놓으면 완성하는 것은 사용자의 몫이 될 수도 있을 듯해 제한적으로나마 매크로를 작성해 봤습니다.

 

1. 논리

"은, 는, 이, 가"가 대표적인 조사이고, '사랑해'의 '해', '사랑하고'의 '하고' 등이 대표적인 어미가 됩니다. 또한 '~에 대해'와 같이 의미는 있지만 중요하지 않은 단어도 있습니다.

 

따라서, 조사나 어미의 경우는 잘라버리고,

'에 대해'에서 '대해'는 중요하지 않은 단어로 빨간색 표시를 하지 않는 것으로 처리하겠습니다.

 

 

2. 처리 방법 및 매크로 작성

 

줄 별로 처리하기 때문에 공통되는 부분이 있으므로

반복적으로 이뤄지는 실행문은 Sub 프로시저로 처리하고,

 

처리한 다음 값을 반환해야 하는 경우는 Function 프로시저로 처리하도록 하겠습니다.

 

가. 어미, 조사 자르기

Function eogan_umi(ArrayName)
    eogan_umi = ArrayName
    ' 글자수가 2자인 경우
    If Len(ArrayName) = 2 Then
        ' 왼쪽 한 글자가 어간인 경우
        Select Case Left(ArrayName, 1)
            Case "삶", "몸"
                eogan_umi = Trim_Umi(ArrayName)
        End Select
    
    Else '두 글자이상이 어간인 경우(글자수로는 3자이상인 경우)
        eogan_umi = Trim_Umi(ArrayName)
    End If
End Function

Function Trim_Umi(ArrayName)
    Trim_Umi = ArrayName
    Select Case Right(ArrayName, 1)
        Case "은", "는", "이", "가", "을", "를", "의", "에", "와", "과", "한", "할", "와", ","
            Trim_Umi = Left(ArrayName, Len(ArrayName) - 1)
    End Select

    '제외할 조사 또는 어미가 두 글자인 경우(부분 일치)
    Select Case Right(ArrayName, 2)
        '제외할 조사 또는 어미(부분 일치)
        Case "하고", "하게", "임을"
            Trim_Umi = Left(ArrayName, Len(ArrayName) - 3)
    End Select

    '제외할 조사 또는 어미가 세 글자인 경우(부분 일치)
    Select Case Right(ArrayName, 3)
        '제외할 조사 또는 어미(부분 일치)
        Case "으로서"
            Trim_Umi = Left(ArrayName, Len(ArrayName) - 3)
    End Select
End Function

 

(1) eogan_umi 함수

어간이 한 글자인 경우, 위에서는 삶과 꿈을 예로 들었고,

나머지는 어간이 두 글자이상인 경우로서

모두 Trim_Umi 함수를 호출합니다.

 

첫 줄 eogan_umi = ArrayName는

Select Case문의 조건에 맞지 않을 경우 처리가 되지 않아 공백이 반환되기 때문에 배열을 eogan_umi에 대입해서 그대로 반환하도록 하기 위한 것입니다.

 

(2) Trim_Umi 함수

오른쪽 한 글자가 은, 는, 이, 가 등에 해당하는 경우는 그 한자를 제외한 나머지 글자를 어간으로 처리하고,

조사 또는 어미가 두 글자인 경우는 두 글자를 제외한 나머지 글자를 어간으로 처리하며,

세 글자인 경우는 세 글자를 제외한 나머지 글자를 어간으로 처리합니다.

 

따라서, 조사와 어미에 해당하는 글자를 한 글자, 두 글자, 세 글자 또는 그 이상으로 구분해서 분류해서 매크로를 수정하면 됩니다.

 

 

나. 제외 단어 처리하기

Sub except_red(ArrayName, num, proc_cell)
    Select Case Right(ArrayName(num), 2)
        Case "대한", "대해"
        Case Else
            font_red ArrayName, num, proc_cell
    End Select
End Sub

오른쪽 두 글자가 '대한' 또는 '대해'인 경우는 이에 대한 처리문이 없기 때문에 처리하지 않고,

'대한' 또는 '대해'가 아닌 경우만(Case Else) 해당 어간을 빨간색으로 칠합니다.

 

 

다. compare_sentence 서브 프로시저 수정

 

(당초) 

' testArray1 배열을 하나씩 이동하면서 처리
For i = 0 To len1

	' testArray2 배열을 하나씩 이동하면서 처리
	For j = 0 To len2
	
		' instr(시작위치, 범위, 찾을 값)
		' testArray1 자체에서 공백을 제거했더니 위치 판단이 잘못돼서
		' testArray1(i)와 testArray2(j)가 공백이 아닐 경우에만 처리하는 것으로 변경
		If testArray1(i) <> "" And testArray2(j) <> "" Then
			
			' testArray1(i)가 testArray2(j)에 포함되는지 또는
			' testArray2(j)가 testArray1(i)에 포함되는지 판단
			If InStr(testArray2(j), testArray1(i)) > 0 Or _
				InStr(testArray1(i), testArray2(j)) > 0 Then
				
				' testArray1의 i번째 글자와 testArray2의 j번째 글자를 빨간색으로 칠함
				font_red testArray1, i, Range("a" & K)
				font_red testArray2, j, Range("a" & L)
				
			End If
		End If
	Next
Next

당초에는 공백 한 칸을 기준으로 분리된 어절 전체를 빨간색으로 표시했습니다.

 

(보완)

' testArray1 배열을 하나씩 이동하면서 처리
For i = 0 To len1

	' testArray2 배열을 하나씩 이동하면서 처리
	For j = 0 To len2
	
		' testArray1(i)와 testArray2(j)가 공백이 아닐 경우에만 처리하는 것으로 변경
		If testArray1(i) <> "" And testArray2(j) <> "" Then
			

			'어미 또는 조사를 잘라냄
			testArray1(i) = eogan_umi(testArray1(i))
			testArray2(j) = eogan_umi(testArray2(j))
			
			'일치하는 경우만 처리
			If testArray1(i) = testArray2(j) Then
												
				'testArray1(i)가 아래 단어일 경우 색 처리에서 제외(완전 일치)
				Call except_red(testArray1, i, Range("a" & K))
				Call except_red(testArray2, j, Range("a" & L))
			
			End If
		End If
	Next
	
Next

위에서 만든 함수와 서브 프로시저를 적용하여 어미 또는 조사를 제거하고, '대해' 또는 '대한'에 대해서는 처리하지 않는 것으로 수정했습니다.

 

함수로 반환되는 값은 아래와 같이 다시 배열에 대입하고,

testArray1(i) = eogan_umi(testArray1(i))

 

서브 프로시저는 Call 명령어로 아래와 같이 호출합니다.

Call except_red(testArray1, i, Range("a" & K))

 

함수나 서브 프로시저나 괄호 안에 필요한 인수를 대입합니다.

 

 

3. 매크로 실행

 

(당초)

아래와 같이 '의', '을' 등을 포함하여 글자색이 빨간색으로 표시됩니다.

 

(보완)

아래와 같이 '우리는'에서 '우리'만, '우리의'에서 '우리'만, '자유와'에서 '자유'만 빨간색 글자로 표시되고,

 

'삶'의 경우 '삶'만 빨간색 글자이고,

'대해'는 글자가 중복되지만 처리하지 않도록 했기 때문에 빨간색 표시가 안되어 있습니다.

한줄과 나머지줄 모두 비교(티스토리).xlsm
0.03MB

 

반응형