PDA

Ver la Versión Completa : Como hacer busqueda en Unit y lo enviar para excel?


Paulao
24-02-2012, 11:53:53
Asi. Tengo un sistema legado en Delphi 5 y Sql Server 2008 R2. Mi jefe me lo pidio esto. Que yo devo hacer un programa, que has un lista de todas las tablas de mi banco(sysobjects) y despues pegue el nombre desas tablas del banco de datos y buscar en ese proyecto antigo quales son las Units que usan essas tablas y hacer una lista con: Tabla -> Unit y exportar para excel. Esa aplicacion nueva estas siendo desarrollada en Delphi XE.

duilioisola
24-02-2012, 12:17:46
Mediante FindFirst, FindNext, deberás recorrer todos los archivos *.pas y *.dfm.
Por cada archivo:
Cargas cada archivo en un TStringList.

Lista := TStringList.Create;
Lista.LoadFromFile(archivo);

Luego recorres cada linea del TStringList buscando las tablas y el nombre de la Unit
for i := 0 to Lista.Count -1 do
begin
...
end;

Paulao
24-02-2012, 15:29:18
Bueno, esto es lo que estoy trabajando y usando TList<String> en lugar de TStringList, que para mi no hace diferencia. La Duda es, tengo que abri el .PAS y hacer yna busqueda asi. Saber en qual Unit, yo tengo el nombre de la tabla, asi: Vamos decir que tengo una tabla que sy llama Cliente. Y esa tabla estas siendo usada en las units: uCliente, uVendas, uCompras(Esto es solo un ejemplo). Y tengo 30 Units. O que yo quiero es que, quando yo impiezar mi busqueda, el va abrinfo las units y percorendo ella para ver si adentro della hay la palavra "Cliente". Si hay, entonces ele graba en una lista y no necesita mas recorer aqulla unit, se va a otra hasta terminar todo y despues el saca otro nombre de tabla y hace otra vez y asi, hasta que tudo se lo termina. No se si fue explicito, pues el idioma no me ayuda mucho, lo mio y los de usteds, pero es mas o menos esto.

ecfisa
24-02-2012, 17:25:48
Hola Paulao.

A ver si interpreté bién lo que estas buscando...

function TextFoundInFile(Ruta: string; const Buscado: string): TStrings;
var
SR: TSearchRec;
txt: TextFile;
Row: string;
Found: Boolean;
begin
Result:= TStringList.Create;
Ruta:= IncludeTrailingPathDelimiter(Ruta);
if FindFirst(Ruta + '*.PAS', $FF, SR) = 0 then
repeat
AssignFile(txt,Ruta + SR.Name);
Reset(txt);
Found:= False;
while not Eof(txt) and not Found do
begin
Readln(txt, Row);
if Pos(Buscado, Row) > 0 then
begin
Result.Add(Ruta + SR.Name);
Found:= True;
end;
end;
CloseFile(txt);
until FindNext(SR) <> 0;
end;


Llamada de ejemplo:

procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items:= TextFoundInFile(edRuta.Text, edBuscado.Text);
TextFoundInFile(edRuta.Text, edBuscado.Text).SaveToFile('C:\LISTA.TXT')
end;


Saludos.

Paulao
29-02-2012, 15:34:03
ecfisa, hizo algunas alteraciones y ahora estas. Una pregunta: Como hago para hacer busqueda en .pas y .dfm al mismo tiempo con FindFirst?

ecfisa
29-02-2012, 16:18:21
ecfisa, hizo algunas alteraciones y ahora estas. Una pregunta: Como hago para hacer busqueda en .pas y .dfm al mismo tiempo con FindFirst?
No se puede hacer con FindFirst en una sola llamada, sin embargo se me ocurre un truco usando TStrings. Podría implementarse de forma recursiva´pero consume más recursos y quizá :rolleyes: sea un poco más lento.

function TextFoundInFile(Ruta: string; const FileMask:string; const Buscado: string): TStrings;
var
SR: TSearchRec;
txt: TextFile;
Row: string;
Found: Boolean;
NroExt: TStrings;
i: Integer;
begin
NroExt:= TStringList.Create;
try
NroExt.Delimiter:= ';';
NroExt.DelimitedText:= FileMask;
Ruta:= IncludeTrailingPathDelimiter(Ruta);
Result:= TStringList.Create;
for i:= 0 to NroExt.Count - 1 do
begin
if FindFirst(Ruta + NroExt, faAnyFile - faDirectory, SR) = 0 then
repeat
AssignFile(txt,Ruta + SR.Name);
Reset(txt);
Found:= False;
while not Eof(txt) and not Found do
begin
Readln(txt, Row);
if Pos(Buscado, Row) > 0 then
begin
Result.Add(Ruta + SR.Name);
Found:= True
end
end;
CloseFile(txt);
until FindNext(SR) <> 0
end
finally
NroExt.Free
end
end;


Llamada:

procedure TForm1.Button1Click(Sender: TObject);
begin
edFileMask.Text:= '*.PAS; *.DFM'; // El separador [I]TIENE que ser ';'
ListBox1.Items:= TextFoundInFile(edRuta.Text, edFileMask.Text, edBuscado.Text).SaveToFile('C:\LISTA.TXT')
end;

De ese modo podés pasar la máscara que desees al argumento FileMask, por ejemplo: '*.PAS;*.DFM;*.TXT;*.BAT;*.RC'

Saludos.

Paulao
29-02-2012, 20:42:11
Hizo estas alteraciones:
function TForm1.TextFoundInFile(path: string; const FileMask:string; const tipo, tabela: string): TStrings;
var
SR: TSearchRec;
txt: TextFile;
Row: string;
Found: Boolean;
i: Integer;
NroExt: TStrings;
begin
NroExt:= TStringList.Create;
try
NroExt.Delimiter:= ';';
NroExt.DelimitedText:= FileMask;
path := IncludeTrailingPathDelimiter(path);
Result := TStringList.Create;
for i:= 0 to NroExt.Count - 1 do
begin
if FindFirst(path + NroExt[i], faAnyFile - faDirectory, SR) = 0 then
repeat
AssignFile(txt,path + SR.Name);
Reset(txt);
Found:= False;
while not Eof(txt) and not Found do
begin
Readln(txt, Row);
if Pos(tabela, Row) > 0 then
begin
Result.Add(tipo + ';' + tabela + ';' + SR.Name);
Found:= True
end
end;
CloseFile(txt);
until FindNext(SR) <> 0
end
finally
NroExt.Free;
end
end;
El problema es quando me voy a exportar para excel. No estas funcionando. Abajo la forma como yo hago:
procedure TForm1.VarrerClick(Sender: TObject);
begin
ClientDataSet1.Open;
pth := IncludeTrailingPathDelimiter(edtDir.Directory);
while not ClientDataSet1.Eof do
begin
TextFoundInFile(pth,'*.pas;*.dfm',ClientDataSet1.FieldByName('xtype').AsString,ClientDataSet1.FieldB yName('name').AsString).SaveToFile('D:\Teste\LISTA.xls');
ClientDataSet1.Next;
end;

end;