Q&A

  • 동일 ParentNode의 ChildNode중에서 같은 이름의 노드 찾기
안녕하세요.

설명절전이나 후나 TreeView에 미쳐(?) 사는 델파이를 사랑하는 사람입니다.



제는 지금 ini파일에서 읽은 내용을 TreeView에 출력하려고 합니다.

다행히 저와 같은 경우로 많은 글들이 올라와 있어서 겨우 겨우 조금씩 조금씩 응용해가면서 일을 진행해나갔습니다. 정말 많은 도움이 되었어요...

(뒤늦게나마 델선배님들께 감사의 말씀 드립니다. 꾸벅!!)



그런데, 일을 계속 진행하던 중 막히는 부분이 생겼고, 아주 쉽게 해결될것 같다는 미련을 버리지 못해 꽤 오랜(?) 시간을 혼자 끙끙 앓다가 이제서야 도움을 요청하게 되었어요.

정말이지 궁금해요. 문제의 답이 무엇인지를.....



문제에 대해 예를 들어 말씀드리자면 다음과 같아요.



(예) ini파일의 내용이 아래와 같을때,



sample.ini

==============================

[TotalCount]

Count=6



[Address]

서울시 강남구 역삼동;

강원도 강릉시 죽헌동;

서울시 송파구 오륜동;

인천시 부평구 부평동;

강원도 강릉시 초당동;

부산시 금정구 오륜동;

-----------------------------



Treeview에서는 다음과 같이 출력되어야 해요.



[결과 A]

===========================================

서울시

강남구

역삼동

송파구

오륜동



강원도

강릉시

죽헌동

초당동



인천시

부평구

부평동



부산시

금정구

오륜동

-----------------------------------------



위에서처럼 Treeview에 출력하려면, 동적으로 생성하기전에 생성하려는 노드가 있는지 없는지 찾아보는 과정이 있어야하기에 다른 분의 FindNode라는 함수를 사용하여서 노드의 존재여부를 검색하는 루틴을 넣었습니다. 그런데 원하는 결과가 나오질 않아요.



다음의 소스는 제가 지금까지 한 내용입니다.



Function CutStr(var st : String; aLength : Integer) : String;

begin

result := Copy(st,1,aLength);

st := Copy(st,aLength+1,length(st) - aLength);

end;



function TForm1.FindNode( Str : String) : TTreeNode; // 다른 분이 만든 함수

var

CurItem: TTreeNode;

begin

Result := nil; // 이 부분은 제가 추가했습니다.

// 이걸 안하면 뒤에 FindNode함수를 사용할때 에러가 발생하더라구요.

CurItem := TreeView1.Items.GetFirstNode;

while CurItem <> nil do

begin

if CurItem.Text = Str then

begin

Result := CurItem;

exit;

end;

CurItem := CurItem.GetNext;

end;

end;



procedure TForm1.FormCreate(Sender: TObject);

var

I, J : Integer;

IniFile: TIniFile;

Fst,Snd,Trd, Section, FName, temp, IP : string;

Sections : TStringList;

ParentNode, ChildNode : TTreeNode;



begin

ItemCount := 0; // 전역 변수

FName := 'c:samp.ini';

Sections := TStringList.Create;

Sections.LoadFromFile(FName);



IniFile := TIniFile.Create(FName); // IniFileName = 사용자 INI 파일명

ItemCount := IniFile.ReadInteger('TotalCount', 'Count', 0);



TreeView1.Items.BeginUpdate;

temp := '';



for I := 0 to Sections.Count - 1 do

begin

Section := Sections[i];

temp := temp + Section;

if Pos(']',temp) <> 0 then CutStr(temp,Pos(']',temp));

end;



for J := 0 to ItemCount-1 do

begin

Fst := IniFile.ReadString('IP Address',temp,CutStr(temp,Pos(' ',temp)-1));

CutStr(temp,1);

Snd := IniFile.ReadString('IP Address',temp,CutStr(temp,Pos(' ',temp)-1));

CutStr(temp,1);

Trd := IniFile.ReadString('Address',temp,CutStr(temp,Pos(';',temp)-1));

