EXCEL - VBA

VBA - vworld 사이트에서 토지 특성 조회(5) : 코드 설명(2)

별동산 2025. 3. 14. 08:12
반응형

(15) 토지특성속성 조회 URL 생성

        ' 토지 특성 조회 URL 만들기(기준연도 초기값 올해)
        base_url = "http://api.vworld.kr/ned/data/getLandCharacteristics"
        params = "?pnu=" & pnu & "&format=xml" & "&key=CEB52025-E065-364C-9DBA-44880E3B02B8"
'        params = params & "&numOfRows=3"
        params = params & "&stdrYear=" & Year(Date)
    
        ' search_url을 base_url과 params의 결합으로 함
        search_url = base_url & params

 
위와 같이 만들면 URL은
http://api.vworld.kr/ned/data/getLandCharacteristics?pnu=1111010100100010001&format=xml&key=CEB52025-E065-364C-9DBA-44880E3B02B8&stdrYear=2025
가 됩니다.
 
중요한 것은 pnu와 format입니다.
 
params = params & "&numOfRows=3"은 주석 처리했는데, 처리 결과를 3개로 제한하는 구문입니다.
pnu가 19자리인 경우는 1건이지만, 자릿수가 작을 경우 해당하는 결과가 많아지게 되므로 이때 numOfRows로 보여주는 결과의 건수를 제한할 수 있습니다.
 
&stdrYear=2025을 삭제하고 검색했더니 numOfRows가 10건으로 나옵니다.

 

토지특성속성조회 레퍼런스에는 "HTTPS, FLEX 등 웹뷰어가 아닌 브라우저에서의 API 사용은 DOMAIN을 추가하여 서비스를 이용할 수 있습니다"라고 되어 있는데 추가하지 않아도 됩니다.


(16) 함수 반환 값을 value 배열에 대입

        ' URL 조회 및 검색 결과 반환 처리
        value = search_value(ws, i, xmlHttp, xmlDoc, search_url)

면적, 기준연도, 개별공시지가 세 가지만 배열에 대입했으므로 배열의 크기는 3이고, 인덱스는 0,1,2입니다.
 
(17) 검색 결과가 없을 때 다음 행 처리

        value = search_value(ws, i, xmlHttp, xmlDoc, search_url)
    
        ' 검색 결과가 없을 때는 C열부터 F열까지 지우고 끝냄
        If value(0) = "" Then
            GoTo cont_loc
        End If

 
(18) 검색 결과를 셀에 입력

        ' 검색 결과 표시
        ' 주소 표시
        ws.Cells(i, 3).value = dong & " " & jibun
        
        ' 면적
        ws.Cells(i, 4).value = value(0)
        
        ' 개별 공시지가 기준연도
        ws.Cells(i, 5).value = value(1)
        
        ' 개별 공시지가
        ws.Cells(i, 6).value = value(2)

'중간을 건너뛰고 여기로 옮
cont_loc:

    Next

 
검색 결과가 여러 개 있지만 면적, 개별공시지가 기준연도, 개별공시지가를 주소와 함께 C열부터 F열까지 표시하는 것입니다.

 
(19) Function 시작과 끝

Function search_value(ws, i, value, xmlHttp, xmlDoc, search_url)
    처리하고 반환할 값
End Function

Sub는 Sub로 시작하고 End Sub로 끝나는데, Function도 Function으로 시작하고, End Function으로 끝납니다.
 
인수가 ws, i, value, xmlHttp, xmlDoc, search_url 여섯 개입니다.
 
(20) Function 내부 변수 선언

    Dim stdrYear As Integer
    Dim strResult As String
    Dim omitYearURL As String

변수명을 지정하고 정수 또는 문자열 형태로 지정하는 것입니다.
 
(21) 개별공시지가 조회를 실패한 경우 연도 조정

    ' 법정동 조회가 아닌 경우 stdrYear 이후를 제거한 다음
    ' stdrYear를 한 해 작은 것으로 연결
    If InStr(search_url, "address") = 0 Then
        '기준연도를 올해로
        stdrYear = Year(Date)
        
        '기준연도를 제외한 url 추출
        omitYearURL = Left(search_url, InStr(search_url, "stdrYear") - 1)

minusYear:
        ' 연도를 하나씩 빼서 결과값이 나올 때까지 반복
        search_url = omitYearURL & "stdrYear=" & stdrYear
    End If

InStr(search_url, "address") = 0
는 "search_url에서 address 문자열을 찾아 없으면"이라는 의미입니다.
다시 말해 토지특성조회인 경우를 말합니다.
 
주석에 쓰인 대로 처음에는 기준연도를 올해로 지정한 다음 기준연도를 입력하는 부분을 제외한 URL을 구한 아음 기준연도를 하나씩 빼서 검색을 반복합니다.
 
minusYear:
는 While문을 적용할 수 없어서 goto문을 이용해 반복 처리하기 위한 것입니다.
2025년에는 검색 결과가 없기 때문에 한 바퀴 돌면 stdrYear가 2024가 되고, 검색 결과가 나옵니다.
http://api.vworld.kr/ned/data/getLandCharacteristics?pnu=1111010100100010001&format=xml&key=CEB52025-E065-364C-9DBA-44880E3B02B8&stdrYear=2024
 
(22) Get 방식으로 검색 URL 전송

    ' GET 방식 URL을 전송
    xmlHttp.Open "GET", search_url, False
    xmlHttp.setRequestHeader "Content-Type", "text/xml"
    xmlHttp.send

