Вот код программы.Программа ответ выводит в окне,а нужно,чтобы на Strin Grid выводила.
Код:
unit class_fMain;
interface
uses
Windows,
Messages,
SysUtils,
Classes,
Variants,
Graphics,
Controls,
Forms,
Dialogs,
Grids,
ComObj,
StdCtrls;
type
TfMain = class(TForm)
sgExcel: TStringGrid;
btnOpenFile: TButton;
OpenDlg: TOpenDialog;
btnFind: TButton;
Label1: TLabel;
procedure btnOpenFileClick(Sender: TObject);
procedure btnFindClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
procedure Xls_Open(XLSFile:string; Grid: TStringGrid);
//Считывает Excel в StringGrid.
const
xlCellTypeLastCell = $0000000B;
var
ExlApp, Sheet: OLEVariant;
i, j, r, c: Integer;
begin
ExlApp := CreateOleObject('Excel.Application');
try
ExlApp.Visible := false;
ExlApp.Workbooks.Open(XLSFile);
Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
r := ExlApp.ActiveCell.Row;
c := ExlApp.ActiveCell.Column;
Grid.RowCount:=r;
Grid.ColCount:=c;
for j:= 1 to r do
for i:= 1 to c do
Grid.Cells[i-1,j-1]:= sheet.cells[j,i];
finally
ExlApp.Quit;
ExlApp := Unassigned;
Sheet := Unassigned;
ShowMessage('Загрузка завершена ,можно работать с файлом');
end;
end;
procedure AutoSizeGridColumn(Grid : TStringGrid; Column : Integer);
//Авторазмер колонок StringGrid под ширину текста.
var
I : Integer;
Temp : Integer;
Max : Integer;
begin
Max := 0;
for i := 0 to (Grid.RowCount - 1) do
begin
Temp := Grid.Canvas.TextWidth(Grid.Cells[Column, I]);
if Temp > Max
then Max := Temp;
end;
Grid.ColWidths[Column] := Max + Grid.GridLineWidth + 10;
end;
procedure TfMain.btnOpenFileClick(Sender: TObject);
var
X: Integer;
begin
OpenDlg.InitialDir:=ExtractFilePath(ParamStr(0));
if OpenDlg.Execute then
begin
Xls_Open(OpenDlg.Files[0], sgExcel);
for x := 0 to sgExcel.ColCount-1 do
AutoSizeGridColumn(sgExcel, x);
end;
end;
procedure TfMain.btnFindClick(Sender: TObject);
type
Rec = record
sgLine: Integer;
cData: String;
sData: String;
fCount: Integer;
end;
var
x: Integer;
cache: array of Rec;
procedure FillData(Col1, Col2: String; Addr: Integer);
var
I: Integer;
Found: Boolean;
begin
Found:=False;
for I := Low(cache) to High(Cache) do
begin
if
(Cache[i].cData = trim(lowercase(Col1))) and
(Cache[i].sData = trim(lowercase(Col2)))
then
begin
Inc(Cache[i].fCount);
Found:=True;
Break;
end;
end;
if not Found then
begin
SetLength(Cache, Length(Cache)+1);
Cache[Length(Cache)-1].cData:=Trim(Lowercase(Col1));
Cache[Length(Cache)-1].sData:=Trim(Lowercase(Col2));
Cache[Length(Cache)-1].fCount:=1;
Cache[Length(Cache)-1].sgLine:=Addr;
end;
end;
begin
//Отфильтруем нужные значения по по 3 и 7-й колонке одновременно.
for x := 1 to sgExcel.RowCount-1 do FillData(sgExcel.Cells[3,x], sgExcel.Cells[7,x], x);
//Покажем где у нас нужные значения.
for x := Low(cache) to High(cache) do
if cache[x].fCount > 1
then MessageBox
(
Handle,
pChar(Format('Значения: [%d],Номер документа %s: , количество: [%d]',
[
cache[x].sgLine,
cache[x].cData + ' ' + cache[x].sData,
cache[x].fCount
])),
pChar(fMain.Caption),
MB_ICONINFORMATION or MB_OK
);
end;
end.
Вот я собираюсь действовать примерно так подскажите правильно или нет?
1. Делаете отдельную форму.
2. Делаете на ней SG.
3. Добавляете в Record который обслуживает дубли - еще одно измерение (номера строк первого SG) в котором будут фиксироваться строки.
4. Вместо MessageBox вставляете заполнение SG на второй форме. И не надо извращаться с Max, оно зачем тут вообще? Простой вывод строки и Inc(SG.RowCount, 1);
План то составил,но при выполнении загвоздка получилась.
Вот как сделать 3 и 4 строку. Код нашел
Код:
rocedure TfMain.btnFindClick(Sender: TObject);
type
Rec = record
sgLine:integer;//её наверно нужно как-то по другому назвать,а то компилятор запутается куда ,что выводить.
sgLine: Integer;
cData: String;
sData: String;
fCount: Integer;
end;
Что-то типа этого нужно написать?