 |
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Qui Ago 06, 2015 10:38 am Assunto: [Resolvido] Alterar arquivos csv |
|
|
Estou iniciando em delphi e preciso de ajuda:
O cliente possui arquivos no formato csv e mensalmente ele faz a integração com o sistema. O aquivo contem valores referentes a mensalidade do plano de saúde, a empresa aplica um valor(que pode ser alterado de um mês para o outro) sobre essa mensalidade e cobra de cada funcionário. O sistema deve integrar o valor cobrado naquele mês, ou seja, preciso alterar os valores no arquivo em csv, até aqui ok, utilizei StringReplace e gerei um novo arquivo com as alterações, porém, no arquivo constam duas colunas com os mesmos valores, preciso informar o valor zero para uma dessas colunas pois se a importação for feita dessa forma os valores vão duplicar.
Tem alguma forma de zerar uma coluna lendo novamente o arquivo em csv?
obrigada
Editado pela última vez por Ellisete em Seg Ago 17, 2015 9:40 am, num total de 1 vez |
|
Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Qui Ago 06, 2015 10:49 am Assunto: |
|
|
Bom dia,
As colunas que devem ser alteradas possuem uma posição fixa, certo?
Você pode postar umas linhas do arquivo como exemplo e como elas deveriam ficar?
Editado pela última vez por imex em Ter Mar 07, 2023 5:03 pm, num total de 1 vez |
|
Voltar ao Topo |
|
 |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Qui Ago 06, 2015 11:00 am Assunto: |
|
|
imex escreveu: | Bom dia,
As colunas que devem ser alteradas possuem uma posição fixa, certo?
Você pode postar umas linhas do arquivo como exemplo e como elas deveriam ficar?
|
Os valores que devem ser zerados serão sempre o da segunda coluna que são iguais ao da 7ª coluna
S 477,09 0 464521 jul/15 0 477,09
S 199,72 0 464521 jul/15 0 199,72
C 337,69 0 464521 jul/15 0 337,69 |
|
Voltar ao Topo |
|
 |
johnny-walker Moderador


Registrado: Sábado, 4 de Outubro de 2003 Mensagens: 10653 Localização: Contagem/MG - BRAZIL
|
Enviada: Qui Ago 06, 2015 11:22 am Assunto: |
|
|
Se for realmente no formato csv, então este arquivo abre via ADO ou DBGO nos delphis mais novos, basta dar uma pesquisada que você acha, muito simples aliás.
Claro que tem de fazer a ligação odbc.
bye _________________ P.O.W.E.R B.Y D.E.L.P.H.I |
|
Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Qui Ago 06, 2015 11:30 am Assunto: |
|
|
Elisete, esse é o conteúdo exatamente como está no arquivo? |
|
Voltar ao Topo |
|
 |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Qui Ago 06, 2015 1:24 pm Assunto: |
|
|
imex escreveu: | Elisete, esse é o conteúdo exatamente como está no arquivo? |
Eu copiei apenas parte do arquivo.
No caso a coluna do valor no arquivo completo seria a 16ª coluna.
Eu poderia excluir a coluna manualmente, mas a intenção é não realizar edições manuais no arquivo para evitar erros. |
|
Voltar ao Topo |
|
 |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Qui Ago 06, 2015 1:31 pm Assunto: |
|
|
johnny-walker escreveu: | Se for realmente no formato csv, então este arquivo abre via ADO ou DBGO nos delphis mais novos, basta dar uma pesquisada que você acha, muito simples aliás.
Claro que tem de fazer a ligação odbc.
bye |
Mas eu não quero importar o arquivo, quero apenas alterar o arquivo csv. Não entendi o pq de usar ADO ou DBGo nesse caso  |
|
Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Qui Ago 06, 2015 6:21 pm Assunto: |
|
|
No exemplo que você postou, cada coluna possui a mesma quantidade de caracteres.
Nesse caso serial possível pegar o valor a partir de uma posição fixa.
Todas as linhas e colunas seguem esse padrão?
Ainda considerando o exemplo, as colunas estão separadas por um espaço em branco.
Nesse caso seria possível separar as colunas nos espaços em branco.
Todas as linhas e colunas seguem esse padrão? Existe alguma coluna que possui espaço em branco no meio do valor e não está delimitada por algum caracter? |
|
Voltar ao Topo |
|
 |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Sex Ago 07, 2015 8:55 am Assunto: |
