[강좌] 비주얼 베이직 클래스가 쉬워진다 ②

일반입력 :2002/10/10 00:00

최지환

4. 개체 배열개체도 새끼를 칠 수 있습니다. 배열은 일반 변수들의 전유물이 아닙니다. 아마도 거의 모든 사용자들이 사용하고 있으리라 여겨지지만요. 그래도 합니다. 다음의 코딩을 살펴보도록 하죠.Private Sub ListBox_DragDrop(A1 As VB.Control, X As Single, Y As Single)  Static CtlDrop() As Control  Dim I As Integer  Static J As Integer  For I = 1 To J    If CrlDrop(I) Is A1 Then      Beep       Exit Sub    End If  Next I  J = J + 1  ReDim Preserve CtlDrop(J)  Set CtlDrop(J) = A1  ListBox.AddItem A1.NameEnd Sub 간단한 코딩이죠? 그래도 저 자신은 상당한 것이라고 여겼지만요. 이런 코딩을 처음 대면했을 때 정말 당혹스럽더군요. 보시면 쉬우리라 여겨집니다. 이 부분이 실질적으로 콘트롤들을 끌어다 놨을 때 리스트박스에 소속시켜주는 역할을 합니다. 우선 코딩을 설명하겠습니다. 이것은 리스트박스로 드래그 시켰을 경우 일어나는 이벤트를 기술한 것입니다. Static으로 변수를 설정함으로써 외부의 저지를 받지 않고 안에서 고유의 값을 유지할 수 있게 합니다. 절대 Dim 등의 것으로 하면 안되요. 뭐 제가 모르는 다른 방법도 있겠지만요. 있다면 가르쳐 주시길.....그래서 값을 유지하도록 합니다. 마우스로 컨트롤을 끌어왔을 때 A1에 그 컨트롤을 받아들입니다. 그리고 우선은 그 컨트롤이 이미 끌어다 놓은 컨트롤인가를 체크해야 하겠죠? 그래서 For....Next 구문을 사용합니다. 왜냐구요? 그것은 리스트 박스에 컨트롤이 하나만 들어올 것은 아니거든요. 이것저것 많이 넣기 위해서 For....Next 구문으로 합니다. 그런데 그걸로 어떻게 하느냐..... Static CtlDrop() As Control이 구문을 통해서 합니다. 이렇게 선언된 개체 변수는 배열이긴 한데 동적 배열입니다. 배열은 고정 배열과 동적 재열이 있습니다. 그 중에 동적 배열을 말합니다. 여기서 고정 배열을 사용해도 되지만 그것은 리소스 낭비겠죠? 왜냐면 이렇게 하면 딱 필요한 만큼만 갖고 있는데, 고정 배열은 아무 것도 없으나 있으나 항상 지정된 영역을 갖고 있죠. 개체 변수는 상당한 크기의 영역을 할애합니다. 생각해 보십시오. 일반적인 데이터가 들어가는 것이 아니라 데이터의 덩어리가 들어가는데 그 크기가 얼마나 할지를요. 그것을 비어 있는게 상당수 있다고 한다면 낭비가 엄청 심하죠? 그래서 처음에 For Loop를 돌립니다. 만약 처음 드래그한 거라면 For..Next 구문은 동작하지 않겠죠? 그래서 처음엔 무조건 넘어가서 배열의 크기를 넓혀주게 됩니다. 그 역할을 다음 구문이 하게되죠.J = J + 1ReDim Preserve CtlDrop(J) 이 구문은 J라는 정수를 증가시키고 개체 배열 변수를 그 크기로 재정의 합니다. 그 구문이 ReDim입니다. 뭐 다 아시지만요. 다음으로는 실제로 컨트롤을 레퍼런스 시키는 작업을 하게 됩니다.Set CtlDrop(J) = A1이 구문은 증폭된 배열 위치에 마우스로 드래그 해서 가져다 놓은 컨트롤을 레퍼런스 시킵니다. 이제는 작업의 끝 작업으로 가져다 놓은 컨트롤을 리스트박스에 디스플레이시켜야 하겠죠?ListBox.AddItem A1.Name 이라는 구문을 수행시킵니다. 이것은 리스트 박스의 아이템 박스에 가져온 컨트롤의 이름을 넣어주는 일을 합니다. 이것은ListBox.AddItem CtlDrop(J).Name 이라는 구문과 같은 뜻입니다. 왜냐구요? 모르신다면 지난 1회를 보세요. 이렇게 해서 하나의 컨트롤이 리스트 박스로 들어갔습니다. 이제 다시 컨트롤을 마우스로 끌어와 보죠. 그렇게 한다면 J라는 인수가 1로 증가되어 있으므로 For...Next 구문을 한번 수행을 하겠죠? 그래서 현재 리스트 박스에 들어와 있는 컨트롤이 하나인데 그것과 다시 들여온 컨트롤이 같은 것인지를 체크하게 됩니다. 만약 같은 것이라면 프로시저를 바로 빠져나가고 아무런 작업을 하지 않게 되죠. 이렇게 해서 컨트롤의 배열을 마칩니다. 이런 개체 배열은 컨트롤 뿐만이 아니라 폼에도 적용됩니다. 왜냐면 폼도 하나의 개체이니까요. 방식은 같습니다. 그럼 끝냅니다. 5. 개체 컬렉션이 뭡니까?컬렉션이 뭘까요? 아직 저도 확실하게는 알지 못하지만 이것저것에서 사용하고 있죠. 몰라도 사용할 줄은 안다는건가? 하지만 그걸 조금이나마 의미를 생각해 본다면 이것은 집합체를 의미합니다. 데이타베이스를 예를 든다면 테이블, 레코드, 컬럼 등이 있죠? 이것을 전부 포함한 것이 데이타베이스입니다. 하나의 규정된 집합체이죠. 개체의 컬렉션도 마찬가지입니다. 이것은 개체들을 모아놓는 가방이라고 할 수 있죠. 하나의 프로그램은 이 컬렉션 덩어리라고 할 수도 있을 겁니다. 프로그램에 콘트롤을 추가한다는 것은 이 컬렉션에 컨트롤을 하나 더 넣는 것과 같은 것입니다. 그럼 위의 일을 수행하는 코딩을 컬렉션을 이용해 해보도록 하겠습니다. 위의 것보다 훨신 속도도 빠른걸로 알고 있어요. 미묘한 차이이기 때문에 눈에는 안띄지만요. 하지만 이것이 모이고 모이면 차이가 나겠죠?Private Sub ListBox_DragDrop(A1 As VB.Control, X As Single, Y As Single)  Static CtlDrop As New Collection  Dim I As Variant  For Each I In CtlDrop    If I Is A1 Then       Beep      Exit Sub    End If  Next I  CtlDrop.Add A1  ListBox.AddItem A1.NameEnd Sub위의 개체 배열보다 훨신 간단하죠? 이렇게 하면 훨씬 속도와 그밖의 여러 면에서 이점이 있습니다. 일단 배열값의 재정의 등의 구타한 작업들을 하지 않아도 되죠. 우선 코딩을 설명하겠습니다. 하는 작업은 전의 코딩과 같은 일을 합니다. 그런데 선언문이 하나 줄었죠? 개체 배열에서는 배열을 항상 제정의를 해주어야 하기 때문에 한 개의 변수가 더 필요했습니다. 하지만 컬렉션은 자체 메소드를 갖고 있죠. 그중의 하나인 Add를 사용해 그러한 구차한 문제를 해결했습니다.CtlDrop.Add A1 이라는 구문이죠. 위에서 두줄로 표현하던 것을 한 번에 해버리니 더하고 정의하는 작업을 단지 더하기만 해서 퍼포먼스와 리소스 문제를 해결했습니다. 재정의를 할 필요도 없으니 빠르죠. 몇몇 초보분들은 생소한 구문이 약간 있으리라 여겨집니다.For Each I In CtlDropNext I 구문이죠. 이것은 I를 CtlDrop 안에서 돌리겠다는 표현입니다. CtlDrop의 내용을 직접 넣어서 사용한다는 것이죠. 약간 옆으로 빠져서 이 구문을 사용한 다른 구문의 예를 한번 설명드리죠. 환경은 Client/Server에서 RDO를 사용할 경우를 보여 드리겠습니다. Private Sub Find_Clic()  Dim I As String  FlexGrid.Col = 1  For Each I In FlexGrid.Text    If I Is Text1 Then      FlexGrid.Col = 2      Text2 = FlexGrid.Text      FlexGrid.Col = 1    Else      MsgBox "데이터가 없습니다."    End If  Next IEnd Sub 위의 예는 데이타베이스 프로그래밍을 하시는 분들이 많기 때문에 그렇게 했습니다. 이미 아시는 분들은 아시겠지만 RDO에서는 Find 기능이 없습니다. 있다면 쿼리를 해서 하는 방법이죠. 하지만 그런 작업들은 데이타베이스를 오픈하고 뭐 그런 복잡한 일들을 수행을 하게 되죠. 그래서 상당한 로스를 갖져옵니다. 그래서 데이타베이스를 오픈하지 않고 그 데이타를 찾고 사용하는 루틴을 본다면 위의 것이 있습니다. 그러면 다중 사용시에 많은 이점이 있겠죠? 물론 완벽한 코딩은 아니지만 약간만 손본다면 쓸 수 있으니 사용하시는 것도 좋을 듯 하군요. 음 이거 미천 다 나오는군요. 하하 그래도 어때요? 진정한 정보의 공유를 하고싶지만 마음대로 안되는군요.샛길에서 나와서 본길로 다시 갑니다. 컬렉션에서 주의할 것은 위의 선언문에서 As New를 사용했다는 것입니다. 컬렉션 클래스의 인스턴스는 처음 변수를 참조할 때 작성이 됩니다. 그렇게 때문에 As New로 선언을 해야 합니다. 이렇게 해서 개체 컬렉션도 만들어 봤습니다. 음 저로서는 상당히 좋은 강좌라 여겨지지만 안그런 분들이 많군요. 히힛 그래도 합니다. "아버지... 바위 굴러와유~~~!"라고 외치는 사람이 있군요. 도망가야 하겠습니다. 바로 위의 코딩이 RDO인 이유는 다른 것들은 Find 기능을 갖고 있지만 그것은 없거든요. 그래서 구현된 루틴이고요. 또 Client/Server 환경인 이유는 로컬이라면 그냥 데이타베이스에서 찾아오지 누가 그리드에서 찾겠습니까? 그리드에서 찾으므로 데이타베이스 서버의 로드를 줄임으로 훨신 많은 유저를 보유할 수 있겠죠? @비주얼 베이직 클래스가 쉬워진다 ①