Ir para conteúdo
Fórum Script Brasil

Micheus

Veteranos
  • Total de itens

    3.189
  • Registro em

  • Última visita

Tudo que Micheus postou

  1. Como você pretende filtrar ITEM_TABELA, acho que a opção mais simples seria utilizar o JOIN. Experimente: * como há campos com o mesmo nome em ambas as tabelas, voce precisa utilizar o alias (apelido), que neste caso foram I e P (pode ser qualquer coisa, mas devem que ser diferentes).Se funcionar, tem como benefício a possibilidade de voce bucar mais campos das tabelas - basta utilizar o referido alias e adicioná-los à linha do SELECT. obs: Este valor fixo (2), voce provavelmente irá trocar por parâmetro, não é?!
  2. Esta é uma questão mais apropriada para a sessão de Banco de Dados do que Delphi, mas acho que posso tentar comentar algo... Pelo pouco que mexo com o FireBird, eu sei que ainda não tem um comando para desabilitar as constraints. Voce pode ver no Firebird Bug Tracker que as solictações para este recurso ainda estão em aberto (Open -> CORE-1924 e CORE-1084). Há a possibilidade de voce excluir a constraint, mas posteriormente terá que criá-la. Opção muito trabalhosa (tem que fazer tabela por tabela), mas possível: Firebird Alter Table Drop Constraint Também há a possibilidade vc "varrer" as tabelas internas do banco (rdb$) e montar consultas que lhe tragam toda a informação sobre as tabelas, mas se algo mudar de uma versão do banco para outra, você pode ter problemas: Dependencias e relacionameto das tabelas nas Systems Tables (ref. DevMedia) Considerando que você fala em zerar todas as tabelas, parece que você quer simplesmente obter um banco zerado - só com a extrutura (sem os dados). Isto você pode fazer facilmente utilizando um frot-end para o Firebird. Poderia ser o ISQL.exe (ferramenta de linha de comando instalada com o Firebird). No prompt do DOS: isql -extract -output c:\metadata.txt c:\teste_isql.gdb -user SYSDBA -password masterkey este metadata.txt poderia ser melhor nomeado para metadata.sql. daí, voce pode usar esta mesma ferramenta para criar o novo banco de dados utilizando o metadata extraído. Dê uma olhada nestes artigos: - Entendendo as ferramentas iSql e gSec (registre-se - que vale a pena) - ISQL - Firebird Interactive SQL Tool Eu uso como front-end a versão free do IBExpert (download - depois de instalar você pode escolher o idioma) - muito útil e no menu de ferramentas ele tem a opção de backup e restauração. Neste caso, você faz um backup e depois, ao restaurar o backup voce usa a opção criar novo banco (obviamente com outro nome) e importa apenas o metadata do arquivo do backup anterior. Espero que algo lhe seja útil. Abraços
  3. Recife, licença para eu me intrometer nesta discussão. :) Acredito que o problema real seja com relação à gravação "indevida" de um determinado campo (data - que não diz muito, exceto o tipo) durante uma consulta. Bom, isto só poderia estar ocorrendo se em algum momento durante a execução da procedure: procedure Tpesq10.JvXPButton1Click(Sender: TObject); a referida consulta entrasse em modo edição. E isto ocorre, logo na primeira procedure associada aos botões (está sem o cabeçalho): O estranho é que ali não é atribuido nada a qualquer campo desta consulta. Logo, acho que este Edit está "voando" (ou parte do código foi omitida). Se em algum evento do componente utilizado para consulta (o qual não foi citado), houver alguma atribuição ao tal campo data (tipo, no evento OnStateChange ou outro) então estaria justificada a mudança indevida. ___________ Agora, sobre o filtro, o colega FABIO-2012 deve ficar atento ao fato de que se estiver sendo gravada a hora juntamente com a data (p.e., atribuindo o retorno da função Now) então, se no filtro for utilizado apenas a data (sem a hora), a data final pode não retornar os registros para aquele dia já que p.e.: "12/01/2012" se tornaria "12/01/2012 00:00" e que é inferior a um registro gravado com "12/01/2012 16:45". Abraços
  4. Micheus

    Dúvida com dbgrid

    Ainda que não seja "simulando", o melhor que você conseguirá é utilizar um checkbox para edição da opção ativa e uma "simulação" para desenhar a situação atual do campo visualizado (marcado/desmarcado). Há um antigo artigo no site About.com ensinando como fazer isto: CheckBox inside a DBGrid (se tiver dificuldades com Inglês, segue tradução pelo Google) Quando você vê todas aquelas linhas em um DBGrid, elas são apenas representação do conteúdo dos respectivos campos de cada registro (record/linha/tupla) ali mostrado. No entanto, apenas a linha correntemente selecionada corresponde ao "ponteiro" para o registro correntemente "selecionado" no dataset. Os componentes como DBEdit, DBCheck e similares podem apenas mostrar (pintar/desenhar) o valor/informação do registro atualmente selecionado no dataset! Assim, se você conseguisse utilizá-los dentro de um DBGrid, eles estariam todos mostrando sempre a mesma informação - a do item na linha (registro/record) correntemente selecionada. Abraços
  5. OFF: Fala Jhonas! estou só de passagem.De vez em quando me aparece uma MP e eu acabo dando uma voltinha por aqui. ;)
  6. Voce ainda pode usar um função para este fim e apenas chamá-la passando alguns parâmetros e se você precisar utilizar o método Show ou ShowModal, talvez seja interessante passar um outro parâmetro para a função que cria o form (sugestão): procedure LoadForm(nome_form: string; owner: TComponent; is_modal :boolean); var vcls_form: TPersistentClass; vobj_form: TForm; begin vcls_form := GetClass(nome_form); if (Assigned(vcls_form)) and (vcls_form.InheritsFrom(TForm)) then begin vobj_form := TFormClass(vcls_form).Create(owner); if is_modal then vobj_form.ShowModal else vobj_form.Show; end else ShowMessage('Tentativa de carga de um formulário inválido ['+nome_form+'].'); end; Voce pode acrescentar o RegisterClass em cada unit do respectivo form utilizando a seção initialization (supostamente torna as coisas simples), como abaixo: unit uFrmTela1; type TfrmTela1 = class(TForm) ... end; procedure TfrmTela1.<evento>(...); begin ... end; initialization RegisterClass(TfrmTela1); end. Abraços
  7. Observar que este procedimento está apenas manipulando as Instâncias e não as Classes de objetos definidas no projeto.É importante o entendimento sobre o que é Instância e Classe em OO (Orientação a Objetos). Na esquerda estão as instâncias da classe apresentada à direita. ref.: site Isto é impossível! Entenda que o método CreateForm recebe como parâmetro dois endereços de memória. O primeiro se refere à definição da classe e o segundo à variável (passada por referência) que acomodará uma instância da referida classe. Assim, para criar uma instância de qualquer classe, nos termos que você gostaria, seria realmente necessário o uso de GetClass ou FindClass (métodos para os quais você passa como parâmetro o nome da classe (previamente registrada) e obtem sua "definição"). Você não precisa utilizar o UnregisterClass. No caso de a classe já ter sido registrada, uma nova chamada à RegisterClass não irá gerar problema algum - ela é suficientemente inteligente para isto. Está lá na documentação (help): If the class is already registered, RegisterClass does nothing. If a different class with the same name is already registered, RegisterClass raises an EFilerError exception. Deve ser lembrado que um programa em Delphi é compilado e não interpretado. O compilador Delphi otimiza o código de modo que uma variável declarada que não seja utilizada é removida do código final (executável) e o mesmo ocorre com as classes ("definições"). Se voce tem adiconado ao seu projeto o arquivo que define um form (que é uma classe descendente de TForm), mas não faz uso explicitamente dele em lugar algum (tipo: CadProduto := TCadProduto.Create(self) ou Application.CreateForm(TCadProduto, CadProduto)), o compilador irá gerar o código final sem qualquer referência à esta classe de formulário, pois você não a está utilzando. Assim, ainda que você não queira criar uma instância explicitamente, mas queira criá-la dinamicamente da forma como foi colocada aqui neste tópico, então você tem que dizer para o compilador incluir a definição desta classe (do seu form) em seu executável. Somente desta forma ele terá condições de criar uma instância deste form em tempo de execução - conhecendo ele - por isto a necessidade de usar o RegisterClass. Quando você faz uso explícito da classe (como já exemplifiquei), o compilador automaticamente irá registrar a classe em questão. Isto também está no help para RegisterClass: "Form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered." A estas alturas pode mesmo ser complicado/trabalhoso fazer os ajustes para 700 forms. Na análise do projeto, este dipo de coisa também já deveria ter sido pensada e assim ele cresceria sem causar transtornos. Na prática, qual seria o benefício esperado com esta abordagem? No meu entendimento (apenas minha opinião), se forem para: - Customizar a aplicação e ocultar opções entre diferentes clientes: bom, se for possível obter o nome das classes no executável, bastaria adicioná-la à tabela no banco de dados e lá estariam todas as telas disponíveis. - Economizar memória: a criação dinâmica dos forms e posterior liberação da memória (como feito usualmente ao remover os FormCreate do projeto) não consumiriam muito mais memória do que o modelo pretendido. - Criação de múltiplas instâncias de um mesmo form: (um form que cria uma nova instância de sua própia classe) Nesta modalidade, cuidados devem ser tomados quando utilizando utiliza-se componentes que referenciam outros forms/datasources (datasets, datasources, ...) - esta referência criada em design-time é traduzida pelo compilador de forma estática. Seguem algumas referências que podem ser úteis à algum dos leitores do tópico: - PROGRAMAÇÃO ORIENTADA A OBJETOS & DELPHI – Parte I – Uma Introdução sobre OO - Introdução ao Paradigma de Orientação a Objetos (artigo muito bom - vale a leitura) - Dynamic packages in Delphi (talvez a melhor forma de modularizar uma aplicação Delphi) Abraços
  8. Nada como um pouco de informação... wania oliveira, usei muito pouco o Rave, mas eu acho que isto não vai funcionar com o ele. Voce teria que ter acesso ao componente richedit seja ele qual for (VCL:TRichEdit/TDBRichEdit, QuickReport:TQRRichEdit/TQRDBRichEdit, JVCL:TJvRichEdit/TJvDBRichEdit,...) - isto é possível com o Rave? Eu acredito que a justificação está funcionando porque talvez você assim a configurou no componente no Rave Designer (seria isso?). Como é que este metexto vai parar "dentro" do relatório Rave? O Rave tem componente RichEdit? Só lembro de ter Memo. :huh: _______ Eu pesquisei um pouco, e vi que provavelmente você usa um TMemoBuf através da propriedade RichEdit (string) (mas pela hierarquia dele não tenho certeza de que ele tratará todas as funcionalidades do richedit - teria que conhecer o seu código ou ter uma documentação mais completa)
  9. wania oliveira, como é que você está usando estas funções? Voce está chamando elas via algum botão, evento (tipo OnShow)? Está passando um componente do tipo TRichEdit ou é o richedit do quickreport ou similar? Dá para exemplificar?
  10. Não exatamente. Não sei o que você já tem hoje, mas penso que seriam sim duas tabelas, uma com as informações dos atletas e outra com a equipe formada. Cabe a você avaliar que informações terão estas tabelas, mas considerando como sendo o básico para a de atletas, ela deve conter: identificador, Nome do atleta e sua habilidade. Com estas informações você deve ser capaz de realizar consultas baseadas nos filtros apresentados (uma consulta para cada habilidade filtrada) descartando aqueles já inclusos na tabela de equipes formadas (é um select no atleta where com habilidade tal and not exists na equipe) Clareou?
  11. luizf, você há de convir que estes dois erros não são iguais, logo não tem origem no mesmo problema. Considerando esta última mensagem de erro e o código que foi postado anteriormente... procedure TForm1.DBGrid1TitleClick(Column: TColumn); var Campo: String; I: Integer; begin Campo:= Column.Fieldname; // Campo recebe o nome da coluna clicada // Application.Processmessages; // esta linha não é exatamente necessária - pode removê-la e observar Query1.Close; Query1.SQL.Clear; Query1.SQL.Add('SELECT * FROM ' + ADOTable1.TableName + ' ORDER BY ' + Campo + ' DESC'); // if not Query1.Prepared then // também não é necessário. Este teste já é feito internamente quando a consulta é aberta // Query1.Prepare; Query1.Open; end;...Eu arriscaria dizer que você não setou a propriedade Database deste seu componente TQuery1. Verifique-o.
  12. Que bom.Mas, seria gentil da sua parte, colocar a solução aqui. Assim, outros poderiam se beneficiar dela. ;)
  13. Só para lembrar, isto é tarefa simples: TMemo1.Lines.SaveToFile(<nome do arquivo>); A flexibilidade no parâmetro (TStrings), lhe da a possibilidade de não mostrar nada durante o processo (em um TMemo ou TListBox) e apenas ao final você gerar o arquivo de log, uma vez que você pode criar uma variável TStringList na procedure e passá-la como parâmetro. O uso das procedures independentes do form, lhe permite colocá-las em uma outra unit para que seja facilmente utilizadas por outros projetos. beleza.
  14. Vou postar este "monstro", mas é só impressão, porque na verdade ela pode fazer um pouco mais do que você precisa. Na real, para você bastaria basicamente a funçõa DeleteFilesOnPath. Mas, ela deve funcionar direitinho. // Esta procedure exclui todos os arquivos localizados em um diretório, conforme mascara // PATH = diretório onde os arquivos serão pesquisados (observar que é concatenada a contra-barra) // FILEMASK = mascara identificando o tipo do arquivo a ser removido - apenas um tipo (ex. *.tmp) // LogList = corresponde a uma lista onde serão armazenados os resultados (é um log do processo) procedure DeleteFilesOnPath(Path, FileMask :string; LogList: TStrings); var SearchRec :TSearchRec; begin LogList.Add(Format('=> Pesquisando pasta [%s] - [%s]', [Path, FileMask])); if FindFirst(Path+'\'+FileMask, faArchive, SearchRec) = 0 then try repeat Application.ProcessMessages; if not DeleteFile(Path +'\' +SearchRec.Name) then LogList.Add(' *** Erro apagando arquivo: '+SearchRec.Name) else LogList.Add(' ->'+SearchRec.Name +' - Ok'); until FindNext(SearchRec) <> 0; finally FindClose(SearchRec); end; end; // Esta procedure exclui todos os arquivos localizados a partir de um diretório, recursivamente, conforme mascaras // STARTPATH = diretório a partir do qual os arquivos serão pesquisados, incluindo sub-diretórios (observar que é concatenada a contra-barra) // FILEMASK = mascara identificando os tipos dos arquivos a ser removido - vários tipo (ex. *.tmp;*.dat;*.log;) // LogList = corresponde a uma lista onde serão armazenados os resultados (é um log do processo) procedure DeleteFilesOnPathRecursive(StartPath, FileMask :String; LogList: TStrings); var TmpMask :string; SearchRec :TSearchRec; begin // busca primeira entra de um diretório dentro do diretório em StartPath if FindFirst(StartPath +'\*.*', faDirectory, SearchRec) = 0 then try repeat Application.ProcessMessages; if (SearchRec.Name <> '..') then begin // para cada diretório, irá excluir uma extensão contida na lista de máscaras TmpMask := FileMask; while TmpMask <> '' do begin Application.ProcessMessages; DeleteFilesOnPath(StartPath, Copy(TmpMask, 1, 5), LogList); Delete(TmpMask, 1, 6); end; // exclusão recursiva - sub-diretórios apenas if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then DeleteFilesOnPathRecursive(StartPath+'\'+SearchRec.Name, FileMask, LogList); end; until FindNext(SearchRec) <> 0; finally FindClose(SearchRec); end; end; procedure DeleteFiles(StartPath, FileMask :String; RecursiveDir: Boolean; LogList: TStrings); begin if not RecursiveDir then begin while FileMask <> '' do begin Application.ProcessMessages; DeleteFilesOnPath(StartPath, Copy(FileMask, 1, 5), LogList); Delete(FileMask, 1, 6); end; end else DeleteFilesOnPathRecursive(StartPath, FileMask, LogList); end; No programa, o uso é simples. Eu coloquei apenas um TMemo e um Botão, mas a interface fica a seu cargo. Voce pode por um checkbox para indicar se devem ser processados os sub-diretórios ou não: procedure TForm1.Button1Click(Sender: TObject); var FileMask :String; begin Memo1.Lines.Clear; FileMask := '*.tmp;*.log;*.ini;*.dat;'; // esta string pode ser obtida do usuário de alguma forma DeleteFiles('C:\WINDOWS\Temp', FileMask, False, Memo1.Lines); // FALSE = Exclusão só na pasta expecificada // DeleteFiles('C:\WINDOWS\Temp', FileMask, True, Memo1.Lines); // TRUE = Exclusão recursiva a partir da pasta indicada end; Para os testes, aconselho a comentar a linha que exclui os arquivos (DeleteFile), localizada na procedure DeleteFilesOnPath. T+
  15. sou das antigas, ainda não adaptei a estas novas expressões. :wacko: Mas acho que você acha alguma coisa neste link: http://inf.unisul.br/~osmarjr/delphi/funcoes.htm segue uma das funções que tem lá: function BinToInt(Value: String): LongInt; {Converte um numero binário em Inteiro} var i,Size: Integer; begin Result := 0; Size := Length(Value); for i:=Size downto 0 do begin if Copy(Value,i,1)='1' then begin Result := Result+(1 shl i); end; end; end;
  16. Sem dúvida não é nada parecido. Aqui você obteve um run-time, lá um erro dentro da consulta - é bem diferente. olhando este post, aqui há algo errado sim: você não deixou espaço antes do ASC, logo o texto fica grudado com o nome do campo. Mas, só para saber qual o ponto da sua consulta está dando erro, quebre ela em mais linhas:
  17. Ronaldo Lanhellas, dei uma olhada em minhas coisas em casa. Agora vai (já testei aqui) Reescreva ela usando ShellExecute (já postei sobre ele antes) que é o mais adequado. WinExec é para as versões antigas do Windos (98 para trás se não me engano). Voce precisa acrescentar à cláusula uses a unit ShellAPI CommandLine := Format('/c net use S: %s', [DataConfigs.DataSet.FieldByName('PATH_FOTOS').AsString]); ShellExecute(0, nil, PChar('cmd.exe'), PChar(CommandLine), nil, SW_SHOWNORMAL); p.s.: Talvez em algum momento você precise "desmapear", ou pelo menos, verificar se já não existe o mapeamento - não esqueça disto.
  18. Micheus

    Quickreport

    Bom, de qualquer forma, o local para você fazer qualquer mudança antes da impressão de cada item (detalhe = detail), é no BeforePrint da referida banda onde ele se encontre. Quanto ao contador de páginas disparar, é meio estranho, exceto pelo fato de que você possa ter colocado todo o seu código inicial na banda detalhe - o que seria errado (sem dúvida). Voce teria que apenas remover, lá do seu evento BeforePrint do QuickRep, aquela parte que eu fiz o comentario e colocá-la no BeforePrint da banda detail.
  19. Aparentemente, apesar de usar SW_ShowNormal para que a janela do terminal seja mostrada, ela está sendo fechada e você não tem como avaliar o que está ocorrendo. Experimente remover o "/C" e veja se a janela do terminal fica ativa para você observar qualquer mensagem de erro. (link sobre os parâmetros para cmd). Pode estar ocorrendo erro, no caso de o string do path ser longo, com espaços. Nestes casos, você deveria colocar o path entre aspas: CommandLine := Format(Format('cmd /c net use S: "%s"', [DataConfigs.DataSet.FieldByName('PATH_FOTOS').AsString]); Experimente. De qualquer modo, em se tratando de aplicação windows, eu acho que seria mais conveniente utilizar a API do windows para realizar o mapeamento. Há funções para rede Veja dois exemplos: simples e outro mais completo (onde server deve ser entendido como o nome do computador compartilha a pasta a ser mapeada; e a senha é no caso de ser necessária para a conexão, quando não é aberta a todos usuário).
  20. Douglas Soares, você está assumindo que o colega luizf está trabalhando com ClientDataset (CDS_CaixaP.IndexName), quando na verdade ele usa um TQuery (Query1), e neste caso, IndexName não existe e pode confundí-lo. procedure TForm1.DBGrid1TitleClick(Column: TColumn); var Campo: String; I: Integer; begin Campo:= Column.Fieldname; // Campo recebe o nome da coluna clicada // Application.Processmessages; // esta linha não é exatamente necessária - pode removê-la e observar Query1.Close; Query1.SQL.Clear; Query1.SQL.Add('SELECT * FROM ' + ADOTable1.TableName + ' ORDER BY ' + Campo + ' DESC'); // if not Query1.Prepared then // também não é necessário. Este teste já é feito internamente quando a consulta é aberta // Query1.Prepare; Query1.Open; end;luizf, não estou certo do porquê de você ter uma tabela (ADOTable1) e uma consulta (Query1, sobre a mesma tabela ADOTable1.TableName), mas de qualquer modo, seria mais comum que você trabalhasse com a mesma paleta de componentes. Entretanto, você usa um TQuery onde poderia ser um TADOQuery (compatível com TADOTable utilizado). Se você souber como depurar (usar break-points e tal), você deveria inspecionar o conteúdo da propriedade SQL para que tire a dúvida sobre o que está errado na consulta antes de ela ser aberta.
  21. Fazendo buscas no forum, é prosível encontrar algo que lhe ajude: Rave - Parâmetros, Duas páginas em parâmetros (o link postado pelo colega, já no primeiro post explica como) Dica: Quando fizer busca no forum, faça similar a que faz no google, utilize AND ou OR para suas buscas. Neste caso, procurando por rave AND parâmetro voce terá alguns resultados.
  22. talvez você possa verificar via variável de ambiente, não sei se no Windows7 o nome seria o mesmo, mas experimente "windir": var WinDisc, WinPath :string; begin WinPath := GetEnvironmentVariable('windir'); WinDisc := Copy(WinPath, 1, 3); // aqui você teria algo como 'C:\' ... end; Em alguns casos, você pode não conseguir gravar a informação onde quizer, por não ter direito de acesso (a menos que seja um admin). De qualquer forma, veja se não fazer um mecanismo de infecção. ;)
  23. wilsonrosa, dê uma olhada neste tópico: Relatório usando duas tabelas filhas sem usar tabela. Para fazer o seu relatório, ao que parece, você precisará trabalhar com a "filosofia" meste/detalhe. Lá pelo post#8, tem uma explicação detalhada, mas é interessante que você acompanhe o problema desde o início para entender como chegou-se lá.
  24. Micheus

    Quickreport

    wilsonrosa, o erro está no local onde você está fazendo o teste de controle. Considerando que este seu relatório esteja mostrando vários crachás, o mais lógico é que você faça este teste exatamente antes de imprimir o crachá específico, ou seja, em sua banda detalhe e não antes de imprimir todo o relatório, pois desta forma você estará aplicando a informação contida no primeiro registro para todos os que vem depois. E observe isto que você está fazendo... ... if dmbancos.QCrachaDT_NR11.Value > StrToDate ('01/01/1900') then begin NR11.Visible := true; QRShape3.Visible := true; end else begin NR11.Visible := false; QRShape3.Visible := false; end; agora pense com um pouco de lógica, não poderia ser apenas NR11.Visible := dmbancos.QCrachaDT_NR11.Value > StrToDate ('01/01/1900'); QRShape3.Visible := NR11.Visible; voce colocará este tipo de código no evento BeforePrint da banda detalhe, onde encontra-se o QRShape em questão.
×
×
  • Criar Novo...