|
|
imex escreveu: | No exemplo que você postou, cada coluna possui a mesma quantidade de caracteres.
Nesse caso serial possível pegar o valor a partir de uma posição fixa.
Todas as linhas e colunas seguem esse padrão?
Ainda considerando o exemplo, as colunas estão separadas por um espaço em branco.
Nesse caso seria possível separar as colunas nos espaços em branco.
Todas as linhas e colunas seguem esse padrão? Existe alguma coluna que possui espaço em branco no meio do valor e não está delimitada por algum caracter? |
CNPJ Contrato Plano – Descrição Matricula Carteira Nome Dt de Nasc CPF RG Titularidade Nome da Mãe Dt da Inclusão Dt Exclusão Sexo Estado Civil Vlr Mensalidade Tx Inscr Nr da Fatura Competência Executante Solicitante Dt da realização Nº Guia Cd Produto Descrição Qtd Vl Beneficiário Vl Empresa Vl tx sobre serviço INSS Credenc. (PF 20%) Plano – Código
12345608000170 202022 FREE TOTAL 600 EXECUTIVO - AMB/HOSP/OBST 111100 98001946800002400000 MARIA DA SILVA 24/11/1966 32132132132 HELENA SILVA HELENA SILVA 01/08/2009 F S 571,15 0 464521 jul/15 0 571,15 1885
12345608000170 202022 FREE TOTAL 600 EXECUTIVO - AMB/HOSP/OBST 113102 98001946800002400000 MARIA DE OLIVEIRA 01/04/1999 65465465465 EUGENIA OLIVEIRA EUGENIA OLIVEIRA 01/08/2009 F S 249,79 0 464521 jul/15 0 249,79 1885
12345608000170 202022 FREE TOTAL 600 EXECUTIVO - AMB/HOSP/OBST 2111100 98001946800005800000 MARIA JOANA MARTINS 16/01/1985 3213213215 FERNANDA MARTINS FERNANDA MARTINS 01/11/2009 F C 408,59 0 464521 jul/15 0 408,59 1885
12345608000170 202022 FREE TOTAL 600 EXECUTIVO - AMB/HOSP/OBST 2132102 98001946800005800000 MARIA APARECIDA DOS REIS 10/10/2012 6548213562 OLGA REIS OLGA REIS 10/11/2012 F S 249,79 0 464521 jul/15 0 249,79 1885
Esse é o arquivo original...
Se abrir o arquivo pelo bloco de notas ele utiliza o ';' como separador.
O número de caracteres de cada campo não é o mesmo... |
|
Voltar ao Topo |
|
 |
