Вопрос по Delphi

serg_pet

New Member
Ответ: Помощь по Delphi

GR!NWY сказав(ла):
люди подскажите может кто знает: необходимо с файла Excel скопировать телефонный справочник, т.е. перебирать с помощью делфи нужные ячейки файла. Например в третьем столбике в Excel у меня находятся фамилии. беру их копирую и вставляю что-то вроде IBQuery1.ParamByName('FIO').Value:=x где в x находится фамилия. Все єто дело зациклюю поскольку записей аж 10 тысяч :eek:
Вопрос как осуществить доступ к ячейкам файла Excel?
есть еще альтернативній вариант перегнать xls файл в mysql базу, вот (ed2k://|file|excel2mysql.zip|4218|5FF3D3FC343E9F547BEB29078B6A4F00|/) скрипт на перле, а потом из мускла, сразу в базу такую какую тебе надо. єто чтобі вообще ничего не писать :)
а если все-таки на делфи, то я когда-то давно писал через ADOTable. там куча методов, для получения листов xls и т.д.
 
Останнє редагування:

Live

Happy Live :)
Ответ: Помощь по Delphi

покапался в статьях и нашел такое.

var
Excel: variant;
i, j: word;
S: string;
begin
Excel := CreateOleObject('Excel.Application');
Excel.Workbooks.Open(FileName);
Excel.Visible:=True;
for i := 1 to 5 do
for j := 1 to 5 do
begin
S := Excel.Sheets[1].Cells[i,j].Text;
ShowMessage(S);// ну или пихаем куда душе угодно
end;
end;

Merlin спасибо за книгу я ее с Солара сразу скачал.
Serg pet методов действительно много как почитал книжки думаю найду то что нужно :mat:
 

Merlіn

dead wizard
Ответ: Помощь по Delphi

GR!NWY,
У тебя в примере используется позднее связывание.
Вот кусок, статьи, там пример с Word,но это не имеет значения.
Код:
uses
  COMOBJ;
...
procedure TForm1.Button1Click(Sender: TObject);
var
  wd: OleVariant;
  fileName: string;
begin
try
  fileName := ExtractFilePath(Application.EXEName) + 'report.DOC';
  //Создаем объект интерфейса для доступа к серверу COM
  wd := CreateOleObject('Word.Application');
  //Проверка наличия методов и правильность передачи параметров будет
  //осуществляться на стадии выполнения приложения
  wd.application.documents.add;
  wd.application.activedocument.range.insertAfter(now);
  wd.application.activedocument.saveas(fileName);
  //выгружаем сервер из памяти компьютера
  wd.application.quit(true, 0);
.....

Пример использования интерфейса с поздним связыванием был показан в начале этой статьи, когда доступ к COM серверу был осуществлен с помощью функции CreateOleObject. Компилятор в этом случае ничего не знает о методах и параметрах сервера, информация о них извлекается на стадии выполнения приложения, отсюда и потеря скорости выполнения приложения и всевозможные ошибки, которые компилятор не в состоянии обработать. При такой разработке приложения программист достает SDK от Microsoft office и начинает старательно изучать большие тома литературы.
Подводя итог можно говорить о том, что для доступа к COM серверу автоматизации существует три способа
- Vtable
- Позднее связывание (Интерфейс IDispatch)
- Позднее связывание (CreateOleObject)
Наиболее прогрессивный – первый способ, через который работают компоненты Delphi 5 для доступа к COM серверам приложений Office.

Пример использования Vtable интерфейса

Постановка задачи:
Имеется шаблон документа – shablon.DOC, подготовленный в MS Word, поля, которые должны быть заменены, помечены символом @. Необходимо прочитать данные из источника информации и заменить метки, на реальные данные, после чего распечатать полученный документ.

