입력 화면에서 사용자가 입력한 것을 확인하기 위한 코드를 작성하였습니다.

코드1
'/***********************************************************************************
' 함수명    : CheckTextBox
' 작성자    : 정진우
' 설명      : TextBox 입력값이 존재하는 지 여부를 판단해 오류가 있을 경우, msgbox를 띄우고 false를 반환
' 리턴값    : [false] 오류 발생
' 매개변수
'           txt     : 대상 TextBox
'           title   : 대상 TextBox 갖고 있는 내용
' 이력사항
'           2011.12.20: 생성
'/***********************************************************************************
Public Function CheckTextBox(ByRef txt As TextBox, ByVal title As String, Optional ByVal isEssencial As Boolean = False, Optional ByVal length As Integer = 1000) As Boolean
    If isEssencial = True And (IsNull(txt.Text) Or txt.Text = "") Then
        MsgBox title & " 입력하세요." & Space(6), 48, "입력 오류"
        txt.SetFocus
        CheckTextBox = False
    End If
    
    If (Not IsNull(txt.Text)) And Len(txt.Text) > length Then
        MsgBox title & "에 대한 입력의 최대 길이는 " & CStr(length) & "를 넘을 수 없습니다." & Space(6), 48, "입력 오류"
        txt.SetFocus
        CheckTextBox = False
    End If
    
    CheckTextBox = True
End Function
텍스트박스가 많으니, 위의 프로시저를 만들고, 빠바박 한 화면에 포함된 모든 텍스트박스를 넘겨주면 코드도 깔끔하게 나올 것이란 판단에서였죠.ㅎㅎ
그리고 잘못된 입력 혹은 미입력 시에 나오는 Message box에 대한 문구도 통일 할 수 있으니 더욱 좋고요 ^^

아래와 같이 호출을 해서 사용하면, 호출하는 코드에서도 보기도 편하고요!!
If modDataChecker.CheckTextBox(txtBox1, "입력 텍스트 상자 1", True, 8) = False Then Exit Sub
If modDataChecker.CheckTextBox(txtBox2, "입력 텍스트 상자 2", True, 10) = False Then Exit Sub
If modDataChecker.CheckTextBox(txtBox3, "입력 텍스트 상자 3", True, 10) = False Then Exit Sub
If modDataChecker.CheckTextBox(txtBox4, "입력 텍스트 상자 4", True, 20) = False Then Exit Sub
If modDataChecker.CheckTextBox(txtBox5, "입력 텍스트 상자 5", True, 20) = False Then Exit Sub

하지만, 호출 시에 오류가 발생합니다.

* 타입 미스 매칭 에러... 타입이 다르다고 하네요 .ㅡ.ㅡ;

함수 호출 시에 넘겨주는 txtBox1도 확인해 보면, TextBox 형식이고,
작성한 함수도 위에 보시는 데로 ByRef txt as TextBox.....아무리 봐도 눈으로는 문제가 없어 보입니다.
그러면 당연히 구글링!!
http://www.mrexcel.com/forum/showthread.php?t=53911
위 url에서 바로 확인할 수 있었네요.

컨트롤을 매개변수로 받는 함수(혹은 프로시져) 작성시에는
ByRef txt As msforms.TextBox

로 매개변수를 선언해줘야 합니다.
"msforms.TextBox"
다른 형식으로도 TextBox가 선언이 되어 있나봅니다.
다른 컨트롤 컴포넌트를 사용하지도 않는 데...
다른 컨트롤에 대해 확인하는 함수에도 모두 "msforms"를 붙여줬답니다..ㅎㅎㅎ