strak2012 Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014 Mensagens: 1518 Localização: Maceió - AL
|
Enviada: Sex Ago 07, 2015 10:39 am Assunto: |
|
|
Você pode usar uma rotina para copiar o conteúdo de uma linha até uma dada coluna depois inserir a nova palavra e continuar com a copia.
Código: |
{ Substitui o texto de uma coluna em uma linha texto }
{ Retorno será a mesma linha com o texto da coluna alterado }
function ChangeCol(Col: integer; Delimt, Texto, Linha: string): string;
var
Temp, WordP, Tnew: string;
p, n: integer;
begin
n := 1;
Temp := Linha;
result := '';
Tnew := '';
if pos(Delimt, Temp) <> 0 then
begin
repeat
p := pos(Delimt, Temp);
if n = Col then
begin
Tnew := Tnew + Texto + Delimt;
delete(Temp, 1, p);
break; // <-- Otimização
end
else
begin
Tnew := Tnew + copy(Temp, 1, p - 1) + Delimt;
delete(Temp, 1, p);
end;
inc(n);
until pos(Delimt, Temp) = 0;
end;
if length(Temp) > 0 then
Tnew := Tnew + Temp;
result := Tnew;
end;
//Notas:
//--------------------
//Col ----> Numero da coluna que terá o texto alterado a primeira coluna inicia com o valor 1
//Delimt -> Delimitador de coluna para um arquivo csv seu delimitador será ';'
//Texto --> Novo texto da coluna
//Linha --> Linha que contem todas as colunas
{ abre um arquivo e realiza a alteração do texto de uma coluna inteira e o salva em seguida}
procedure ChangeColFile(IniRow, Col: integer; Delimt, Texto, Filename: string);
var
xfile: tstrings;
I: integer;
begin
xfile := tstringlist.Create;
xfile.LoadFromFile(Filename);
for I := IniRow to xfile.Count - 1 do
xfile.Strings[I] := ChangeCol(Col, Delimt, Texto, xfile.Strings[I]);
xfile.SaveToFile(Filename);
xfile.Free;
end;
//Notas:
//--------------------
//IniRow--> Numero da primeira linha a ter seu conteúdo alterado, neste caso se a linha 0 for cabeçalho então IniRow deve ser 1
//Col ----> Numero da coluna que terá o texto alterado a primeira coluna inicia com o valor 1
//Delimt -> Delimitador de coluna para um arquivo csv seu delimitador será ';'
//Texto --> Novo texto da coluna
//Linha --> Linha que contem todas as colunas
|
Do modo de uso
Alterando o conteúdo da coluna de numero 6 para o texto "bbb" de uma arquivo chamado "teste.csv" que usa o delimitador ';'
Código: | procedure TForm1.Button1Click(Sender: TObject);
begin
ChangeColFile(1, 6, ';', 'bbb', 'C:\Users\Strak\Desktop\teste.csv');
end; |
_________________ Tudo podemos quando tudo sabemos! |
|
Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Sex Ago 07, 2015 11:14 am Assunto: |
|
|
Elisete, dependendo da versão do Delphi que você estiver utilizando é possível separar as colunas utilizando uma TStringList conforme o exemplo abaixo:
Código: | procedure TForm2.Button1Click(Sender: TObject);
var
ListaAux: TStringList;
begin
ListaAux := TStringList.Create;
try
ListaAux.Delimiter := ';';
ListaAux.StrictDelimiter := true;
ListaAux.DelimitedText := '12345608000170;202022;FREE TOTAL 600 EXECUTIVO - AMB/HOSP/OBST;111100;98001946800002400000;MARIA DA SILVA;24/11/1966;32132132132;HELENA SILVA HELENA SILVA;01/08/2009;F;S;571,15;0;464521;jul/15;0;571,15;1885';
ListaAux[12] := '123,45';
ShowMessage(ListaAux.DelimitedText);
finally
ListaAux.Free;
end;
end; |
obs:
- dependendo da versão do Delphi a propriedade StringDelimiter não será reconhecida
- talvez o ShowMessage exiba a string dividida em partes, mas é só porque ela é muito longa
Espero que seja útil. |
|
Voltar ao Topo |
|
 |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Seg Ago 10, 2015 9:02 am Assunto: |