Воспользуемся методом Vtable . Выложим на форму компоненту WordApplication, WordDocument и кнопку Button. Для события OnClick компоненты Button1 пропишем следующий код:
.....
А вот пример использавания метода Vtable,для Excel.
Обмен данными с Excel
В Delphi 5, для обмена данными между Вашим приложением и Excel можно использовать компонент TExcelApplication, доступный на Servers Page в Component Palette.
На форме находится TStringGrid, заполненный некоторыми данными и две кнопки, с названиями To Excel и From Excel. Так же на форме находится компонент TExcelApplication со свойством Name, содержащим XLApp и свойством ConnectKind, содержащим ckNewInstance.
Когда нам необходимо работать с Excel, то обычно мы открываем ExcelApplication, затем открываем WorkBook и в конце используем WorkSheet.
Итак, несомненный интерес представляет для нас листы (WorkSheets) в книге (WorkBook). Давайте посмотрим как всё это работает.
Посылка данных в Excel
Это можно сделать с помощью следующей процедуры :
Код:
procedure TForm1.BitBtnToExcelOnClick(Sender: TObject);
var
  WorkBk: _WorkBook; //  определяем WorkBook
  WorkSheet: _WorkSheet; //  определяем WorkSheet
  I, J, K, R, C: Integer;
  IIndex: OleVariant;
  TabGrid: Variant;
begin
  if GenericStringGrid.Cells[0,1] <> '' then
  begin
    IIndex := 1;
    R := GenericStringGrid.RowCount;
    C := GenericStringGrid.ColCount;
    // Создаём массив-матрицу
    TabGrid := VarArrayCreate([0,(R - 1),0,(C - 1)],VarOleStr);
    I := 0;
    //  Определяем цикл для заполнения массива-матрицы
    repeat
    for J := 0 to (C - 1) do
      TabGrid[I,J] := GenericStringGrid.Cells[J,I];
    Inc(I,1);
    until
    I > (R - 1);

    // Соединяемся с сервером TExcelApplication
    XLApp.Connect;
    // Добавляем WorkBooks в ExcelApplication
    XLApp.WorkBooks.Add(xlWBatWorkSheet,0);
    // Выбираем первую WorkBook
    WorkBk := XLApp.WorkBooks.Item[IIndex];
    // Определяем первый WorkSheet
    WorkSheet := WorkBk.WorkSheets.Get_Item(1) as _WorkSheet;
    // Сопоставляем Delphi массив-матрицу с матрицей в WorkSheet
    Worksheet.Range['A1',Worksheet.Cells.Item[R,C]].Value := TabGrid;
    // Заполняем свойства WorkSheet
    WorkSheet.name := 'Customers';
    Worksheet.Columns.Font.Bold := True;
    Worksheet.Columns.HorizontalAlignment := xlRight;
    WorkSheet.Columns.ColumnWidth := 14;
    // Заполняем всю первую колонку
    WorkSheet.Range['A' + IntToStr(1),'A' + IntToStr(R)].Font.Color := clBlue;
    WorkSheet.Range['A' + IntToStr(1),'A' + IntToStr(R)].HorizontalAlignment := xlHAlignLeft;
    WorkSheet.Range['A' + IntToStr(1),'A' + IntToStr(R)].ColumnWidth := 31;
    // Показываем Excel
    XLApp.Visible[0] := True;
    // Разрываем связь с сервером
    XLApp.Disconnect;
    // Unassign the Delphi Variant Matrix
    TabGrid := Unassigned;
  end;
end;
Получение данных из Excel
Это можно сделать с помощью следующей процедуры
Код:
procedure TForm1.BitBtnFromExcelOnClick(Sender: TObject);
var
  WorkBk: _WorkBook;
  WorkSheet: _WorkSheet;
  K, R, X, Y: Integer;
  IIndex: OleVariant;
  RangeMatrix: Variant;
  NomFich: WideString;
