Dúvida com select
Tenho uma tabela2 com os campos composição1 (string) com apenas 1 palavra, composição2 (string) com apenas 1 palavra e o campo reação(string).
Agora a pesquisa: a pessoa digita num edit1 o nome1, e no edit2 o nome2, ao clicar um botão, deverá fazer o seguinte:
1) buscar o nome1 na tabela1, pegar todos as composições contidas no campo composição e montar uma matriz X de M elementos (de acordo com a quantidade de componentes contidos neste campo);
2) buscar o nome2 na tabela1, pegar todos as composições contidas no campo composição e montar uma matriz Y de N elementos (de acordo com a quantidade de componentes contidos neste campo);
3) montar uma combinação entre as duas matrizes, digamos uma matriz Z para jogar o resultado da pesquisa neste matriz;
4) pegar a matriz X[I] e buscar na tabela2 no campo composição1, se achar então pega a matriz Y[I] e busca na tabela2 no campo composição2, caso ache pega o resultado contido na tabela2, campo reação e joga na matriz Z[I].
Eu não tenho problema em criar as matrizes, nem em criar a combinação, o meu problema está em construir esta SQL
Edilcimar
Respostas
Emerson Nascimento
04/02/2006
creio que isso seja possível com Stored Procedures.
Marco Salles
04/02/2006
1) buscar o nome1 na tabela1, pegar todos as composições contidas no campo composição e montar uma matriz X de M elementos (de acordo com a quantidade de componentes contidos neste campo);
2) buscar o nome2 na tabela1, pegar todos as composições contidas no campo composição e montar uma matriz Y de N elementos (de acordo com a quantidade de componentes contidos neste campo);
Estas duas etapas acho que pode ser resolvido com sql seguido de um laço para que se monte as matriz X e Y . Ja que se tem no camo composição os componentes separados por Virgula
A terceira e quarta etapa tenho duvidas
Qual seria a estrutura dessa matriz.. Digo em termos de linha e colunas
Por exemplo Na etapa 1) Retorne 3 composicoes Na etapa 2) Retorne 2 Composiçoes
Como seria a estrutura de Z ???
Seria uma matriz Z(3+2,1)... cinco Linhas e Uma Coluna
Seria uma matriz Z(1,3+2)... Uma linha e cinco Colunas
Seria uma matriz Z(3,2)... tres linhas e duas Colunas
Seria uma matriz Z(2,3)... duas linhas e Tres Colunas
Esta etapa para mim é a mais confusa...Pois alem da estrutura da Matriz Z
recorre problema de ordem dos indices. Vejamos :
quem garante que a quantidade de Xi seja igua a quantidade de Yi..
o entendimento desta etapas parece ser a parte mais dificil.. Parece que voce que fazer um combinação de composiçoes..
Edilcimar
04/02/2006
Tabela1 tenho 2 produtos Produto1 e Produto2
Produto1 é composto de (A e B) ->Matriz X[1] = ´A´ e X[2] = ´B´
Produto2 é composto por (A, C, D) -> Matriz Y[1] = ´A´, Y[2] = ´C´ e Y[3] = ´D´
Crio então uma matriz Z que terá 6 elementos para captar o resultado das combinações [AA,AC,AD,BA,BC,BD]
faço agora a pesquisa na Tabela2 pelo elemento X[1] no campo composição1, e depois busco no campo composição2 todos os 3 elementos da matriz Y ou seja Y[1], Y[2] E Y[3] se o resultado for encontrado é porque existe uma reação negativa, então o Z[I] pega este resultado, depois passo para o X[2] e faço o mesmo processo. Então eu teria que:
Z[1] que veio de AA é nulo,
Z[2] que veio de AC é febre
Z[3] que veio de AC é nulo
Z[4] que veio de BA é diarréia
Z[5] que veio de BC é dor de cabeça e vômito
Z[6] que veio de BD é diminuição do efeito de B
Eu até sei montar isto usando for e while, porém com uma tabela deste tamanho e a quantidade de combinações possíveis, iria virar uma carroça, por isto estou querendo fazer com sql
O banco ainda não foi montado, mas pode ser firebird com ibquery ou piradox com query
Marco Salles
04/02/2006
Da dando para entender... Mas para ser dez e ter este resultado
[b:0c609e4c6d]Como voce definiu a sua tabela 2 ???? para mim isto e crucial[/b:0c609e4c6d]
Edilcimar
04/02/2006
Marco Salles
04/02/2006
isto eu entendi , so que não daria para voce definir tb a tabela 2 para que a gente possa a partir de :
e efetuando a pesquisa na tabela 2 chegar no resultado em Z
so para entender melhor :
Edilcimar
04/02/2006
na tabela 1 eu coloquei 2 produtos
Produto1-> A, B, C
Produto2-> A, D, E, F
Na tabela 2 eu coloquei as seguintes reações
A+D -> dor de barriga
A+F -> febre
B+D -> asia
B+E -> náusea
C+E -> diarréia
C+F -> vômito
portanto quando eu procurar por estes 2 produtos o resultado da matriz z terá que ser o acima mais os campos nulos
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Marco Salles
04/02/2006
mas em relação a tabela 2
vejo um problema na construção da mesma.. Talvez tenha que sempre que inserir uma combinação de medicamentos , voce deva faze-lo também na ordem inversa , ou uma outra saida e fazer uma pesquisa de X[i] pelo campo composicao2 se achar pesquise também Y[i] pelo campo Cpmposicao1 , simultaneamente
Porque por exemplo , na tabela 2 pode estar cadastrado
A + D = Dor de barriga , mas não necessáriamente pode estar cadastrado
D + A = Dor de barriga
[b:19d60c8dfa]concorda com esta colocação ????[/b:19d60c8dfa]
Edilcimar
04/02/2006
Marco Salles
04/02/2006
então vamos ver se da tempo para acabar hoje
antes de irmos para o sql , voce conhece alguma função que separa pela virgula as composiçoes
acho que ja ate fiz um código desse aqui
vou pesquisar
Edilcimar
04/02/2006
Marco Salles
04/02/2006
mas vamos criar uma .
Marco Salles
04/02/2006
procedure CriarMatrizX(Composicao:String); var i,indiceanterior:integer; texto:String; begin i:=1; indiceAnterior:=1; while i <= length(composicao) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); indiceAnterior:=i+1; //aqui voce vaui criar a MatrizX[i] form1.Memo1.Lines.Add(texto); end; i:=i+1; end; end;
Edilcimar
04/02/2006
procedure TForm4.Button2Click(Sender: TObject);
var
I, J : Integer;
Texto, Temp : String;
X : array of string;
begin
Temp := ´´;
J := 1;
Texto := Edit1.Text;
For I := 0 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Temp := Temp + Texto[I]
Else
Begin
SetLength(X, J);
J := J + 1;
X[I] := Temp;
Temp := ´´;
End;
End;
end;
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Temp := ´´;
J := 1;
Texto := Edit1.Text;
With Table1 do
Begin
If Locate(´Produto´,Edit1.Text,[]) then
Texto := FieldByName(´COMPOSICAO´).AsString;
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 0 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Temp := Temp + Texto[I]
Else
Begin
SetLength(X, J);
J := J + 1;
X[I] := Temp;
Temp := ´´;
End;
End;
Marco Salles
04/02/2006
Coloquei
X : array of string; somente no eu código mas da erro de acesso vilolado
procedure CriarMatrizX(Composicao:String); var i,indiceanterior,q:integer; texto:String; X : array [1..10] of string; begin q:=0; i:=1; indiceAnterior:=1; while i <= length(composicao) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); indiceAnterior:=i+1; //aqui voce vaui criar a MatrizX[i] X[q]:=texto; q:=q+1; form1.Memo1.Lines.Add(texto); end; i:=i+1; end; end;
Edilcimar
04/02/2006
procedure TForm4.Button2Click(Sender: TObject);
var
I, J : Integer;
Texto, Temp : String;
[b:b946e17ed6]X : array of string;[/b:b946e17ed6]
begin
Temp := ´´;
J := 1;
With Table1 do
Begin
If Locate(´Produto´,Edit1.Text,[]) then
Texto := FieldByName(´COMPOSICAO´).AsString
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 0 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Temp := Temp + Texto[I]
Else
Begin
[b:b946e17ed6]SetLength(X, J);[/b:b946e17ed6]
J := J + 1;
X[I] := Trim(Temp);
Temp := ´´;
End;
End;
end;
Edilcimar
04/02/2006
X[J] := Trim(Temp);
porém no nosso processo o terminador está sendo a vírgula e no último elemento não tem, vou corrigir
Edilcimar
04/02/2006
For I := 0 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
SetLength(X, J);
X[J] := Trim(Temp);
End
Else
Begin
SetLength(X, J);
J := J + 1;
X[J] := Trim(Temp);
Temp := ´´;
End;
End;
Marco Salles
04/02/2006
Agora a outra parte importante , o que facilitaria muito , e sobre a criação de Z
nos seus exemplos voce trabalha sempre com caracter para representar
as Matrizes X e Y ...Tenho uma função de combinação pronta para este tipo de situação..Mas so vale para caracter..
Função :
function GeraCombinacoes(S: string; NumDig: Integer): TStrings; var I, J: Integer; X: Char; TS: TStrings; S1: string; begin Result := TStringList.Create; TS := TStringList.Create; for I := 1 to Length(S) do Result.Add(S[I]); while Length(Result.Strings[0]) < NumDig do begin for I := 0 to (Result.Count - 1) do begin S1 := ´´; for J := 1 to Length(S) do begin X := S[J]; if Pos(X, Result.Strings[I]) = 0 then S1 := S1 + X; end; for J := 1 to Length(S1) do begin X := S1[J]; TS.Add(Result.Strings[I] + X); end; end; Result.Text := TS.Text; TS.Clear; end; TS.Free; end;
Para chamar por exemplo
Memo3.Lines.Assign(GeraCombinacoes(´ABCDEFG´, 2));
esta função ta na mao , caso contrario teremos que desenvolver outra , o que vai ser um pouco dificil aparentemente
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Marco Salles
04/02/2006
se voce vai criar com apenas uma.. O que eu to te perguntando e se :
porque fora isto vaiu dar mais trabalho, ja que a fuçao GerarCombinacoes ja esta pronta
Pense que ao inves de ser assim
Memo3.Lines.Assign(GeraCombinacoes(´ABCDEFG´, 2));
eu escrevesse assim
***Instrução a seguir so como exemplo **não vale . Não compila
Memo3.Lines.Assign(GeraCombinacoes(X+Y, 2));
Edilcimar
04/02/2006
Edilcimar
04/02/2006
procedure TForm4.Button2Click(Sender: TObject);
var
I, J : Integer;
Texto, Temp : String;
X, Y : array of string;
begin
Temp := ´´;
J := 1;
With Table1 do
Begin
If Locate(´Produto´,Edit1.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
SetLength(X, J);
X[J] := Trim(Temp);
End;
End
Else
Begin
SetLength(X, J);
J := J + 1;
X[J] := Trim(Temp);
Temp := ´´;
End;
End;
With Table1 do
Begin
If Locate(´Produto´,Edit2.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
J := 1;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
SetLength(Y, J);
Y[J] := Trim(Temp);
End;
End
Else
Begin
SetLength(Y, J);
J := J + 1;
Y[J] := Trim(Temp);
Temp := ´´;
End;
End;
end;
Marco Salles
04/02/2006
se for o caso , da ate para desenvover outra .. Mas eu estou emperrado
na criação da matriz dinamica
Por gentileza , aonde estou errando
Copie o codigo e veja o err que aparece
procedure CriarMatrizX(Composicao:String); var i,indiceanterior,q:integer; texto:String; X : array of string; begin q:=0; i:=1; indiceAnterior:=1; while i <= length(composicao) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); indiceAnterior:=i+1; //aqui voce vaui criar a MatrizX[i] X[q]:=Trim(texto); q:=q+1; form1.Memo1.Lines.Add(texto); end; i:=i+1; end; end;
para chamar
procedure TForm1.Button2Click(Sender: TObject); begin CriarMatrizX(´ABS ; DE ; W; H ; J; I´); end;
eu preciso disso para proseguir
Edilcimar
04/02/2006
X : array of string;
begin
.
setlength(x, 100), veja lá em cima onde coloquei em negrito
Marco Salles
04/02/2006
2)ja que voce esta trabalhando com matriz , como saber quantos elementos tem esta matriz... Tip um recorcCound
Edilcimar
04/02/2006
Edilcimar
04/02/2006
X[J] := Trim(Temp);
Marco Salles
04/02/2006
X[J] := Trim(Temp);
para isto voce deve fazer antes
[b:3cccd45148]setlength(x, 100), [/b:3cccd45148]
mas eu to querendo fazer
Como usa ::
Edilcimar
04/02/2006
Temp := ´´;
J := 1;
SetLength(X,1);
SetLength(Y,1);
With Table1 do
Begin
If Locate(´PRODUTO´,Edit1.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
X[J-1] := Trim(Temp);
SetLength(X, J);
End;
End
Else
Begin
X[J-1] := Trim(Temp);
J := J + 1;
SetLength(X, J);
Temp := ´´;
End;
End;
With Table1 do
Begin
If Locate(´PRODUTO´,Edit2.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
J := 1;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
Y[J-1] := Trim(Temp);
SetLength(Y, J);
End;
End
Else
Begin
Y[J-1] := Trim(Temp);
J := J + 1;
SetLength(Y, J);
Temp := ´´;
End;
End;
TamanhoX := Length(X);
TamanhoY := Length(Y);
se usar lenght(x) terá o tamanho da matriz, se usar high(x) terá o valor do maior índice da matriz, ou seja length - 1
Marco Salles
04/02/2006
como definir a Matriz Z uma matriz n,2 .. onde o n não se sabe
Edilcimar
04/02/2006
X, Y : array of string;
StLength(X,1);
SetLength(Y,1);
SetLength(X, J);
SetLength(Y J);
Marco Salles
04/02/2006
Edilcimar
04/02/2006
TamanhoX := Length(X);
TamanhoY := Length(Y);
SetLength(Z, TamanhoX * TamanhoY);
Edilcimar
04/02/2006
procedure TForm4.Button2Click(Sender: TObject);
var
I, J, K, TamanhoX, TamanhoY : Integer;
Texto, Temp : String;
X, Y, Z : array of string;
begin
Temp := ´´;
J := 1;
SetLength(X,1);
SetLength(Y,1);
With Table1 do
Begin
If Locate(´PRODUTO´,Edit1.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
X[J-1] := Trim(Temp);
SetLength(X, J);
End;
End
Else
Begin
X[J-1] := Trim(Temp);
J := J + 1;
SetLength(X, J);
Temp := ´´;
End;
End;
Temp := ´´;
With Table1 do
Begin
If Locate(´PRODUTO´,Edit2.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
J := 1;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
Y[J-1] := Trim(Temp);
SetLength(Y, J);
End;
End
Else
Begin
Y[J-1] := Trim(Temp);
J := J + 1;
SetLength(Y, J);
Temp := ´´;
End;
End;
TamanhoX := Length(X);
TamanhoY := Length(Y);
K := 0;
SetLength(Z, TamanhoX * TamanhoY);
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Z[K] := X[I] + ´+´ + Y[J] +´= ´;
Memo1.Lines.Add(Z[K]);
K := K + 1;
End;
End;
end;
Marco Salles
04/02/2006
falta alguns ajustes ,,,
é apenas o esboço
daqui ha pouco vai
Edilcimar
04/02/2006
Marco Salles
04/02/2006
implementation {$R *.DFM}
procedure CriarMatrizX(Composicao:String); var i,indiceanterior,q:integer; texto:String; begin q:=0; i:=1; indiceAnterior:=1; while i <= length(composicao) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); indiceAnterior:=i+1; //aqui voce vaui criar a MatrizX[i] X[q]:=Trim(texto); q:=q+1; form1.Memo1.Lines.Add(texto); FormacaoString:=formacaoString+texto; end; i:=i+1; end; end;
procedure CriarMatrizY(Composicao:String); var i,indiceanterior,q:integer; texto:String; begin setlength(Y, 100); i:=1; indiceAnterior:=1; while i <= length(composicao) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); indiceAnterior:=i+1; //aqui voce vai criar a MatrizY[i] Y[q]:=Trim(texto); form1.Memo2.Lines.Add(texto); FormacaoString:=FormacaoString+texto; end; i:=i+1; end; end;
//Veja que é uma reduntancia os dois métodos serem iguais... É so fazer uma passagem de parametro com Var
function GeraCombinacoes(S: string; NumDig: Integer): TStrings; var I, J: Integer; X: Char; TS: TStrings; S1: string; begin Result := TStringList.Create; TS := TStringList.Create; for I := 1 to Length(S) do Result.Add(S[I]); while Length(Result.Strings[0]) < NumDig do begin for I := 0 to (Result.Count - 1) do begin S1 := ´´; for J := 1 to Length(S) do begin X := S[J]; if Pos(X, Result.Strings[I]) = 0 then S1 := S1 + X; end; for J := 1 to Length(S1) do begin X := S1[J]; TS.Add(Result.Strings[I] + X); end; end; Result.Text := TS.Text; TS.Clear; end; TS.Free; end;
//esta função que a partir de X e de Y Gera-la a Matriz Z
//Tb não implementei esta parte.. Coloquei apenas na forma de Memo3
procedure TForm1.Button1Click(Sender: TObject); var i,j,indice:integer; begin //pesquisa na tabela1 Query1.Close; Query1.SQL.Clear; Query1.Sql.Add(´Select *From Tabela1´); Query1.Sql.Add(´Where Produto=:NomePrimeiroProduto´); Query1.ParamByName(´NomePrimeiroProduto´).asstring:=edit1.text; Query1.Sql.Add(´And Produto=:NomesegundoProduto´); Query1.ParamByName(´NomesegundoProduto´).asstring:=edit2.text; Query1.Prepare; Query1.open; Criaçao da MatrizX tamanhox:=0; setlength(x, 100); CriarMatrizX(query1.FieldByName(´Produto´).asstring); Query1.Next; //Criaçao da Matriz Y tamanhoy:=0; setlength(y, 100); CriarMatrizY(query1.FieldByName(´Produto´).asstring); //******ETAPA ABAIXO DEVE SER SUBSTITUIDA Memo3.Lines.Assign(GeraCombinacoes(formacaoString,2)); //aqui voce deve criar a sua matriz Z .. Ela é da forma N,2 //eu não to fazendo este passo..suponha que a partir de Memo3 se consiga isto //Novamente mais uma consulTa , agora na tabela 2 i:=1; for i:=1 to tamanhox do begin for j:=1 to tamanhoy do begin Query2.Close; Query2.SQL.Clear; Query2.Sql.Add(´Select *From Tabela2´); Query2.Sql.Add(´Where (Composicao1=:Comp1´); Query2.Sql.Add(´And Composicao2=:Comp2)´); query2.sql.add(´Or(composicao1:=comp2´); query2.sql.add(´and(composicao2:=comp1))´); Query2.ParamByName(´Comp1´).asstring:=X[i]; Query2.ParamByName(´Comp2´).asstring:=Y[J]; Query2.Prepare; Query2.open; //esta é a lei de formação servira para implementar Z****** Indice:=(i*j)+(i-1)*(3-j); //A formula anteiror no meu conceito e de extrema importancia para //a formação da futura Matriz Z if query2.fieldByName(´Reacao´).AsString <> ´´ Then Memo4.Lines.Add(query2.fieldByName(´Reacao´).AsString) //Z[i,Indice]:=query2.fieldByName(´Reacao´).AsString //nada foi encontrado else Memo4.Lines.Add(´´); // Z[I,indice]:=´´; end; end; end;
[b:cac9145575][b]outro passo importante que não foi mencionado e não foi jevantado e sobre os Produtos da Tabela1.. Por suposição na Tabela1 Nunca Tera 2
Produtos Iguais, isto é os Pordutos são sempre diferentes[/b:cac9145575]
espero que tenha tirado alguma idéia , pois deu trabalho
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Query1.ParamByName(´Comp1´).AsString:=X[I - 1];
Query1.ParamByName(´Comp2´).AsString:=Y[J - 1]; nesta linha, dizendo que query1.parameter ´Comp2´ not found, isto na primeira passada do loop, porém se dou um showmessage no y[j-1] ele me mostra o valor
Marco Salles
04/02/2006
o código que lhe passei não tem isto
outra coisa edicilmar , voltei aqui so para te dizer isto:
1)para testar deve cadastrar a composicao na tabela1 sem deixar espaços,
isto porque estamos trabalhando com caracter
Assimdev-se ter por exemplo
Produto1 A;S;D;F
Produto2 H;J;K;L
2)outra coisa que quero deixar levantado e sobre esta citação
esta formula não esta certa.. Vou desenvolver uma outra formula e post amanha de manha
[b:db5ac3f1c8]Por mais modifique a sql para o código que eu postei.. Note que to trabalhando com duas query[/b:db5ac3f1c8] Uma consulta na tabela1 e outra na tabela2
É claro que este cídigos no fim podem ser todos Maximizados.. Mas isto é para ver aonde podemos chegar
Boa sorte
Edilcimar
04/02/2006
K := 0;
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select * From Reacao´);
Query1.Sql.Add(´Where ((ELEMENTO1 =:Comp1 ´);
Query1.Sql.Add(´And (ELEMENTO2 =:Comp2)) ´);
Query1.Sql.Add(´Or ((ELEMENTO1 :=Comp2) ´);
Query1.Sql.Add(´And (ELEMENTO2 :=Comp1))´);
Query1.ParamByName(´Comp1´).AsString := X[I];
Query1.ParamByName(´Comp2´).AsString := Y[J];
Query1.Prepare;
Query1.Open;
//esta é a lei de formação servira para implementar Z******
// Indice:=(i*j)+(i-1)*(3-j);
//A formula anteiror no meu conceito e de extrema importancia para
//a formação da futura Matriz Z
If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
// Memo4.Lines.Add(Query2.FieldByName(´Reacao´).AsString)
//Z[i,Indice]:=query2.fieldByName(´Reacao´).AsString
//nada foi encontrado
// Else
// Memo4.Lines.Add(´´);
// Z[I,indice]:=´´;
End;
End;
For I := 1 to Length(Z) do
Memo1.Lines.Add(Z[K]);
Edilcimar
04/02/2006
If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
K := K + 1;
Marco Salles
04/02/2006
Eu não entendi.. Deu para chegar em algum lugar ou não ???
o meu select2 Deve ser refletido,, eu fiz sem testar. A idéia e testar o valor de X[I] Y[j] simultaneamente
[b:97fa5e45aa](X[i] na Composica1 e Y[j] na composicao2)Or
(X[i] na Composica2 e Y[j] na composicao1)[/b:97fa5e45aa]
Pelo que nos combinamos logo no inicio lembra
Edilcimar
04/02/2006
Z[1] := A+B= (isto já foi colocado antes) + ´dor de barriga´ isto deverá ser colocado aqui, caso a reação A+B não exista então será colocado ´sem reação conhecida´
Isto já foi colocado para quando a sql venha a funcionar, quanto da pesquisa dos 2 campos x[i] e y[j], não vejo problema algum
Marco Salles
04/02/2006
mudei algumas instruçoes..
alem disso testei
parece Ok
so precisa colocar pimenta a seu gosto
type
A = Array of string;
var
X : A;
tamanhox:integer;
Y : A;
tamanhoy:integer;
Z : A;
procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String); var i,indiceanterior,q:integer; texto:String; begin tamanho:=0; setlength(B, 100); i:=0; indiceAnterior:=1; q:=0; while i <= (length(composicao)-1) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); indiceAnterior:=i+1; B[q]:=Trim(texto); q:=q+1; tamanho:=Tamanho+1; end; i:=i+1; end; if length(composicao) > 0 then begin if composicao[i]=´;´ then texto:=copy(composicao,indiceanterior,i-indiceAnterior) else texto:=copy(composicao,indiceanterior,(i+1) - indiceAnterior); B[q]:=Trim(texto); tamanho:=Tamanho+1; end; end;
procedure TForm1.Button1Click(Sender: TObject); var i,j,indice:integer; begin Query1.Close; Query1.SQL.Clear; Query1.Sql.Add(´Select *From Tabela1´); Query1.Sql.Add(´Where Produto=:NomePrimeiroProduto´); Query1.ParamByName(´NomePrimeiroProduto´).asstring:=edit1.text; Query1.Sql.Add(´OR Produto=:NomesegundoProduto´); Query1.ParamByName(´NomesegundoProduto´).asstring:=edit2.text; Query1.Prepare; Query1.open; if query1.RecordCount = 2 then begin CriarMatriz(X,tamanhox,query1.FieldByName(´Composicao´).asstring); Query1.Next; CriarMatriz(y,tamanhoy,query1.FieldByName(´Composicao´).asstring); setlength(Z, 100); indice:=0; for i:=0 to tamanhox-1 do begin for j:=0 to tamanhoy-1 do begin Query1.Close; Query1.SQL.Clear; Query1.Sql.Add(´Select *From Tabela2´); Query1.Sql.Add(´Where ((Composicao1=:Comp1)and(Composicao2=:Comp2))or((Composicao1=:Comp2)and(Composicao2=:Comp1))´); Query1.ParamByName(´Comp1´).asstring:=X[i]; Query1.ParamByName(´Comp2´).asstring:=Y[J]; Query1.Prepare; Query1.open; Z[indice]:=X[i]+´ ´+Y[J]; if query1.fieldByName(´Reacao´).AsString <> ´´ Then Z[Indice]:=Z[Indice]+´ ´+query1.fieldByName(´Reacao´).AsString //nada foi encontrado else Z[indice]:=Z[Indice]+´ Sem Reação Conhecida´; Indice:=indice+1; end; end; for i:=0 to indice do memo1.Lines.Add(Z[i]); end else showmessage(´Pesquisa concluida . Nada fora encontrado´); end;
testei e a principio foi satisfatorio
O que eu mudei
1) Z não é mais bidiemensional
2) Maximizei o código
3)utililei a mesma procedure criar Matriz Para X e Y
4)A combinação Matriz Z , não precisa mais de uma função de Combinação.. Ela é contruida no próprio Loop
5)Importante ... Coloquei toda a instrução do segundo Select dentro de Uma mesma Linha... Sofro em tentar separa-lo e ja ha muito tempo atrás abri um tópico sobre isso
[b:6df99c5ec5]//Mesma Linha[/b:6df99c5ec5]
6)Alterei a função CriarMatriz
7)Alterei no primeir sql
query1.FieldByName(´Produto´).asstring para
query1.FieldByName(´Composicao´).asstring
, pois as matrizes devem ser criadas a partir da composição e naõ do nome do Produto
8)A intrução
é a gosto e há como fazer outros testes , usando o Próprio
[b:6df99c5ec5]query1.FieldByName(´Composicao´).asstring <> ´´ Faça Senão Não Faça[/b:6df99c5ec5]
9)Emfim , acho que não ira ter problemas
Edilcimar
04/02/2006
aqui está a que eu terminei de modificar, vou testar a sua função, a minha está funcionando perfeitamente inclusive na inversão das posições na tabela;
Marcos, grato pela ajuda, valeu pela força
procedure TForm4.Button2Click(Sender: TObject);
var
I, J, K, TamanhoX, TamanhoY : Integer;
Texto, Temp : String;
X, Y, Z : array of string;
begin
Temp := ´´;
Memo1.Lines.Clear;
J := 1;
SetLength(X,1);
SetLength(Y,1);
With Table1 do
Begin
If Locate(´PRODUTO´,Edit1.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
X[J-1] := Trim(Temp);
SetLength(X, J);
End;
End
Else
Begin
X[J-1] := Trim(Temp);
J := J + 1;
SetLength(X, J);
Temp := ´´;
End;
End;
Temp := ´´;
With Table1 do
Begin
If Locate(´PRODUTO´,Edit2.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
J := 1;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
Y[J-1] := Trim(Temp);
SetLength(Y, J);
End;
End
Else
Begin
Y[J-1] := Trim(Temp);
J := J + 1;
SetLength(Y, J);
Temp := ´´;
End;
End;
TamanhoX := Length(X);
TamanhoY := Length(Y);
K := 0;
SetLength(Z, TamanhoX * TamanhoY);
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Z[K] := X[I] + ´+´ + Y[J] +´= ´;
K := K + 1;
End;
End;
K := 0;
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select * From Reacao´);
Query1.Sql.Add(´Where (ELEMENTO1 = :Comp1 And ELEMENTO2 = :Comp2) ´);
Query1.Sql.Add(´Or (ELEMENTO1 = :Comp2 And ELEMENTO2 = :Comp1)´);
Query1.ParamByName(´Comp1´).AsString := X[I];
Query1.ParamByName(´Comp2´).AsString := Y[J];
Query1.Prepare;
Query1.Open;
If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
K := K + 1;
End;
End;
For I := 0 to High(Z) do
Memo1.Lines.Add(Z[I]);
end;
pode testar a minha que funciona, agora vou testar a sua
Edilcimar
04/02/2006
procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String);
o que significa var B:A ?
Edilcimar
04/02/2006
Marco Salles
04/02/2006
não na verdade eu dei porque voce me explicou assim...
Lembra da minha dúvida em post passados como definir Array Dinamicos
Citação de marcos Pagina 2
Citacao de Edicilmar Pagina3
Mas agora to vendo que o negoci o pode ser este
setlength(x, i); a cada lopp .. Vou testar com esta instrução
Marco Salles
04/02/2006
procedure CriarMatriz(var B:A;var tamanho:integer;Composicao:String); var i,indiceanterior,q:integer; texto:String; begin tamanho:=0; i:=0; indiceAnterior:=1; q:=0; while i <= (length(composicao)-1) do begin if composicao[i]=´;´ then begin texto:=copy(composicao,indiceanterior,i - indiceAnterior); tamanho:=Tamanho+1; setlength(B,tamanho); //******corrigido B[q]:=Trim(texto); indiceAnterior:=i+1; q:=q+1; end; i:=i+1; end; if length(composicao) > 0 then begin if composicao[i]=´;´ then texto:=copy(composicao,indiceanterior,i-indiceAnterior) else texto:=copy(composicao,indiceanterior,(i+1) - indiceAnterior); tamanho:=Tamanho+1; setlength(B,tamanho); //*********corrigido B[q]:=Trim(texto); end; end;
procedure TForm1.Button1Click(Sender: TObject); var i,j,indice:integer; begin Query1.Close; Query1.SQL.Clear; Query1.Sql.Add(´Select *From Tabela1´); Query1.Sql.Add(´Where Produto=:NomePrimeiroProduto´); Query1.ParamByName(´NomePrimeiroProduto´).asstring:=edit1.text; Query1.Sql.Add(´OR Produto=:NomesegundoProduto´); Query1.ParamByName(´NomesegundoProduto´).asstring:=edit2.text; Query1.Prepare; Query1.open; if query1.RecordCount = 2 then begin CriarMatriz(X,tamanhox,query1.FieldByName(´Composicao´).asstring); Query1.Next; CriarMatriz(y,tamanhoy,query1.FieldByName(´Composicao´).asstring); indice:=0; for i:=0 to tamanhox-1 do begin for j:=0 to tamanhoy-1 do begin Query1.Close; Query1.SQL.Clear; Query1.Sql.Add(´Select *From Tabela2´); Query1.Sql.Add(´Where ((Composicao1=:Comp1)and(Composicao2=:Comp2))or((Composicao1=:Comp2)and(Composicao2=:Comp1))´); Query1.ParamByName(´Comp1´).asstring:=X[i]; Query1.ParamByName(´Comp2´).asstring:=Y[J]; Query1.Prepare; Query1.open; setlength(Z,indice+1); //******corrigido Z[indice]:=X[i]+´ ´+Y[J]; if query1.fieldByName(´Reacao´).AsString <> ´´ Then Z[Indice]:=Z[Indice]+´ ´+query1.fieldByName(´Reacao´).AsString //nada foi encontrado else Z[indice]:=Z[Indice]+´ Sem Reação Conhecida´; Indice:=indice+1; end; end; for i:=0 to indice-1 do //********corrigido memo1.Lines.Add(Z[i]); end else showmessage(´Pesquisa concluida . Nada fora encontrado´); end;
Edilcimar
04/02/2006
Marco Salles
04/02/2006
Tabela 1 ; tabela2
Ver como esta a base de dados da Tabela 1 e da Tabela2
[URL=http://imageshack.us][img:c69ddf97c1]http://img392.imageshack.us/img392/8950/imagemparaedicilmar32kf.jpg[/img:c69ddf97c1][/URL]
Executei agora od dosi métodos ... Button1(Marco) o método que lhe passei , Button2(Edicilmar) o método que me passou
Execução do Button1(Marco).. O resultado no Memo1 Foi este ;
[URL=http://imageshack.us][img:c69ddf97c1]http://img99.imageshack.us/img99/9528/imagemparaedicilmar45ny.jpg[/img:c69ddf97c1][/URL]
Execução do Button2(Edicilmar).. O resultado fo ieste ;
[URL=http://imageshack.us][img:c69ddf97c1]http://img353.imageshack.us/img353/934/imagemparaedicilmar52fr.jpg[/img:c69ddf97c1][/URL]
Não to entendendo porque da diferença ????
Edilcimar
04/02/2006
Execução do Button2(Edicilmar).. O resultado fo ieste ;
Não to entendendo porque da diferença ????
O que deveria haver entre estas 2 linhas? está em branco
Marco Salles
04/02/2006
Deveria ter os desenhos que gerei a partir da execução do programa... Usei o ImageShack para cria-los .. Consegue ver agora ????
Edilcimar
04/02/2006
Edilcimar
04/02/2006
http://forum.clubedelphi.net/viewtopic.php?t=71209
Marco Salles
04/02/2006
[b:c3cc88d1f6]Tabela 1 ; tabela2
Ver como esta a base de dados da Tabela 1 e da Tabela2 [/b:c3cc88d1f6]
[url=http://img488.imageshack.us/my.php?image=imagemparaedicilmar31ec.jpg][img=http://img488.imageshack.us/img488/4091/imagemparaedicilmar31ec.th.jpg][/url]
[URL=http://imageshack.us][img:c3cc88d1f6]http://img488.imageshack.us/img488/4091/imagemparaedicilmar31ec.jpg[/img:c3cc88d1f6][/URL]
[b:c3cc88d1f6]Executei agora os dois métodos ... Button1(Marco) o método que lhe passei , Button2(Edicilmar) o método que me passou [/b:c3cc88d1f6]
Execução do Button1(Marco).. O resultado no Memo1 Foi este ;
Talves o endereço lhe sirva , caso não de visualização
[url=http://img382.imageshack.us/my.php?image=imagemparaedicilmar41lu.jpg][img=http://img382.imageshack.us/img382/6742/imagemparaedicilmar41lu.th.jpg][/url]
[URL=http://imageshack.us][img:c3cc88d1f6]http://img382.imageshack.us/img382/6742/imagemparaedicilmar41lu.jpg[/img:c3cc88d1f6][/URL]
Execução do Button2(Edicilmar).. O resultado foi este ;
Talves o endereço lhe sirva , caso não de visualização
[url=http://img382.imageshack.us/my.php?image=imagemparaedicilmar50yn.jpg][img=http://img382.imageshack.us/img382/1271/imagemparaedicilmar50yn.th.jpg][/url]
[URL=http://imageshack.us][img:c3cc88d1f6]http://img382.imageshack.us/img382/1271/imagemparaedicilmar50yn.jpg[/img:c3cc88d1f6][/URL]
[b:c3cc88d1f6]Não to entendendo porque da diferença[/b:c3cc88d1f6] ????
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Edilcimar
04/02/2006
[URL=http://img385.imageshack.us/my.php?image=imagemjog9md.jpg][img:48e99b939f]http://img385.imageshack.us/img385/8028/imagemjog9md.th.jpg[/img:48e99b939f][/URL]
Marco Salles
04/02/2006
Nãopode haver tamanha diferença ?????
Edilcimar
04/02/2006
Marco Salles
04/02/2006
os dois métodos estão de acordos
:oops: :oops: :oops:
é porque voce disse que a composição ia ser separadas pore [b:501e3f57cc]virgula[/b:501e3f57cc] e eu o fiz separados por [b:501e3f57cc]Ponto e virgula[/b:501e3f57cc]
Logo meu raciocineo e todo em função do Ponto e virgula e minha base de dados tb
Modifiquei sua instrução onde se tinha
If Texto[I] <> ´,´ then coloquei para If Texto[I] <> ´;´ then
Para ficar coerentre com minha base de dados
:arrow: :arrow: :arrow:
:P
e obtive os mesmos resultados
Se voce quiser testar o meu código , tem que alterar na procedure CriarMatriz e trocar o Ponto_Virgula por Ponto
Ja que a virgula e seu Limitador e o Ponto e virgula foi o usado por mim
Acho que é isso ai
Edilcimar
04/02/2006
Edilcimar
04/02/2006
rocedure TForm4.Button2Click(Sender: TObject);
var
I, J, K, TamanhoX, TamanhoY : Integer;
Texto, Temp : String;
X, Y, Z : array of string;
begin
Temp := ´´;
Memo1.Lines.Clear;
J := 1;
SetLength(X,1);
SetLength(Y,1);
With Table1 do
Begin
If Locate(´PRODUTO´,Edit1.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
X[J-1] := Trim(Temp);
SetLength(X, J);
End;
End
Else
Begin
X[J-1] := Trim(Temp);
J := J + 1;
SetLength(X, J);
Temp := ´´;
End;
End;
Temp := ´´;
With Table1 do
Begin
If Locate(´PRODUTO´,Edit2.Text,[]) then
Texto := Trim(FieldByName(´COMPOSICAO´).AsString)
Else
Begin
ShowMessage(´PRODUTO NÃO ENCONTRADO´);
Abort;
End;
End;
J := 1;
For I := 1 to Length(Texto) do
Begin
If Texto[I] <> ´,´ then
Begin
Temp := Temp + Texto[I];
If I = Length(Texto) then
Begin
Y[J-1] := Trim(Temp);
SetLength(Y, J);
End;
End
Else
Begin
Y[J-1] := Trim(Temp);
J := J + 1;
SetLength(Y, J);
Temp := ´´;
End;
End;
TamanhoX := Length(X);
TamanhoY := Length(Y);
K := 0;
SetLength(Z, TamanhoX * TamanhoY);
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Z[K] := X[I] + ´+´ + Y[J] +´= ´;
K := K + 1;
End;
End;
K := 0;
For I := 0 to TamanhoX - 1 do
Begin
For J := 0 to TamanhoY - 1 do
Begin
Query1.Close;
Query1.SQL.Clear;
Query1.Sql.Add(´Select * From Reacao´);
Query1.Sql.Add(´Where (ELEMENTO1 = :Comp1 And ELEMENTO2 = :Comp2) ´);
Query1.Sql.Add(´Or (ELEMENTO1 = :Comp2 And ELEMENTO2 = :Comp1)´);
Query1.ParamByName(´Comp1´).AsString := X[I];
Query1.ParamByName(´Comp2´).AsString := Y[J];
Query1.Prepare;
Query1.Open;
If Query1.FieldByName(´RESULTADO´).AsString <> ´´ then
Z[K] := Z[K] + Query1.FieldByName(´RESULTADO´).AsString
Else
Z[K] := Z[K] + ´Sem Reação Conhecida´;
K := K + 1;
End;
End;
For I := 0 to High(Z) do
Memo1.Lines.Add(Z[I]);
end;
valeu pela força marcos
Emerson Nascimento
04/02/2006
segue a rotina modificada:
var I, J, TamanhoX, TamanhoY: Integer; Resultado: string; X, Y, Z: array of string; slStringListAux: TStrings; Encontrou: boolean; begin slStringListAux := TStringList.Create; slStringListAux.Delimiter := ´;´; // delimitador Memo1.Clear; Table1.First; for j := 1 to 2 do //numero de edit´s begin with Table1 do begin if j = 1 then Encontrou := Locate(´PRODUTO´,Edit1.Text,[]) else Encontrou := Locate(´PRODUTO´,Edit2.Text,[]); if not Encontrou then begin ShowMessage(´PRODUTO NÃO ENCONTRADO´); abort; end; end; slStringListAux.DelimitedText := Trim(Table1.FieldByName(´COMPOSICAO´).AsString); if j = 1 then SetLength(X,slStringListAux.Count) else SetLength(Y,slStringListAux.Count); for i := 0 to slStringListAux.Count-1 do if j = 1 then X[i] := slStringListAux[i] else Y[i] := slStringListAux[i]; end; TamanhoX := Length(X); TamanhoY := Length(Y); Query1.Close; Query1.SQL.Clear; Query1.Sql.Add(´Select * From Reacao´); Query1.Sql.Add(´Where (ELEMENTO1 = :Comp1 And ELEMENTO2 = :Comp2) ´); Query1.Sql.Add(´Or (ELEMENTO1 = :Comp2 And ELEMENTO2 = :Comp1)´); for I := 0 to TamanhoX - 1 do for J := 0 to TamanhoY - 1 do begin Query1.Close; Query1.ParamByName(´Comp1´).AsString := X[I]; Query1.ParamByName(´Comp2´).AsString := Y[J]; Query1.Prepare; Query1.Open; Resultado := Query1.FieldByName(´RESULTADO´).AsString; if Resultado = ´´ then Resultado := ´Sem Reação Conhecida´; SetLength(Z, Length(Z)+1); Z[High(Z)] := X[I] + ´+´ + Y[J] +´ = ´+Resultado; end; for I := 0 to High(Z) do Memo1.Lines.Add(Z[I]); slStringListAux.Free; end;
Edilcimar
04/02/2006
composição(A,B,C,D)
composição(A, B, C,D)
a sua rotina vai conseguir diferenciar os espaços (ou não) após a vírgula, pois no cadastramento das reações, não vai ter espaço antes das palavras?
Emerson Nascimento
04/02/2006
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Emerson Nascimento
04/02/2006
Edilcimar
04/02/2006
Martins
04/02/2006
Isso mesmo o Emerson.en está usando ´;´ como delimitador. Então quer dizer q funcionou perfeitamente?
Edilcimar
04/02/2006
Martins
04/02/2006
Certo colega, obrigado pelo retorno.
Valew!!!!
Emerson Nascimento
04/02/2006
mas o que eu queria mesmo era mostrar essa forma de trabalhar com delimitadores juntamente com o StringList. isso economiza um bom tempo de ´queimação´ de neurônios.
Edilcimar
04/02/2006
Edilcimar
04/02/2006
Edilcimar
04/02/2006