Ola, gostaria de saber como mover arquivos de lugar e criar diretorios com o delphi.
Para que?
Eu estava fazendo meu programa com gravação das imagens em um banco de dados, mas estava ficando muito pesado e as imagens estavam dobrando de tamanho ou até mais no processo, o que estava gerando um alto lag no programa.
O que quero tentar agora é o seguinte:
Eu cadastro a casa de ID 243
Apos salvar vou na opção de acrescentar imagem no imovel
Quando adiciono a imagem caso não exista é criada a pasta "Fotos" e dentro dela a pasta "243"(Id da casa) e as imagens que eu for adicionando iram sendo copiadas para essa pasta, para exibir a imagem isarei o caminho "Fotos\"IDdaCasa"\foto1.jpeg".
Concluindo para casa casa salva ja ser criada altomaticamente a pasta com com o ID da casa em "Fotos" e o programa armazena o caminho das fotos desse modo.
Bom, eu sei o que quero, mas não tenho a minima ideia de como fazer, alguem poderia me ajudar?
var
Caminho: string;
begin
Caminho := 'C:\Fotos' + NomeSubDir;//Substitua 'C:\Fotos' pelo caminho que a subpasta deve ser criada
if DirectoryExists(Caminho) then
Result := true
else
Result := CreateDir(Caminho);
end;Exemplo de uso: No evento onclick do botão de inserir fotos digite: if not CriaSubDir(SuaQuery.FieldByName('CODiMOVEL').AsString) then
ShowMessage('Não foi possível criar o sub-diretório ' + SuaQuery.FieldByName('CODiMOVEL').AsString); Faça funcionar esta parte, que depois fazemos funcionar a cópia do arquivo para a pasta criada.
Origem, Destino, caminho: string;
begin
caminho := 'C:\Fotos\' + SuaQuery.FieldByName('CODIMOVEL').AsString;
if not DirectoryExists(caminho) then
CreateDir(caminho);
if OpenPictureDialog1.Execute then
begin
//Aqui pego o caminho inteiro inclusive com o nome do arquivo
origem := OpenPictureDialog1.FileName;
//Aqui pego somente o nome do arquivo com a extenção
Delete(Origem, 1, Length(ExtractFilePath(OpenPictureDialog1.FileName)));
Destino := caminho + '\' + origem;
CopyFile(PChar(Origem), PChar(Destino), False);
end;
end;
Funcionou, so tive que fazer uma mudança, a parte em negrito. Aparentemente ele so consegue criar uma pasta, não estava sendo criada nenhuma pasta, depois que tentei azer ele colocar antes apenas a pasta 'Fotos' começou a funcionar. Vlw
var
Origem, Destino, caminho: string;
begin
if not DirectoryExists('C:\Fotos') then
CreateDir('C:Fotos');
caminho := 'C:\Fotos\' + DM.ADOQImoveis.FieldByName('ID').AsString;
if not DirectoryExists(caminho) then
CreateDir(caminho);
if OpenPictureDialog1.Execute then
begin
//Aqui pego o caminho inteiro inclusive com o nome do arquivo
origem := OpenPictureDialog1.FileName;
//Aqui pego somente o nome do arquivo com a extenção
Delete(Origem, 1, Length(ExtractFilePath(OpenPictureDialog1.FileName)));
Destino := caminho + '\' + origem;
CopyFile(PChar(Origem), PChar(Destino), False);
end;
end;
Outra duvida, pra mandar o caminho da imagem pro BD é so criar uma tabela com ID(auto), codImovel(integer) e Foto(Texto) e jogar o OpenPictureDialog1.FileName; pra dentro da Foto? O DBImage vai ler o caminho e mostrar a imagem normalmente?
PS: Li o seu artigo, achei muito legal, vou até implementar em um programa mais simples que to fazendo e tem 8 forms diferentes de cadastro, fazer um unico form com botões e usar para todos os formularios fica muito mais pratico.
Consegui gravar o caminho no BD, mas os DBImage não exibem mais as fotos de determinado Imovel, creio que seja porque o DataSource e DataField não sirvam mais ja qeu apontam para um caminho e não uma imagem como faziam antes.
Eu adicionei 5 fotos e ficaram aparecendo 5 DBImages em branco no DBCtrlGrid, detalhe é que esses campos aparecem para qualquer imovel que eu tente alterar.
Alguem poderia me ajudar? Como faço para as fotos aparecerem nos DBImages do DBCtrlGrid quando clico em X Imovel no DBGrid?
Hum, acho que não entendi, pensei que o DBGrid iria substituir o DBCtrlGrid mas ele so mostra o caminho da imagem, como farei para exibir todas as imagens do imovel X em algum local pequeno como fazia antes com o DBCtrlGrid? Pra mostrar todas as imagens em tamanho grande não se faz necessario mas acho o DBCtrlGrid de grande ajuda pro cliente ter certesa de que imagens ja gravou até o momento.
O relacionamento eu tinha feito pelo proprio access mas não parece ter funcionado.
Ta dificil, se jogo a imagem na DB ela aumenta 10x de tamanho e torna o processo inviavel, se uso caminho perco o DBCtrlGrid que é uma mão na roda.
Fiz um pouco diferente mas funcionou, no afterscroll tava dando erro ae mudei pra OncellClick do DBgrid e coloquei
#Código
EDBImage1.Picture.LoadFromFile(DM.cdsFotosImoveisFoto.AsString);
Uma duvida, tem como tirar a parte C:\Fotos e deixar mostrando somente o nome da foto no DBGridw nem que eu presise criar outro campo pra mostrar so o nome da foto.
Agora para montar o Slide Show com as imagens em tamanho grande presiso de uma ajuda, como posso fazer as imagens irem pra frente e pra tras sem o DBNAVIGATOR?
procedure TForm.DBCtrlGridPaintPanel(DBCtrlGrid: TDBCtrlGrid; Index: Integer);begin //TImage dentro do DBCtrlGrid e no evento PaintPanel carregar a imagem gravada no banco Image1.Picture.LoadFromFile(ClientDataSet.FieldByName('CampoComEndereçoImagem').AsString);end;
i, posicao: Integer;
begin
if not(sender.Isnull) then
begin
for i := 1 to Length(sender.asstring) do
begin
if (sender.asstring[i] in ['\']) then
posicao := i;
end;
Text := Copy(Sender.Value, posicao + 1, Length(Sender.Value));
end;
end;
@Renan funcionou, ta carregando todas as fotos no DBCtrlGrid mas quando vc clica em uma das fotos ela é sobreposta pela ultima foto gravada no registro, e como ja vem como se vc tivese clicado na primeira foto ela vem sempre errada mostrando a ultima imagem gravada em vez da primeira, se vc clica em outra foto ela muda pra ultima foto gravada e a anterir fica correta e assim por diante.
Tem como alterar isso pra sempre mostrar a correta mesmo quando eu clico na imagem?
@Eriley sua função funcionou certinho, ta mostrando so o nome da foto agora.
Agora, como alternar entre as fotos com botões? quero simular um DBNavigator so com o avançar,voltar, ir pro final e ir pro inicio.
O AfterScroll começo a dar erro direto agora, eu mando iniciar o programa ele começa a carregar e da um erro loco cheio de numero, e depois me aponta essa linha em Negrito.
if not(cdsFotosImoveis.State in [dsEdit, dsInsert]) then
frmImovel.EDBImage3.Picture.LoadFromFile(cdsFotosImoveisfoto.AsString);
Resolvi o problema da parte de Slides colocando no Onclick do DBNavigator o caminho da imagem, ae a cada vez que passo ele joga um novo caminho no EDBImage.
O CtrlGrid fico lagando muito a tela depois que testei colocar 30 imagens de 2MB nele por isso até ver porque do lag to dropando ele . Se ele so pega o caminho alguem sabe o motivo que pode estar gerando o lag?
Eriley você saberia me dizer como fazer o relacionamento que você me mostro no ClientDataSet com o ADOQuery? Não tem o campo mastersource, masterfield, ect no ADOQuery.
É que to querendo jogar a tabela fotos no access pra ficar mais facil, agora que a tabela não carrega mais fotos não tem mais porque deixar ela separada em um arquivo .cds. Relacionei a tabela pelo access mas não funcionou, não sei porque.
Outra duvida, como posso fazer um IF pra saber se o imovel X tem Fotos ou não? Isso evitaria um erro que estou tendo quando clico em um imovel sem fotos.
Quero colocar assim,
IF (tem fotos) EDBImage recebe
ADOQimobFotosFotos.ASString
ELSE
Exibe Mensagem('O Imovel XXX ainda não possui fotos').
Select * From Imoveis
E você deve ter um DataSource talvez chamado de DsImoveis e conectado a AdoQryImoveis pela propriedade DataSet do DataSource. Este Datasource servirá de ponte entre as duas querys.
E você deve ter uma outra Query chamada de AdoQryFotos, na propriedade DataSource da AdoQryFotos iniciaremos o relacionamento, indicando o Datasource que está ligado ao outro DataSet (DsImoveis). O próximo passo é indicar a instrução sql de acesso na propriedade SQL:
Select * From Fotos Where Cod_Imovel = :Cod_Imovel
Cod_Imovel após os dois pontos deve ter o mesmo nome do campo código do imóvel da tabela de imóveis.
Você achou estranho esta condição criada na instrução sql ? Deve estar se perguntando : Se é pra colocar um parâmetro para filtrar as fotos do imóvel via código eu não precisaria ter este trabalho todo ? Então eu lhe responderei, este parâmetro será automaticamente alimentado por causa do relacionamento entre as Querys através do DataSource, isto é, sempre que for filtrado um imóvel na AdoQryImoveis, automaticamente as fotos deste imóvel serão filtradas por conta do relacionamento. Isto não quer dizer que, em uma eventual manipulação (inclusão), as fotos serão automaticamente associadas ao imóvel em questão, a passagem do código do imóvel para as fotos deverá ser feito manualmente, isto geralmente é realizado no evento before post do AdoQryFotos. AdoQryFotosCod_Imovel.Value := AdoQryImoveisCodImovel.Value; Sobre sua segunda pergunta, faça assim: IF not(AdoQryFotos.IsEmpty) then EDBImage recebe ADOQimobFotosFotos.ASStringELSE
Exibe Mensagem('O Imovel XXX ainda não possui fotos').
Para que este código funcione as duas querys devem estar abertas no onshow do formulário.
AdoQryImoveis.OPen; AdoQryFotos.Open;Minha proxima duvida é como fazer um botão para sincronizar o banco de dados do meu programa com o mesmo programa em outro computador.
De modo abstrato queria montar algo mais ou menos assim.
Opção 1:Clica no Botão "Atualizar automatico".
If 'Caminho até o servidor= ON' então // caminho iria até o arquivo do banco de dados do Access no Servidor
// EX: \\Servidor\Users\Public\Imob\Imobiliaria.mdb
Compara tabelas Servidor x PCFuncionario
Servidor Recebe registros novos que o funcionario possui
PCFuncionario recebe registros novos do servidor caso haja algum
Copia Pasta C:\Imob\Fotos //Ideal seria copiar so as fotos novas mas acho que seria meio complexo
else
ShowMessage('O Servidor esta OFF')
Opção 2: CLica no Botão "Atualizar Manualmente".
Abre um OpenDialog e vc escolhe o caminho até um Arquivo do Acess do mesmo programa em outro computador
Copia os registros Novos
Copia pasta a pasta Fotos usando o caminho do OpenDialog ja que a pasta Fotos vai estar na mesma pasta do arquivo do Access
ShowMessage('Registro de Imoveis Atualizado').
--------------------------------------------
A parte de ficar copiando toda Pasta Imob\Fotos sempre não me parece boa mas não consigo pensar em uma solução melhor, caso alguem tenha ajudaria muito.
O arquivo do access da pra so copiar o arquivo todo e simplesmente substituir o do computador, mas seria pouco elegante e pratico ja que teria que limitar o acesso a cadastro de imoveis somente no Servidor, os outros somente poderiam visualizar os imoveis e seus dados.
Se houvese uma sincronização de dados de um programa com o outro so seria pego o que tem de novo não apagando os cadastros anteriores, e caso cada um cadastre-se imoveis diferentes em cada computador um novo funcionario teria apenas que sincronizar com os dados dos 5 funcionarios com o programa ou com o servidor que seria sempre mantido atualizado.
2º Compartilhe a pasta onde o mesmo se encontra.
3º Faça as maquinas q estao na rede enxergarem no servidor a pasta compartilhada
4º Configure o ADOconnection do seu projeto principal pra enxergar o banco de dados.
Veja o link abaixo: http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=13139 Dica crie o arquivo udl no mesmo diretório do executável e após fazer as alterações no delphi e compilar o programa, va de máquina em máquina configurando o udl e depois abrindo o executável. se fez esses passos todos e pra funcionar, sem problemas...ok
O metodo que você descreveu vou usar nos PCs fixos que de fato é a melhor opção, mas nos Notebooks creio que teria que usar algo diferente que não dependese de estar conectado ao servidor.
O modo Simples creio que seria simplesmente fazer uma copia do Arquivos do Banco de dados e sempre substituir os existentes no Note, um mais elaborado seria acrescentar ao banco de dados do Note os registros novos e modificações, e no caso também copiar a pasta fotos.
Estou aberto a sugestões pro proglema do notebook sem rede
O dos PCs na rede so me preocupa o conflito de cadastros, se 5 pessoas madam dados ao mesmo tempo iria dar pau nos IDs, o que me leva a crer que nos PCs seria ideial uma interface sem cadastro também.
Quando eu mando copiar um dados pelos delphi ele subistitui se ja tiver um igual na pasta em questão ou da problema? No windows ele pergunta se quer mesmo substituir por exemplo.







