2010-01-12 8 views
0

작성된 모든 adoquery를 닫고 (임의의) 양식에서 열려는 절차를 작성 중입니다. 문제는 구성 요소를 식별하기 위해 양식에 대한 형변환을해야한다는 것입니다. 예제와 같이 동적 캐스트를 만들려면 어떻게해야합니까?양식을 동적으로 전송하십시오.

나는이 코드입니다이

Procedure OpenADODataSets(Form:TForm;FormType:TClass); 
... 
... 
(Form as FormType).ComponentCount 

또는

Procedure OpenADODataSets(Form:TForm;FormType:TClass); 
... 
... 
FormType(Form).ComponentCount 

뭔가를해야합니다. (내가 주석으로) 당신이 (FormType 같은 양식) 필요합니까 왜 @Edelcom

Procedure OpenADODataSets(Form:TForm); 
var 
    i: integer; 
begin 

    for i:=0 to Form.ComponentCount-1 do 
    if Form.Components[i].ClassType=TADOQuery then 
     if not TADOQuery(Form.Components[i]).Active then 
     TADOQuery(Form.Components[i]).Open; 

end; 
+0

왜 (Form을 FormType으로) 필요합니까? – Edelcom

+1

구성 요소의 유형이 * TADOQuery와 정확히 같은지 테스트하는 대신 ** is ** 연산자를 사용하여 구성 요소가 * TADOQuery에서 파생되는지 테스트해야합니다 : if Form.Components [i] is is TADOQuery가 아니라 TADOQuery (Form.Components [i])입니다. 활성 상태입니다. ' –

답변

2

의 대답 해결

Procedure OpenADODataSets(Form:TForm;FormType:TClass); 
var 
    i: integer; 
begin 

    for i:=0 to (Form as FormType).ComponentCount-1 do 
    if (Form as FormType).Components[i].ClassType=TADOQuery then 
     if not TADOQuery((Form as FormType).Components[i]).Active then 
     TADOQuery((Form as FormType).Components[i]).Open; 

end; 

UPDATE

문제.

procedure TProgSettingsVisual.FillStandardSaveFilesForForm(const pForm: TForm;); 
var i : integer; 
    x : string; 
    thisComponent : TComponent; 
begin 
    With pForm do 
    begin 
     for i := 0 to ComponentCount-1 do 
     begin 
     thisComponent := Components[i]; 

     x := LowerCase(Components[i].ClassName); 


     if x = 'tovcinifilestore' 
     then begin 
      TOvcIniFileStore(Components[i]).IniFileName := FormSaveFile(pForm); 
     end; 

     if x = 'tovdformstate' 
     then begin 
      ... 
     end; 

     if x = 'tovccomponentstate' 
     then begin 
       ... 
+0

+1, 모든 양식은 TForm의 하위 항목이므로 TForm이 잘 작동하므로 변환 할 필요가 없습니다. TDataModule은 TForm에서 파생되지 않기 때문에 별도로 처리해야 할 수도 있습니다. –

+1

아니요, J, 별도로 처리 할 필요가 없습니다.* 'TComponent'의 모든 * 자손은'ComponentCount', 'Component' 및'ClassName'과 같은 필수 속성을가집니다. 후자는 실제로 사용하는 것이 좋습니다. ** is ** 연산자를 사용하여 문자열 비교가 아닌 구성 요소 유형을 테스트하십시오. 두 객체가 같은 클래스 이름을 가질 수 있지만 다른 유형이 될 수 있습니다. –

1

타입 캐스팅의 목적이 그 식별자를 사용하여 올바른 코드를 생성 할 수 있도록 컴파일러에게 식별자의 종류를 이야기하는 것입니다 잘 작동 내 자신의 코드의 일부를 보았다. 원하는 형식이 변수에 저장되면 컴파일러는 형식 검사를 수행 할 수 없습니다. FormType의 런타임 값이 Components 속성을 가진 형식이므로 코드를 컴파일 할 수 없음을 확인할 수 없습니다.

유형이 무엇인지 모르는 경우 유형을 유형 변환 할 수 없습니다. 그렇게 할 필요가 있음을 알게되면, 당신은 잘못된 행동을하고있는 것입니다. 당신이 정말로하려고하는 것에 관한 질문을 게시하십시오. ("XY 문제."를 참조하십시오.)

귀하의 경우, 여러 가지 형태로 작동하는 함수를 작성하는 것이 좋습니다. 그러나 양식 객체에서 사용중인 모든 속성은 TForm 또는 이전에 소개 된 속성이기 때문에 모든 양식 유형에서 실제로 사용할 수 있습니다. 실제로 사용하는 속성은 TComponent에 있으며 모든 구성 요소는 다른 구성 요소를 소유 할 수 있으므로 모두 ComponentsComponentCount 속성을가집니다. 코드가 구성 요소 유형과 동일하게 작동 할 수 있으므로 양식의 특정 유형을 알 필요가 없습니다. 델파이 2005 년

procedure OpenADODataSets(Owner: TComponent); 
var 
    i: Integer; 
begin 
    for i := 0 to Owner.ComponentCount - 1 do 
    if Owner.Components[i] is TADOQuery 
     and not TADOQuery(Owner.Components[i]).Active then 
     TADOQuery(Owner.Components[i]).Open; 
end; 

심지어 :

procedure OpenADODataSets(Owner: TComponent); 
var 
    comp: TComponent; 
begin 
    for comp in Owner do 
    if comp is TADOQuery 
     and not TADOQuery(comp).Active then 
     TADOQuery(comp).Open; 
end; 

데이터 세트가 이미 그들 자신을 열기 전에 활성있어 여부를 확인하기 때문에, 당신은 정말 먼저 확인하지 않아도 :

if comp is TADOQuery then 
    TADOQuery(comp).Open; 
+0

Rob, AdoQuery를 열기 전에이 코드에서 AdoQuery의 활성 상태를 확인하는 이유는 무엇입니까? 활성 속성의 Setter 메서드는 이미 데이터 집합이 활성 상태인지 여부를 확인하고 닫혀있는 경우에만 활성화합니다. – vcldeveloper

+0

질문에있는 코드에 기반한 코드입니다. 질문의 초점은 검색어를 여는 최선의 방법이 아니기 때문에 요점을 혼란스럽게하지 않도록 코드의 해당 부분을 변경하지 않기로 결정했습니다. 게다가, 나는 내 대답의 끝까지 읽지 않을 것이라고 생각한다. 그렇지 않다면, 내가 궁금해하는 바로 그 문제를 궁극적으로 다룰 수 있다는 것을 알았다. –

+0

네, 맞습니다. 두 코드 상자 사이의 마지막 줄을 읽지 않았습니다. 설명해 주셔서 감사합니다. – vcldeveloper

관련 문제