begin
  NomFich := 'C:\MyDirectory\NameOfFile.xls';
  IIndex := 1;
  XLApp.Connect;
  // Открываем файл Excel
  XLApp.WorkBooks.Open(NomFich, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
  EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,EmptyParam,0);
  WorkBk := XLApp.WorkBooks.Item[IIndex];
  WorkSheet := WorkBk.WorkSheets.Get_Item(1) as _WorkSheet;
  // Чтобы знать размер листа (WorkSheet), т.е. количество строк и количество
  // столбцов, мы активируем его последнюю непустую ячейку
  WorkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).Activate;
  // Получаем значение последней строки
  X := XLApp.ActiveCell.Row;
  // Получаем значение последней колонки
  Y := XLApp.ActiveCell.Column;
  // Определяем количество колонок в TStringGrid
  GenericStringGrid.ColCount := Y;
  // Сопоставляем матрицу WorkSheet с нашей Delphi матрицей
  RangeMatrix := XLApp.Range['A1',XLApp.Cells.Item[X,Y]].Value;
  // Выходим из Excel и отсоединяемся от сервера
  XLApp.Quit;
  XLApp.Disconnect;
  //  Определяем цикл для заполнения TStringGrid
  K := 1;
  repeat
    for R := 1 to Y do
      GenericStringGrid.Cells[(R - 1),(K - 1)] := RangeMatrix[K,R];
    Inc(K,1);
    GenericStringGrid.RowCount := K + 1;
  until
    K > X;
  // Unassign the Delphi Variant Matrix
  RangeMatrix := Unassigned;
end;
Так что думай
 
Останнє редагування:

Live

Happy Live :)
Ответ: Помощь по Delphi

не пойму чем плох CreateOleObject
Вот писал с помошью библии делфи. Экспорт базы с ДБГрида на ура :kos:
HTML:
procedure TForm1.N2Click(Sender: TObject);
var XLApp,Sheet,Colum:Variant;
    index,i:integer;
begin
XLApp:=CreateOleObject('Excel.Application');
XLApp.visible:=true;
XLApp.Workbooks.add(-4167);
XLApp.Workbooks[1].WorkSheets[1].name:='Отчет';
Colum:=XLApp.Workbooks[1].WorkSheets['Отчет'].Columns;
Colum.Columns[1].ColumnWidth:=10;
Colum.Columns[2].ColumnWidth:=20;
Colum.Columns[3].ColumnWidth:=15;
Colum.Columns[4].ColumnWidth:=15;
Colum.Columns[5].ColumnWidth:=40;
Colum:=XLApp.Workbooks[1].WorkSheets['Отчет'].Rows;
Colum.Rows[2].Font.Bold:=true;
Colum.Rows[1].Font.Bold:=true;
Colum.Rows[1].Font.Color:=ClNavy;
Colum.Rows[1].Font.Size:=14;

Sheet:=XLApp.Workbooks[1].WorkSheets['Отчет'];
Sheet.Cells[1,2]:='База данных';
Sheet.Cells[2,1]:='ID';
Sheet.Cells[2,2]:='Покупатель';
Sheet.Cells[2,3]:='Дата покупки';
Sheet.Cells[2,4]:='Цена квартиры';
Sheet.Cells[2,5]:='Адрес';

            index:=3;
        Datamodule1.Query1.First;
        for i:=0 to Datamodule1.Query1.RecordCount-1 do
           begin
           Sheet.Cells[index,1]:=Datamodule1.Query1.Fields.Fields[0].AsString;
           Sheet.Cells[index,2]:=Datamodule1.Query1.Fields.Fields[1].AsString;
           Sheet.Cells[index,3]:=Datamodule1.Query1.Fields.Fields[2].AsString;
           Sheet.Cells[index,4]:=Datamodule1.Query1.Fields.Fields[3].AsString;
           Sheet.Cells[index,5]:=Datamodule1.Query1.Fields.Fields[4].AsString;
           Inc(index);
           Datamodule1.Query1.Next;
           end;
через спец компоненты делфи для Excel думаю будет надежнее по скорости и качеству так что спасибо за просвещение.
ЗЫы про существование таковых не знал :yaya:
 

Merlіn

dead wizard
Ответ: Помощь по Delphi