CutStr(temp,1);



if (FindNode(Fst) <> nil) then ParentNode := FindNode(Fst)

else ParentNode := TreeView1.Items.Add(Treeview1.Selected,Fst);



if (FindNode(Snd) <> nil) then ChildNode := FindNode(Snd)

else ChildNode := TreeView1.Items.AddChild(ParentNode,Snd);



if (FindNode(Trd) <> nil) then ShowMessage('같은 이름이 이미 존재합니다.')

else TreeView1.Items.AddChild(ChildNode,Trd);

end;



TreeView1.Items.EndUpdate;

IniFile.Free;

end;





위 소스대로하면 "같은 이름이 이미 존재합니다."라는 메세지창이 뜨고, ini파일의 내용이 아래처럼 출력됩니다. (물론 당연한 결과이죠)



[결과 B]

===========================================

서울시

강남구

역삼동

송파구

오륜동



강원도

강릉시

죽헌동

초당동



인천시

부평구

부평동



부산시

금정구

-----------------------------------------



"오륜동"이 서울시 송파구와 부산시 금정구에 둘다 있잖아요.

같은 이름의 "동"(ChildNode)이 있어도 ParentNode는 다르니까 [결과 A]처럼 해야되는데 [결과 B]처럼 출력돼요. T.T



문제가 뭔지는 알겠는데 해결방법을 잘 모르겠어요.

FindNode라는 함수는 Treeview안에 있는 모든 노드들중에서 찾는 함수라서 제가 사용하는데 적합하지않아서 이렇게 저렇게 바꾸어 보았는데 번번히 실패예요.

저는 모든 노드에서가 아닌, 동일ParentNode안의 ChildNode중에서 같은 이름의 노드가 있는지를 체크해야 하는데 어떻게 해야하는지 도저히 모르겠습니다.



더 이상 진전이 없습니다.

지금에 이르기까지도 무척 고생했거든요. 처음 일을 시작할때는 금방 끝날줄 알았는데 ...



일의 초반부터 이렇게 헤메고 있어 앞이 캄캄합니다.

아직 갈길이 멀기만 한데...

하나 하나 풀어나가는 재미가 있긴 하지만, 혼자 공부하는것도 아닌, 기한이 있는 일인데 제자리에서 계속 맴맴하니까 답답하고 시간도 너무 많이 흘렀어요.



앞으로 동적으로 Treeview의 Items를 입력할수 있도록 해서 Ini파일에 쓰도록 해야도 되고 ... 여러가지로 할 일은 많은데...



제발 델선배님들의 따뜻한 관심과 일타를 부탁드립니다.

(얼굴도 모르는 델선배님들께 도움을 요청해서 너무 죄송하지만.... 그래도 도와주셨으면 합니다.)



늦은 인사지만 새해복 많이 많이 받으시고 건강하세요.

그리고 하시는 일 모두 모두 성취되시길 기원합니다.



@--&~~





