Консультация № 183815
25.07.2011, 14:50
91.20 руб.
0 18 1
Уважаемые эксперты! Подскажите как правильно орагнизовать загрузку данных из Excel. Есть готовый документ, в нем может быть от 2 до 5 листов.
1-Мне необходимо узнать количество листов
2- С помощью OpenDialog загрузить данные из имеющихся листов. Данные будут грузится в комбобоксы, и едиты для редактирования.
Заранее благодарю за помощь.

Обсуждение

Неизвестный
25.07.2011, 16:41
общий
Адресаты:
По первому пункту вопроса:

uses ComObj;
...
procedure TForm1.Button1Click(Sender: TObject);
var XLApp, XLWorkBook, XLSheet: Variant;
i: Integer;

begin

if OpenDialog1.Execute then
begin
XlApp := CreateOleObject('Excel.Application');
XLWorkBook := XlApp.WorkBooks.Open(OpenDialog1.FileName); // открытие файла
for i:= 1 to XLWorkBook.Sheets.Count do // пробегаем по всем листам
begin
XLSheet := XLWorkBook.WorkSheets[i];
// какие-то операции с листом

end;
XLWorkBook.Close;
XlApp.Quit;
end;
end;


Данные будут грузится в комбобоксы, и едиты для редактирования


А что дальше? Немного непонятна формулировка второй части второго вопроса.
давно
Посетитель
352040
133
25.07.2011, 16:51
общий
Благодарю за быстрый ответ.

Виноват. Открыли книгу, и начинаем перенос данных. Допустим с Лист1(D3) нужно данные взять в Комбобокс 3, с Лист2(F2) данные в Едит2 и т.д. Адреса ячеек откуда взять и куда вставить я знаю. А вот как это организовать? Не пойму.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
25.07.2011, 17:01
общий
Предлагаю как-то так:

...
for i:= 1 to XLWorkBook.Sheets.Count do
begin
XLSheet := XLWorkBook.WorkSheets[i];
case i of // прописываем в зависимости от номера листа присвоение данных
1: Edit1.Text:= XLSheet.Range['a1'].Value;
2: ComboBox1.text:= XLSheet.Range['a2'].Value;
end;
end;

...
Неизвестный
25.07.2011, 17:03
общий
Адресаты:
Прошу прощения, ячейки взял для примера a1 и a2. Но, думаю, смысл понятен.
Неизвестный
25.07.2011, 17:05
общий
Адресаты:
Будут еще вопросы, пишите в форум, доеду до дома - отвечу.
давно
Посетитель
352040
133
25.07.2011, 18:56
общий
25.07.2011, 19:13
Попробовал сделать как вы писали, вот что получилось.
Код:
procedure TForm2.BitBtn3Click(Sender: TObject);
var
Ex, WorkBook, Sheet: Variant;
i: Integer;
begin

if OpenDialog3.Execute then
begin
Ex := CreateOleObject('Excel.Application');
WorkBook := Ex.WorkBooks.Open(OpenDialog3.FileName); // открытие файла
for i:= 1 to WorkBook.Sheets.Count do //пробегаем по всем листам
begin
Sheet := WorkBook.WorkSheets[i];
case i of // прописываем в зависимости от номера листа присвоение данных
ComboBox3.Text:= Sheet.Range['Q12'].Value;
ComboBox4.text:= Sheet.Range['M13'].Value;
end;
end;

end;
WorkBook.Close;
Ex.Quit;
end;
end;


Выдает ошибку [Ошибка] Unit2.pas(4334): Constant expression expected

И еще вопрос. Где в коде ссылка на лист?
Если можно вот этот кусок кода объясните.
case i of // прописываем в зависимости от номера листа присвоение данных
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
25.07.2011, 20:51
общий
Адресаты:
Вот Ваш подправленный код:

for i:= 1 to WorkBook.Sheets.Count do //пробегаем по всем листам
begin
Sheet := WorkBook.WorkSheets[i];
case i of // прописываем в зависимости от номера листа присвоение данных
1: ComboBox3.Text:= Sheet.Range['Q12'].Value;
2: ComboBox4.text:= Sheet.Range['M13'].Value;
end;
end;

Ошибку " Unit2.pas(4334): Constant expression expected " выдает при отсутствии в конструкции case of ... end; значений, которым переходить. (они выделены жирным).

Т.е. если подробно:
...
Sheet := WorkBook.WorkSheets[i]; - получение ссылки на лист номер i.
case i
1:ComboBox3.Text:= Sheet.Range['Q12'].Value; // если номер листа 1 то присваиваем ComboBox3.Text значение с первого листа ячейки q12
2: ComboBox4.text:= Sheet.Range['M13'].Value; // если номер листа 2 то присваиваем ComboBox4.Text значение со второго листа ячейки m13
end;
...

как-то так. Если непонятно объяснил, то задавайте вопросы.
Неизвестный
26.07.2011, 08:07
общий
Адресаты:
Заработала ли у Вас программа?
Можно оформить в виде ответа или еще доработать какой-либо момент?
давно
Посетитель
352040
133
26.07.2011, 11:20
общий
Добрый день.
Сделал так.
Код:
 var
