Q&A

  • ODAC Fetch 질문입니다 (김지훈님 부탁드립니다)
안녕하세요 ODAC에 관련된 질문입니다
팁란에 김지훈님이 작성하신 내용중 일부입니다

================================================
* 추가사항
제가 하는 프로젝트의 경우 워낙 데이터가 많다보니(이동통신회사) 보고서 조회시 속도문제가 가장 큽니다.(물론 데어터의 정확성은 기본이구요)

데이터를 조회해서 그리드로 보여줄때 FetchRow를 기본row 25 개로 지정해서 조회를 하는데
사용자가 다시 그리드의 pagedown을 하여 데이터를 더 가져오거나,(25 record 단위)
그리드 스크롤을 최하단으로 끌어내리면 모든 데이터를 한꺼번에 가져오게 되는데 이경우 화면이 정지된것처럼
보여 이부분에 대해 odac 소스를 약간 수정해서 refresh 되도록 현재가져오는 데이터의 record 건수를 실시간으로 보여주도록 처리했습니다.

최초 25건을 그리드에 뿌려주고,  그리드는 마지막 데이터를 가져올때까지 계속 Fetchrow 만큼 데이터를 그리드에 추가해 주면서 record count는 refresh 해주게 됩니다. 물론 사용자는 다른 작업을 할 수 있습니다. 그리드로 원하는 데이터를 선택할 수 있습니다. 폼의 위치를 옮길수 도 있구요. 중간에 멈추게 할 수도 있구요.
(화면이 멈춰있는 것보단 덜 답답하더군요)

OraClass.pas 소스에서 ( 실시간 record 건수 가져오는 부분)

function TOCIRecordSet.FetchArray(FetchBack: boolean = False): boolean;
를 약간 수정을 하였습니다.

최하단에 현재까지 진행된 FetchedRows 를 그리드가 있는 폼으로 메세지를 날립니다.
SendMessage( TARGET_FORM.Handle, WM_USER_FETCHEDROWS,   Command.FFetchedRows,  0 );

실제 db 프로그램을 작성하신 분이라면 금방 이해하실 만한 내용이라
실제 소스에서 구현된 세세한 부분은 제외 시켰습니다.


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

저희도 DBGrid에 ODAC를 이용하여 개발중인데요
많은양의 데이터를 DBGrid에 출력했을때 스크롤를 마지막으로 내리면 행이 걸린거 처럼 나타납니다
그래서 팁란에 김지훈님이 작성하신 내용을 보고 소스를 수정중인데 잘안되네요

일단 TARGET_FORM은 프로세스에서 찾아서 핸들을 구했는데 메세지가 전달이 안됩니다
위방법을 성공하신분은 답변 꼭 부탁드립니다

그럼 즐거운 주말 보내세요.....
4  COMMENTS
  • Profile
    김씨 2006.08.20 19:25



    그리드가 있는 폼에서 메세지를 못 받는 경우라면 아래 처럼 받는 부분에 대한 처리를 추가 하셨는지요?


    --선언부
        //20060324 kjh
        procedure WmFetchRows(var Msg :TMessage); message WM_USER_FETCHEDROWS;


    --구현부
    procedure TfrmReportResult.WmFetchRows(var Msg :TMessage);
    begin
        //if uf_CheckOpenForm = True then exit;

        fThreadQry.DisableControls;

        //if Trim(LabelEa.Hint) = '' then
        //begin
            IF Msg.WParam > 0 THEN
                LabelEa.Caption := 'Rec = ' + IntToStr(Msg.WParam) ; // + ' / ' + LabelEa.Hint;
        //end
        //else
        //begin
        //    LabelEa.Caption := 'Rec = ' + IntToStr(Msg.WParam)  + ' / ' + LabelEa.Hint;
        //end;
        fThreadQry.EnableControls;

        application.ProcessMessages;


    end;
  • Profile
    언제나초보 2006.08.21 17:35
    답변 감사드립니다.
    그리드가 있는 쪽에서 메세지 처리는 했는데요
    ODAC 소스 수정부분이 잘못된거 같습니다.
    Target Form의 핸들은

      function SearchProcess32(SearchProcess: string): DWORD;
      var
      Process32: TProcessEntry32;
      SHandle:   THandle;  // the handle of the Windows object
      Next:      BOOL;
      begin
        result := 0;

        Process32.dwSize := SizeOf(TProcessEntry32);
        SHandle          := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        try
          if Process32First(SHandle, Process32) then
          begin
            // 실행화일명과 process object 저장
            if Uppercase(Process32.szExeFile) = SearchProcess then
            begin
              Result := Process32.th32ProcessID;
            end
            else
              repeat
                Next := Process32Next(SHandle, Process32);
                if Next then
                  if Uppercase(Process32.szExeFile) = SearchProcess then
                  begin
                    Result := Process32.th32ProcessID;
                    exit;
                  end
              until not Next;
          end;
        finally
          CloseHandle(SHandle);
        end;
      end;

    이 함수를 사용하여 핸들값을 구한후
    SendMessage(hRcv, WM_USER_FETCHEDROWS, FCommand.FFetchedRows,  0 );
    이렇게 메세지를 보냈습니다.
    성공하신 ODAC수정된 부분좀 가르쳐 주실수 있나요
    답변 부탁드립니다.
  • Profile
    김씨 2006.08.21 19:36



    target이 해당 폼 아닌가요? 그리드가 있는 폼~

    저의경우는 같은 프로그램내의 그리드가 있는 폼의 핸들을 넘겨주면 되는데... 프로세스 아이디까지 찾으시는걸보니..또 다른 실행파일 내에 있는 폼인가보죠? form.Handle 이거면 되는데...

    별도의 파일이라면 실행파일이 핸들을 아시니까 그 파일내의 폼의 핸들을 넘겨주시면 될듯합니다.
  • Profile
    언제나초보 2006.08.21 20:09
    이렇게 빨리 답변 주셔서 감사드립니다
    제가 컴포넌트 수정을 잘 몰라서 그러는데요
    그리드가 있는쪽에서 OraClasses.pas로 어떻게 form의 handle을 넘겨 주어야 하는건가요?
    SendMessage(Application.MainForm.ActiveMDIChild.Handle, WM_USER_FETCHEDROWS, FCommand.FFetchedRows,  0 );
    이렇게 하면 표시는 데는데요
    PageDown을 누르면 잘 나타납니다
    그런데 스크롤을 마지막으로 내리면 여전히 먹통이 되네요
    전 SendMessage를 TOCIRecordSet.FetchArray 의 마지막 부분인
      finally
        SendMessage(Application.MainForm.ActiveMDIChild.Handle, WM_USER_FETCHEDROWS, FCommand.FFetchedRows,  0 );
        FCommand.Release;
      end;
    이렇게 하니 잘 안됩니다

    또 한가지는 OraClasses.pas에 Handle변수를 만들어 그리드가 있는폼이 Create될때
    그리드폼의 핸들을 넘겨주었습니다.
    이것도 마찬가지더군요.
    SendMessage의 위치가 잘못되었나요?
    혹시 OraClasses.pas의 어디를 수정해야 하나요?
    답변 꼭 부탁드립니다