Jump to content
Fórum Script Brasil
  • 0

agenda


Question

olá galera..

assim... o programa é de reserva de salas,

tenho salas cadastradas e elas tem horarios fixos, tipo "1M", "2M", etc..

o problema é o seguinte, eu tenho uma tabela no SQL Server(que botarei mais abaixo),

e preciso mostrar os resultados em Edit's(se tiverem sugestões pra ficar mais facil eu aceito)

e tenho que mostrar os resultados de uma semana..

no caso segunda, terça, quarta...

aqui o link pra vocês verem como é a tela...

<http://download.mandeibem.com.br/arquivos/20081208-100332-0610/tela.jpg>

a tabela que tenho é essa:

CREATE TABLE [Reserva] (

[idreserva] [int] IDENTITY (1, 1) NOT NULL ,

[CodSala] [int] NOT NULL ,

[data] [smalldatetime] NOT NULL ,

[M1] [bit] NULL ,

[M2] [bit] NULL ,

[M3] [bit] NULL ,

[M4] [bit] NULL ,

[M5] [bit] NULL ,

[T1] [bit] NULL ,

[T2] [bit] NULL ,

[T3] [bit] NULL ,

[T4] [bit] NULL ,

[N1] [bit] NULL ,

[N2] [bit] NULL ,

[N3] [bit] NULL ,

[N4] [bit] NULL ,

[professor] [varchar] (15) COLLATE Latin1_General_CI_AS NULL ,

CONSTRAINT [PK_Reserva] PRIMARY KEY CLUSTERED

(

[idreserva],

[CodSala]

) ON [PRIMARY] ,

FOREIGN KEY

(

[CodSala]

) REFERENCES [CadSalas] (

[CodSala]

)

) ON [PRIMARY]

GO

desde já muito obrigado.

André.

Link to post
Share on other sites

13 answers to this question

Recommended Posts

  • 0

meu professor disse que tem que programar em cada Edit...

no SQL Server seria acho que 'Select 'M1' e 'smaldatetime' from Reserva' (eu não sei direito como é a programação..)

no delphi teria que ser algo desse tipo, mas num sei como ficaria e nem sei oque usar..

ifs, ou when..

essa parte tá me quebrando...

Link to post
Share on other sites
  • 0

Baseado na figura em seu post, fica a dúvida sobre o que deverá aparecer nos edits. Como os campos Mn, Tn e Nn são do tipo bit, parece que apenas representarão a situação destes (marcado ou desmarcado).

Já pela estrutura da tabela, e figura, parece que cada registro na tabela contém a informação de todo um dia. Isto é certo?

Supondo que a resposta seja sim a este último questionamento, ao que parece, sua consulta teria que ser mais ou menos assim:

select M1, M2, M3, M4, M5, T1, T2, T4, N1, N2, N3, N4
from Reserva where CodSala = :CodSala and Data = :Data

Onde o parâmetro CodSala, baseado na figura, seria o referente ao "Laboratório 1" e o parâmetro Data corresponderia ao dia a ser obtido. Neste caso, seria realizado uma consulta para cada data correspondente ao dia da semana a ser mostrado na sua tela. A cada resultado obtido, você teria que "preencher" o respectivo edit com a informação desejada.

Possivelmente haja forma diferente de fazer a mesma coisa, mas pode depender do seu nível de conhecimento. Aparentemente, este seria o modo mais simples para sua compreensão.

Abraços

Link to post
Share on other sites
  • 0

os Edits são só pra mostrar o que está reservado...

digamos que na quarta feira, no periodo T1, o professor Augusto(exemplo) tem reservado a sala...

tenho que mostrar o professor(q é uma propriedade q tenho na tabela) nos periodos que foram marcados como 'verdadeiros'..

no dia tal em tal sala...

cada vez q tu for fazer uma reserva, vai criar um registro na tabela...

no SQL mostra assim:

idreserva|CodSala|______data|_M1|M2|_M3|M4|M5_|T1|_T2|T3_|T4|N1_|N2|_N3|N4_|professor

