
Micheus
Veteranos-
Total de itens
3.189 -
Registro em
-
Última visita
Tudo que Micheus postou
-
Então, se você agrupará por tipo e listará o item, apenas estes dois campos deveriam estar na cláusula SELECT - mais nada. Isso deverá gerar linhas onde o tipo aparecerá várias vezes, mas o item apenas um para cada tipo.No relatório, ao utilizar quebra pelo tipo, você mostrará o tipo apenas uma vez seguido pelos itens. Abraços
-
Pirambu!, o objetivo seria o usuário informar (via edit.Text) o pedido a ser processado e então você mostrar os items a processar num DBGrid, para daí, a título de confirmação o usuário, por ex. clicar num botão para processá-lo?Se a idéia é esta, então, seu procedimento seria mais ou menos aquele passado pelo Kikonanet e no seu post #4: - você precisa de um SQL para seleção dos itens a serem mostrados no DBGrid - serão os items a serem processados; - partindo do princípio que o usuário irá confirmar este processamento, no momento da confirmação (p.e. um evento OnClick de um botão associado a esta ação) você utiliza o SQL de insersão - serão os item inclusos na tabela TableProcessamentoPedido; Observe que no DBGrid você apresenta dados vindos de uma instrução SQL utilizando um SELECT. O resultado da Query (TQuery), neste caso, é obtido pelo comando Open, entretanto, quando você utiza comandos como INSET, DELETE ou UPDADE, você utiliza o método ExecSQL o qual não retornará linha alguma - logo, apesar de você popular sua tabela, com esta mesma Query você não verá nada no DBGrid. Mas, pelos últimos posts, parece que você já percebeu isto. Se você estiver utilizando TQuey, você deverá retirar o params, o método é chamado da seguinte forma <tquery>.ParamByName(<nome_campo>).Value (ou .AsString, .AsInteger). Já se estiver utilizando componente da paleta ADO, então terá que trocar params para parameters.Qual banco de dados você está utilizando? Qual componente de acesso? Entretanto, observe que o Kikonanet apenas exemplificou. você não vai querer atribuir valores fixos, então seguindo sua SQL inicial: INSERT INTO ProcessamentoPedido(PedidoID,produtoID,quantidade) SELECT pedidos.pedidoID, pedidos.ProdutoID, pedidos.Quantidade FROM pedidos; with query1 do begin close; sql.Clear; sql.Add('select pedidoID, ProdutoID, Quantidade'); sql.Add('from pedidos'); sql.Add('where pedidoid =:ID'); ParamByName('ID').Value := StrToInt(edit.Text); // pressupondo que seja do tipo inteiro open; end; // basta inicializá-la uma vez antes do loop with query3 do begin sql.clear; sql.add('insert into itensprocessamentopedido(PedidoID,produtoID,quantidade)'); sql.Add('VALUES(:produtoID,:quantidade)'); end; // percorre todas as linhas retornadas em query1 while not query1.eof do begin query1.ParamByName('PedidoID').Value := Query1.FieldByName('PedidoID').Value; query1.ParamByName('produtoID').Value := Query1.FieldByName('produtoID').Value; query1.ParamByName('quantidade').Value := Query1.FieldByName('quantidade').Value; execSQL; // inclui o item atual de query1 em query3 query1.next; // avança para próxima linha na query1 end; Tenha cuidado quando utilizar estruturas aninhadas com o comando With..do. Se houver possibilidade de dúvida de quem seja a propriedade ou método utilizados, utilize o objeto de referência explicitamente. Voce pode, ainda, mostrar no DBGrid os itens que serão processados (query1) e utilizar aquela query inicial que fará o insert. Para bastaria colocar a instrução SQL na query3 e passar a mesma parametrização utilizada na query1. Substituindo no exemplo acima:... with query3 do begin sql.clear; sql.add('INSERT INTO ProcessamentoPedido(PedidoID,produtoID,quantidade)'); sql.Add('SELECT pedidoID, ProdutoID, Quantidade'); sql.Add('FROM pedidos'); sql.Add('WHERE PedidoID =:ID'); ParamByName('ID').Value := StrToInt(edit.Text); // pressupondo que seja do tipo inteiro ExecSQL; end; e não teria mais a parte do loop, já que as inclusões foram feitas via SQL. Abraços
-
Provavelmente porque o dataset está posicionado no referido registro e, ao digitar algo no DBEdit, o dataset entra em modo edição (Status = dsEdit) já que por default a propriedade AutoEdit do DataSource é TRUE. Acredito que seria então apropriado que você mantivesse os DBEdit's desabilitados (evitando a edição), até que a ação desejada seja acionada: Inserção ou Editção. Deste modo, ao inserir (seu F8), um novo registro seria criado ficando todos os campos em branco ou ao editar, você habilitaria os campos para que o usuário pudesse modificar os dados. Observe que se seu programa é utilizado por vários usuários em rede, utiizar findlast + 1, já na inclusão pode não ser uma boa idéia, visto que poderá ocorrer de mais de um "pegar" um mesmo número. O ideal é que este tipo de procedimento ocorra no último momento antes da gravação do registro - BeforePost. E nem assim, é 100% garantido - um dia alguém pode obter o mesmo número e receber um "Key Violation" no post. Abraços
-
rodrigo, apenas completando a informação, a referência a tabela só é obrigatória caso o campo exista em mais que uma tabela informada na cláusula FROM. esta observação é válida, mas o uso do AS não é obrigatório, ao menos para a maioria dos bancos de dados. Abraços
-
Quickreport: Carregar Um Arquivo Qrp Do Quickreport Em Tempo De Execuç
pergunta respondeu ao cristianobackup de Micheus em Delphi, Kylix
Qual seria exatamente a dificuldade? Quando você executa um preview, deve haver um botão para carregar um arquivo salvo anteriormente. Por acaso você quer fazer isto em linha de código: carregar o arquivo salvo e mostrá-lo direto no preview? Abraços -
Alisson, por regra (digamos assim) na cláusula ORDER BY você tem que incluir todos os campos constante da cláusula SELECT que não sejam funções de agrupamento. Assim, seu select deveria ficar como abaixo, só não sei se é o que você quer como resultado. SELECT ITEM.Titulo, ITEM.Tipo_Item, Sum(Cod_Item)Cod_Item, TIPO_ITEM.Descricao from ITEM, TIPO_ITEM WHERE ITEM.Tipo_Item = TIPO_ITEM.Cod_Tipo_Item group by ITEM.Titulo, ITEM.Tipo_Item, TIPO_ITEM.Descricao Está um pouco estranho você somar o Cod_Item, é isto mesmo? Não seria contar - COUNT Abraços
-
Amarildo, os componentes DBEdit estão ligados a um dataset, de modo que , eles estarão limpos apenas quando o referido dataset estiver fechado ou após uma chamada aos métodos Insert ou Append.Qual seria exatamente a necessidade de mantê-los limpo? Abraços
-
Quebra De Linha Com Fortes Report
pergunta respondeu ao rodrigo biagioli de Micheus em Delphi, Kylix
rodrigo biagioli, se aparece apenas um único quadrado, é porque a combinação de quebra de linha não está correta. Ela normalmente é composta pelo carrie-return + line-feed (#13#10 ou $0D+$0A). Como você está inserindo a quebra de linha? -
Consulta Sql Entre Duas Tabelas
pergunta respondeu ao Vivendo&Aprendendo de Micheus em Delphi, Kylix
Dê uma olhada na sua caixa de mensagem aqui do forum. -
Vivendo&Aprendendo, só no final do seu outro post você mensionou algo que volta e meia faz toda a diferença - o banco de dado utilizado. Também pelo fato de você utilizar minha sugestão, deu para perceber que você está utilizando componentes da paleta ADO - normalmente utilizados com MSAccess. Volto a reforçar à todos os que lêem este post, para que sempre que a questão envolva SQL, que informem o banco de dado que utilizam. Vivendo&Aprendendo, ocorre que no MSAccess não tem EXTRACT (FireBird e Interbase sim), no MSAccess e MSSQL você utiliza as funções Year(<data>) Month(<data>) e Day(<data>) para extrair este valores de campos datas. Então altere para: ... Alunos.SQL.Add('WHERE MONTH(DATANASC) between :MesI and :MesF '); Alunos.SQL.Add('AND DAY(DATANASC) between :DiaI and :DiaF '); ... Abraços
-
Consulta Sql Entre Duas Tabelas
pergunta respondeu ao Vivendo&Aprendendo de Micheus em Delphi, Kylix
Vivendo&Aprendendo, vai ser difícil de dar mais palpites. Por acaso você estaria utilizando uma base de teste (essa em access), porque daí se lhe interessar, você poderia enviar-me para que possa tentar obter a mesma cituação que você está tendo aí. No campo do "virtual", já não consigo pensar em mais nenhuma opção. Abraços. -
DELPHI-Man32, se você estiver utilizando a chave primária na tabela TBAgendas, que você citou ser um número seqüêncial, então você não precisaria utilizar a query auxiliar. Basta que você posicione no último registro da tabela: begin HoraAgenda := StrToTime(Agora.Text); QtdHorarios := StrToInt(QdtHorario.Text); IntervTempo := StrToTime(Intervalo.Text); DMBanco.TBAgendas.Active := True; DMBanco.TBAgendas.Last; conta := DMBanco.TBAgendasID_AGE.AsInteger +1; while QtdHorarios > 0 do begin ... Entretanto, se houver a possibilidade de outro usuário, gerar esta agenda em outro computador no mesmo momento, então o mais correto seria obter o max (utilizando a query) a cada interação do loop, ou seja, colocá-lo dentro do loop while - evitando assim, a possibilidade de erro de duplicação de chave. Abraços.
-
for ou while, ambos podem ser utilizados. Observe apenas que a 1º hora agendada não deve ter o horário incrementado, então você o incrementa após adicioná-lo na tabela. Abraços
-
Amarildo, para utilizar este recurso, como mensionei antes, você manteria o string inteiro em seu comando SQL. Imagino que você tenha adicionado os campos (fields) no seu dataset, certo?! Se não isto facilitaria as coisas.Para adicionar um campo calculado ao seu dataset (acredito que seja um TQuery), você acessa o editor de campos (duplo click sobre o componente), clicando o botão direito do mouse você selecina no menu pop-up New field. Vamos digitar NOMEX em name, em Type selecionamos String e em Field type selecionameos Calculated e clicamos em OK. Pronto, temos nosso campo calculado. Agora, para atribuí-lo um valor, utilizamos o evento OnCalcFields do dataset. neste evento escrevemos o seguinte: procedure TForm1.Query1CalcFields(DataSet: TDataSet); begin Query1NAMEX.Value := Copy(Query1CLI_NOME.Value, 1, 10); end;você tem que ajustar o nome do form e dataset conforme seu caso, mas é basicamente só isto. Daí em seu gráfico você utiliza o campo NAMEX e não CLI_NOME. Mas se a utilização do campo calculado não resolver, acho que essa será sua última alternativa. Abraços
-
DELPHI-Man32, acho que além destas duas informações, talvez fosse interessante informar a hora de início dos agendamentos. O processo é simples, já que você terá um loop em função da quantidade de horários e irá incrementar a hora no tempo informado. var HoraAgenda, IntervTempo :TDateTime; QtdHorarios :Integer; begin HoraAgenda := Date +StrToTime(edHoraDeInicio.Text); // data (dia em questão) e hora do 1º agendamento QtdHorarios := StrToInt(edQuantidadeHorarios.Text); // agendamentos por dia IntervTempo := StrToTime(edIntervaloTempo.Text); // tempo entre agendamentos while QtdHorarios > 0 do begin tabAgenda.Append; tabAgendaDATA.Value := Int(HoraAgenda); // move data da agenda para o registro tabAgendaHORA.Value := Frac(HoraAgenda); // move hora da agenda para o registro ... tabAgenda.Post; HoraAgenda := HoraAgenda +IntervTempo; Dec(QtdHorarios); end;Algo mais ou menos assim. Não esqueça de validar os campos dos edit's antes de utilizá-los. Abraços
-
Consulta Sql Entre Duas Tabelas
pergunta respondeu ao Vivendo&Aprendendo de Micheus em Delphi, Kylix
Vivendo&Aprendendo, você não estaria utilizando mais que um database e daí, no dataset em questão, poderia estar apontando para um onde a tabela alunos não exista? Qual banco de dados você está utilizando? Já estão se esgotando as opções. :D Abraços -
Amarildo, parece que esse seu problema é bem antigo não?! (ForumWeb -2004) O uso da instrução SUBSTRING no Paradox (ForumWeb - Hoje) só pode ser desta forma: SUBSTRING(nome_campo from inicio for num_caracteres). O outro formato não é utilizado pelo paradox. O SQLServer, por exemplo utiliza na outra forma citada, já no Oracle, IBM DB2 a função tem o nome SUBSTR. No Interbase ou Firebird, o primeiro formato é utilizado, porém se instalada uma UDF, você terá o segundo formato, sendo que o nome da função é SUBSTR. O problema está associado a cláusula GROUP BY. Só para você confirmar, escreva a instrução SQL desta forma: SELECT CADCLI.CLI_NOME, Sum(RECEBER.REC_VALORDUPLICATA) as Total FROM CADCLI,RECEBER WHERE RECEBER.REC_CLIENTE = CADCLI.CLI_CPFGC AND RECEBER.REC_DATAVENCIMENTO BETWEEN :VarDataI AND :VarDataF GROUP BY CADCLI.CLI_NOME No PARADOX, a cláusula ORDER BY não aceita que você coloque a função SUBSTRING ou indicação da posição do campo (1) - para esses a mensagem é 'Capability not supported'. Se colocar o ALIAS (NOMEX) a mensagem será 'Invalid field name'. Então, não tem jeito. Pela sua consulta, não parece-me problemático que você deixe de utilizar SUBSTRING. Se você está falando em totalizar valor de duplicata, parece-me que devem ser totalizados apenas de um cliente específico e não por nome, não é?! Por exemplo, havendo homônimos ou nomes similares pode ocorrer a totalização indevida. Assim, ADERBAL DA SILVA, ADERBAL DA FONSECA, ADERBAL DA PIEDADE, ficariam todos agrupados em ADERBAL DA. Mas acho que não é o correto. Então se o problema é apenas reduzir o comprimento do texto para utilizá-lo num gráfico, como sugere no 1º post do ForumWeb, você pode selecionar o campo CLI_NOME normalmente e, então, criar um campo calculado para conter apenas o substring no tamanho desejado e utilizá-lo onde precisar.
-
Vivendo&Aprendendo, provavelmente porque você está concatenando da data inteira (dd/mm/yy) ao invés de apenas o mês e o dia. Vou dar um exemplo utilizando parametrização que, no meu modo de ver, torna a leitura do código mais clara, bem como evita algumas dores de cabeça:with DmDados do begin Alunos.Close; Alunos.SQL.Clear; Alunos.SQL.Add('SELECT NOME, DATANASC '); Alunos.SQL.Add('FROM Alunos '); Alunos.SQL.Add('WHERE EXTRACT(MONTH FROM DATA_NASC) between :MesI and :MesF ' Alunos.SQL.Add( 'AND EXTRACT(DAY FROM DATANASC) between :DiaI and :DiaF '); Alunos.SQL.Add('ORDER BY Codigo'); Alunos.ParamByName('MesI').AsInteger := MonthOf(EdtInicial.text); Alunos.ParamByName('MesF').AsInteger := MonthOf(EdtFinal.text); Alunos.ParamByName('DiaI').AsInteger := DayOf(EdtInicial.text); Alunos.ParamByName('DiaF').AsInteger := DayOf(EdtFinal.text); Alunos.Open; end; Obs 1) As funções MonthOf e DayOf estão disponíves na unit DateUtils (a partir do D7 eu sei que tem). Obs 2) Se você estiver utilizando os componentes da paleta ADO, então onde existe ParamByName, deverá ser substituído por: <dataset>.Parameters.ParamByName(<nome campo>).Value := <valor>; Obs 3) Nas instruções SQL você não precisa incluir o nome da tabela junto de cada campo (Alunos.NOME), quando há apenas uma tabela definida na cláusula FROM. Se necessário for, fica mais curto a escrita se você utilizar os ALIASES (apelido - ex. FROM Aluno A); Abraços
-
Integra, erros deste tipo ao fazer o backup, sugerem corrupção do banco, ainda que você consiga acesso as tabelas e pareça tudo normal (em algum momento a coisa vai ficar feia :o). Já experimentei erros durante este processo (FB + IBExpert), mas não consegui contorná-lo (voltei um backup anterior - santo backup!). Dei uma pesquisada e encontrei um post em que um colega indica alguns passos para tentar resolver um problema similar (se não for o mesmo). Aparentemente a dica ajudou ao colega que perguntou. Então, dê uma olhada neste Post (DevMedia) e veja se lhe ajudará também. Abraços
-
já que você está imprimindo a numeração de páginas num formano não convencional (lembro-me de seu post), você por acaso não estaria interferindo no processo normal de impressão do QuickReport? Controlando o evento OnNeedData (ou similar) ou, ainda, forçando quebras? Abraços
-
Ao Invez De Apagar O Nó Apenas Recolhe... :(
pergunta respondeu ao Ivano de Micheus em Delphi, Kylix
Ivano, você precisa apenas utilizar o treeview para deletar o item. Por ex., para excluir o item da TreeView1 selecionado, basta o comando: TreeView1.Items.Delete(TreeView1.Selected); no seu caso, vou supor que o TreeView que possui o nItem, tenha o nome TreeView1. Então o comando ficaria:TreeView1.Items.Delete(nItem); Não tem nada a ver com o ponteiro não. Está corredo desalocá-lo, antes de eliminar o item, como você deve estar fazendo. Abraços -
VDLR, do jeito que as coisas estão, acho que não custaria nada você adicionar um TSQLQuery (não precisa remover o seu TSQLDataSet) e tentar fazer o locate utilizando ele, daí tíra-se esta dúvida.
-
Consulta Sql Entre Duas Tabelas
pergunta respondeu ao Vivendo&Aprendendo de Micheus em Delphi, Kylix
Vivendo&Aprendendo, parece que não deveria haver qualquer problema mesmo. Mas insisto para que você coloque a mensagem de erro exatamente como você a recebe. Eu poderia dizer que você adicionou os campos (fields) ao seu componente (dataset - não sei qual) e ao definir a propriedade DisplayLabel como Código, pode ter digitado esta informação na propriedade FieldName (estamos todos sujeitos a fazer isso). Daí, quando você abre a query em tempo de execução (e mesmo em design-time) você vai obter a mensagem: "Alunos: Field 'Código' not found" e nem se dar conta da acentuação. []s -
Bloquear Edição Em Dbgrid
pergunta respondeu ao Cleverson Honório Gouvêa de Micheus em Delphi, Kylix
Cleverson, experimente alterar a propriedade Options do DBGrid - dgEditing para False. -
Could Not Convert Variant Of Type(null) Into Type(double)
uma questão respondeu Micheus em Delphi, Kylix
Fabiano, você já verificou o conteúdo de AValue. Por acaso ele não está vazio neste momento? Também ao que parece, CD_CLIENTE é numérico, então você não deve utilizar QuotedStr, mas sim StrToIntDef; Observe que o erro fala sobre converter null para double. Se AValue é uma string vazia e você faz a comparação como mostrado, o filtro ficará: 'CD_CLIENTE= '''; Se CD_CLIENTE é numérico, ao tentar aplicar o filtro, o dataset irá tentar converter '' para um número o que possivelmente resultará no erro citado. Se utilizar a função StrToIntDef ( 'CD_CLIENTE='+StrToIntDef(AValue) ) o filtro ficará: 'CD_CLIENTE=0'; []s