Ir para conteúdo
Fórum Script Brasil

Micheus

Veteranos
  • Total de itens

    3.189
  • Registro em

  • Última visita

Tudo que Micheus postou

  1. Micheus

    agenda

    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
  2. Sim!Se possível, defina tambem um índice para este campo. Data e Access -> tópicos que podem ser uteis no futuro:Seleção Entre Datas, Da uma ajuda aí galera Problem Com Data, campo do tipo timestamp Como posso solucionar o "ERRO" EdatabaseError Abraços
  3. dan_visualdm, por acaso você não teria definido estes seu campo data_entrega como sendo do tipo VARCHAR? Se sim, esta ordenação está correta (apesar de não ser a que você deseja). Se não lhe for causar muito transtorno, a melhor opção seria passar a utilizar campos do tipo DATE. Do contrário, você tem a possibilidade de fazer a conversão da data string para o tipo date na consulta, mas com perda de performance. Não esqueça de informar o banco de dados que utilizar, pois há diferenças no que diz respeito a manipulação das datas (funções, formatos,...). Abraços
  4. Bem observado Jhonas. A definição de índices para campos de consulta, acelera e muito as buscas. Manoel Zancheta, você não mencionou o banco de dados que está utilizando. No caso de banco de dados como SQLServer (o qual já utilizei, com TTable), o simples fato de definir na propriedade FieldsIndex o nome do campo a ser ordenado, resulta na criação de um índice temporário (no caso de que este ainda não exista). Já no caso de tabelas Paradox, o índice tem que ser criado mesmo. Abraços
  5. Vendo que você conseguiu compreender o que mencionei, tenho a acrescentar mais uma informação sobre um dos recurso que citei. O evento OnDataChange, irá ocorrer também quando um dos campos do dataset em questão for alterado. Explicando... Além de ele ocorrer quando você movimenta entre os registros do seu dataset q_clientes (via next, prior,...), quando você estiver com este dataset em modo edição ou inserção, ao ser modificado o conteúdo de um dos campos este evento também ocorrerá. Assim, quando os dados do dataset puderem ser alterados (há casos em que apenas o usamos em um DBGrid para visualização), torna-se conveniente que verifiquemos o estado do mesmo, pois deste modo, evitamos que o procedimento seja chamado mais vezes que o necessário. Neste sentido, o exemplo anterior teria uma linha a mais: procedure TForm1.DS_q_clientesDataChange(Sender: TObject; Field: TField); begin if TDataSource(Sender).State = dsBrowse then SomaValores; end; O importante é tentar entender em que momento o evento ocorre. Isto entendido, você pode utilizar dele em diversas situações. Abraços
  6. cristofermartins, eu apenas instalei os componentes e testei os vários exemplos que acompanham o pacote, apenas para avaliar o potencial deles (não tenho qualquer aplicação que faça uso destes recursos). É importante lembrar que você pode encontrar neles algumas limitações - não os veja como sendo um compilador Delphi colocado em sua aplicação. Assim, eu não teria condições de lhe ajudar nesta questão, mas sugiro que você avalie os exemplos. Com um pouco de paciência e garimpando no Google, talvez você consiga sanar suas dúvidas. Abraços
  7. R: Amigo não funcionou não...continua desabilitado o botão. Eder, desculpe se não fui claro. O botão não será habilitado, mas a impressora que você escolheu através do PrinterSetupDialog já estará definida e pronta para uso pelo botão de impressão - então não tem porque habilitar o dito cujo. ;) Voce não deve ter impresso um relatório para teste (após ter alterado a seleção da impressora)? Eu assumi que nesse seu processo de automação, você apenas quer mudar a impressora destino, nada mais. Como disse, você não poderá mudar tamanho de folha e a orientação, apenas a informação sobre página inicial e final. Abraços
  8. Eder, ele fica assim porque, a princípio, você não poderia mudar algumas informações do relatório (como tamanho da folha), pois ele na verdade já foi gerado (toda a informação já está no arquivo). Jhonas, acredito que esteja "tudo" certo nesta sua dica. O que faltou foi observar que o componente PrinterSetupDialog manipula o objeto Printer (declarado em Printers), entretanto o objeto QRPrinter é inicializado apontando para a impressora padrão. Assim, se PrinterSetupDialog for chamado antes da instanciação de QRPrinter, provavelmente a impressora na visualização já estará trocada. Mas, mantendo o código como está, basta que seja acrescentada a linha abaixo, antes de chamar o Preview: QRPrinter.PrinterIndex := Printer.PrinterIndex; Confiram por favo. Eder , se a idéia for gerar um for para visualizar um .qrp depois do outro, não vai ser interessante você chamar PrinterSetupDialog1.Execute para cada um. Então, coloque esta chamada antes do laço que fará a carga dos arquivos. Abraços
  9. Jhonas, acredito que o colega esteja se referindo a inserir um interpretador de código pascal na aplicação dele, com o que pode ser obtido utilizando Pascal Script 3.0 citado neste post da seção Links. Ou então, o DelphiWebScript (muito bom - e um pouco mais complexo) tem que ver os exemplos. Alguns links no Google. Abraços
  10. José, acrescentando ao que o colega Jhonas já sugeriu, eu diria que, se você tem uma boa organização com relação a localização de seus componentes, bastaria que você copiasse eles do local onde estão (pasta na origem) para o mesmo local no destino (criar pastas se necessário). Copiar os arquivos .bpl e .dcp que estejam na pasta BIN Copiar os arquivos .dcp, .res, .dcu, .dfm e .dpk que estejam na pasta LIB Quando fiz um procedimento parecido, observei a necessidade estar logado com um usuário do grupo administrador para ler na máquina origem as informações do registro do Windows e para gravar na máquina destino as informações existentes abaixo da chave: HKEY_CURRENT_USER\Software\Borland\Delphi\7.0 São informações referentes aos pacotes instalados e paths. É um pouco trabalhoso se a estrutura de diretórios for diferente (há necessidades de ajustes), mas se for igual, é praticamente copiar e colar/acrescentar. Coisa a ser feita com paciência. Eu fiz um backup desta chave antes (exportando ela) e procedi com as alterações nestas chaves: [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\History Lists\hIBrowsingPath] [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\History Lists\hIPackgeSearchPath] [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\History Lists\hlLibraryPath] [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\Known Packages] [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\Library] [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\Palette] Se não tiver "intimidade" com o registro do windows, talvez seja melhor não acessá-lo. Quanto ao gosth que o Jhonas citou, se não estou enganado também deve ter cuidado com relação a ele, visto que resulta na cópia de todo o HD e se a máquina de destino já tiver informações lá... (Jhonas, corrija-me se eu estiver errado) Abraços
  11. me intrometendo um pouquinho... dan_visualdm, a mensagem sugere que na situação apresentada (por algum motivo) o componente TDataBase está fechado.É conveniente citar os componentes de acesso ao banco que você está utilizando, bem como o banco de dados em uso. quanto ao que ele faz, o que o colega Eder Moraes lhe sugeriu é a utilização de parametrização da query (uso de parâmetros). Isto é feito quando você coloca os dois pontos (":") seguido de um identificador (no exemplo do colega, seria param) e antes de abrir a consulta, você deve inicializar o valor deste parâmetro normalmente utilizando o método ParamByName do dataset (lembrando que se o componente de acesso for da paleta ADO, ele deve ser antecedido por Parameters, ou seja, dataset.Parameters.ParamByName(<identificador>).Value := <valor>). Uma observação sobre o uso do LIKE: ele deve ser usado apenas quando você quer fazer uma pesquisa em um campo (texto) onde você terá apenas parte dele. Quanto você tem o valor exato, use o sinal de igualdade - é muito mais rápido! Nesta sua aplicação, observo que você te um componente para cada visualização (q_clientes, q_relatorio_clientes e q_relatorio_clientes_pg) e que o campo de relacionamento entre eles chama-se Codigo. Dê uma lida neste meu post e depois continue com o que segue e veja se você não vai poder usar este método em sua aplicação. Como os componentes q_relatorio_clientes e q_relatorio_clientes_pg já estão adicionados em seu projeto, e eles não mudam em momento algum, não faz sentido você estar sempre fazendo sua inicialização dinamicamente, a cada vez que o botão é pressionado. Baseado no post que citei, estes dois componentes ficariam vinculados ao dataset q_clientes através do uso da propriedade DataSource utilizando como vínculo o campo Codigo. Para isso, vou assumir que o componente DataSource que você usa para ligar o dataset q_clientes aos componentes data-aware (como é o caso do DBEdit1) chama-se DS_q_clientes. Assim, você configura os componentes em design-time deste modo: q_relatorio_clientes - SQL => select * from tbl_relatorio_clientes where codigo = :codigo - DataSource => DS_q_clientes q_relatorio_clientes_pg - SQL => select * from tbl_relatorio_clientes_pg where codigo = :codigo - DataSource => DS_q_clientes Antes de você abrir o seu dataset q_clientes, você deve também abrir q_relatorio_clientes e q_relatorio_clientes_pg. Com isto, cada vez que você mover uma linha em q_clientes (com Next/Prior/First/Last), automaticamente as consultas serão refeitas (você não precisará fazer nada - o filtro é automático). Com isto, poderíamos ajustar o código para algo assim: // este evento ocorre sempre que há alteração/movimento no dataset q_clientes // assim, podemos usá-lo para refazer o cálculo procedure TForm1.DS_q_clientesDataChange(Sender: TObject; Field: TField); begin SomaValores; end; // existindo o procedimento apenas para o cálculo, podemos chamá-lo // de qualquer parte do programa, quando necessário, e sem duplicar código // OBS: este procedimento deverá ser declarado na sessão private do TForm procedure TForm1.SomaValores; var soma1: Double; soma2: Double; begin with dm do begin soma1 := 0; soma2 := 0; q_relatorio_clientes.DisableControls; while not q_relatorio_clientes.Eof do begin soma1 := soma1 + q_relatorio_clientes.Fieldbyname('valor').Value; q_relatorio_clientes.Next; end; q_relatorio_clientes.First; q_relatorio_clientes.EnableControls; v_total1.Caption := FloatToStrF(soma1,ffCurrency , 15,2); q_relatorio_clientes_pg.DisableControls; while not q_relatorio_clientes_pg.Eof do begin soma2 := soma2 + q_relatorio_clientes_pg.Fieldbyname('valor').Value; q_relatorio_clientes_pg.Next; end; q_relatorio_clientes_pg.First; q_relatorio_clientes_pg.EnableControls; v_total2.Caption := FloatToStrF(soma2,ffCurrency , 15,2); end; end; O uso de DisableControls e First/EnableControls é necessário caso os datasets em questão estejam ligados a componentes que mostrarão suas informações no form (como um TDBGrid ou TDBEdit's), pois assim, a movimentação no registro não gera atualização na tela desnecessáriamente. Ficou meio extenso, mas se eu consegui explicar adequadamente, acredito que esta informação lhe será útil. Não sabendo o seu nível de conhecimento, tentei fazer um detalhamento intermediário. OBS: no caso de tentar implementar, lembre-se de fazer um backup do que você tem atualmente. Abraços
  12. A nova marca alcançada, novamente aconteceu em plena madrugada de uma terça-feira: "O número máximo de usuários on-line foi 16006 em 02/12/2008 - 04:29h" :o Se forem os tupiniquins, só se estiverem acordando cedinho para acessar o forum antes de ir para o trabalho. ^_^ Mesmo assim, parabéns a todos que ajudam a manter o forum neste pique!
  13. o que parece relativamente lógico, pois neste momento você está novamente habilitando a pintura da janela "lockada".Sinceramente, neste código, não vejo o benefício do uso da função. Voce verá inúmeros códigos deste tipo (mas sem o uso da função) funcionando perfeitamente. Abraços
  14. Manoel Zancheta, este é o tipo de coisa bem trabalhosa de fazer funcionar a contento. Talvez fosse interessante dar uma olhada no software WinPolicy (versão freeware). Veja as telas e, se interessar, acesse download para instruções. Se ainda preferir seguir pelo caminho da implementação, alguns pontos a bloquear podem ser obtidos através deste artigo: Bloqueando o Windows pelo Delphi. É só uma parte, ainda falta desabilitar o botão Iniciar, atalhos como WIN+E (que ativa o explorer), CTRL+ALT+DEL que permite acesso ao gerenciador de tarefas, o qual possibilita a execução de uma nova tarefa,... Abraços
  15. marlonCampos, e em algum lugar você fez o lock dele?Qual o seu objetivo ao usar este procedimento? A função desabilita (handle) ou reabilita (0=zero) o desenho da janela especificada. Abraços
  16. pimpocvl, não sei se seria a isso que você se refere, mas neste exemplo que postei antes, considerando que o seu Param1 é o Número do atendimento, Param2 é o Codigo do Cliente (Integer), então o status do atendimento (String) seria Param3. Eu acredito que fazendo as alterações abaixo (informar o tipo do parâmetro via As<tipo>) deva funcionar: ... if Param1 <> '' then IBQueryfiltro.ParamByName('pParametro1').AsInteger := StrToInt(Param1); if Param2 <> '' then IBQueryfiltro.ParamByName('pParametro2').AsInteger := StrToInt(Param2); if Param3 <> '' then IBQueryfiltro.ParamByName('pParametro3').AsString := Param3; IBQueryfiltro.Open; end; Abraços
  17. Micheus

    DBGrid

    e esta seria a posição onde você estaria sobrepondo a imagem? vou tentar fazer um exemplo.Rodrigo Abraços p.s. Evite "quotar" todo o tópico (botão Resp.). Se houver parte de alguma coisa que deva ser mantida para comentário, remova o excedente com cuidado de não deixar a tag aberta (use a opção Visualizar post). Se não houver, use o botão Responder. Isto evita que os posts fiquem confusos. ;)
  18. De que forma você está fazendo a seleção do produto na tela de vendas? Usando o esquema do lookup?Se for, basta que você inclua no dataset que vai em ListSource o campo referente à quantidade. Com isto, ao selecionar o item, este dataset estará também possibilitando obter a quantidade referente ao item selecionado e você pode usar o evento OnExit do componente para fazer a crítica. o procedimento pode ser o mesmo do citado - inclua mais este campo. Voce coloca um componente DBEdit (ReadOnly=true) para mostrar esta informação e em DataSource você seleciona o ListSource e em Field você seleciona o campo referente ao valor do produto. Veja o que consegue... dan_visualdm
  19. Micheus

    DBGrid

    Rodrigao, está quase tudo certo, inclusive o fato de você ter posto o desenho das imagens após chamar o método DefaultDrawColumnCell, apesar do que como eu disse:"DefaultDrawColumnCell apenas precisa ser chamado uma única vez antes do end final do evento" Este o único tipo de ação cabível de ser usado após o citado método, visto que o desenho padrão é feito por este método. O problema está associado ao fato de você ter pintado o fundo (FillRect) após ter chamado ele. Veja o seu código organizado visualmente e com a referida linha comentada - deverá funcionar do jeito que você espera. if Date > DMX.IBChequeDataVencimento.Value then begin // já com as mudanças sugeridas... if DMX.IBChequeVENCEU.Value = 'S' then DBGrid1.Canvas.Font.Color:= clBlue else DBGrid1.Canvas.Font.Color:= clred; end; DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State); if Column.Field = DMX.IBChequeVenceu then begin // DBGrid1.Canvas.FillRect(Rect); <==== RETIRAR if DMX.IBChequeVenceu.Value = 'S' then ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 14, Rect.Top + 1, 1) else ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 14, Rect.Top + 1, 0); end; Abraços
  20. Micheus

    Quick Report

    VLDR, concordo com o que o colega Jhonas postou, apenas fico intrigado com o fato de nesta versão 5 do Quick o preview não vir mais em modo Maximizado (até a 3.5.1 o preview vem maximado). Pode até ser que eles tenham mesmo mudado isto. Se você é usuário registrado, deve poder baixar a última atualização, caso não a tenha: Download Quick Report 5.04 (pode ser que tenham "corrigido" isto). Abraços
  21. Felipe Gomes, apenas para não ficar dúvidas, o que o colega Jhonas lhe sugere é que adicione ao seu ToolBar o botão da paleta Additional - TBitBtn. O botão TToolButton, que é o padrão a ser adicionado ao ToolBar (via menu de contexto New Button) não oferecem a possibilidade de posicionamento da imagem. A substituição funcionará perfeitamente, apenas lembro que você deverá adicionar a imagem ao botão via propriedade Glyph do TBitBtn (no caso do TToolButton, a imagem vinha do ImageList associado a propriedade Images do TToolBar). Porém, se você pretende fazer uso da propriedade Down do TToolButton (manter o botão pressionado), então você poderá fazer uso do componente TSpeedButton, que permite manter o botão neste estado, bem como o alinhamento da imagem (Layout) e deslocamento da margem de alinhamento (Margin) Abraços
  22. vamos tentar... - Marcar, no field, a propriedade Required = True; Esta não há o que exemplificar - apenas altere a propriedade citada - Antes do de chamar Post, testar se os respectivos campos estão, ou não, vazios; procedure TForm1.BtnGravaClick(Sender :TObject); begin if DatasetCAMPO.IsNull then // campo do dataset ligado ao DBEdit begin DatasetCAMPO.FocusControl; ShowMessage('Deve ser informado ... '); Exit; end; ... Dataset.Post; end; - No evento BeforePost do dataset, testar se os respectivos campos estão, ou não, vazios. Se estiver você chama o procedimento Abort; procedure TDatamodule.DatasetBeforePost(DataSet: TDataSet); begin if Dataset.FieldByName('CAMPO').IsNull then begin Dataset.FieldByName('CAMPO').FocusControl; // pode ser usado se o componente não estiver oculto ShowMessage('Deve ser informado ... '); Abort; end; end; ou, sem usar o conjunto ShowMessage e Abort - usando o Raise: procedure TDatamodule.DatasetBeforePost(DataSet: TDataSet); begin if Dataset.FieldByName('CAMPO').IsNull then begin Dataset.FieldByName('CAMPO').FocusControl; // pode ser usado se o componente não estiver oculto Raise Exception.Create('Deve ser informado ... '); end; end; - No evento OnExit do componente, testar se o seu conteúdo foi, ou não, informado; Se não foi, mostra mensagem e mantém o foco nele; procedure TForm1.DBEdit1Exit(Sender :TObject); begin if Dataset.FieldByName('CAMPO').IsNull then // campo do dataset ligado ao DBEdit // ou // if DatasetCAMPO.IsNull then // campo do dataset ligado ao DBEdit // if Trim(DBEdit1.Text) = '' then // eu prefiro um dos acima begin ShowMessage('Deve ser informado ... '); DBEdit1.SetFocus; end; end; Procure testá-los e ver o que é conveniente ou não no seu caso. É um bom hábito tentar padronizar o método, entretanto, nada impede que você os combine. Observar que ao usar o evento OnExit, é conveniente você testar o componente que recebeu o foco (ActiveControl), pois caso você tenha um botão para a opção cancelar gravação e ele seja pressionado não há porque fazer a validação: begin if ActiveControl = btnCancelar then Exit; if .... // continua com a validação ... end; Abraços
  23. Uma opção seria usar o DBLookupComboBox. ConfiguraçãoDataField : campo a receber o valor DataSource : dataset em edição ListSource : dataset de onde você busca os dados de consulta ListField : campo da consulta a ser mostrado na lista KeyField : campo da consulta a ser atribuido ao campo listado na propriedade datafield. Veja este tópico Abraços
  24. Há várias possibilidades: - Marcar, no field, a propriedade Required = True; - Antes do de chamar Post, testar se os respectivos campos estão, ou não, vazios; - No evento BeforePost do dataset, testar se os respectivos campos estão, ou não, vazios. Se estiver você chama o procedimento Abort; - No evento OnExit do componente, testar se o seu conteúdo foi, ou não, informado; Se não foi, mostra mensagem e mantém o foco nele; - ... ... e por aí vai. Abraços
×
×
  • Criar Novo...