______1|______1 |12-12-2008|null|null|null|null|null|_1|null|null|null|null|null|null|null|Augusto

e também outro problema..

quando seleciono a data ali.. tenho que mostrar a semana correspondente.. não somente o dia...

(depois de tudo tenho que dar um jeito de colocar no quickreport...)

meu nivel de conheçimento é pouco nessa parte de programação...

mas entendi o que você falou...

devo colocar então em cada edit, exemplo do primeiro periodo..

Select M1

From Reserva where CodSala = :CodSala and Data = :Data

mas como faço pra ligar a data que eu escolher(do datetimepicker ali da tela) a isso?

e muito obrigado pela ajuda Micheus.

André

Link to post
Share on other sites
  • 0

pesquisei por ae e encontrei o seguinte programação...

ADOQuery1.SQL.Add('select professor');

ADOQuery1.SQL.Add('from Reserva');

ADOQuery1.SQL.Add('where CodSala = :CodSala and data = :Data');

ADOQuery1.Parameters.ParamByName('CodSala').Value := 'DBCDsala';

ADOQuery1.Parameters.ParamByName('Data').Value := 'DateTimePicker1';

me pareçe estar funcionando, porque não dá nenhum erro.

mas como eu faço pra mostra o resultado dessa busca?

e eu tenho que dizer q é pra mostrar o nome do professor só nos Bit que são 'verdadeiros'

muito obrigado.

André.

Link to post
Share on other sites
  • 0
os Edits são só pra mostrar o que está reservado...

digamos que na quarta feira, no periodo T1, o professor Augusto(exemplo) tem reservado a sala...

tenho que mostrar o professor(q é uma propriedade q tenho na tabela) nos periodos que foram marcados como 'verdadeiros'..

no dia tal em tal sala...

Então, a resposta é: "os Edits são para mostrar o nome do professor que reservou a sala naquele horário".

cada vez q tu for fazer uma reserva, vai criar um registro na tabela...

no SQL mostra assim:

idreserva|CodSala|______data|_M1|M2|_M3|M4|M5_|T1|_T2|T3_|T4|N1_|N2|_N3|N4_|professor

______1|______1 |12-12-2008|null|null|null|null|null|_1|null|null|null|null|null|null|null|Augusto

e imagino que se este mesmo professor reservar outro horário no mesmo dia, então outro campo terá o valor 1 (e não o null). Certo?!

e também outro problema..

quando seleciono a data ali.. tenho que mostrar a semana correspondente.. não somente o dia...

(depois de tudo tenho que dar um jeito de colocar no quickreport...)

ou seja, se a data escolhida cair em uma quinta-feira, você terá que mostrar os dados daquela semana de segunda a sexta-feira em que o dia se encontra. Isso não é problema.

Com a data em mãos, você obtém o dia da semana a que corresponde e calcula a data referente a segunda e sexta feira.

A função DayOfWeek (unit SysUtils), retorna o número do dia (Domingo = 1 ... Sábado = 7)

meu nivel de conheçimento é pouco nessa parte de programação...

mas entendi o que você falou...

devo colocar então em cada edit, exemplo do primeiro periodo..

Select M1

From Reserva where CodSala = :CodSala and Data = :Data

mas como faço pra ligar a data que eu escolher(do datetimepicker ali da tela) a isso?

Não entendeu não.

O seu exemplo anterior tem o resultado mais de acordo com o que tentei explicar. Com a estrutura de tabela que você tem, você terá que trazer todos os campos necessários, logo a consulta continuaria sendo aquela que propus, adicionado do campo professor:

