доброго дня имеются две колонки в Excel. Необходимо вывести куда нибудь на форму две таблицы. Значение ячейки "111" в первой таблице нужно оформить в виде выпадающего списка, значения для которого берутся из первой колонки в Excel. Аналогично для "222", только значения берутся из второй колонки. Все остальные ячейки вычисляются по формулам, в зависимости от значений ячеек "111" и "222". Вопрос: какой тут компонент использовать, чтобы можно было так выводить на форму?
С событиями все нормально. Просто достаточно было включить опцию goEditing у гридов, чтобы всё заработало как нужно. Но твой код прямо образец того, как не надо делать. Я не удержался и чуть-чуть его сократил (на самом деле, от него может остаться половина того, что есть сейчас). Смотри:
Сокращённый вариант(Показать/Скрыть)
type
TForm1 = class(TForm)
// ...
private{ Private declarations }procedure MySelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
public{ Public declarations }end;
var
Form1: TForm1;
E,Sheet, E2,Sheet2:variant;
iRow, iClm, iRow2, iClm2: integer;
implementationuses ComObj;
{$R *.dfm}procedure TForm1.ComboBox1Change(Sender: TObject);
begin{Получаем выбранный элемент из ComboBox и помещаем его в грид}if ComboBox1.ItemIndex<>-1thenbegin
StringGrid1.Cells[StringGrid1.Col,
StringGrid1.Row] :=
ComboBox1.Items[ComboBox1.ItemIndex];
StringGrid1.Cells[StringGrid1.Col+1, StringGrid1.Row]:=Sheet.Cells[ComboBox1.ItemIndex+1,2].Text;
end;
ComboBox1.Visible := False;
StringGrid1.SetFocus;
end;
procedure TForm1.ComboBox1Exit(Sender: TObject);
begin{Получаем выбранный элемент из ComboBox и помещаем его в грид}if ComboBox1.ItemIndex<>-1thenbegin
StringGrid1.Cells[StringGrid1.Col,
StringGrid1.Row] :=
ComboBox1.Items[ComboBox1.ItemIndex];
StringGrid1.Cells[StringGrid1.Col+1, StringGrid1.Row]:=Sheet.Cells[ComboBox1.ItemIndex+1,2].Text;
StringGrid1.RowCount:=StringGrid1.RowCount+1;
end;
ComboBox1.Visible := False;
StringGrid1.SetFocus;
// ComboBox1.ItemIndex:=-1;
end;
procedure TForm1.ComboBox2Change(Sender: TObject);
begin{Получаем выбранный элемент из ComboBox и помещаем его в грид}if ComboBox2.ItemIndex<>-1thenbegin
StringGrid2.Cells[StringGrid2.Col,
StringGrid2.Row] :=
ComboBox2.Items[ComboBox2.ItemIndex];
StringGrid2.Cells[StringGrid2.Col+2, StringGrid2.Row]:=Sheet2.Cells[ComboBox2.ItemIndex+1,2].Text;
end;
ComboBox1.Visible := False;
StringGrid1.SetFocus;
end;
procedure TForm1.ComboBox2Exit(Sender: TObject);
begin{Получаем выбранный элемент из ComboBox и помещаем его в грид}if ComboBox2.ItemIndex<>-1thenbegin
StringGrid2.Cells[StringGrid2.Col,
StringGrid2.Row] :=
ComboBox2.Items[ComboBox2.ItemIndex];
StringGrid2.Cells[StringGrid2.Col+2, StringGrid2.Row]:=Sheet2.Cells[ComboBox2.ItemIndex+1,2].Text;
StringGrid2.RowCount:=StringGrid2.RowCount+1;
end;
ComboBox2.Visible := False;
StringGrid2.SetFocus;
ComboBox2.ItemIndex:=-1;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
E.Workbooks[1].Close;
E:=Unassigned;
E2.Workbooks[1].Close;
E2:=Unassigned;
end;
// Вот к этому я приложил руку...
procedure TForm1.FormCreate(Sender: TObject);
procedure InitGrid(grid : TStringGrid; cbx : TComboBox;
Cols : arrayof integer; Rows : Integer; Sheet : Variant);
var i : Integer;
begin
grid.DefaultRowHeight := cbx.Height;
cbx.Visible := False;
cbx.Style := csDropDownList;
for i := 0to High(Cols) do
grid.ColWidths[i] := Cols[i];
cbx.DropDownCount := Rows;
for i := 1to Rows do
cbx.Items.Add(Sheet.Cells[i, 1].Text);
grid.Options := grid.Options + [goEditing];
grid.OnSelectCell := MySelectCell;
grid.Tag := Integer(cbx);
end;
begin
StringGrid3.ColWidths[0]:=40;
StringGrid3.ColWidths[1]:=300;
StringGrid3.ColWidths[2]:=110;
StringGrid3.ColWidths[3]:=110;
StringGrid3.ColWidths[4]:=110;
E:=CreateOleObject('Excel.Application');
E.WorkBooks.Open('F:\123.xls'); // Пути заменишь на свои. Двойной бэкслеш не нужен...
E.WorkBooks.item [1].Activate;
Sheet:=E.WorkBooks.item [1].Sheets.item[1];
E2:=CreateOleObject('Excel.Application');
E2.WorkBooks.Open('F:\234.xls');
E2.WorkBooks.item [1].Activate;
Sheet2:=E2.WorkBooks.item [1].Sheets.item[1];
iRow := Sheet.UsedRange.Row + Sheet.UsedRange.Rows.Count - 1; //последняя заполненная строка
iClm := Sheet.UsedRange.Column + Sheet.UsedRange.Columns.Count - 1; //последний заполненный столбец
iRow2 := Sheet2.UsedRange.Row + Sheet2.UsedRange.Rows.Count - 1; //последняя заполненная строка
iClm2 := Sheet2.UsedRange.Column + Sheet2.UsedRange.Columns.Count - 1; //последний заполненный столбец
InitGrid(StringGrid1, ComboBox1, [40, 300, 110, 110, 110],
iRow, Sheet);
InitGrid(StringGrid2, ComboBox2, [40, 300, 60, 120, 140, 140, 140],
iRow2, Sheet2);
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
i,j: integer;
beginif Key=vk_delete thenbegin
StringGrid1.Rows[StringGrid1.Row].Clear;
for i:=StringGrid1.Row to StringGrid1.RowCount-1dobeginfor j:=0to StringGrid1.ColCount dobegin
StringGrid1.Cells[j,i]:=StringGrid1.Cells[j,i+1]
end;
end;
if StringGrid1.RowCount>2then StringGrid1.RowCount:=StringGrid1.RowCount-1;
end;
end;
procedure TForm1.MySelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
R : TRect;
Grid : TStringGrid;
beginif (ACol = 1) and (ARow <> 0) thenbegin
Grid := Sender as TStringGrid;
R := Grid.CellRect(ACol, ARow);
OffsetRect(R, Grid.Left, Grid.Top);
with TComboBox(Grid.Tag) dobegin
Left := R.Left + 1;
Top := R.Top + 1;
Width := (R.Right + 1) - R.Left;
Height := (R.Bottom + 1) - R.Top;
{ Показываем combobox }
Visible := True;
SetFocus;
DroppedDown := True; // <---
end;
end;
CanSelect := True;
end;
procedure TForm1.StringGrid2KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
i,j: integer;
beginif Key=vk_delete thenbegin
StringGrid2.Rows[StringGrid2.Row].Clear;
for i:=StringGrid2.Row to StringGrid2.RowCount-1dobeginfor j:=0to StringGrid2.ColCount dobegin
StringGrid2.Cells[j,i]:=StringGrid2.Cells[j,i+1];
end;
end;
if StringGrid2.RowCount>2then StringGrid2.RowCount:=StringGrid2.RowCount-1;
end;
end;