쩝;;난감;;; 완성된 코드는 아래에...모 함수 선언만 바뀌었을 뿐입니다;
Public Function CheckTextBox(ByRef txt As msforms.TextBox, ByVal title As String, Optional ByVal isEssencial As Boolean = False, Optional ByVal length As Integer = 1000) As Boolean
    If isEssencial = True And (IsNull(txt.Text) Or txt.Text = "") Then
        MsgBox title & " 입력하세요." & Space(6), 48, "입력 오류"
        txt.SetFocus
        CheckTextBox = False
    End If
    
    If (Not IsNull(txt.Text)) And Len(txt.Text) > length Then
        MsgBox title & "에 대한 입력의 최대 길이는 " & CStr(length) & "를 넘을 수 없습니다." & Space(6), 48, "입력 오류"
        txt.SetFocus
        CheckTextBox = False
    End If
    
    CheckTextBox = True
End Function

내용 자체는 짧은 것입니다만은... 이렇게 길게 포스팅을 한 이유는 "refactoring"에 대한 것입니다.
입력 화면을 개발하는 분들이 많을 텐데요.
짧은 코드라고 하더라도, 저런 형태로 함수를 추출하고, 재사용하게 된다면, 유지보수에 엄청난 도움이 됩니다!!

짧은 코드라고 하더라도, ctrl + c, ctrl + v를 하신다면, 그 즉시 함수로 추출하는 습관을 들이세요 ^^
엑셀을 접할 때, 가장 중요한 것은 하나의 sheet는 한 형식(type)에 대한 정의로 구성하는 것으로 시작해야 한다는 것입니다.

'열(column)'과 '행(row)'로 이뤄지게끔 구성하는 것이죠.

하나의 '정보 조각', 그것을 설명할 수 있는 '설명'들로 열을 구성하고, 일련의 '정보'들을 행으로 구성하는 것이죠.

그래야지 하나의 정보가 깔끔하게 구성이 되어, 이해하기가 편하게 됩니다.

/***************************************************************************************************
* 정보 혹은 데이터에 대한 용어가 깔끔하지 않네요. 둘다 결국은 같은 사전적 의미를 가지니까요. datum이 data의 단수이지만, 잘 사용하지 않는 용어다보니..
* 그래서 위에서는 '설명'이 모여서 '정보 조각'을 이루고, 일련의 정보 조각의 모음을 '정보'라고 사용했습니다. 그래도 어렵네요;;
***************************************************************************************************/

위에서 설명한 것과 마찬가지로, 정보들은 그것을 구성하는 정보 조각들로 구분해 더욱 상세하게 풀어서 설명을 할 수 있습니다. 정보 조각들 또한 그것을 더욱 세세하게 나누어 더욱 작은 정보 조각들로 구성할 수 있구요.

필요에 따라 엑셀에도 정보들을 쪼개어서 표현할 수가 있기는 합니다.

'깊이(depth)'를 한 단계 더 두는 것인데요.

한 단계 더 깊은 것들은 보일 필요가 있을 때가 있고, 숨길 때가 있습니다.

엑셀 사용시에 흔히 사용하는 '열 숨기기' 혹은 '행 숨기기' 기능입니다. 이 기능을 통해서 행 또는 열을 숨겨서 보고자 하는 정보만을 한 번에 확인할 수 있도록 하는 거죠.

그런데, 저 기능을 사용하다보면 조금은 불편할 때가 있습니다. 일일이 행과 열을 선택해서 우클릭 후에 보이는 팝업 메뉴(혹은 컨텍스트 메뉴)를 통해서만 제어가 가능하다는 점인데요. 자주 '숨기기'하고, '숨기기 취소'하게 된다면, 여간 불편한게 아닙니다.

이런 이들을 위해서 엑셀에서 제공하는 기능이 있는 데, 바로 '윤곽'이라는 기능입니다.
일련의 행들을 하나로 묶어 '윤곽'을 설정해두면, 좌측에 나타나는 [+]와 [-]를 클릭하는 것으로 [숨기기]와 [숨기기 취소]를 할 수 있게 도와줍니다.

사용법은 다음과 같습니다.

1. 일련의 [행/열]을 선택합니다.
2. 메뉴에 [데이터] - [그룹 및 윤곽 설정] - [그룹]을 클릭하면 선택한 [행/열]이 하나의 덩어리로 구성이 됩니다.