select M1, M2, M3, M4, M5, T1, T2, T4, N1, N2, N3, N4, Professor
from Reserva where CodSala = :CodSala and Data = :Data
que poderá resultar em algo como abaixo (baseado em seu exemplo): |null|null|null|null|null|_1|null|null|null|null|null|null|null|Augusto| |null|null|null|_1|null|null|null|null|null|null|null|null|null|Coelho| |null|null|null|null|null|null|null|null|null|_1|_1|null|null|Carlão| É como deverá ser seu resultado se houverem reservas para 3 professores neste dia.
pesquisei por ae e encontrei o seguinte programação... ADOQuery1.SQL.Add('select professor'); ADOQuery1.SQL.Add('from Reserva'); ADOQuery1.SQL.Add('where CodSala = :CodSala and data = :Data'); ADOQuery1.Parameters.ParamByName('CodSala').Value := 'DBCDsala'; ADOQuery1.Parameters.ParamByName('Data').Value := 'DateTimePicker1'; me pareçe estar funcionando, porque não dá nenhum erro.
Possivelmente. Mas você tem que passar como parâmetro o valor dos componentes e não uma string com seu nome, ou seja, no lugar de 'DateTimePicker1' será DateTimePicker1.Date e no lugar de 'DBCDsala', ... bom, esse eu não sei. Que componente é este? Um ComboBox, um DBComboBox, um DBLookupComboBox? Mas você nota que você não quer apenas esta informação? (o professor) Terá que usar a consulta como pus acima.
mas como eu faço pra mostra o resultado dessa busca?
Com a consulta correta, você terá o resultado em condições de ser usado para mostrá-lo na tela. Então, baseado no exemplo acima (3 linhas de resultado), digamos que o resultado tenha sido obtido para o dia 08/12/2008 (segunda-feira): |null|null|null|null|null|_1|null|null|null|null|null|null|null|Augusto| |null|null|null|_1|null|null|null|null|null|null|null|null|null|Coelho| |null|null|null|null|null|null|null|null|null|_1|_1|null|null|Carlão| você precisa "varrer" cada linha e verificar cada campo de Mn até Nn e onde o valor do campo não for nulo, você coloca o nome do professor no Edit correspondente. Para ser sincero, se você usar um StringGrid, sua vida pode ficar mais fácil - vai trabalhar com Linha (horários) x Coluna (dia da semana). Mas, por hora, vamos sofrer um pouquinho, assim você aprende mais. :D Supondo que você tenha usado uma nomenclatura formatada/padronizada para o nome de seus edits, digamos que os edits da primeira coluna (ref. a segunda-feira), tenham o nome: edAgenda11, edAgenda12, edAgenda13 ... edAgenda113 (ou seja, edAgenda<coluna><linha>); Ao ler cada linha do dataset (sua consulta), o edit correspondente ao horário é inicializado com o nome do professor:
// procedimento para inicialização da agenda na tela - Implementada apenas para a segunda-feira
procedure TForm1.InicializaAgenda;
var
  CodSala :Integer;
  Data :TDateTime;
begin
  CodSala := // atribui o valor em DBCDsala (não sei que componente é)
             // mas a título de teste, você pode mover um valor fixo para esta variável
  Data := DateTimePicker1.Date;  // use uma segunda-feira para o teste
  ADOQuery1.SQL.Clear;  // limpa a propriedade SQL
  ADOQuery1.SQL.Add('select M1, M2, M3, M4, M5, T1, T2, T4, N1, N2, N3, N4, Professor');
  ADOQuery1.SQL.Add('from Reserva');
  ADOQuery1.SQL.Add('where CodSala = :CodSala and data = :Data');
  ADOQuery1.Parameters.ParamByName('CodSala').Value := CodSala;
  ADOQuery1.Parameters.ParamByName('Data').Value := Data;
  ADOQuery1.Open;  // executa a consulta
  while not ADOQuery1.EOF do  // continua no while enquanto não for fim do dataset
  begin
    if not ADOQuery1.FieldByName('M1').IsNull then  // se não for nulo, atribui nome do professor
      edAgenda11.Text := ADOQuery1.FieldByName('Professor').AsString
    else  // do contrário, limpa o conteúdo
      edAgenda11.Text := '';

    if not ADOQuery1.FieldByName('M2').IsNull then
      edAgenda12.Text := ADOQuery1.FieldByName('Professor').AsString
    else
      edAgenda12.Text := '';

    if not ADOQuery1.FieldByName('M3').IsNull then
      edAgenda13.Text := ADOQuery1.FieldByName('Professor').AsString
    else
      edAgenda13.Text := '';
    : 
    : neste intervalo vão as outras atribuições
    :
    if not ADOQuery1.FieldByName('N4').IsNull then
      edAgenda113.Text := ADOQuery1.FieldByName('Professor').AsString
    else
      edAgenda113.Text := '';

    ADOQuery1.Next;  // avança para o próximo registro no dataset
  end;
  ADOQuery1.Close;