4  COMMENTS
  • Profile
    김재억 2001.01.29 23:06
    일단 제가 그냥 해당 노드의 Child중에 같은 Child노드가 있는지 검색하는 것을 대충 만들어봤습니다. 아래 소스가 그것이구요...



    var

    aList: TStringList;

    I: Integer;

    begin

    aList := TStringList.Create;

    for I := 0 to Treeview1.Selected.Count - 1 do

    begin

    if aList.IndexOf(Treeview1.Selected.Item[I].Text) < 0 then

    aList.Add(Treeview1.Selected.Item[I].Text)

    else begin

    MessageBox(handle, '이미 같은 이름의 노드가 있습니다!', '메세지',

    MB_IconInformation);

    continue;

    end;

    end;

    end;



    그런데, 님의 경우와 비슷한 경우를 저도 구현해본적이 있는데요...

    그땐 저도 시간이 워낙 없어서 아주 빨리 만들려고 한 적이 있습니다.

    저는 그것을 님의 방식과 좀더 다르게 만들었었습니다.

    그래서 잠깐 보여드릴까 합니다.

    물론 허접 노가다 코딩이라서 절대 님에게 도움이 될리는 없겠지만서두요...

    그냥 약간의 도움이라도 됐으면 하는 바램에서 보여드립니다.



    Unit의 Private절에 TreeNodeList: TStringList;

    라고 하나 선언해주고 Form의 Create나 Show절에서 생성해주구요, Close절에서 Free시켜주면 되구요...

    type

    pvList = ^TvList;

    TvList = record

    Path: String;

    end;

    와 같이 구조체를 하나 만들어줍니다.



    '서울시 강남구 역삼동' 이라는 걸 만들게 되면...

    서울시 라는 노드와 그 밑에 강남구, 그리고 그 밑에 역삼동 이라는 것을 만들게 되지요.

    구조체의 Path변수 에다가는 '서울시', '서울시 강남구', '서울시 강남구 역삼동'과 같은 형태로 저장을 하면 될꺼구요...

    만약 역삼동 부분을 저장할때 그 저장방식은 다음과 같습니다.



    var

    aRecord: pvList;

    aNode, bNode: TTreeNode;

    I, J: Integer;

    begin

    for I := 0 to TreeNodeList.Count - 1 do

    begin

    aNode := TTreeNode(TreeNodeList.Objects[I]);

    aRecord := aNode.Data;

    if Trim(aRecord^.Path) = '서울시 강남구' then

    begin

    for J := 0 to aNode.Count - 1 do

    begin

    if aNode.Item[J].Text = '역삼동' then

    begin

    // 중복 메세지 처리

    Exit;

    end;

    end;

    bNode ;= Treeview1.Items.ADd(aNode, '역삼동');

    new(aRecord);

    aRecord^.Path := '서울시 강남구 역삼동';

    bNode.Data := aRecord;

    TreeNodeList.AddObject('역삼동', bNode);

    Exit;

    end;

    end;

    end;



    위의 소스는 제가 상당히 많은 부분을 축약했습니다. 저는 당시 이걸 구현할때 각 트리의 노드의 데이타에 해당 시/구/동에 대한 정보를 바로 저장해둘 수가 있어야 했던 이유가 있어서 위와 같이 구현을 했더랬습니다.

    그런데, 님의 문제를 보니깐 그냥 제가 구현했던 방법을 조금 응용해서 위와같이 변경시키면 쉽게 될것 같아서 이렇게 몇자 허접하게 끄적였습니다.

    수고하십시오.



    sis7 wrote:

    > 안녕하세요.

    > 설명절전이나 후나 TreeView에 미쳐(?) 사는 델파이를 사랑하는 사람입니다.

    >

    > 제는 지금 ini파일에서 읽은 내용을 TreeView에 출력하려고 합니다.

    > 다행히 저와 같은 경우로 많은 글들이 올라와 있어서 겨우 겨우 조금씩 조금씩 응용해가면서 일을 진행해나갔습니다. 정말 많은 도움이 되었어요...

    > (뒤늦게나마 델선배님들께 감사의 말씀 드립니다. 꾸벅!!)

    >

    > 그런데, 일을 계속 진행하던 중 막히는 부분이 생겼고, 아주 쉽게 해결될것 같다는 미련을 버리지 못해 꽤 오랜(?) 시간을 혼자 끙끙 앓다가 이제서야 도움을 요청하게 되었어요.

    > 정말이지 궁금해요. 문제의 답이 무엇인지를.....

    >

    > 문제에 대해 예를 들어 말씀드리자면 다음과 같아요.

    >

    > (예) ini파일의 내용이 아래와 같을때,

    >

    > sample.ini

    > ==============================

    > [TotalCount]

    > Count=6

    >

    > [Address]

    > 서울시 강남구 역삼동;

    > 강원도 강릉시 죽헌동;

    > 서울시 송파구 오륜동;

    > 인천시 부평구 부평동;

    > 강원도 강릉시 초당동;

    > 부산시 금정구 오륜동;

    > -----------------------------

    >

    > Treeview에서는 다음과 같이 출력되어야 해요.

    >

    > [결과 A]

    > ===========================================

    > 서울시

    > 강남구

    > 역삼동

    > 송파구

    > 오륜동

    >

    > 강원도

    > 강릉시

    > 죽헌동

    > 초당동

    >

    > 인천시

    > 부평구

    > 부평동

    >

    > 부산시

    > 금정구

    > 오륜동

    > -----------------------------------------

    >

    > 위에서처럼 Treeview에 출력하려면, 동적으로 생성하기전에 생성하려는 노드가 있는지 없는지 찾아보는 과정이 있어야하기에 다른 분의 FindNode라는 함수를 사용하여서 노드의 존재여부를 검색하는 루틴을 넣었습니다. 그런데 원하는 결과가 나오질 않아요.

    >

    > 다음의 소스는 제가 지금까지 한 내용입니다.

    >

    > Function CutStr(var st : String; aLength : Integer) : String;

    > begin

    > result := Copy(st,1,aLength);

    > st := Copy(st,aLength+1,length(st) - aLength);

    > end;

    >

    > function TForm1.FindNode( Str : String) : TTreeNode; // 다른 분이 만든 함수

    > var

    > CurItem: TTreeNode;

    > begin

    > Result := nil; // 이 부분은 제가 추가했습니다.

    > // 이걸 안하면 뒤에 FindNode함수를 사용할때 에러가 발생하더라구요.

    > CurItem := TreeView1.Items.GetFirstNode;

    > while CurItem <> nil do

    > begin

    > if CurItem.Text = Str then

    > begin

    > Result := CurItem;

    > exit;

    > end;

    > CurItem := CurItem.GetNext;

    > end;

    > end;

    >

    > procedure TForm1.FormCreate(Sender: TObject);

    > var

    > I, J : Integer;

    > IniFile: TIniFile;

    > Fst,Snd,Trd, Section, FName, temp, IP : string;

    > Sections : TStringList;

    > ParentNode, ChildNode : TTreeNode;

    >

    > begin

    > ItemCount := 0; // 전역 변수

    > FName := 'c:samp.ini';

    > Sections := TStringList.Create;

    > Sections.LoadFromFile(FName);

    >

    > IniFile := TIniFile.Create(FName); // IniFileName = 사용자 INI 파일명

    > ItemCount := IniFile.ReadInteger('TotalCount', 'Count', 0);

    >

    > TreeView1.Items.BeginUpdate;

    > temp := '';

    >

    > for I := 0 to Sections.Count - 1 do

    > begin

    > Section := Sections[i];

    > temp := temp + Section;

    > if Pos(']',temp) <> 0 then CutStr(temp,Pos(']',temp));

    > end;

    >

    > for J := 0 to ItemCount-1 do

    > begin

    > Fst := IniFile.ReadString('IP Address',temp,CutStr(temp,Pos(' ',temp)-1));

    > CutStr(temp,1);

    > Snd := IniFile.ReadString('IP Address',temp,CutStr(temp,Pos(' ',temp)-1));

    > CutStr(temp,1);

    > Trd := IniFile.ReadString('Address',temp,CutStr(temp,Pos(';',temp)-1));

    > CutStr(temp,1);

    >

    > if (FindNode(Fst) <> nil) then ParentNode := FindNode(Fst)

    > else ParentNode := TreeView1.Items.Add(Treeview1.Selected,Fst);

    >

    > if (FindNode(Snd) <> nil) then ChildNode := FindNode(Snd)

    > else ChildNode := TreeView1.Items.AddChild(ParentNode,Snd);

    >

    > if (FindNode(Trd) <> nil) then ShowMessage('같은 이름이 이미 존재합니다.')

    > else TreeView1.Items.AddChild(ChildNode,Trd);

    > end;

    >

    > TreeView1.Items.EndUpdate;

    > IniFile.Free;

    > end;

    >

    >

    > 위 소스대로하면 "같은 이름이 이미 존재합니다."라는 메세지창이 뜨고, ini파일의 내용이 아래처럼 출력됩니다. (물론 당연한 결과이죠)

    >

    > [결과 B]

    > ===========================================

    > 서울시

    > 강남구

    > 역삼동

    > 송파구

    > 오륜동

    >

    > 강원도

    > 강릉시

    > 죽헌동

    > 초당동

    >

    > 인천시

    > 부평구

    > 부평동

    >

    > 부산시

    > 금정구

    > -----------------------------------------

    >

    > "오륜동"이 서울시 송파구와 부산시 금정구에 둘다 있잖아요.

    > 같은 이름의 "동"(ChildNode)이 있어도 ParentNode는 다르니까 [결과 A]처럼 해야되는데 [결과 B]처럼 출력돼요. T.T

    >

    > 문제가 뭔지는 알겠는데 해결방법을 잘 모르겠어요.

    > FindNode라는 함수는 Treeview안에 있는 모든 노드들중에서 찾는 함수라서 제가 사용하는데 적합하지않아서 이렇게 저렇게 바꾸어 보았는데 번번히 실패예요.

    > 저는 모든 노드에서가 아닌, 동일ParentNode안의 ChildNode중에서 같은 이름의 노드가 있는지를 체크해야 하는데 어떻게 해야하는지 도저히 모르겠습니다.

    >

    > 더 이상 진전이 없습니다.

    > 지금에 이르기까지도 무척 고생했거든요. 처음 일을 시작할때는 금방 끝날줄 알았는데 ...

    >

    > 일의 초반부터 이렇게 헤메고 있어 앞이 캄캄합니다.

    > 아직 갈길이 멀기만 한데...

    > 하나 하나 풀어나가는 재미가 있긴 하지만, 혼자 공부하는것도 아닌, 기한이 있는 일인데 제자리에서 계속 맴맴하니까 답답하고 시간도 너무 많이 흘렀어요.

    >

    > 앞으로 동적으로 Treeview의 Items를 입력할수 있도록 해서 Ini파일에 쓰도록 해야도 되고 ... 여러가지로 할 일은 많은데...

    >

    > 제발 델선배님들의 따뜻한 관심과 일타를 부탁드립니다.

    > (얼굴도 모르는 델선배님들께 도움을 요청해서 너무 죄송하지만.... 그래도 도와주셨으면 합니다.)

    >

    > 늦은 인사지만 새해복 많이 많이 받으시고 건강하세요.

    > 그리고 하시는 일 모두 모두 성취되시길 기원합니다.

    >

    > @--&~~

    >

    >

  • Profile
    sis7 2001.01.30 19:55
    안녕하세요.



    먼저 귀중한 시간을 할애하셔서 도움을 주셔서 감사드려요.

    아무도 답변을 해주지않으면 어떡해하나? 하는 생각에

    질문을 올려놓고도 내심 초조했거든요.



    너무 쉬운 질문을 올린건 아닌지... 중복된 질문을 올려서 답변해주시는 분들을

    혹시 짜증나게 하는건 아닐까? 하는 생각에 여기저기 제가 아는 사이트에 들어가서

    관련 자료를 50장정도 찾아서 읽고 또 읽고 분석해보고 적용해보기를 몇주...



    아무 소득없이 시간만 흘러 얼마나 애가 탔던지...

    도저히 시간의 흐름을 방치할수 없고 능력밖이라도 판단하여 질문을 올리게 되었는데

    다행히 답변을 주신 분들이 계셔서 얼마나 감사하고 기뻤는지 모릅니다.



    저도 앞으로 다른 분들을 도우면서 살도록 하겠습니다.

    아~! 관연 그날이 올까 ???



    다시한번 정말 감사드립니다.

    좋은 소스 공개해주셔서 감사드리며 건강하세요.



    @--&~~





  • Profile
    신호성 2001.01.29 22:47
    말씀하신것 처럼 같은 텍스트값을 갇는 노드가 존재하기 때문에

    트리항목을 검색할때 레벨에 따라 찾는 방법으로 변경하여야 합니다.





    먼저 FindNode함수를 아래와 같이 작성하세요



    function TForm1.FindNode(ItemArray : array of String) : TTreeNode;

    var

    Node : TTreeNode;

    Level : Integer;

    i : Integer;

    begin

    Result := nil;

    Level := High(ItemArray);

    Node := TreeView1.Items.GetFirstNode;



    for i:=0 to Level do

    begin



    while Node <> nil do

    begin

    if (Node.Text = ItemArray[i]) then

    begin

    if (i = Level) then // 같은값의 노드를 찾은 경우

    begin

    Result := Node;

    Exit;

    end

    else // 같은 값을 찾았으나 하위 레벨을 더 검사해야함

    Break;

    end;

    Node := Node.getNextSibling; // 형제노드를 찾는다

    if (Node = nil) then Exit; // 더이상 형제노드가 없으면 찾는노드가 없음

    end;



    Node := Node.getFirstChild; // 자식노드중 첫번째 노드를 찾는다

    if (Node = nil) then Exit; // 자식노드가 없으면 찾는노드가 없음

    end;



    end;



    코드를 차근히 읽어보면 이해하는데는 그리 어려움이 없을겁니다.







    다음은 FindNode를 호출하는 부분을 아래처럼 변경하세요.



    ParentNode := FindNode([Fst]);

    if (ParentNode = nil) then

    ParentNode := TreeView1.Items.Add(nil,Fst);



    ChildNode := FindNode([Fst,Snd]);

    if (ChildNode = nil) then

    ChildNode := TreeView1.Items.AddChild(ParentNode,Snd);



    if (FindNode([Fst,Snd,Trd]) <> nil) then

    ShowMessage('같은 이름이 이미 존재합니다.')

    else

    TreeView1.Items.AddChild(ChildNode,Trd);



    FindNode호출시 인수 형식만 바꾸면 되지만 원래 작성했던 부분은 같은 값을 두번 찾도록 비효율적으로 작성되어 있어 조금 바꿨습니다.



    그리고 시,구,동 부분을 파싱하는 부분도 조금더 생각해서 수정할 필요성이 있다고 생각됩니다.





    테스트를 해보지 못했습니다. 문제가 발생하면 다시 질문을 올리세요.





    sis7 wrote:

    > 안녕하세요.

    > 설명절전이나 후나 TreeView에 미쳐(?) 사는 델파이를 사랑하는 사람입니다.

    >

    > 제는 지금 ini파일에서 읽은 내용을 TreeView에 출력하려고 합니다.

    > 다행히 저와 같은 경우로 많은 글들이 올라와 있어서 겨우 겨우 조금씩 조금씩 응용해가면서 일을 진행해나갔습니다. 정말 많은 도움이 되었어요...

    > (뒤늦게나마 델선배님들께 감사의 말씀 드립니다. 꾸벅!!)

    >

    > 그런데, 일을 계속 진행하던 중 막히는 부분이 생겼고, 아주 쉽게 해결될것 같다는 미련을 버리지 못해 꽤 오랜(?) 시간을 혼자 끙끙 앓다가 이제서야 도움을 요청하게 되었어요.

    > 정말이지 궁금해요. 문제의 답이 무엇인지를.....

    >

    > 문제에 대해 예를 들어 말씀드리자면 다음과 같아요.

    >

    > (예) ini파일의 내용이 아래와 같을때,

    >

    > sample.ini

    > ==============================

    > [TotalCount]

    > Count=6

    >

    > [Address]

    > 서울시 강남구 역삼동;

    > 강원도 강릉시 죽헌동;

    > 서울시 송파구 오륜동;

    > 인천시 부평구 부평동;

    > 강원도 강릉시 초당동;

    > 부산시 금정구 오륜동;

    > -----------------------------

    >

    > Treeview에서는 다음과 같이 출력되어야 해요.

    >

    > [결과 A]

    > ===========================================

    > 서울시

    > 강남구

    > 역삼동

    > 송파구

    > 오륜동

    >

    > 강원도

    > 강릉시

    > 죽헌동

    > 초당동

    >

    > 인천시

    > 부평구

    > 부평동

    >

    > 부산시

    > 금정구

    > 오륜동

    > -----------------------------------------

    >

    > 위에서처럼 Treeview에 출력하려면, 동적으로 생성하기전에 생성하려는 노드가 있는지 없는지 찾아보는 과정이 있어야하기에 다른 분의 FindNode라는 함수를 사용하여서 노드의 존재여부를 검색하는 루틴을 넣었습니다. 그런데 원하는 결과가 나오질 않아요.

    >

    > 다음의 소스는 제가 지금까지 한 내용입니다.

    >

    > Function CutStr(var st : String; aLength : Integer) : String;

    > begin

    > result := Copy(st,1,aLength);

    > st := Copy(st,aLength+1,length(st) - aLength);

    > end;

    >

    > function TForm1.FindNode( Str : String) : TTreeNode; // 다른 분이 만든 함수

    > var

    > CurItem: TTreeNode;

    > begin

    > Result := nil; // 이 부분은 제가 추가했습니다.

    > // 이걸 안하면 뒤에 FindNode함수를 사용할때 에러가 발생하더라구요.

    > CurItem := TreeView1.Items.GetFirstNode;

    > while CurItem <> nil do

    > begin

    > if CurItem.Text = Str then

    > begin

    > Result := CurItem;

    > exit;

    > end;

    > CurItem := CurItem.GetNext;

    > end;

    > end;

    >

    > procedure TForm1.FormCreate(Sender: TObject);

    > var

    > I, J : Integer;

    > IniFile: TIniFile;

    > Fst,Snd,Trd, Section, FName, temp, IP : string;

    > Sections : TStringList;

    > ParentNode, ChildNode : TTreeNode;

    >

    > begin

    > ItemCount := 0; // 전역 변수

    > FName := 'c:samp.ini';

    > Sections := TStringList.Create;

    > Sections.LoadFromFile(FName);

    >

    > IniFile := TIniFile.Create(FName); // IniFileName = 사용자 INI 파일명

    > ItemCount := IniFile.ReadInteger('TotalCount', 'Count', 0);

    >

    > TreeView1.Items.BeginUpdate;

    > temp := '';

    >

    > for I := 0 to Sections.Count - 1 do

    > begin

    > Section := Sections[i];

    > temp := temp + Section;

    > if Pos(']',temp) <> 0 then CutStr(temp,Pos(']',temp));

    > end;

    >

    > for J := 0 to ItemCount-1 do

    > begin

    > Fst := IniFile.ReadString('IP Address',temp,CutStr(temp,Pos(' ',temp)-1));

    > CutStr(temp,1);

    > Snd := IniFile.ReadString('IP Address',temp,CutStr(temp,Pos(' ',temp)-1));

    > CutStr(temp,1);

    > Trd := IniFile.ReadString('Address',temp,CutStr(temp,Pos(';',temp)-1));

    > CutStr(temp,1);

    >

    > if (FindNode(Fst) <> nil) then ParentNode := FindNode(Fst)

    > else ParentNode := TreeView1.Items.Add(Treeview1.Selected,Fst);

    >

    > if (FindNode(Snd) <> nil) then ChildNode := FindNode(Snd)

    > else ChildNode := TreeView1.Items.AddChild(ParentNode,Snd);

    >

    > if (FindNode(Trd) <> nil) then ShowMessage('같은 이름이 이미 존재합니다.')

    > else TreeView1.Items.AddChild(ChildNode,Trd);

    > end;

    >

    > TreeView1.Items.EndUpdate;

    > IniFile.Free;

    > end;

    >

    >

    > 위 소스대로하면 "같은 이름이 이미 존재합니다."라는 메세지창이 뜨고, ini파일의 내용이 아래처럼 출력됩니다. (물론 당연한 결과이죠)

    >

    > [결과 B]

    > ===========================================

    > 서울시

    > 강남구

    > 역삼동

    > 송파구

    > 오륜동

    >

    > 강원도

    > 강릉시

    > 죽헌동

    > 초당동

    >

    > 인천시

    > 부평구

    > 부평동

    >

    > 부산시

    > 금정구

    > -----------------------------------------

    >

    > "오륜동"이 서울시 송파구와 부산시 금정구에 둘다 있잖아요.

    > 같은 이름의 "동"(ChildNode)이 있어도 ParentNode는 다르니까 [결과 A]처럼 해야되는데 [결과 B]처럼 출력돼요. T.T

    >

    > 문제가 뭔지는 알겠는데 해결방법을 잘 모르겠어요.

    > FindNode라는 함수는 Treeview안에 있는 모든 노드들중에서 찾는 함수라서 제가 사용하는데 적합하지않아서 이렇게 저렇게 바꾸어 보았는데 번번히 실패예요.

    > 저는 모든 노드에서가 아닌, 동일ParentNode안의 ChildNode중에서 같은 이름의 노드가 있는지를 체크해야 하는데 어떻게 해야하는지 도저히 모르겠습니다.

    >

    > 더 이상 진전이 없습니다.

    > 지금에 이르기까지도 무척 고생했거든요. 처음 일을 시작할때는 금방 끝날줄 알았는데 ...

    >

    > 일의 초반부터 이렇게 헤메고 있어 앞이 캄캄합니다.

    > 아직 갈길이 멀기만 한데...

    > 하나 하나 풀어나가는 재미가 있긴 하지만, 혼자 공부하는것도 아닌, 기한이 있는 일인데 제자리에서 계속 맴맴하니까 답답하고 시간도 너무 많이 흘렀어요.

    >

    > 앞으로 동적으로 Treeview의 Items를 입력할수 있도록 해서 Ini파일에 쓰도록 해야도 되고 ... 여러가지로 할 일은 많은데...

    >

    > 제발 델선배님들의 따뜻한 관심과 일타를 부탁드립니다.

    > (얼굴도 모르는 델선배님들께 도움을 요청해서 너무 죄송하지만.... 그래도 도와주셨으면 합니다.)

    >

    > 늦은 인사지만 새해복 많이 많이 받으시고 건강하세요.

    > 그리고 하시는 일 모두 모두 성취되시길 기원합니다.

    >

    > @--&~~

    >

    >

  • Profile
    sis7 2001.01.30 19:44
    안녕하세요.



    우선 바쁘신 중에도 얼굴도 이름도 모르는 제게 시간을 할애해서 답변해주셔서

    진심으로 감사드립니다.



    답변해주신 내용대로 소스를 수정하였는데 컴파일시에는 아무런 에러가 발생하지

    않았는데, 실행을 시키면 다음과 같은 에러가 발생하면서,



    Access violation at address 0043546C in module 'MYPROJECT.EXE'.

    Read of address FFFFFFFF.



    ParentNode := FindNode([Fst]); 라인에 화살표 표시와 파란색의 줄이 생깁니다.





    제가 Treeview의 노드를 읽는 루틴중에 뭔가 잘못된것 같은데... 잘 모르겠습니다.

    처음엔 답변해주신 내용을 제가 입력하면서 오타가 나서 그런줄 알고, 신호성님의

    답변을 그대로 복사해서 해보았는데도 마찬가지입니다.



    근데 이상한건 분명히 제가 처음 신호성님 답변 그대로 입력해서 실행했을때는 그런

    에러가 발생하지 않았는데, 세번째 실행한 이후로 위의 문제가 발생하더라구요.



    그러니까 처음 첫번째, 두번째까지는 실행이 잘 되었습니다.

    그래서 Treeview에 "강릉시"가 두번 나오는것까지 확인했었거든요.



    ====================================



    강원도

    강릉시

    죽헌동

    강릉시

    초당동



    ====================================



    "강릉시"가 두번 나오니까 그만 당황(?)해서 프로그램을 종료시키고, 소스를 자세히

    분석하고 다시 세번째 실행했을때는 더이상 프로그램이 실행되지 않아서 제가 그렇게

    알고자했던 "오륜동"이 어떻게 출력되는지는 미처 확인을 못해봤습니다.



    왜 그럴까요 ?

    처음 두번까지는 실행이 잘 되었다가 갑자기 실행이 안되는 이유가 .....

    소스도 바꾼것없이 그대로 실행했는데....

    그리고 왜 Error가 발생하는지 ...

    어디 부분에서 데이타를 읽다가 에러가 발생하는건지 ...



    아무튼, 소중한 시간을 할애해서 답변해주셨는데, 또 답변을 부탁드려서 죄송합니다..



    좋은 하루되세요... @--&~~