GR!NWY сказав(ла):
не пойму чем плох CreateOleObject
Вот отрывок из статьи, в ней говорится про IDispatch, но думаю тоже можно отнести и к CreateOleObject.
Позднее связывание (Интерфейс IDispatch)
При использовании данного метода имена функций и типы параметров решаются во время выполнения программы, все параметры определены вариантным типом.
Поскольку во время компиляции невозможно определить соответствия имен функций и типов параметров, данный метод чреват ошибками.
Так как имена функций и типы параметров должны проверяться во время выполнения программы, данный метод выполняется медленно.
Единственное преимущество данного метода при программировании в Delphi заключается в том, что отпадает необходимость передачи всех параметров вызываемой функции.
Пример использования Dispatch интерфейса
Постановка задачи: получить информацию о документе, который открывается MS Word, при этом не должны использоваться никакие компоненты для доступа к серверам автоматизации.
Создадим новое приложение и выложим на форму кнопку. Пропишем событие onDoubleClick для кнопки следующим образом:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  Shablon: OleVariant;
  word: _ApplicationDisp;
begin
  Shablon := ExtractFilePath(Application.EXEName) + 'shablon.DOC';
  word := CoWordapplicaTion.Create as _ApplicationDisp;
  (Word.Documents as DocumentsDisp).Open(Shablon, EmptyParam,
  EmptyParam, EmptyParam, EmptyParam, EmptyParam,
  EmptyParam, EmptyParam, EmptyParam, EmptyParam);
  showmessage((Word.Application as _application).Get_Name + #13 +
  ((Word.Application as _application).ActiveDocument
  as _documentDisp).Path );
  word.quit(EmptyParam, EmptyParam, EmptyParam);
end;
Переменная word имеет тип ApplicatiwonDisp = dispinterface ['{00020970-0000-0000-C000-000000000046}'], который описан в библиотеки типов Word97_TLB.Pas. Строка word:=CoWordapplicaTion.Create as _ApplicationDisp; создает экземпляр сервера и возвращает DispInterface. Благодаря наличию библиотеки и жесткому приведению типов разработчик имеет возможность делать меньше ошибок, так как компилятор имеет определенную информацию о типах данных. В сравнении с использованием метода позднего связывания через функцию CreateOleObject этот метод более прогрессивный. По крайней мере, хотя бы часть информации компилятору да известна.
Подводя итог выше сказанному, можно отметить, что действительно использование компонент для доступа к COM серверам через Vtable интерфейс значительно ускоряет работу приложения и ограждает разработчика от ошибок.
 

Vladimir B.

милый добрый кот
Модератор
Ответ: Помощь по Delphi

Может есть у кого компоненты RxTools для 6-7 делфи, дайте пожалуйста. Диск полетел с ними, а нужны позарез :(
 

Live

Happy Live :)
Ответ: Помощь по Delphi

бери у меня (вечером)



или ищи здесь...
 

Hamster

Well-Known Member
Ответ: Помощь по Delphi

У меня вопрос по паскалю.
Дело вот в чем.
...................
type student=record
gruppa:string; fio:string;
step:real;
end;

var s:array[1..12]of student;
i,n,k:integer;
bl:string;
begin k:=0;
write('vvedite k-vo studentoff: ');
read(n);
for i:=1 to n do

begin
write('Gruppa:');
readln(s.gruppa);
write('Famili9: ');
readln(s.fio);
write('stependi9: ');
readln(s.step);
end;
.................

почему поле №1 (группа) при вводе информации для студетна №1 прпускаеться? (автоматически заноситься пустота). Преподы молчат....
 

Вкладення

serg_pet

New Member
Ответ: Помощь по Delphi

GH0ST сказав(ла):
У меня вопрос по паскалю.
Дело вот в чем.
...................
type student=record
gruppa:string; fio:string;
step:real;
end;

var s:array[1..12]of student;
i,n,k:integer;
bl:string;
begin k:=0;
write('vvedite k-vo studentoff: ');
read(n);
for i:=1 to n do

begin
write('Gruppa:');
readln(s.gruppa);
write('Famili9: ');
readln(s.fio);
write('stependi9: ');
readln(s.step);
end;
.................

почему поле №1 (группа) при вводе информации для студетна №1 прпускаеться? (автоматически заноситься пустота). Преподы молчат....

гг. препы лажбаны :)
вместо read(n);
напиши readLN(n) и все будет в ажуре :)
P.S. если будет интерестно почему, то напиши в ЛС -- разъясню.
 

Hamster

Well-Known Member
Ответ: Помощь по Delphi

=))))))))
работает.

Объясни плиз, почему так происходит, аж самому интересно стало.
 
Зверху