여기서 구성된 [하나의 덩어리]가 위에서 설명한 '깊이'와 연관이 됩니다.
처음에 구성된 하나의 sheet에 있는 정보들은 기본적으로 level 1의 깊이를 가진 데이터입니다.
그리고 위의 행위를 통해 만들어진 [하나의 덩어리]는 level 2의 깊이를 가진 데이터가 됩니다.
level 2의 깊이를 가진 정보들의 내부에 다시 [덩어리]를 만들게 되면 그것은 level 3의 깊이를 가진 데이터가 되는 식이죠.

대한민국의 교육 체계를 바탕으로 설명을 드리면,
가장 표면적인 것을 '고등 교육', '중등 교육', '초등 교육'으로 나뉠 수 있습니다. 이것을 level 1으로 보도록 하겠습니다.
이를 조금더 자세히 본다면,
'고등 교육'에는 [대학]이 있고요, '중등 교육'에는 [고등학교]와 [중학교]로 구분할 수 있습니다.
'초등 교육'에는 [초등학교]가 있고요. 이는 level 2가 됩니다.
다시 이를 나누면, [대학]에는 박사 과정, 석사 과정, 학사 과정 그리고 전문 학사 과정으로 나뉠 수 있고요. 이것이 level 3가 되겠죠.
그 아래에는 각 학년 별 과정이 존재합니다. 학변 별 과정은 level 4가 되죠.

정확한 것은 아니나, 이렇듯 정보를 단계별로 구성이 가능합니다.

+ 너무 얘기가 돌아다니네요...ㅡ.ㅡ;;;

여튼 이 포스트에서 설명하고자 하는 것은 엑셀을 통해 정보를 구성할 수 있으며, 이를 구조화할 수 있다는 것입니다.
이것은 [그룹] 혹은 [윤곽]이라는 기능이고요.

참고로 윤곽 기호가 나타남으로 인해, [행] 또는 [열]을 표시하는 공간이 넓어진다는 건데요.
이를 보이지 않도록 하는 설정도 존재합니다.

[도구] - [옵션] - [화면 표시] 탭 - [윤곽 기호]에 대한 체크를 해제하시면 됩니다.

일련의 정보들을 숨기고, 숨기기 취소하고를 편하게 하기위해서 [윤곽]을 사용하는 건데, 이를 안보이게 한다니...
조금 아이러니 하긴 하죠... 하지만 다 필요는 합니다.

일련의 묶음을 일일이 [+]와 [-]를 통해서 제어하며, 데이터를 확인하는 것이 귀찮을 수도 있습니다.

이에 대한 제어를 편하게 하는 것에는 vba 코드가 필요한데요.
vba코드에서는 Outline.Showlevels라는 프로시저(함수)를 사용합니다.
Public Sub btnGuide_Click()
    Dim DD As Shape
    Set DD = ActiveSheet.Shapes(Application.Caller)
    Dim caption As String
    caption = DD.TextFrame.Characters.Text
    call modSystem.SheetUnproject()
    If caption = "Guide 보기" Then
        DD.TextFrame.Characters.Text = "Guide 숨기기"
        ActiveSheet.Outline.ShowLevels RowLevels:=2
    Else
        DD.TextFrame.Characters.Text = "Guide 보기"
        ActiveSheet.Outline.ShowLevels RowLevels:=1
    End If
call modSystem.SheetProject()
End Sub
* ActiveSheet.Outline.ShowLevels RowLevels:=2
위의 명령어입니다. [ShowLevels] 프로시저에 [RowLevels]라는 매개변수(parameter)에 '2'로 설정을 해라. 라는 건데요.
위에서 설명한 '깊이'에 대한 level을 2로 설정한다고 생각하시면 됩니다.
위의 코드에서는 엑셀에 하나의 버튼을 두고, 그것을 통해서 level 2를 보이게 하고, 숨기고를 작업하도록 구성하였습니다.