URL을 Get 방식으로 하고, 반환받는 형식은 XML로 지정해서 요청(Send)하는 것입니다.
 
(23) 전송 결과 성공 여부에 따른 처리

    If xmlHttp.Status = 200 Then
        '전송 결과가 200, 성공일 경우 처리할 구문
    Else
        search_value = fail(ws, i)
    End If

전송 결과 응답이 200, 성공이면 if 안의 구문을 처리하고, 실패하면 Else 다음의 구문을 실행합니다.
 
(24) 응답 결과를 xmlDoc에 저장

        '응답결과를 strResult 변수에 저장
        strResult = xmlHttp.responseText
        xmlDoc.LoadXML (strResult)

22번에서 전송한 URL의 반환값인 responseText를 strResult변수에 대입한 후
xmlDoc에 로드(적재)합니다.
 
(25) 검색 URL에 따른 구분 처리

        '법정동 코드 조회인 경우
        If InStr(search_url, "address") Then
            법정동 코드 조회시 처리 구문

        '개별 공시지가 조회인 경우
        Else
             개별 공시지가 조회인 경우
        End If

법정동 코드 조회와 개별공시지가 조회를 하나의 함수에서 처리하기 위한 분기문입니다.
 
(26) 법정동 코드 조회 결과 처리

            '검색 결과에 level4LC가 있는 경우
            If InStr(strResult, "level4LC") > 0 Then
            
                ' value 배열의 요소 개수 재선언
                ReDim value(0)
                value(0) = xmlDoc.SelectSingleNode("//level4LC").Text
        '        value(0) = xmlDoc.SelectSingleNode("/response/refined/structure/level4LC").Text
                
                ' value 배열을 반환 값인 searchvalue에 대입
                search_value = value
            Else
                search_value = fail(ws, i)
            End If

검색 결과에 level4LC가 있는 경우는
value 배열의 크기를 1(0부터 시작하기 때문에 0이 되는 것임)로 재설정(ReDim)하고
xmlDoc.SelectSingleNode("//level4LC").Text으로 level4LC에 해당하는 값인 법정동코드를 value(0)에 대입합니다.
 
이것은 level4LC를 위치와 관계없이 찾는 것이고, 정확한 경로는 주석으로 표시한 /response/refined/structure/level4LC입니다.
 
JavaScript나 PHP와 달리 //라고 해서 위치와 관계없이 일치하는 것을 찾을 수 있고, 전체 경로를 지정할 때도 폴더 형식으로 경로를 지정하니 이해하기 편합니다.
 
search_value = value
는 value 배열 변수를 함수명인 search_value에 대입해서 반환하는 것입니다.
 
VBA는 반환값을 반환할 때 return문을 사용하지 않고 함수명에 값을 대입하는 식으로 합니다.
 
(27) 기준연도 1 차감

            If InStr(strResult, "pblntfPclnd") = 0 Then
                stdrYear = stdrYear - 1
                GoTo minusYear
            End If

InStr(strResult, "pblntfPclnd") = 0
는 strResult에 pblntfPclnd가 없는 경우, 다시 말해 개별공시지가가 없는 경우에 
stdrYear = stdrYear - 1로 stdrYear를 1줄이고,
GoTo minusYear:이라는 표시된 부분으로 이동하는 것입니다.
 
(28) xmlDoc의 토지특성속성을 배열에 입력

            ' value 배열의 요소(item) 개수 재선언
            ReDim value(2)
            
            '면적
    '        value(0) = xmlDoc.SelectSingleNode("/response/fields/field/lndpclAr").Text
            value(0) = xmlDoc.SelectSingleNode("//lndpclAr").Text
            
            '기준연도
            value(1) = xmlDoc.SelectSingleNode("//stdrYear").Text
            
            '개별공시지가
            value(2) = xmlDoc.SelectSingleNode("//pblntfPclnd").Text
            
            ' value 배열을 반환 값인 searchvalue에 대입
            search_value = value

 
ReDim value(2)
는 value의 인덱스를 2로 설정해서 0,1,2로 크기를 3으로 설정하는 것입니다.
 
value(0) = xmlDoc.SelectSingleNode("//lndpclAr").Text
는 위에서 설명한 것과 같이 lndpclAr을 찾아 그 값을 value배열의 인덱스 0에 저장하는 것입니다.
 
그리고, 3개 배열을 갖는 value 변수를 함수명인 search_value에 저장해서 Sub 프로시저로 반환합니다.
 
(29) 검색 실패 시 처리

Function fail(ws, i)
    ReDim value(0)
    value(0) = ""
    ws.Cells(i, 3).Resize(1, 4).ClearContents
    fail = value
End Function

 
검색 결과가 없을 때 처리하는 함수로
value의 크기를 1로 한 다음 ""을 대입하고,
 
ws.Cells(i, 3), 다시 말해 C열의 처리행을 기준으로
Resize(1, 4), 다시 말해 행을 1로 하고, 열은 4로 사이즈를 다시 정합니다. 그러면 ws.Cells(i, 3).Resize(1, 4)는 i가 2라면
C2:F2가 됩니다.
 
ClearContents는 '내용 지우기'입니다.

 
그러면 C2셀에서 F2셀의 내용이 아래와 같이 지워지게 됩니다.

 
 
완성된 파일은 아래와 같습니다.

get_land_char.xlsm
0.03MB

 
위에서는 세 가지 항목만 검색했지만 다른 항목도 추출할 수 있고, 다른 URL도 검색해서 추가로 적용할 수 있을 것입니다.
 
다음에는 디버깅에 대해 간단히 다뤄보도록 하겠습니다.

반응형