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

    Ler Arquivo Txt

    Pirambu!, basta que você copie direto o resto do texto para seu último campo! Não esqueça que você não gravou no fim da linha o caracter delimitador, então Pos(Separator, szLine) -1 resultará em -1, logo nada será copiado para seu último campo. você grava: campo1 + ";" + campo2 + ";" + campo3 E quer ler: - campo1 até ";" - campo2 até ";" - campo3 até ";" Percebeu?! Abraços
  2. Micheus

    Ampulheta

    Eder, que componentes e banco você utiliza? Se está utilizando os componentes da paleta BDE, verifique a propriedade SQLHourGlass da classe TSession. Quando você não adiciona o componente TSession, uma instância padrão é criada e você pode acessá-la pelo seu nome Session (está declarada na unit DBTables). Neste caso se você fosse alterar o conteúdo dela seria apenas incluir este código na criação do seu datamodule ou form principal: Session.SQLHourGlass := True; Que me lembre, por padrão deveria já estar em True. E neste caso não seria realmente necessário trocar a ampulheta na mão. Abraços
  3. Micheus

    Relatório

    Pirambu!, e a TBFuncionario é o DataSource da query que é utilizada no relatório?Sugestão: você não poderia passar esse código como parâmetro para seu form que contém o relatório e, então, inicializar o parâmetro via código seguido do Open da query e o preview? (ou +/- isso, já que a construção do seu código pode não similar ao que eu costumo utilizar) Assim, você garantiria que a cada chamada ao relatório o posicionamento ocorresse corretamente. Outra coisa, esse código que você colocou, normalmente vai no evento OnClose e não no OnDestroy. Abraços
  4. mcsmarmcs, tente utilizar a idéia que postei para o colega Pirambu! uns dias atrás - link - acho que atende sua necessidade. Observe o uso de parâmetro na cláusula WHERE e a ligação via propriedade DataSource. Qualquer dúvida, posta aqui. Abraços
  5. Renyo, fiz uma busca e a resposta, que está neste link, eu confirmei no help:TSQLQuery is a unidirectional dataset. Unlike other datasets, unidirectional datasets do not buffer multiple records in memory. Because of this, you can only navigate using the First and Next methods. There is no built-in editing support: you can only edit the data in an SQL query by explicitly creating an SQL UPDATE command or by connecting the dataset to a client dataset using a provider. Features that require buffering multiple records, such as filters or lookup fields, are not available. Lá tem umas sugestões. Abraços
  6. Micheus

    Clique No Dbgrid

    carlos peraira, se o seu DBGrid está ligado, via datasource, a um dataset do tipo TTable, então é simples - desde que você utilize um Datamodule.Supondo que utilize, basta que no form em questão, os componentes Dataware (os TDB's da vida) estejam ligados a um datasource que aponte para o mesmo dataset ligado ao DBGrid - só isto! Já se no seu DBGrid você tem ligado a ele um dataset do tipo TQuery, então, neste seu form, você precisará posicionar o dataset no registro de "código" equivalente ao que é apresentado no DBGrid. Se for este o caso, dê uma espiada neste exemplo de um tutorial que vou postar em breve. Abraços
  7. Aparentemente o problema inicial referente ao path ficou resolvido e este é um novo problema, certo?! Sobre o D2007 não tenho o que falar porque estou parado no D7. Então fugiu um pouco do meu escopo, mas pelos sintomas, me parece algum problema com os drivers (só um palpite). ----------- Estava olhando o post novamente e esse seu último .ini é sem dúvida bem diferente daquele do post inicial. Inclusive, na linha DriverAssembly=Borland.Data.DbxCommonDriver,Version=11.0.5000.0,Culture=neutral, esta última vírgula não sugere que deveria ter algo além dela? É assim mesmo?
  8. Utilizando TQuery, você não poderia utilizar algo como:"select * from nome_tabela where fotografia is not null" ? Não funcionaria?
  9. fajo, você consegue depurar o código e observar o conteúdo de Params após a leitura e antes da abertura da conexção? (utilizar um break-point)Se o erro ocorre na abertura da conexão, a mensagem sugere que o parâmetro database não está com um valor válido.
  10. mcsmarmcs, a sugestão do colega jo_user está correta - utilizar between é o mais adequado - mas acredito que a principal questão no seu caso seja a forma como você está passando os parâmetros. Quando utilizar parametrização, indique o tipo de dado que você está passando (e espera receber na SQL) para que não ocorram problemas. Por ex., você montou seu SQL comparando o tipo data (date) com o parâmetro, logo este é o tipo que você deveria passar ao parâmetro, de modo que a etapa que ocorre entre o valor passado e a query a ser processada pelo banco seja corretamente montada. Assim, seria preferível passar desta forma: query1.ParamByName('Pdata1').AsDate :=DateTimePicker1.Date; query1.ParamByName('Pdata2').AsDate :=DateTimePicker2.Date; E este é o grande lance de utilizar a parametrização, já que você não precisa indicar qual formatação este campo data deve ter, já que você não está passando a data no formato texto - está simplesmente passando a data. Mas se quiser realmente passar no formato texto, então você deve pensar de forma similar: se vai passar a data como um texto formatado então você tem que preparar seu SQL para receber desta forma: query1.SQL.Add('WHERE nascimento>= STR_TO_DATE(:Pdata1, "%Y/%m/%d") and nascimento<=STR_TO_DATE(:Pdata2, "%Y/%m/%d")'); query1.ParamByName('Pdata1').AsString:=FormatDateTime('YYYY/mm/dd', DateTimePicker1.Date); query1.ParamByName('Pdata2').AsString:=FormatDateTime('YYYY/mm/dd', DateTimePicker2.Date); Referência às funções Date e Time do MySQL. Abraços
  11. Fajo, se o código está como o postado, seu problema é similar ao que o colega Marcos-rj (link) postou esses dias. Lá no OnDataModuleCreate você está esquecendo de uma barrinha ("\"). Está assim: teste.LoadFromFile(extractfilepath(application.exename)+'base.ini'); e deveria ser assim: teste.LoadFromFile(extractfilepath(application.exename)+'\base.ini'); Sugestão para este trecho do código - experimente: teste.LoadFromFile(extractfilepath(application.exename)+'\base.ini'); SQLConnection1.Connected := False; SQLConnection1.Params.Clear; for I := 0 to teste.Count - 1 do SQLConnection1.Params.Add(teste.Strings[i]); SQLConnection1.Params.Add('Password=masterkey'); Como Params já é um TList, não há necessidade de você alocar um objeto apenas para carregar os dados e depois mover para outro obtjeto da mesma classe - simplesmente utilize ele direto:SQLConnection1.Connected := False; SQLConnection1.Params.Clear; SQLConnection1.Params.LoadFromFile(extractfilepath(application.exename)+'\base.ini'); SQLConnection1.Params.Add('Password=masterkey'); Confirme se era isto mesmo. Abraços.
  12. Pirambu! estou meio sem tempo para lhe dar uma resposta decente, então, apenas resolvendo seu problema... Utilize as propriedades MasterSource da tabela TBDocumento para ligá-la Table1 (selecione o datasource que está ligado a ela), em seguida utilize as propriedades MasterField e KeyField (se não me engano) para selecionar os campos que fazem parte do relacionamento entre ambas as tabelas. Também se não estou enganado, no paradox, será necessário que as tabelas tenha índice por esses campos - não estou 100% certo, mas você saberá pois o campo não estará disponível para seleção. Lembre-se de ajustar o databasename nesta tabela também - se for o caso. Abraços
  13. Carlos Rocha, cara tive um trabalhinho extra, já que você não me respondeu que versão do Zeos está utilizando - As versões recentes não apresentam as propriedades RequestLive e ShowRecordTypes no componente TZQuery e que o compilador insistia em utilizar - tive que remover seus componentes e adicionar os da minha paleta (claro que só troquei os da tela de pedidos). <_< Primeiramente, acho que seria interessante você definir os relacionamentos em seu banco de dados caso não os tenha definido (no script não havia nenhuma definição) - isso garantirá a integridade das informações e dará um aspecto mais profissional ao seu projeto. Em Paradox este recurso era problemático, porque neste "protótipo de banco" os arquivos corrompem com certa facilidade - o que não é fácil com banco de dados "de verdade". Se precisar de uma ferramenta de modelagem de dados para o MySQL dê uma olhada neste post. Executando o programa, consegui realmente ver o que você queria dizer, entretanto o problema ocorre devido ao fato de ter sido definido o relacionamento entre os dataset's QryPedidos e QryItens dentro do programa. Isso poderia ser feito utilizando Filter, clausula WHERE e deveria funcionar também ao setar MasterSource/MasterField/LinkedFields. Eu prefiro utilizar a cláusula WHERE. Então a sugestão para correção seria substituir o SQL de QryItens para: Select * from Itens where NumeroPedido = :CodigoPedido E associar a sua propriedade DataSource o datasource DSPedidos de onde será obtido o parâmetro CodigoPedido definido no novo SQL. Deste modo, ao abrir QryItens, será filtrado apenas os itens correspondentes ao Pedido selecionado. Na procedure RecalculaPedido substitua: StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').Value); por StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').AsCurrency); isso evitará erro quando Total for nulo (ocorre sempre que não existirem itens ainda). Quando você utiliza o AsCurrency a conversão é feita implicitamente e você tem como resultado 0 (zero). O evento OnCalcFields ocorre para cada item existente no DBGrid, assim recalcular o total a cada evento não será muito interessante. Digamos que o lógico seria: - quando mudamos de pedido; - quando gravamos um item do pedido (post de um insert ou edit); - quando excluímos um item do pedido. Assim a sugestão seria utilizar o evento AfterPost, AfterDelete de QryItens e o evento OnDataChange do datasource DSPedidos: procedure TCPedidos.QryItensAfterPost(DataSet: TDataSet); begin RecalculaPedido; end; esta procedure seria atribuída ao evento AfterDelete também (é só associar o evento ao procedimento já existente) procedure TCPedidos.DSPedidosDataChange(Sender: TObject; Field: TField); begin RecalculaPedido; end; Faça a ordenação dos seus campos na tela - o Tab Order, já que é chato você teclar TAB e ir para outro campo que não seja o próximo. Dê uma olhada no evento OnClick do botão de impressão do relatório, você vai observar que no texto da propriedade Filter do dataset QryItens você está utilizando "CodigoPedido = ...", mas o nome do campo na tabela de itens na verdade é NumeroPedido! (aqui você é vítima de sua própria pegadinha...). É conveniente que os campos de relacionamentos tenham o mesmo nome nas tabelas envolvidas. Voce enctrará outros pequenos problemas, mas é melhor que você os encontre. ;) Por hora acho que é só, espero não ter esquecido de nada. Abraços
  14. Não sei o que é que eu estava procurando, porque não enxerguei este arquivo - agora eu o encontrei. :rolleyes: Vou verificar e até amanhã dou um "parecer" - ainda tenho que instalar o MySQL aqui em casa.
  15. Por favor não grite. você utiliza o apóstrofo assim: 'where NOME like '''GISELE%''' ou se for concaternar uma variável: 'where NOME like '''+ edit1.text +'%''';
  16. você vai precisar de ter um driver ODBC ou OLE DB (preferencial) instalado:- OLE DB - zStyleGroup - ODBC - Firebird Dá uma espiada neste link que dá umas dicas (é para VB, mas tem algo a aproveitar), veja tópico "Instalando o driver para acesso" (observe a tela de configuração da conexão) Caso não seja postado mais nada, veja se você já consegue avançar um pouco com isto. Abraços
  17. Recebi sim, mas como você trabalha com MySQL e como eu imaginava - não tenho a estrutura do seu banco para gerá-lo aqui - logo, só posso ver suas telas mas não posso executar o programa. Se não tiver como gerar print-screen que mostrem a situação, então exporte a estrutura do banco (metadata) para que eu possa tentar visualizar o que você está querendo que eu entenda. Outra informação é a versão do Zeos que você utiliza, já que ao abrir o projeto, há duas propriedades do componente TZQuery que minha versão (6.6.0 - beta) instalada não reconhece. Abraços
  18. Micheus

    Imagens

    Bom, é complicado informar algo que seja muito útil, já que as escolhas são muito pessoais. Então seguem dois que já utilizei: - CristalXP.net (eu gosto muito do efeito "aqua" - tem um monte lá) - MaxPower (tem links para sites com diferentes tipos de licenças) Abraços
  19. Micheus

    Alias

    Churc, apenas para completar e o colega Marcos-rj entender o motivo de o código dele não estar funcionando. Faltou justamente o delimitador de diretório. No código ele colocou ExtractFilePath(Application.ExeName) + 'BD', o que resultaria em algo como "c:\arquivos de programas\pasta meu progBD", quando na verdade deveria ser ExtractFilePath(Application.ExeName) + '\BD', o que resultaria em algo como "c:\arquivos de programas\pasta meu prog\BD". Mas a forma mais apropriada, em que se ganha flexibilidade e compatibilidade é implementar da maneira sugerida pelo Churc. O uso do ForceDirectories garante que o path exista, criando ele em caso necessário. Abraços
  20. Carlos Rocha, acho que não captei a idéia então. Quando você inclui um novo pedido, inicialmente (até que ele tenha itens) ele não deveria apresentar o valor "0,00" ? :unsure: No comentário que eu fiz no post anterior, tomei como regra que em não havendo itens (caso da inclusão) o valor do pedido apresentado seria "0,00": 3) quando você observa: Observe que, para um novo pedido, o CodigoPedido ainda não foi gerado. Daí QryPedidosCodigoPedido.AsString sempre tera valor nulo e não terá ítens o pedido.; entendo que não haveria nada a fazer (processar) neste caso; Esta situação já estava descrita nesta linha do código sugerido: StaticTextTotal.Caption := '0,00'; // se o pedido não tiver itens ou houver exception, este é o valor apresentado Abraços
  21. Micheus

    Tchart

    Fernando, demorou um pouquinho, mas não estava fácil de encontrar uma pista - achei apenas hoje (fonte). O exemplo proposto mostra, em um label (poderia ser um hint), os valores no eixo X e Y quando o mouse é clicado dentro da área de fundo (painel delimitado pelos eixos - cpChartRect) do gráfico, sendo que pelo teste da Part a que representa a posição clicada, ocorre que não há obtenção do valor quando o mouse é clicado sobre a barra (quando for deste tipo). Para gráfico de linhas isso não se repetiu: procedure TForm1.Chart1ClickBackground(Sender: TCustomChart; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var XValue, YValue :Double; ChartClickedPart :TChartClickedPart; begin Sender.CalcClickedPart(Point(X, Y), ChartClickedPart); if ChartClickedPart.Part = cpChartRect then begin XValue := Sender.BottomAxis.CalcPosPoint(X); YValue := Sender.LeftAxis.CalcPosPoint(Y); Label1.Caption := Format('X:%f, Y:%f', [XValue, YValue]); end else Label1.Caption := ''; end; Uma variação, fazendo testes mais "demorados", possibilita a leitura de valores em qualquer posicionamento dentro dos limites do painel de fundo:procedure TForm1.Chart1ClickBackground(Sender: TCustomChart; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var XValue, YValue :Double; begin XValue := (Sender as TCustomChart).BottomAxis.CalcPosPoint(X); YValue := (Sender as TCustomChart).LeftAxis.CalcPosPoint(Y); if ((XValue > (Sender as TCustomChart).BottomAxis.Minimum) and (XValue < (Sender as TCustomChart).BottomAxis.Maximum)) and ((YValue > (Sender as TCustomChart).LeftAxis.Minimum) and (YValue < (Sender as TCustomChart).LeftAxis.Maximum)) then Label1.Caption := Format('X:%f, Y:%f', [XValue, YValue]) else Label1.Caption := ''; end; Estes procedimentos também podem ser utilizados no evento OnMouseMove - testei e fica muito bom. Abraços
  22. Carlos Rocha, parece-me que você quer recalcular o valor total de um determinado pedido, certo?! Primeiramente algumas observações: 1) note que o exemplo original é limitado pelo uso de dataset do tipo Table. Quando você utiliza dataset do tipo Query, muitas limitações não existem e facilidades nos estão disponíveis; 2) a linha TmpQry.Name := QryItens.Name deverá resultar em problema já que os identificadores devem ser únicos e deste modo você está tentando duplicar o nome do componente; 3) quando você observa: Observe que, para um novo pedido, o CodigoPedido ainda não foi gerado. Daí QryPedidosCodigoPedido.AsString sempre tera valor nulo e não terá ítens o pedido.; entendo que não haveria nada a fazer (processar) neste caso; 4) apesar de estar comentada, a linha TmpQry.FindField(QryPedidosCodigoPedido.AsString); não deve ser utilizada da forma como parece ter sido imaginada. FindField procura pelo nome de um campo na lista de Fields do dataset, não nno resultado da consulta/tabela; Então, vamos tentar abandonar alguns dos vícios impostos pelas limitações do Paradox e simplificar. Inicialmente, verificamos se devemos fazer, ou não, qualquer processamento em função da situação do pedido (Novo ou não). Segundo sua observação, quando CodigoPedido for nulo (novo pedido) ainda não haverão itens, logo, não faremos qualquer contabilização. Já quando o pedido estiver gravado e poder ter itens, então vamos procurar pelos mesmos e executar os cálculos. Entretanto, o SQL nos oferece funções como o SUM (somatório) que nos permite enviar numa instrução SELECT a orientação para que o banco faça os cálculos e nos retorne o resultado prontinho. Fazemos, então, uso deste recurso, limitando os itens a serem calculados em função do CodigoPedido passado como parâmetro para a cláusula WHERE.procedure TCPedidos.RecalculaPedido; var TmpQry:TZQuery; Total:Currency; // armazena valores do tipo moeda begin StaticTextTotal.Caption := '0,00'; // se o pedido não tiver itens ou houver exception, este é o valor apresentado if not QryPedidosCodigoPedido.IsNull then begin // cria um objeto Qry via codificação TmpQry := TZQuery.Create(Application); try // define DatabaseName e QryName via codificação TmpQry.Connection := QryItens.Connection; TmpQry.Name := 'TmpQry'; // *** o Nome do componente deve ser único!!! TmpQry.SQL.Add('Select SUM(PrecoUni *Quantidade) as Total'); TmpQry.SQL.Add('From Itens'); TmpQry.SQL.Add('Where NumeroPedido = :NumeroPedido'); TmpQry.ParamByName('NumeroPedido').Value := QryPedidosCodigoPedido.AsInteger; TmpQry.Open; StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').Value); finally TmpQry.Free; end; end;A forma como foi montada a instrução SQL (temos apenas a função de agregação - SUM no SELECT) permite que omitamos a cláusula GROUP BY, utilizado quando queremos agrupar os valores. Por exemplo, se fosse para gerar uma lista com o total de todos os pedidos, totalizado pedido-a-pedido, teríamos de definí-la desta forma: Nesta situação, todos as colunas no SELECT, que não são função de agregação devem ser colocadas na cláusula Group By.Aquele AS antes do nome do campo que estamos calculando, não é obrigatório, mas no MSAccess (se não me engano) é necessário. Abraços
  23. Micheus

    Duplo Clique

    Fernando, imagino que você esteja propriedade DragMode = dmAutomatic. Fiz uma gambiarra encima de uma teste com drag-and-drop manual que eu tinha. Aparentemente funciona, então experimente e veja se funciona para o que você quer. 1) Primeiramente as propriedades DragMode dos componentes envolvidos deve ser colocada em dmManual; 2) Os eventos OnStartDrag, OnDragOver, OnDragDrop e OnDragEnd continuam valendo; 3) Declaramos, na sessão private do form, duas variáveis para controle do mouse pressionado (Pressed :boolean) e do duplo-click(DblClick :boolean); 4) No evento OnMouseDown, a ser utilizados pelos componentes envolvidos, colocamos o seguinte código: procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Pressed := True; end; 5) No evento OnMouseUp, o seguinte código:procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if DblClick then DblClick := False; Pressed := False; end; 6) No evento OnMouseMove, o seguinte código:procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Pressed and not ((Sender as TControl).Dragging) then (Sender as TControl).BeginDrag(True); end; 7) No evento OnDblClick, inicializamos a variável DblClick para indicar que o evento ocorreu:procedure TForm1.Panel1DblClick(Sender: TObject); begin DblClick := True; // seu código continua logo abaixo ... end; 8) No evento OnStartDrag, adicionamos o código que verificará se o click do mouse que iniciou o processo foi gerado a partir do duplo click do mouse. Em caso afirmativo, cancelamos o processo:procedure TForm1.Panel1StartDrag(Sender: TObject; var DragObject: TDragObject); begin if DblClick then begin CancelDrag; Exit; end; // seu código continua logo abaixo ... end; A idéia é que se você dá um duplo click então o mouse não se move (99,99% das vezes isso ocorre - rsrs) eu você não está tentando fazer o drag-and-drop. Já se o mouse for pressionado e movido, iniciamos manualmente o processo. No meu exemplo, ambos os Panels compartilharam os mesmos eventos. Confira se funciona. Abraços
  24. Até funciona, veja este artigo "Ajustando Driver ODBC para Acessar Firebird via BDE". Poderia ser um quebra galho inicial - se for necessário. Mas o recomendado é que siga a dica do Churc - utilize componentes que acessam o banco diretamente. Com relação a migração das tabelas/dados, talvez você possa fazer uso de alguma ferramenta criada para este fim. É só procurar que você vai achar. Seguem algumas que encontrei: 1) Se não tiver dificuldade com Inglês, uma opção seria utilizar uma ferramenta chamada InterBase Datapump (Freeware). Dê uma olhada (tour) na ferramenta - link. Link direto para Download. Nesta página da IBPhoenix você encontra diversas opções de ferramentas para migração dos dados. 2) Em português, encontrei esta, mas mais simples, que converte DBF e DB para Firebird - link (Comunidade Firebird de Língua Portuguesa) Abraços
  25. Micheus

    Consulta Sql

    Vivendo&Aprendendo, preciso corrigir esta afirmação (isto é válido para o post do mcsmarmcs também).O procedimento está correto, mas o local não. Esta propriedade diz respeito a conexão com o banco que, portanto, é realizada pelo TDatabase - ele tem esta propriedade. Abraços
×
×
  • Criar Novo...