Ex, WorkBook, Sheet: Variant;
i: Integer;
begin

if OpenDialog3.Execute then
begin
Ex := CreateOleObject('Excel.Application');
WorkBook := Ex.WorkBooks.Open(OpenDialog3.FileName); // открытие файла
for i:= 1 to WorkBook.Sheets.Count do //пробегаем по всем листам
begin
Sheet := WorkBook.WorkSheets[i];
case i of // прописываем в зависимости от номера листа присвоение данных
1: ComboBox3.Text:= Sheet.Range['Q12'].Value;
1: ComboBox4.text:= Sheet.Range['M13'].Value;
1: Memo1.Text:= Sheet.Range['B26:B43'].Value;
end;
end;

end;
WorkBook.Close;
Ex.Quit;

end;

Ругается компилятор.
[Ошибка] Unit2.pas(4404): Duplicate case label
И еще вопрос. Правильно ли я в Мемо пытаюсь грузить данные?
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
26.07.2011, 11:23
общий
Unit2.pas(4404): Duplicate case label
У Вас в операторе case два дублирующих номера.

В этом случае нужно делать (если несколько операций с одного листа):
case i of // прописываем в зависимости от номера листа присвоение данных
1:
begin
ComboBox3.Text:= Sheet.Range['Q12'].Value;
ComboBox4.text:= Sheet.Range['M13'].Value;
Memo1.Text:= Sheet.Range['B26:B43'].Value;
end;
end;
давно
Посетитель
352040
133
26.07.2011, 11:54
общий
26.07.2011, 12:01
При загрузке в комбобоксы проблем нет, если пытаюсь загрузить в Мемо выдает такую ошибку.

Could not convert variant of type (Array Variant) into type (String)
Не удется преобразовать тип. Как эту проблему обойти?
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
26.07.2011, 12:02
общий
Адресаты:
И еще вопрос. Правильно ли я в Мемо пытаюсь грузить данные?


Так не пройдет. Нужно построчно из листа добавлять в Memo1.
Неизвестный
26.07.2011, 12:10
общий
Адресаты:
Для работы c Memo можно реализовать такой вариант

...

begin
...
Sheet.Range['B26:B43'].Copy;
Memo1.PasteFromClipboard;
end;
...
давно
Посетитель
352040
133
26.07.2011, 12:19
общий
Благодарю за помощь. Все получилось. Для Мемо использовал предложенный вариант, прекрасно работает. Думаю что можно закрывать этот вопрос.
И делать в виде ответа.
Еще раз спасибо за помощь.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
26.07.2011, 12:21
общий
Адресаты:
Удачи в разработках
Неизвестный
26.07.2011, 12:32
общий
это ответ
Здравствуйте, Владимир!

Предлагаю вариант решения задачи с описанием по результатам обсуждения в форуме.

Полный текст модуля в приложении.

Удачи.

Приложение:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComObj, StdCtrls, OleServer, ExcelXP;

type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Edit1: TEdit;
ComboBox1: TComboBox;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var XLApp, XLWorkBook, XLSheet: Variant;
i: Integer;

begin

if OpenDialog1.Execute then
begin
XlApp := CreateOleObject('Excel.Application');
XLWorkBook := XlApp.WorkBooks.Open(OpenDialog1.FileName);
for i:= 1 to XLWorkBook.Sheets.Count do // проходим по всем листам рабочей книги
begin
XLSheet := XLWorkBook.WorkSheets[i];
case i of // в зависимости от номера листа выполняем действия
1:
begin // перенос с первой страницы
Edit1.Text:= XLSheet.Range['a1'].Value; // перенос в поле Edit
XLSheet.Range['a1:a5'].Copy; // вариант для переноса в поле Memo
memo1.PasteFromClipboard;
end;
2: ComboBox1.text:= XLSheet.Range['a2'].Value; // перенос со второй страницы в ComboBox
end;
end;
XLWorkBook.Close;
XlApp.Quit;
end;

end;

end.
Неизвестный
30.07.2011, 15:50
общий
Можно разяснить как управлят совместное (с Ексцел) пользование xls файла.
Как пользовать WorkBooks.Open если файл уже занят Excel-а (или дрогое приложение)?
Как писать из Excel-а в файл, занят нами с WorkBooks.Open?

давно
Посетитель
352040
133
30.07.2011, 16:02
общий
Ну во первых Excel не мешает (если документ в нем открыт), программа открывает книгу на чтение, без внесения изменений.
Файл открывается через OpenDialog, считался и прога от него отключается. И то что документ открыт еще где то не мешает.
Хотя у меня он только для печати. Все остальное хранится в ini файле.
Просто у меня прога вормирует бланки в Excel, и что бы каждый раз не забивать все заново пользователи попросили сделать такуб возможностьЮ загружать "старые" бланки для корректировки.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Форма ответа