end;

Observe que este procedimento está programado para processar apenas um dia, e conforme citei, este dia seria uma segunda-feira.

Pelo seu pouco conhecimento, sugiro que você tente compreender e implementar o falei até aqui, bem como faça o teste apenas para esta data (uma segunda-feira). Depois teremos que calcular a data de início e término da semana para que possamos preencher toda a agenda. Estando compreendido o processo, podemos melhorar e muito o código - você não vai querer repetir este código para as outras 5 colunas. Vai?! ;)

Abraços

p.s. Como meu post ficou enooorrrme, não QUOTE todo ele, se for respondê-lo - vai tornar péssima a leitura do seu.

Link to post
Share on other sites
  • 0
está dando erro...

Data := DateTimePicker1.Data

[Error] Principal.pas(217): Undeclared identifier: 'DateTimePicker1'

andre_seco, você tem que me dar uma forcinha...

DateTimePicker1 é, a título de exemplo, um componente TDateTimePicker da paleta Win32 e que é utilizado para obter datas. Na sua tela (imagem), você usa alguma outra coisa parecida com um combo - é deste "cara" que tem que vir a data. Ou, então, substitua-o pelo componente que usei no exemplo.

Abraços

Link to post
Share on other sites
  • 0
andre_seco, você tem que me dar uma forcinha...

DateTimePicker1 é, a título de exemplo, um componente TDateTimePicker da paleta Win32 e que é utilizado para obter datas. Na sua tela (imagem), você usa alguma outra coisa parecida com um combo - é deste "cara" que tem que vir a data. Ou, então, substitua-o pelo componente que usei no exemplo.

Abraços

mas estou usando esse componente, e ele tem o nome de DateTimePicker1... só esta dando esse erro...

Link to post
Share on other sites
  • 0

hoje de manha falei com meu professor, ele me deu uma ajuda nos codigos...

olha o que ele acrescentou..

no SQL..

"CREATE PROCEDURE [dbo].[ConsultaHorario] @data varchar(10), @sala integer

AS

declare @data_tmp smalldatetime

set @data_tmp = DATEADD ( dd , (datepart(dw, convert(smalldatetime,@data,103))-1)*-1 , convert(smalldatetime,@data,103) )

Select * from (select @data_tmp + 1 as data) a left join Reserva r on ([email protected] and [email protected]_tmp + 1)

union

Select * from (select @data_tmp + 2 as data) a left join Reserva r on ([email protected] and [email protected]_tmp + 2)

union

Select * from (select @data_tmp + 3 as data) a left join Reserva r on ([email protected] and [email protected]_tmp + 3)

union

Select * from (select @data_tmp + 4 as data) a left join Reserva r on ([email protected] and [email protected]_tmp + 4)

union

Select * from (select @data_tmp + 5 as data) a left join Reserva r on ([email protected] and [email protected]_tmp + 5)

union

Select * from (select @data_tmp + 6 as data) a left join Reserva r on ([email protected] and [email protected]_tmp + 6)

GO"

e no Delphi criamos um botão chamado "consultar" e nele está o seguinte codigo...

"procedure TFPrincipal.BConsultaClick(Sender: TObject);

begin

AdoQueryConsulta.Close;

AdoQueryConsulta.SQL.Clear;

AdoQueryConsulta.SQL.Add('exec dbo.ConsultaHorario ' + QuotedStr('25/12/2008') + ',1');