|
|
strak2012 escreveu: | Você pode usar uma rotina para copiar o conteúdo de uma linha até uma dada coluna depois inserir a nova palavra e continuar com a copia.
Código: |
{ Substitui o texto de uma coluna em uma linha texto }
{ Retorno será a mesma linha com o texto da coluna alterado }
function ChangeCol(Col: integer; Delimt, Texto, Linha: string): string;
var
Temp, WordP, Tnew: string;
p, n: integer;
begin
n := 1;
Temp := Linha;
result := '';
Tnew := '';
if pos(Delimt, Temp) <> 0 then
begin
repeat
p := pos(Delimt, Temp);
if n = Col then
begin
Tnew := Tnew + Texto + Delimt;
delete(Temp, 1, p);
break; // <Otimiza> 0 then
Tnew := Tnew + Temp;
result := Tnew;
end;
//Notas:
//--------------------
//Col ----> Numero da coluna que terá o texto alterado a primeira coluna inicia com o valor 1
//Delimt -> Delimitador de coluna para um arquivo csv seu delimitador será ';'
//Texto --> Novo texto da coluna
//Linha --> Linha que contem todas as colunas
{ abre um arquivo e realiza a alteração do texto de uma coluna inteira e o salva em seguida}
procedure ChangeColFile(IniRow, Col: integer; Delimt, Texto, Filename: string);
var
xfile: tstrings;
I: integer;
begin
xfile := tstringlist.Create;
xfile.LoadFromFile(Filename);
for I := IniRow to xfile.Count - 1 do
xfile.Strings[I] := ChangeCol(Col, Delimt, Texto, xfile.Strings[I]);
xfile.SaveToFile(Filename);
xfile.Free;
end;
//Notas:
//--------------------
//IniRow--> Numero da primeira linha a ter seu conteúdo alterado, neste caso se a linha 0 for cabeçalho então IniRow deve ser 1
//Col ----> Numero da coluna que terá o texto alterado a primeira coluna inicia com o valor 1
//Delimt -> Delimitador de coluna para um arquivo csv seu delimitador será ';'
//Texto --> Novo texto da coluna
//Linha --> Linha que contem todas as colunas
|
Do modo de uso
Alterando o conteúdo da coluna de numero 6 para o texto "bbb" de uma arquivo chamado "teste.csv" que usa o delimitador ';'
Código: | procedure TForm1.Button1Click(Sender: TObject);
begin
ChangeColFile(1, 6, ';', 'bbb', 'C:\Users\Strak\Desktop\teste.csv');
end; |
|
Fiz assim:
unit uMain;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
Mask,
ToolEdit,
Buttons,
ComCtrls,
IniFiles, IBDatabase, DB, IBCustomDataSet, IBQuery, IBERRORCODES, strutils, dateutils,
uUtil, ClipBrd, Gauges;
type
TfMain = class(TForm)
Label3: TLabel;
BitBtnOK: TBitBtn;
BitBtn2: TBitBtn;
ProgressBar: TProgressBar;
OpenDialog1: TOpenDialog;
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
procedure BitBtn2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure BitBtnOKClick(Sender: TObject);
procedure ChangeColFile(Sender: TObject);
private
// function ConnectDataBase: Boolean;
procedure Atualiza;
{ Private declarations }
public
// Manual, Local: Boolean;
// SalvouIni: Boolean;
Estilo: string;
Acento: Boolean;
LocalArquivo: string;
Arquivo: TextFile;
Linha: string;
end;
var
fMain: TfMain;
senhadb, userdb: string;
booltest: bool;
implementation
uses
uDMUp,
IBScript, IBSQL;
{$R *.dfm}
type
PNetResourceArray = ^TNetResourceArray;
TNetResourceArray = array[0..100] of TNetResource;
procedure TfMain.BitBtnOKClick(Sender: TObject);
const
ADDPROGRESS = 50;
begin
BitBtnOK.Enabled := False;
BitBtn2.Enabled := False;
begin
with fDMUp do
begin
Self.Update;
Atualiza;
ProgressBar.Position := 100;
end;
BitBtnOK.Enabled := True;
BitBtn2.Enabled := True;
MessageDlg('Realizado com Sucesso!', mtInformation, [mbOK], 0);
end;
Close;
end;
procedure TfMain.BitBtn2Click(Sender: TObject);
begin
close;
end;
procedure TfMain.Atualiza;
label
Vencimento, Vencimento_2;
var
X, Contador, Contador1: Integer;
Vazio, Erro: Boolean;
// texto: string;
Informacao: array[1..110] of string;
Arquivos: array of string;
i: Integer;
ARQ: TStringList;
begin
with fDMUp do
begin
//# --------------------------------------------------------------------------------------------
//Mensagem( 5, 'Validando Informações' );
//# --------------------------------------------------------------------------------------------
//# Pegando a quantidade de arquivos que existem.
X := fnContarArquivos(fnCaminhoDiretorio('Arquivos'), 'csv');
if X > 0 then
begin
//# Setando o tamanho do Array de Arquivos.
SetLength(Arquivos, X);
//# Criar um Array com os nomes de todos os arquivos.
fnContarArquivosArray(Arquivos, fnCaminhoDiretorio('Arquivos'), 'csv');
//# Setamos nosso contador de Linhas para 0.
Contador := 0;
//# A cada arquivo, somamos nosso contador com a quantidade de linhas que o arquivo possui.
for X := 0 to High(Arquivos) do
Contador := Contador + fnPegarLinhas(fnCaminhoArquivo('Arquivos', Arquivos[X], False, True));
end;
Contador := 0;
Contador1 := 0;
//# --------------------------------------------------------------------------------------------
//# Iniciando Variáveis Boleanas
Vazio := False;
Erro := False;
//# --------------------------------------------------------------------------------------------
Estilo := 'Nada';
LocalArquivo := fnCaminhoArquivo('Arquivos', 'valores.csv', True, True);
AssignFile(Arquivo, LocalArquivo);
Reset(Arquivo);
ReadLn(Arquivo, Linha);
ARQ := TStringList.Create;
ARQ.LoadFromFile(Edit1.Text);
while not Eof(Arquivo) do
begin
ReadLn(Arquivo, Linha);
fnExplode(Informacao, ';', Linha);
Application.ProcessMessages;
begin
ARQ.Text := StringReplace(ARQ.Text, informacao[1], informacao[3], [rfReplaceAll]);
ARQ.SavetoFile(Edit2.text);
end;
ProgressBar.Stepby(1);
Application.ProcessMessages;
end;
end;
end;
procedure ChangeColFile(IniRow, Col: integer; Delimt, texto, Filename: string);
var
xfile: tstrings;
I: integer;
begin
xfile := tstringlist.Create;
xfile.LoadFromFile(Filename);
for I := IniRow to xfile.Count - 1 do
xfile.Strings[I] := ChangeColFile(Col, Delimt, texto, xfile.Strings[i]);
xfile.SaveToFile(Filename);
xfile.Free;
end;
procedure TfMain.Button1Click(Sender: TObject);
begin
ChangeColFile(16, ';', '0', 'edit2.csv');
end;
procedure TfMain.Button1Click(Sender: TObject);
var
arq: string;
begin
if OpenDialog1.Execute then
arq := OpenDialog1.FileName;
Edit1.Text := arq;
edit2.text := arq;
end;
end.
Mas está dando erro nessa linha
xfile.Strings[I] := ChangeColFile(Col, Delimt, texto, xfile.Strings[i]); |
|
Voltar ao Topo |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Seg Ago 10, 2015 10:57 am Assunto: |
|
|
Qual a mensagem de erro? _________________ ''A persistência é o caminho para o êxito.''
Charlie Chaplin |
|
Voltar ao Topo |
|
 |
