
Micheus
Veteranos-
Total de itens
3.189 -
Registro em
-
Última visita
Tudo que Micheus postou
-
Supondo que esse seu script possa ir aumentando com o tempo, seria mais conveniente modificar as propriedades para executar a tarefa de definir qual é o avanço (progresso): procedure TFormAtua.XiButton1Click(Sender: TObject); begin gauge1.Maxvalue := 12; // *** neste seu exemplo é 12, se incluir mais uma ação, aumenta este número with TQuery.Create(nil) do try DatabaseName := 'PENDENCIA'; //aqui o local onde será atualizado OU O ALIAS // SQL.Text := 'Alter Table "PENDENCIA.DB" Add CIFOB character(3)'; //aqui nome da tabela e nome do campo, tipo, tamanho a ser criado ExecSQL; gauge1.AddProgress(1); // *** incrementa um no progresso - fica assim para todos os seguintes // .... []s
-
maikel, entendo que sua resposta já foi suprida, mas lendo ela a impressão que dá é que você desejaria parametrizar sua query: e neste caso sugeriria : SELECT COUNT(usuarios.cod_usuario) as mês FROM usuarios WHERE EXTRACT(month FROM usuarios.ultimo_acesso) = :NUM_MESOnde o parâmetro seria passado à query e substituído na consulta.
-
Supondo que você deseje informar o andamento dos seus ExecSQL que são em número de 3, adicione a progressbar no seu form e proceda conforme alterações em seu código: procedure TFormAtua.XiButton1Click(Sender: TObject); begin // *** De quanto será incremento a cada avanço. Onde 3 é o número de ExecSQL que você realizará. // *** Max está inicializado em 100(%), assim no seu caso, a cada avanço a barra progridira 33% ProgressBar1.Step := ProgressBar1.Max div 3; with TQuery.Create(nil) do try DatabaseName := 'XXXXXXX'; //aqui o local onde será atualizado OU O ALIAS // SQL.Text := 'Alter Table "PENDENCIA.DB" Add CIFOB character(3)'; //aqui nome da tabela e nome do campo, tipo, tamanho a ser criado ExecSQL; ProgressBar1.StepIt; // *** Avançará posição em 33(%) // SQL.Text := 'Alter Table "PENDENCIA.DB" Add MANIFESTO numeric'; //aqui nome da tabela e nome do campo, tipo, tamanho a ser criado ExecSQL; ProgressBar1.StepIt; // *** Avançará posição em 33(%) // SQL.Text := 'Alter Table "PENDENCIA.DB" Add MOTORISTA character(60)'; //aqui nome da tabela e nome do campo, tipo, tamanho a ser criado ExecSQL; ProgressBar1.StepIt; // *** Avançará posição em 33(%) // finally Free; end; MessageDlg('Alteração Realizada!!', mtInformation, [mbOk],0); ProgressBar1.Position := 0; // *** reinicializa a barra, deixando-a "em branco" end;
-
Lembrando também, que ao fazer validação no evento OnExit, caso haja a possibilidade de o usuário desistir da tela, algo como clicar em um botão de cancelamento, pode ser conveniente verificar se o componente com o foco é este botão e então não executar a validação. Utilizando o código do Churc, ficaria assim: var _date: tdatetime; begin if ActiveControl <> nomebotão then // *** só aplica validação se for utilizar o conteúdo digitado try _date := strtodate(edit1.text); except showmessage('A data digitada é inválida!'); edit1.setfocus; exit; end;
-
É verdade, são possibilidades. Mas foi uma solução simplista para um sistema pequeno, com poucos usuários e que, para o tipo de aplicação que é, tem funcionado bem.Mesmo assim, vale apena ler o artigo. Ele não trata apenas da opção que citei (um pouco mais de conhecimento nunca é demais).
-
Ruyfreis dê uma olhada neste artigo (link). Eu utilizo a opção disponível no Firebird 1.5, mensionada no artigo (Select ... From Table [Where ...] [Order By ...] For Update With Lock) e funciona a contento, só tive que fazer uns testes para verificar qual o nível de isolação da transação que deveria utilizar.
-
Dê uma olhada neste link (final da página, mais à esquerda) e veja se lhe atende. []s
-
Beleza de código CorN_Sk8. É a versão menos simplista (oposto do que foi o meu post), mas muito mais precisa. Como observei que no seu exemplo o arquivo aberto sempre será um Bitmap (e acredito que o colega Paulo Nobre precisará abrir outros tipos), tenho a acrescentar o seguinte: - Acrescente um componente TOpenPictureDialog; - Adicione a unit Jpeg (citada no meu outro post) caso não tenha outra que permita abrir arquivos jpg e; - Altere o código do CorN_Sk8 conforme abaixo. procedure TForm1.Button1Click(Sender: TObject); var Picture :TPicture; begin P.X := 0; P.Y := 0; if OpenPictureDialog1.Execute then begin BMP := TBitmap.Create; Picture := TPicture.Create; try Picture.LoadFromFile(OpenPictureDialog1.FileName); BMP.Assign(Picture.Graphic); finally Picture.Free; end; Load; end; end; Como não ficou clara a aplicação que será dada a rotina, gostaria de observar ao colega Paulo Nobre que se o objetivo for apenas visualizar a imagem, o exemplo ficará completo, porém se o objetivo for editar a imagem (manipular os pixels) deve ser observado que na janela estará sendo visualizada uma cópia de parte da imagem original. Assim, qualquer alteração no fragmento da imagem visualizada terá que, de algum modo, ser repassado à original para quem sabe salvá-la. []s
-
O colega bolomaster tem está certo, a única forma é criando botões descendentes do padrão, vão algumas opções que encontrei: Equivalente ao TButton 1) TColorButton (1) (link) 2) TColorBtn (link) 3) TColorButton (2) (link) Equivalente ao TBitBtn 1) ButtonWithColot (link)
-
Na dúvida coloque sempre os ";" (ponto e vírgulas) necessários. implementation uses frmVendasUnt,frmClientesUnt; {$R *.dfm} procedure TfrmControle.SpeedButton1Click(Sender: TObject); begin frmClientes.Show; // este é opcional, mas vale o eu disse antes end; end.
-
Paulo, de uma maneira simples, daria para adicionar um ScrollBox (paleta Aditional) ao seu form e dentro dele colocar um Image (com align = alClient). O único inconveniente seria a presença das barras de rolagem quando a imagem for maior que a área de visualização. Meu form tem um Botão, um ScrollBox, um Image e um OpenPictureDialog. Também utilizo a unit jpeg 1.1(link) O código ficaria assim: TForm1 = class(TForm) ... private SavedPoint :TPoint; ... end; // abertura do arquivo de imagem procedure TForm1.Button1Click(Sender: TObject); begin if OpenPictureDialog1.Execute then begin Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName); // ajusta o scrollbox para o tamanho da imagem carregada ScrollBox1.HorzScrollBar.Range := Image1.Picture.Width; ScrollBox1.VertScrollBar.Range := Image1.Picture.Height; end; end; procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin SavedPoint := Point(X, Y); end; procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin X := ScrollBox1.HorzScrollBar.Position -(X -SavedPoint.X); Y := ScrollBox1.VertScrollBar.Position -(Y -SavedPoint.Y); if X < 0 then X := 0 else if X > ScrollBox1.HorzScrollBar.Range then X := ScrollBox1.HorzScrollBar.Range; if Y < 0 then Y := 0 else if Y > ScrollBox1.VertScrollBar.Range then Y := ScrollBox1.VertScrollBar.Range; ScrollBox1.HorzScrollBar.Position := X; ScrollBox1.VertScrollBar.Position := Y; end; p.s. só faltou trocar o ponteiro do mouse.
-
Segue um exemplo. Em meus testes mantendo a propriedade DefaultDrawing = False o resultado é melhor, caso contrário, você terá que tratar as colunas fixas que ficam em 3D. As linhas e colunas começam em 0, por isso conforme sua solicitação, as colunas 3 e 5 correpondem às 2 e 4 utilizadas no if. O teste com Row > 0 evita que seja modificado o cabeçalho da coluna. procedure TForm1.StringGrid1DrawCell(Sender: TObject; Col, Row: Integer; Rect: TRect; State: TGridDrawState); begin if Row > 0 then begin if (Col in [2, 4]) and not (gdFocused in State) then StringGrid1.Canvas.Brush.Color := cl3DLight; StringGrid1.Canvas.FillRect(Rect); StringGrid1.Canvas.TextRect(Rect, Rect.Left +2, Rect.Top +2, StringGrid1.Cells[Col, Row]); end; end;
-
Segue abaixo uma rotina de blend (mistura) a qual talvez você possa adaptar a sua necessidade. No meu teste adicionei um Timer (com a propriedade Interval = 150) e dois Images ao form. No evento OnTimer, Valor (que foi inicializado com 0) é incrementado em 4 - isto resultará no efeito Fade-In. Se começar em 100 e trocar Inc(Valor, 4) por Dec(Valor, 4) você obterá o Fade-Out. A procedure BlendBitmap, recebe como source um Bitmap para facilitar a reutilização em sua aplicação (você pode carregar um bitmap a partir de resources), já Dest deverá ser um Image. BlendColor representa a cor a qual o bitmap deverá ser misturado e BlendValue é o percentual a misturar de 0 a 100. procedure BlendBitmap(Source :TBitmap; Dest :TImage; BlendColor :TColor; BlendValue :byte); var X, Y, R, G, B, PR, PG, PB :Integer; blColor :LongInt; scColor :TColor; Percent :Single; tmpBitmap :TBitmap; begin if BlendValue > 100 then BlendValue := 100; tmpBitmap := TBitmap.Create; try // copia bitmap de origem para o temporário (o qual será modificado) tmpBitmap.Assign(Source); // Calcula percentual a aplicar Percent := BlendValue/100; // obtém as componentes da cor da imagem fonte blColor := ColorToRGB(BlendColor); R := (blColor and $000000FF); // Red G := (blColor and $0000FF00) shr 8; // Green B := (blColor and $00FF0000) shr 16; // Blue // varre todo o bitmap de origem for X := 0 to tmpBitmap.Width -1 do for Y := 0 to tmpBitmap.Height -1 do begin // obtém as componentes da cor da imagem fonte scColor := tmpBitmap.Canvas.Pixels[X, Y]; PR := (scColor and $000000FF); // % Red PG := ((scColor and $0000FF00) shr 8); // % Green PB := ((scColor and $00FF0000) shr 16); // % Blu // calcula o nível de mistura e determina novo valor para os componentes do pixel PR := Trunc(R +((PR -R) *Percent)); PG := Trunc(G +((PG -G) *Percent)); PB := Trunc(B +((PB -B) *Percent)); // atribui o pixel calculado ao bitmap tmpBitmap.Canvas.Pixels[X, Y] := RGB(PR ,PG, PB); end; // copia o bitmap temporário para o destino Dest.Picture.Bitmap.Assign(tmpBitmap); finally tmpBitmap.Free; end; end; var Valor :Byte; Blending :Boolean; procedure TForm1.Timer1Timer(Sender: TObject); begin if Valor < 100 then begin if not Blending then begin Blending := True; BlendBitmap(Image1.Picture.Bitmap, Image2, Self.Color, Valor); Inc(Valor, 4); Blending := False; end; end else Timer1.Enabled := False; end; procedure TForm1.FormShow(Sender: TObject); begin Valor := 0; Blending := False; Timer1.Enabled := True; end;
-
Typecast é algo como dizer que um determinado tipo de dados é outro (normalmente compatíveis). Não consigo encontrar palavras para lhe explicar melhor, então vou lhe dar alguns exemplos de uso: 1) Uma situação que muito uso é para flags numéricos. Numa listbox com duas opções, onde ItemIndex será 0 ou 1, quando necessito fazer algum teste, faço da seguinte maneira if LongBool(ListBox1.ItemIndex) then, da mesma forma que o inverso é verdadeiro; 2) Quando utilizo a tag de um botão, para implementar duplo estado. Então, no OnClick faço algo como TBitBtn(Sender).Tag := Ord(not Boolean(TBitBtn(Sender).Tag)); Observe que aqui utilizei um outro typecast muito comum. Todos os eventos passam Sender como parâmetro e normalmente trata-se do objeto que o gerou. Originalmente Sender é um TObject, sendo que é a classe base de todos os componentes descendem deste. Também poderia ser feito utilizando o operador "as": (Sender as TBitBtn).Tag := Ord(not Boolean((Sender as TBitBtn).Tag)) 3) Outra aplicação que faço uso é quando utilizo TreeNodes. Observe que além do texto que inserimos na Treeview, podemos armazenar dados associados a cada um deles. Afunção AddChildObject(Node: TTreeNode; const S: string; Ptr: Pointer) nos permite isto. Assim você pode associar objetos a cada item bastando passar o endereço do mesmo para a função no parâmetro Ptr. Então, ao utilizar a propriedade Selected (do TreeView), você poderá acessar a propriedade Data a qual contém o ponteiro passado na função e fazer um typecast dele para a classe que você adicionou. Tenha em mente que os tipos, apesar de diferentes, são compatíveis entre si. Caso contrário, o risco de obter erros é grande. Quanto ao seu segundo questionamento, não saberia responder (se ninguém responder, posso tentar verificar). []s
-
Isto provavelmente ocorreu pelo fato que as versões posteriores costumam manter compatibilidade com as versões anteriores. Já o contrário não é verdade. Assim, quando você fez o Type Cast para o Word2000, o programa continuou funcionando na sua máquina (que tem uma versão posterior do Word que deve ser compativel com a 2000). Se você abir o editor de registros (RegEdit) e verificar HKEY_CLASSES_ROOT, você constatará que estão registradas algumas versões do Word e uma "genérica" (Word.Application). Nom meu caso que tenho instalado o Office 2000: []s
-
Usar Campo Calculado No Campo Agregado Em Dbgrid
pergunta respondeu ao paulobergo de Micheus em Delphi, Kylix
Nunca utilizei o Aggregate, dei uma pesquisada para entender melhor como funciona e realmente você tem razão - desculpe o mau paupite. Utilizando ainda aquele seu primeiro exemplo: Mas, e se você realizar este processo na sua consulta (SQL)? Se no comando SQL você criar uma coluna com o cálculo do tipo "SELEC ..., (ROUND((preço * Quantidade)*100)/100) AS Valor, ..." talvez resolva seu problema (apesar de ficar um pouco mais pesada). Alguns boncos aceitam a instrução ROUND (encontrei uma tabela que diz que os bancos Access, MySQL, PostGreSQL e SQLServer aceitam). Será o seu caso? Ou, quem sabe, utilizar uma outra query (contendo as informações a calcular) devidamente parametrizada e realizar este arredondamento "na mão" através de campo calculado. -
Se você está fechando o DataSet, associado ao DBGrid, quando seleciona a opção no ComboBox e apenas o abre após concluída a digitação isto sempre vai ocorrer. Há de se saber em que momento você fecha e retorna a abrir o dataset. Em alguns casos, escolher o momento de fechar para em seguida abrir o dataset pode ser o suficiente para resolver o "problema", visto que algumas consultas são retornadas rapidamente. Mas, se achar que esta opção não está lhe servindo, pode utilizar as procedures DisableControls e EnableControls do componente TDataSet (ex. extraído do help): with CustTable do begin DisableControls; try First; while not EOF do begin { Process each record here } ... Next; end; finally EnableControls; end; end;Estes procedimentos farão com que os componentes que estão ligados ao DataSet fiquem "congelados" (DisableControls) até que você diga para descongelá-los (EnableControls) quando, então, serão atualizados.
-
Usar Campo Calculado No Campo Agregado Em Dbgrid
pergunta respondeu ao paulobergo de Micheus em Delphi, Kylix
Se você faz sum(preço * quantidade) e valor é 2,226, você terá o somatório igual a 2,226 + 2,226 que é igual a 4,452 e que arredondado será 4,45. Já se você tiver algo como sum(round_de_duas_casas(preço * quantidade)), então você terá 2,23 + 2,23 que será igual a 4,46. Assim, talvez seja uma questão de veficar onde deverá ser feito o arredondamento. Ou seja, se você arredondar o campo valor em dois dígitos antes da totalização, provavelmente obterá o esperado. -
Com relação a este exemplo, se você depurar este código verá que haverá apenas uma nova chamada no momento da atribuição do novo valor - porque evidentimente ele mudou (change) e não haverá estouro de pilha, logo, tal cuidado não chega a ser crítico para este caso (também, poderia ser resolvido se fosse alterada a propriedade CharCase para ecUpperCase no componente). Contudo talvez o mais relevante seja observar (às vezes nota-se que não é observado) que a cada tecla pressionada neste campo (componente) será gerado o evento OnChange e para algumas codificações este não seria o evento mais apropriado.A parti do seu código o que sugeri foi o seguinte: Busca := True; if (busca) and (CbbBusca.ItemIndex = 1) then begin try ADOContasReceber.Close; ADOContasReceber.SQL.Clear; ADOContasReceber.SQL.Add('Select * From ContasReceber'); ADOContasReceber.SQL.Add('Where Situacao = "A PAGAR" and DataVencimento = :pDat '); ADOContasReceber.SQL.Add('Order By Cliente'); // na linha abaixo, havendo erro, repõe o foco no Edit1 ADOContasReceber.ParamByName('pDat').AsDateTime := StrToDate(EdtBusca.Text); ADOContasReceber.Open; end; except on EConvertError do begin Edit1.SetFocus; busca := False; // aqui, uma mensagem informando sobre o erro seria conveniente end; end;Observe que este código deveria ser aplicado apenas com o campo de data completamente preenchido já que passamos para a query a data convertida. Assim, o local mais apropriado para execução do código seria, como o colega paulobergo, no evento OnKeyPressed onde você testaria a tecla ENTER (#13), ou no evento OnExit. Observe que se você altera um campo e deseja atualizar alguma coisa como reflexo disto, não necessariamente apenas ENTER seja a tecla a ser verificada, já que para mudar de campo dentro de uma janela do Windows, você utiliza a tecla TAB ou o MOUSE e nestes casos o evento OnExit sempre é gerado (eu dou preferência a esta opção). Algumas vezes utilizo um botão (onde efetivo o processo de localização). Para utilizar a digitação parcial da data como você faria com um texto (string) através do LIKE e utilizando o evento OnChange, vale o que o colega Graymalkin disse: Mesmo assim tenha em mente que estando a data no formato dd/mm/yyyy, você digita o nº 1 e serão listados todos os registros onde a data começa com um (15/10/1995; 1/6/2005), logo o resultado estará (provavelmente) muito longe do desejado. Assim, acredito que quando se tratar de pesquisa por data, a melhor opção é pesquisar pelo campo completo. A título de validação, vale o que o colega paulobergo disse: []s
-
Bom, já que ninguém opnou nada sobre o assunto, vou colocar meu parecer, quem sabe alguém descorde e possa adicionar mais informações. Bom, se eu fizesse um programa para utilizar paradox não seria diferente. Porém, já li muito sobre o paradox dar muito problema. Eu mesmo já tive, principalmente, problemas com índices e auto-increment devido aos arquivos corromperem. Talvez você pudesse avaliar a adoção de um banco de dados de verdade (o paradox é um aglomerado de tabelas - palavras minhas), tenho utilizado Firebird, MySQL. Se bem me lembro, é necessário que o BDE seja instalado (não sei se completo - acho que sim). Se utilizar o instalador que vem com o Delphi para gerar a instalação do seu programa, se não estou enganado, ele lhe oferecerá opção para adicionar o BDE a sua instalação.
-
Dê uma olhada neste post: http://scriptbrasil.com.br/forum/index.php...ndpost&p=341000
-
Nunca utilizei LIKE com campo data (acredito que não deva funcionar), a memos que o campo date na query seja transformado para string e daí comparado à uma data no formato string. O que costumo fazer é atualizar a query no evento OnExit (falando de um campo tipo date) quando o campo data já está devidamente preenchido e validado. Como questionei no post anterior, acredito que o seu bloco try except (em "Busca no OnChange do edit") deveria ficar dentro da validação "if (busca) and (CbbBusca.ItemIndex = 1) then", já que aparentemente apenas nesta condição você utiliza o valor de EdtBusca.Text como um campo de data. Para situações que não o seja, a execption com certeza ocorrerá.
-
Graymalkin, não seria também necessário que o colega Vivendo&Aprendendo testasse a opção selecionada no combo, já que: e o seu exemplo considera este campo como sendo sempre data? (sá para clarear)
-
Aparentemente você utilizou o mesmo nome para os componentes Edit e variáveis globais, assim acredito que o exemplo colocado pelo colega CorN_Sk8 mostra como corrigir seu código para utilizar as variáveis globais: Se for utilizar os componentes Edit ou DBEdit, você deverá utilizar a propriedade Text (também observei que faltou adicionar o ")" da instrução Values): datamodule1.AdoQuery.SQL.Add('Values('+inttostr(id)+','+quotedstr(ncadastro.Text)+','+quotedstr(fcadastro.Text)+')'); // Aqui
-
Tive este tipo de problema quando comecei a utilizar transações, e neste caso foi só ajustar o modo de iniciar a transação para resolver o problema. Que banco você utiliza? Como acessa ele? Nos relatórios você utiliza query? O relatório é criado na inicialização do sistema? Se sim, e utilizar query, elas também não estariam sendo abertas na criação do mesmo? (Neste caso não estariam sendo atualizadas).