AdoQueryConsulta.Active := true;

AdoQueryConsulta.ExecSQL;

if AdoQueryConsulta.Fields[4].value = True then

edAgenda11.Text := AdoQueryConsulta.Fields[17].Text;

AdoQueryConsulta.Next;

if AdoQueryConsulta.Fields[4].value = True then

edAgenda21.Text := AdoQueryConsulta.Fields[17].Text;

end;"

não coloquei todas as colunas pra não ficar muito grande...

agora está funcionando essa consulta.. mas ainda tenho minhas duvidas...

quando fiz uma reserva pra testar, só mostrou o primeiro periodo de segunda feira, mas não os outros, intão eu não deveria colocar o If pra todos os Edits?

e pareçe que depois de uma consulta, o AdoQueryConsulta, fexa a conexão e não consigo mais consultar..

não sei c é eu que estou fazendo errado ou ainda tem umas falhas no codigo...

agradeço ao Micheus por me ajudar em todo o processo, apesar de não usar o seu codigo, eu fiquei muito mais interessado em aprender a mexer no delphi. muito obrigado Micheus.

André.

Link to post
Share on other sites
  • 0

andre_seco, o que o seu professor lhe passou foi outro modo de gerar o resultado que você precisa - usando uma Stored Procedure.

Neste caso, você passará a data equivalente ao primeiro dia da semana (segunda-feira) e o código da sala e terá todos os resultados para a semana (uma matriz). Da forma, como eu havia lhe sugerido, você teria passar a data do dia da semana sendo processado e o código da sala e teria apenas o resultado daquele dia (um vetor) - mas também poderíamos usar de unions e uma data de início, de modo similar, para gerar a matriz. (há muitas formas de se fazer uma mesma coisa)

... mas ainda tenho minhas duvidas...

quando fiz uma reserva pra testar, só mostrou o primeiro periodo de segunda feira, mas não os outros, intão eu não deveria colocar o If pra todos os Edits?

Quando você executar a sua consulta (ExecSQL), você ainda terá que fazer do modo como eu lhe sugeri no post#6 - terá que fazer um loop para ler cada registros do resultado que, do mesmo modo como eu havia sugerido, será composto por uma linha para cada dia da semana (segunda, terça,..., sábado). Assim, o que eu havia citado naquele post continua valendo. Observe que você praticamente faz o que postei lá, exceto que você preferiu acessar o campo do resultado através do seu índice Fields[<posição>] - que até é interessante. Mas, particularmente, não sou muito favorável a esta abordagem, pelo simples fato de que se você muda a posição de um campo na sua consulta, e não muda o índice no código, você passará a acessar a informação errada - cada caso é um caso, e este possível problema deve ser lembrado.

Estou um pouco intrigado sobre como está sendo retornado o resultado da procedure, uma vez que não consta da declaração as colunas de saída (Stored Procedure - Parâmetros de Saída em SQL Server 2000).

Na paleta ADO, há um componente específico para uso de stored procedures: ADOStoredProc, que talvez pudesse ser usado por você. Entretanto, se estiver conseguindo os resultados corretos com o ADOQuery, manda brasa. :D

A questão de "colocar o If para todos os Edits" é realmente algo a ser contornado, e estava previsto naquela parte final em que citei: "Estando compreendido o processo, podemos melhorar e muito o código - você não vai querer repetir este código para as outras 5 colunas. Vai?!"

Para adiantar, digo que a idéia é que você precisa ter o nome dos edits padronizados, como eu também já havia sugerido lá. Isto garantido, você faria uma laço para preenchimento dos edits (coluna) onde buscaria o nome do componente na lista. Segue um esqueleto:

procedure TFPrincipal.BConsultaClick(Sender: TObject);
var
  Linha,
  Coluna :Integer;
  Edit :TEdit;