결국 저러한 일련의 코드가 있다는 것을 설명하고 싶었는 데, 이를 위한 잡소리가 많아졌네요.ㅎㅎ;;

엑셀에서의 몰랐던 기능!!

'이름 지정'
많은 데이터를 관리할 수 있도록 도와주는 엑셀!!
엑셀은 기본적으로 하나의 SHEET에 한 종류의 데이터를 행과 열에 따라 정리하는 게 맞습니다!
하지만, 사용하다 보면 그렇게만 되지 않죠..^^;

그래서 대부분 한 SHEET를 나름의 규칙으로 다수의 영역으로 쪼개어 사용하기도 합니다.

이 때, 각 영역의 시작점 혹은 그 영역으로 이동하고 싶을 시에..

 * 스타크래프트1에서 자신이 자주 보는 지역을 지정할 수 있는 기능이 있는 것과 동일하다고 생각됩니다.
    자신의 본진, 주력 멀티, 그리고 전장...을 주로 설정하죠.ㅎㅎㅎ
    (아;;;저는 그럴 실력까진 안되고요;;;

이 '이름 지정' 기능을 하용하면 됩니다.

평소에는 그냥 현재 선택된 셀의 이름을 확인 할 수 있는 용도로 사용하거나, 아니면 그냥 대수롭지 않게 지나치던 그곳이죠!!
그곳은!!!

바로 수식 입력창 바로 왼쪽에 위치하고 있습니다.


위 캡쳐는 EXCEL 2003 이나... 아마 그 이후 버젼에서도 별반 다르진 않았던 기억이네요..^^;

이름 지정을 원하는 셀 혹은 영역(다수의 cell)을 지정한 후, 이름 지정 창에 원하는 ‘이름’을 넣으면 설정이 완료됩니다.
임의의 이름을 넣은 후 엔터!!

그리고 다른 셀에 있다가, 다시 같은 이름을 넣고, 엔터를 치면 지정한 곳으로 즉시 이동이 됩니다.ㅎㅎㅎ

지정된 이름을 삭제하는 것은 저기서 바로 되진 않습니다.

Ctrl+F2 혹은 [메인 메뉴] - [삽입] - [이름] - [정의]를 통해 관리가 가능합니다.


제가 임의로 지정한 이름들이 보이고요. 그 하단 [참조 대상]에 설정한 셀 혹은 영역이 보이네요..^^;



제가 엑셀의 이러한 기능을 포스팅한 이유는 사실 따로 있습니다.
이 기능을 통해, VBA 코드 작성시에 매우 큰 도움이 되기 때문이죠.ㅎㅎ


   
    For rowIndex = 0 To intRowCount - 1
        For fldIndex = 0 To fldCount
            Worksheets(MAIN_SHEET).Range(SHEET_TABLE).Offset(rowIndex, fldIndex - 1).value = ""
        Next
    Next

위 코드는 간단히 일정 영역을 초기화하는 코드입니다.
  - "MAIN_SHEET"와 "SHEET_TABLE"은 전역 상수로 설정한 것입니다.^^;

여기서 "SHEET_TABLE"이 해당 SHEET의 한 영역에 '이름'을 지정해둔 것이죠.
저렇듯, 코드 상에서도 WORKSHEETS의 RANGE에 이름을 넣어줌으로 해당 CELL 혹은 영역으로 바로 이동이 가능하고.
또한 OFFSET 함수를 통해 일정 구간에 대한 핸들링을 손쉽게 할 수 있습니다.

코딩하시는 개발자 분들 중에 데이터 임시 저장 파일로 EXCEL을 사용하신다면,
제가 오늘 알려드린 '이름' 기능을 써보세요.
확실히 편해집니다.^^
마치 INDEX를 통해 ARRAY를 열심히 찾아다니던 것을 KEY를 통해 바로 찾아갈 수 있는 HASHTABLE처럼요..^^