
Micheus
Veteranos-
Total de itens
3.189 -
Registro em
-
Última visita
Tudo que Micheus postou
-
Como você está fazendo isto? Está mudando o tipo do campo e retornando a autoincrement? você faz tudo utilizando o mesmo componente? Já tentou abrir a tabela via database desktop após os procedimentos?
-
Se não necessitar armazenar a hora, convém utilizar Date no lugar de Now.Isto pode evitar problemas numa consulta em que você, por ex. filtre pela data. Terá que levar em conta que se passar como parâmetro do filtro da data apenas, a parte correspondente a horas estará zerada. Deste modo filtrar de 01/10/2006 a 04/10/2006 não incluirá registros armazenados com 04/10/2006 12:36. Para tanto teria que lembrar desta situação e incrementar um dia para então incluir registros até as 23:59hs do dia 04/10/2006 (que corresponderia a 05/10/2006 00:00). Tenho 99,99% de certeza disto (sabe como é nunca dá para estar 100% certo :D) []s
-
Que tipo de coisa? Se você utiliza o método SetRange, para modificar este range deve chamar CancelRange. O objetivo do SetRange é na verdade restringir a consulta às linhas que contenham o filtro indicado. Se a questão for apenas ordenar, e não filtrar no Grid baseado no ComboBox, então cancele a idéia do SetRange. Não daria para utilizar neste uma Query também? []s
-
Complexidade mesmo é inserir nota a nota as informações em arquivo wave. :blink: Não. Se você observar o read é feito em um buffer de 4kb. E olhando melhor a classe, vai observar que ele lê do arquivo a partir da posição em que parou. Tipo, leu 4kb, posiciona nos próximos 4kb e lê. Foi o que conseguí visualizar. Inclusive, você deverá observar que o tamanho máximo do buffer, que é inicializado, é de 160kb (PLAYBACK_HIGH_BUFFER_SIZE na unit waveoutthread.pas). Acho que é melhor dar uma olhada no arquivo que eu inclui na versão que alterei - RIFF.TXT - ele apresente todo o lay-out do arquivo WAV. Acho que passando o buffer para a lista circular, que será "tocado" pela thread (via resume) acho que daria para implementar. []s
-
Thales, também achei interessante o artigo e, pelo que eu tinha entendido inicialmente, parecia estar na linha do que você queira implementar. Na verdade eu estava mesmo é procurando por um artigo que li há algum tempo atrás com relação ao uso dos "instrumentos presentes na placa", mas não encontrei. É verdade. Mas se você quizer utilizar os "instrumentos na placa" ou tocar MP3 acho que não dá. Acho que encontrei algo que vai lhe interessar. Utiliza MMSystem e trabalha com thereading, usando um buffer circular. Fiz uma modificação para viabilizar um loop.A questão é que o arquivo é lido do disco (não gerado em tempo de execução como parece que você pretende usar) e nesta condição, a classe responsável pela leitura do arquivo, supostamente há a posibilidade da leitura de partes do arquivo para este buffer. Entretanto, o exemplo não implementa este recurso, tem que ser feita a adaptação para que o arquivo seja lido do início ao fim. Pelo menos foi a impressão que tive depois que carreguei um arquivo com 440Kb (apenas o início do som é ouvido). O procedimento para testar é pressionar carregar bloco e a seguir resume (ou simplesmente marcar repetição). Os originais estão neste link, mas há algumas inconsistências que não estam permitindo carregar o arquivo WAV. Fiz as correções e coloquei neste outro Download (Audio Thread Object.zip) Caso não conheça o site Programmers Heaven, dê uma olhada neste (link). Alguns artigos estão desatualizados, mas acho que você vai poder aproveitar alguma coisa. []s
-
gfav, consultando a documentação do MySQL dá para ver que não é uma única situação que gera este erro (link). Mas deve dar para eliminar algumas. Notou se só ocorre com uma determinada consulta? Se sim, tente verificar se ela está 100%. A falta de um campo de relacionamento na cláusula WHERE pode gerar um resultado (nº de linhas) maior que o esperado e esta é uma situação em que este erro pode ocorrer. Não sei se você conhece, mais em todos os casos, o link para a documentação do MySQL (tem versão em português, html/pdf/chm): http://dev.mysql.com/doc/ []s
-
Ruyfreis, como está organizado seu relatório? Bandas Group, Detail, SubDetail... O Datasets utilizados nas duas opções são distintos. []s
-
Erso, permita-me sugerir o uso mais comum desta sua idéia: Utiliza-se uma query auxiliar, apenas para obter o maior valor presente na tabela. Depois, soma-se 1 a este valor para gerar o próximo número. A obtenção e atribuição deste item deve preferencialmente ser feito no momento imediatamente anterior a gravação definitiva no banco (BeforePost). Isto porque, em sistemas com múltiplos usuários, obter este número em outro momento pode resultar que na hora da gravação efetiva um usuário já tenha gravado os dados utilizando o código que um segundo tentará utilizar - resultando em key-violation. Este procedimento não garante que tal fato não possa ocorrer, entretanto, minimiza esta possibilidade. Ex.: procedure TabNOMEBeforePost(DataSet: TDataSet); begin QryCodigo.SQL.Clear; QryCodigo.SQL.Add('select MAX(codigo) from tabela order by codigo'); QryCodigo.SQL.Open; TabNOMECodigo.Value := QryCodigo.Fields[0].AsInteger +1; end; []s
-
Thales, ou talvez algo parecido com este exemplo no msdn? -> link
-
rjcerri, depois desta etapa, para que Zquerycadmedci utilize ZqueryDivutemp como "filtro", basta que você coloque na cláusula WHERE do SQL em Zquerycadmedci uma instrução que receberá como parâmetro o campo de relação (filtro) correspondente e que virá da consulta ZqueryDivutemp.Não sei a estrutura das suas tabelas, então vou usar o que temos aqui. No SQL em ZqueryDivutemp deve ter o campo Codigo na cláusula SELECT: SELECT Codigo, ... FROM divutemp Daí no SQL em Zquerycadmedci deve ter a declaração de um parâmetro que será recebido via DataSource: SELECT Codigo, ... FROM cadmedic WHERE Codigo = :Codigo ... Observe que isto resultará em que a consulta Zquerycadmedci ao ser aberta "solicitará" um parâmetro que será obtido do DataSource visto que neste existe um campo Codigo (na cláusula select e de mesmo nome do parâmetro), sendo equivalente ao que você utilizava: divutemp.codigo=cadmedic.codigo Diga se conseguiu entender ou não. Se não coloque as duas consultas SQL, de cada tabela para poder utilzá-las como exemplo. []s
-
Era o que imaginava. rjcerri, você tem duas opções, como não citou os componentes que utiliza, vou "falar" genericamente: 1) Tentar abrir um dataset (Query ou tabela) que aponte para este arquivo dentro de um try except end. Se NÃO houver erro na abertura é porque existe; try QryTeste.Open // se executar esta linha não houve erro e a tabela existe except // se executar esta linha então houve // erro e provavelmente a tabela não existe end; 2) Utilizar uma query para excutar a instrução SQL:SELECT distinct RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME AS TABELA FROM RDB$RELATION_CONSTRAINTS WHERE upper(RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME) = upper('AQUI O NOME DA TABELA') Então ao abrir a consulta, você testa o EOF.QryTeste.Open; if QryTeste.EOF then // Tabela não existe else // Tabela existe Tenha em mente que o FireBird é um gerenciador de banco de dados, onde, diferente do Paradox, as tabelas não existem separadas umas das outras numa pasta do seu HD - ficam todas dentro do banco de dados (um único arquivo - *.fdb). []s
-
Eder, altere apenas o SQL em QryGerarMens: select CodAluno, Turma from ALUNOS A where DATADEM IS NULL and not exists(select CodAluno from MENSALIDADE M where M.CodAluno = A.CodAluno and M.mês = :mês and M.ANO = :ano) []s
-
traira007, se por algum motivo você passar um valor nulo (Edit1.Text = '') ou algo que não seja um núvel válido, haverá erro na conversão. Seria conveniente você testar o valor digirado no Exit do edit, de modo a validá-lo. Em todos os casos você pode utilizar StrToFloatDef(Edit1.Text, 0) que retornará um valor padrão em caso de erro na conversão.
-
Paulo Nobre, provavelmente porque deve atingir o limite do tipo Extender = 1.1 x 10^4932
-
Eder, a idéia foi realmente de simplificar, mas não é garantia de nada enquanto não funcionar. Então, espero que antes de você sair alterando, você tenha feito um backup desta tela. Só mais uma dica, que vale para todos é claro; Um código tão longo como o que você postou, fica mais legível se vê utilizar a tag CODE (botão # no editor), pois são mantidas as identações. Tudo alinhado à esquerda dá um nó nas ideias. :wacko: Perfeito! Correto! Quando utilizar um componente com o SQL adicinado em design-time, torna-se convenente que você adicione os field's. Porém, como utilizamos parâmetros, primeiro devemos adicionar estes:- Na propriedade Params do comopente TQuery, click no botãozinho [...] - Na caixinha que aparece, selecione parâmetro a parâmetro e na janela Object Inspector configure as propriedades DataType, ParamType; No seu caso o parâmetro mês e Ano são do tipo inteiro, então set para ftInteger(o tipo do parâmetro é sempre igual ao tipo de dados na tabela); ParamType, em 99,99% dos casos é ptInput. Agora podemos adicionar os fields, veja procedimento: - Dê um duplo click no componente TQuery; - Na caixinha que aparece, acesse o menu via click do botão direito do mouse; - Selecione a opção Add All Fields. Neste momento, já estará existindo o field QryGerarMensCodigo. Mas se você não quizer utilizar esta abordagem, então terá que se referenciar aos campos retornados no TQuery pelo seu nome, via método FieldByName ou, como alguns gostam, pelo índice em Fields[<índice>]. Particularmente prefiro FieldByName porque estou certo de que campo estou buscando, sem contar que fica mais legígel para qualquer outra pessoa. Neste caso ficaria assim: if Table1.Locate('Codigo', QryGerarMens.FieldByName('Codigo').Value, []) then Table2CodTurma.AsInteger:= QryGerarMens.FieldByName('Turma').AsInteger; Fica a gosto do freguês. Opções não faltam. beleza?! ... Acho que está ok. Depois de você fazer os ajustes para correção dos problemas encontrados, acho que não haverá mais problema de compilação. []s p.s. Não é Michels e sim Micheus.
-
Paulo Nobre, a sugestão do uso do TActionMainMenuBar foi apenas uma sugestão imediatista, mas também para mostrar que existem outras opções e com mais recursos (sempre tem alguém que lê o post e ainda não usou outra coisa que não o TMainMenu). Se desenhar o menu já atende as necessides(e acho que é o seu caso), então, com certeza esta é a melhor e talvez mais simples opção. Mas, a título de não desmerecer o componente TActionList, como você disse: o actionList serve para todos os componetes. Podemos realmente tirar proveito dos Actions quando se tem menus e botões acessando as mesmas opções. Por ex. um grid com botões para Inclusão, Alteração e Exclusão e um menu PopUp que tambem acessam estas opções. Quando você associa um Action (Incluir) para o botão e para a respectiva opção do menu, você tem a possibilidade de executar uma operação onde antes executaria duas. Vamos supor que você queira desabilitar ou ocultar uma das opções, com o action, basta que você manipule propriedades como Caption, Enable ou Visible deste para que as respectivas propriedades do item de Menu e Botão assumam o mesmo valor. Neste cenário, quando você trabalha com "controle de acesso", haverá basicamente uma classe a ser manipulada no que diz respeito a opções de menus e botões, o que pode ser vantajoso. É sempre uma questão de avaliar a situação. Quanto mais conhecemos as ferramentas que temos, mas facilmente empregaremos eslas nas situações apropriadas. []s
-
rjcerri, qual seria o objetivo deste teste?
-
Eder, vamos ver se conseguimos ajudar a resolver o problema... (1ª tentativa) você não falou, mas imagino que esteja utilizando Paradox, certo?! substituia este processo por um componente TQuery (vou chamar QryGerarMens) e coloque na propriedade SQL (em design-time) o seguinte código:select CodAluno, Turma from ALUNOS A where not exists(select CodAluno from MENSALIDADE M where M.CodAluno = A.CodAluno and M.mês = :mês and M.ANO = :ano) Explicando: o select que está na cláusula WHERE "irá retornar" os alunos com mensalidade lançadas para o mês e ANO informados; Como listamos na instrução SQL principal todos os alunos que NÃO (not) aparecem na listagem do sub-select, então teremos uma relação de apenas os que estão faltando. Com isso, não terá como um aluno que pague adiantado para o mês e ANO informados, aparecer na lista e, por conseqüência, você não duplicará a informação. O código substituto ficaria agora assim: //INICIO //Abaixo verifica se já foi gerado a mensalidao do mês/ano para não dar duplicidade QryGerarMens.ParamByName('mês').AsInteger := StrToInt(COMBOBOX1.TEXT); QryGerarMens.ParamByName('ANO').AsInteger := StrToInt(COMBOBOX2.TEXT); QryGerarMens.Open; //FIM.... (mais ou menos o "fim") if not QryGerarMens.EOF then begin //Aqui começa a gerar as mensalidades automaticas... while not QryGerarMens.eof do // *** prefira "Not TABLE1.eof" modo à "TABLE1.eof = false" begin // *** Se estiver usando um índice pelo CodAluno utilize o FindKey, do contrário Locate // if Table1.FindKey([QryGerarMensCodAluno.AsInteger]) then if Table1.Locate('CodAluno', QryGerarMensCodAluno.Value, []) then begin Table2.Insert; // ou seja da um insert para cada aluno Table2codAluno.asinteger := Table1codigo.asinteger; //alimento o campo cod_aluno com o registro da tabela alunos atual Table2Data.asDateTime := Date; Table2Mes.asInteger := strtoint(combobox1.TEXT); Table2Ano.asInteger := strtoint(combobox2.TEXT); Table2CodTurma.AsInteger:= QryGerarMensTurma.AsInteger; Table2Vencimento.asDateTime := StrToDate(EditVencimento.TEXT); Table2Descontos.ascurrency := 0; Table2Acrescimo.ascurrency := 0; Table2Baixa.asString := 'não'; //abaixo filtra na query para filtrar o codigo da tuma e valor da mensalidade Query1.ParamByName('Codigo').AsInteger := QryGerarMensTurma.AsInteger; Query1.Open; Table2Valor.ascurrency := Query1ValorMensalidade.AsCurrency; //aqui coloca o valor filtrada da mensalidade Table2Total.ascurrency := Query1ValorMensalidade.AsCurrency; Query1.Close; //Table2Valor.ascurrency := STRTOFLOAT(EditValor.TEXT); // valor da mensalidade (irá a mesama para todos alunos, pois não esta sendo feito na matricula) //Table2Total.ascurrency := STRTOFLOAT(EditValor.TEXT); // valor da mensalidade (irá a mesama para todos alunos, pois não esta sendo feito na matricula) Table2.Post; //Salvo a mensalidade deste aluno end; QryGerarMens.next; //avanço para o proximo aluno parar gerar a mesalidade do proximo end; SHOWMESSAGE('OK...Gerado as Mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text); end else SHOWMESSAGE('As mensalidades para este mês/Ano'+' = '+combobox1.text+'/'+combobox2.text+'já foram geradas'); QryGerarMens.Close; Como você adiciona os campos de Query1 em deseing-time, tomei a liberdade de modificar sua "abertura" de modo que você deve alterar o conteúdo da propriedade SQL (em desing-time) para: Select Valormensalidade From Turma Where Codigo = :Codigo Obs 1) Sempre que possível, utilize parametrização - facilita muito as coisas. Obs 2) Os parâmetros e campos com o nome mês foram acentuados por conta do editor do forum. Não acentue nada (você deve saber, mas não custa lembrar) Obs 3) Dê uma boa olhada na parte do loop, pois troquei um pouco a ordem das atribuições apenas para ficar mais claro para mim. :rolleyes: Obs 4) Confira o nome do campo da turma, eu entendí que não é CodTurma, e sim, apenas Turma. Logo se estiver errado ajuste o código. Bom, isto tudo é virtual, espero que na real funcione. :D []s
-
Somando mais um pouquinho ao que o Thales postou... para retornar o string correto na hora de passá-lo ao canvas, utilize a função:function StripHotKey (const Text: string): string; // unit Menu só para não ficar dúvida para os iniciantes que por ventura leiam este tópico, basta que apenas o evento de um item seja escrito. Depois é só selecionar este evento para o OnDrawItem dos demais itens - não é repetido o código para cada item. []s
-
gfav, acho que assim ficaria mais adequado então: if Trim(zquery2.fieldbyname('foto').AsString) <> '' then try img.Picture.LoadFromFile('http://www.escritoriodosexo.com.br/fotos_peq/'+zquery2.fieldbyname('foto').AsString); except end; você deve incluir a unit Jpeg na cláusula uses do seu form. Caso não a tenha instalada, click aqui para baixar. É como eu disse antes, acho que não vai dar para fazer direto da URL para o componente. Como disse, é provável que tenha que utilizar um componente de FTP (idFTP da paleta Indy), de modo que você solicita a transferência (método Get) da imagem para um TStream (salvando temporariamente) e, depois sim, utilizar o LoadFromFile apontando para este arquivo. defina a propriedade PasswordChar do componente Edit, DBEdit ou MaskEdit para '*' - por default é '#0' que significa que não está definida. []s
-
gfav, nunca fiz nada deste tipo não, mas acho que você vai precisar trabalhar com componente para acesso FTP (para upload com certeza). Vou dar uma pesquisada quando tiver um tempinho, até por que tem um tempo que quero mexer com os componentes da paleta Indy. Qualquer coisa, se achar uma solução, posta ai. ;) Talvez fosse conveniente abrir um novo tópico para isto especificamente neste ponto, uma opção poderia ser usar um try except end inibindo a ocorrência da exceção (continuará quando executando via Delphi, mas "por fora" não) try img.Picture.LoadFromFile('http://www.meusite.com.br/fotos_peq/'+zquery2.fieldbyname('foto').AsString); except // sem qualquer código dentro do except end end; []s
-
Eder, não estou certo se funciona(experimente), mas acho que teria que ser:Expression => SUM(query1.ValorR) - SUM(Query2.ValorP) Esta opção deve funcionar com certeza: adicione um QRLabel na sumary e utilizar os QRExpr's das GroupFooter (Receber e Pagar) para obter o valor. No evento BeforePrint da banda sumary: QRLabel.Caption := FormatFloat('#,##0.00', QRExprReceber.Value.dblResult -QRExprPagar.Value.dblResult); []s
-
Eder, acho que esqueci de dizer, quando falei em dois quick's, que você utiliza um dataset para cada. Ou seja, você terá um para o Receber e outro para o Pagar. Cada qual associado ao respectivo relatório. seu select está "simples" assim? Acho que deveria ter algum filtro não? isto resultará em: (nº registros em RECEBER) x (nº registros em RECEBER) = (total de linhas retornadas) (que é o que se percebe na imagem que você postou).Duas tabelas num FROM lhe "obriga" a ter uma cláusula WHERE que relacione uma a outra (pelo menos) e um filtro (eventualmente). Posto desta forma e vendo o resultado do seu relatório, tenho a acrescentar que ele poderia também ser feito utilizando apenas um QuickRep, com bandas Group, Detail e Sumary. Para isso, como você utiliza uma tabela para cada evento, você faria em sua consulta SQL um UNION SELECT 0 AS IND_TIPO, CODIGO, VALOR FROM RECEBER WHERE .... UNION ALL SELECT 1 AS IND_TIPO, CODIGO, VALOR FROM PAGAR WHERE .... ORDER BY 1, CODIGO Esta consulta resultará na concatenação das duas tabelas, porém separadas uma da outra (na sequência) onde IND_TIPO será utilizado pela banda Group para a quebra que separará Receber de Pagar. você pode, então, utilizar GroupFooter's para apresentar o total de cada grupo através de um QRExpr (com SUM); Na banda Sumary, você totaliza todo o relatório (Receber - Pagar) como já está o fazendo. []s Micheus ;)
-
<_< Sempre que possível, utilize a segunda alternativa (modelo de passagem de parâmetros). Se a questão é montar o SQL na hora, misture os dois exemplos: Quando você utiliza parâmetros, não terá que se preocupar, por exemplo: - com o delimitador de string; - com o delimitador de data (no access é #, em outros isso não existe); - com o formato da data. se você cocatenar no formato ' where data = dd/mm/yyyy' pode ser que devesse ser yyyy/mm/dd (MySQL). É claro que ao passar o parâmetro você deverá invocar o método correto, deste modo você evitar ter algum tipo de surpresa. Por ex., se DatDebito é do tipo dada: QryUser.Params.ParamByName('DatDebito').AsDateTime := StrToDate(eDatDebito.Text); Bom, são algumas itens apenas. Depois que você se acostuma a utilizar deste modo, dificilmente tem essas dores de cabeça quando muda de um banco de dados para outro. Eu não saberia lhe indicar não. Talvez outro colega. Mas não há nada que não possa ser encontrado quanto se tem o Google ao nosso lado. ;) []s
-
Paulo Nobre, deve ser possível, já que existe a propriedade OwnerDraw no compoente TMainMenu e os eventos OnDrawItem e OnAdvancedDrawItem no TMenuItem. É uma questão de explorar as opções. isto é porque não há qualquer evento para o item do menu, utilizando estes componentes. Eles talvez desconheçam o uso do TActionList. É associando à propriedade ActionClientItem (itens do menu no TActionMainMenuBar) à um Action (item no TActionList) que as coisas acontecem. Este último tem o evento OnExecute, que é onde as coisas acontecem - equivale ao OnClick. Mas, não saia alterando seu projeto. Sugiro que utilize o exemplo explorando estes itens, principalmente se forem novos para você. No exemplo, tem dois componentes para "customização" das cores(ColorMap no ActionMainMenuBar) do menu. Elimine um deles (TwilightColorMap1) para não lhe atrapalhar. você terá que adicionar o tal TActionList (paleta Standard). Dois clicks nele e terá acesso ao editor. Clicando em New Action (teclar INS na lista), você adiciona um item, seleciona ele e altera suas propriedades. Basicamente Caption e Name. Essa propriedade categoria equivale a opção no menu principal. obs: Este componente pode ser utilizado com os items de "menu normais". []s