begin
  :
  :
  AdoQueryConsulta.ExecSQL;
  Coluna := 1; // referente Edits
  while not AdoQueryConsulta.EOF do
  begin
    for Linha := 1 to 13 do  // referente Edits
    begin
      Edit := TEdit(FindComponent(Format('edAgenda$d%d', [Linha, Coluna])));
      if Assigned(Edit) then  // apenas garantindo que o comp. existe
      begin
       // aqui vão os if's...
        if AdoQueryConsulta.Fields[4].Value or
           AdoQueryConsulta.Fields[5].Value or
           :
           AdoQueryConsulta.Fields[16].Value then
          Edit.Text := AdoQueryConsulta.Fields[17].Text
        else
          Edit.Text := '';
      end;
    end
    AdoQueryConsulta.Next;  // próxima linha => próximo dia
  end;
end;
a função format irá preparar o nome do Edit a ser usado para preenchimento. Com este recurso, você já estará poupando muita digitação/código. Caso os campos do tipo bit, "gerem" no dataset AdoQueryConsulta campos do tipo TBooleanField, não há porque você testar .Value=True nos if's - a expressão avaliada já será booleana, logo não tem porque fazer a comparação.
e pareçe que depois de uma consulta, o AdoQueryConsulta, fexa a conexão e não consigo mais consultar.. não sei c é eu que estou fazendo errado ou ainda tem umas falhas no codigo...
quando você executa stored procedures, não se usa o método Open ou a propriedade Active=True - usa-se apenas o método ExecSQL. Assim, no seu código, você pode suprimir algumas linhas e deixar apenas:
// AdoQueryConsulta.Close; <*** Desnecessária se você usar AdoQueryConsulta apenas para esta consulta
AdoQueryConsulta.SQL.Clear;
AdoQueryConsulta.SQL.Add('exec dbo.ConsultaHorario ' + QuotedStr('25/12/2008') + ',1');
// AdoQueryConsulta.Active := true; < *** Sem função
AdoQueryConsulta.ExecSQL;

Veja se consegue adaptar ao seu código.

Abraços

Link to post
Share on other sites
  • 0
AdoQueryConsulta.SQL.Add('exec dbo.ConsultaHorario ' + QuotedStr('25/12/2008') + ',1');

ali em "QuotedStr('25/12/2008')" oque eu boto no lugar do dia 25...

por que só volta reservas dessa semana..

andre_seco, vejo que você está bastante crú na programação Delphi - siga lendo mais. ;)

Tentando explicar a função de QuotedeStr naquela linha:

A função QuotedeStr tem como objetivo colocar o texto '25/12/2008' com aspas simples dentro da string do SQL. Como o Delphi usa a aspa simples ('), como delimitador de string, ao introduzir este caracter em uma string do delphi, você tem que sinalizar ao compilador que você não está terminando a sua string, mas sim querendo usar nesta string o caracter ('). Como facilitador, foi criada esta função para que não gere muita confusão e evite erros. Mas seria possível fazer a mesma coisa sem usar a função, simplesmente repetindo o caracter (') 2 vezes:

AdoQueryConsulta.SQL.Add('exec dba.ConsultaHorario ''25/12/2008'',1');

Observe que as aspas simples vermelhas são o delimitador da string, e que onde deverá aparecer as aspas simples no texto, colocamos duas aspas simples seguidas - no resultado a data estará entre aspas simples.

Sabido isto, para você consultar outras semanas, você terá que mudar aquela data que está lá!

Assim, ao invés de você colocar fixa a data, você tem que usar aquela que será selecionada no componente TDateTimePicker:

AdoQueryConsulta.SQL.Add('exec dbo.ConsultaHorario ' + QuotedStr(DateTimePicker1.Data) + ',1');

Eu acredito que você poderia utilizar, também, a versão com parâmetro:

AdoQueryConsulta.SQL.Add('exec dbo.ConsultaHorario :Data,1');

AdoQueryConsulta.Params.ParamByName('Data').Value := DateToStr(DateTimePicker1.Data);

Abraços

Edited by Micheus
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      149296
    • Total Posts
      645693
×
×
  • Create New...