Ellisete Novato

Registrado: Quinta-Feira, 6 de Agosto de 2015 Mensagens: 16
|
Enviada: Seg Ago 10, 2015 11:05 am Assunto: |
|
|
natanbh1 escreveu: | Qual a mensagem de erro? |
[Error] uMain.pas(226): Incompatible types: 'Integer' and 'String'
[Error] uMain.pas(226): Not enough actual parameters |
|
Voltar ao Topo |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Seg Ago 10, 2015 11:45 am Assunto: |
|
|
Notei alguns erros no momento da implementação do código que o strak2012:
- Não encontrei no seu código a função ChangeCol.
- Dentro da procedure ChangeColFile você chamou a própria procedure ao invés de ChangeCol.
Faça estas alterações:
Acrescente esta procedure:
Código: | function ChangeCol(Col: integer; Delimt, Texto, Linha: string): string;
var
Temp, WordP, Tnew: string;
p, n: integer;
begin
n := 1;
Temp := Linha;
result := '';
Tnew := '';
if pos(Delimt, Temp) <> 0 then
begin
repeat
p := pos(Delimt, Temp);
if n = Col then
begin
Tnew := Tnew + Texto + Delimt;
delete(Temp, 1, p);
break; // <-- Otimização
end
else
begin
Tnew := Tnew + copy(Temp, 1, p - 1) + Delimt;
delete(Temp, 1, p);
end;
inc(n);
until pos(Delimt, Temp) = 0;
end;
if length(Temp) > 0 then
Tnew := Tnew + Temp;
result := Tnew;
end; |
Altere sua procedure ChangeColFile para que fique assim:
Código: | procedure ChangeColFile(IniRow, Col: integer; Delimt, Texto, Filename: string);
var
xfile: tstrings;
I: integer;
begin
xfile := tstringlist.Create;
xfile.LoadFromFile(Filename);
for I := IniRow to xfile.Count - 1 do
xfile.Strings[I] := ChangeCol(Col, Delimt, Texto, xfile.Strings[I]);
xfile.SaveToFile(Filename);
xfile.Free;
end; |
Use assim:
Código: | ChangeColFile(1, 16, ';', '0', 'edit2.csv'); |
_________________ ''A persistência é o caminho para o êxito.''
Charlie Chaplin |
|
Voltar ao Topo |
|
 |
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|