FAQ VCL
Работа с MS Office\Word

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как поставить в соответствие числу буквы столбцов в Excel?

function NumToR1C1(Num: Cardinal): string;
const
  BASE = 26;
var
  d, m: Cardinal;
begin
   Result := '';

   repeat
      d := Num div BASE;
      m := Num mod BASE;

      if (d > 0) and (m = 0) then
      begin
         Dec(d);
         m := BASE;
      end;

      Num := d;
      Result := Chr(m + Ord('A') - 1) + Result;
   until Num = 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(NumToR1C1(703));
end;


Как поставить в соответствие буквам столбцов в Excel число?

uses
  Math;

function R1C1ToNum(Num: string): Cardinal;
const
  BASE = 26;
var
  i, j, Len: Integer;
  c: Char;
begin
   i := 0;
   Result := 0;
   Len := Length(Num);
   Num := AnsiUpperCase(Num);

   while Num <> '' do
   begin
      c := Num[Len-i];
      case c of
         'A'..'Z': j := Ord(c) - 64;
         else
            raise Exception.Create('Неверное число в формате R1C1');
      end;

      Result := Result + j * Trunc(Power(BASE, i));

      Inc(i);
      SetLength(Num, Len-i);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(IntToStr(R1C1ToNum('AAA')));
end;


Как запустить/закрыть Excel?

uses
  {...,} ComObj;

var
  E: OleVariant;

procedure TForm1.Button1Click(Sender: TObject);
begin
   E := CreateOleObject('Excel.Application');
   // показывать/не показывать системные сообщения Excel
   // (лучше не показывать)
   E.Application.EnableEvents := False;
   E.Visible := True;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   if not VarIsEmpty(E) then
   begin
      E.Quit;
      E := Unassigned;
   end;
end;


Как отключить выполнение макросов при открытии документа?

uses
  {...,} ComObj;

var
  E: OleVariant;

procedure TForm1.Button1Click(Sender: TObject);
const
  msoAutomationSecurityLow = 1;
  msoAutomationSecurityByUI = 2;
  msoAutomationSecurityForceDisable = 3;
begin
   E := CreateOleObject('Excel.Application');

   E.AutomationSecurity := msoAutomationSecurityForceDisable;

   E.Application.EnableEvents := False;
   E.WorkBooks.Open('d:\test.xlsx');
   E.Visible := True;
end;


Как динамически создать макрос в документе Excel и выполнить его?

// Способ первый
uses
  {...,} ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  E, B: OleVariant;
  i: OleVariant;
begin
   E := CreateOleObject( 'Excel.Application' );
   B := E.Workbooks.Add;
   E.Visible := true;
   i := E.VBE.ActiveVBProject.VBComponents.Count;
   E.VBE.ActiveVBProject.VBComponents.Add( 1 );
   // Добавляем в модуль книги код на VB
   B.VBProject.VBComponents.Item( i+1 ).CodeModule.InsertLines( 1, 'Sub Test()' );
   B.VBProject.VBComponents.Item( i+1 ).CodeModule.InsertLines( 2, '   MsgBox "Привет от книги!"' );
   B.VBProject.VBComponents.Item( i+1 ).CodeModule.InsertLines( 3, 'End Sub' );
   // Добавляем то же самое в код листа
   B.VBProject.VBComponents.Item( 'Лист1' ).CodeModule.InsertLines( 1, 'Sub Test()' );
   B.VBProject.VBComponents.Item( 'Лист1' ).CodeModule.InsertLines( 2, '   MsgBox "Привет от листа!"' );
   B.VBProject.VBComponents.Item( 'Лист1' ).CodeModule.InsertLines( 3, 'End Sub' );
   E.Application.Run( 'Test' );
   E.Application.Run( 'Лист1.Test' );

   B.Close;
   B := Unassigned;
   E.Quit;
   E := Unassigned;
end;

// Способ второй
uses
  {...,} ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  E, B: OleVariant;
  i: OleVariant;
begin
   E := CreateOleObject( 'Excel.Application' );
   B := E.Workbooks.Add;
   E.Visible := true;
   i := E.VBE.ActiveVBProject.VBComponents.Count;
   E.VBE.ActiveVBProject.VBComponents.Add( 1 );
   // Добавляем в модуль книги код на VB
   B.VBProject.VBComponents.Item( i+1  ).CodeModule.AddFromString( 'Sub Test()' + #13 + '   MsgBox "Привет от книги!"' + #13 + 'End Sub' );
   // Добавляем то же самое в код листа
   B.VBProject.VBComponents.Item( 'Лист1' ).CodeModule.AddFromString( 'Sub Test()' + #13 + '   MsgBox "Привет от листа!"' + #13 + 'End Sub' );
   E.Application.Run( 'Test' );
   E.Application.Run( 'Лист1.Test' );

   B.Close;
   B := Unassigned;
   E.Quit;
   E := Unassigned;
end;

// Способ третий (импорт из файла)
uses
  {...,} ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  E, B: OleVariant;
  i: OleVariant;
begin
   E := CreateOleObject( 'Excel.Application' );
   B := E.Workbooks.Add;
   E.Visible := true;
   i := E.VBE.ActiveVBProject.VBComponents.Count;
   E.VBE.ActiveVBProject.VBComponents.Add( 1 );
   // Импорт из файла в книгу
   B.VBProject.VBComponents.Import( 'C:\ModuleTest.bas' );
   E.Application.Run( 'Test' );

   B.Close;
   B := Unassigned;
   E.Quit;
   E := Unassigned;
end;

// Текст файла ModuleTest.bas
'Attribute VB_Name = "ModuleTest"
Public Sub Test()
   MsgBox( "Этот модуль вставили из текстового файла" )
End Sub

// Если раскомментировать первую строчку, то при добавлении текста из файла
// как обычный модуль, имя модуля будет ModuleTest

// Способ четвертый (вставка из файла)
uses
  {...,} ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  E, B: OleVariant;
  i: OleVariant;
begin
   E := CreateOleObject( 'Excel.Application' );
   B := E.Workbooks.Add;
   E.Visible := true;
   i := E.VBE.ActiveVBProject.VBComponents.Count;
   E.VBE.ActiveVBProject.VBComponents.Add( 1 );
   // Добавляем в модуль книги код на VB
   B.VBProject.VBComponents.Item( i+1 ).CodeModule.AddFromFile( 'C:\ModuleTest.bas' );
   // Добавляем то же самое в код листа
   B.VBProject.VBComponents.Item( 'Лист1' ).CodeModule.AddFromFile( 'C:\ModuleTest.bas' );
   E.Application.Run( 'Test' );
   E.Application.Run( 'Лист1.Test' );

   B.Close;
   B := Unassigned;
   E.Quit;
   E := Unassigned;
end;

// Текст файла ModuleTest.bas
'Attribute VB_Name = "ModuleTest"
Public Sub Test()
   MsgBox( "Этот модуль вставили из текстового файла" )
End Sub

// Если раскомментировать первую строчку, то при добавлении текста из файла
// как обычный модуль, имя модуля будет ModuleTest

// Чтобы при создании макроса не вылетала ошибка, нужно разрешить программный доступ к среде VB.
// Как это сделать? - В разных версиях Excel по-разному
// В ранних версиях: пункт меню Сервис -> Макрос -> Безопасность -> Вкладка надежные издатели ->
// поставить галку "Доверять доступ к Visual Basic Project".
// В Excel 2010: Файл -> Параметры -> Центр управления безопасностью -> кнопка "Параметры центра управления безопасностью..." ->
// Параметры макросов -> поставить галку "Доверять доступ к объектной модели проектов VBA".


Как подключиться к запущенному экземпляру Excel?

function CheckRun(Obj: WideString; var Excel: OleVariant): Boolean;
begin
   try
      // В Windows7 этот код валится под отладчиком,
      // но без отладчика работает нормально
      Excel := GetActiveOleObject(Obj);
      Result := True;
   except
      Result := False;
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Excel: OleVariant;
begin
   if CheckRun('Excel.Application', Excel) then
   begin
      Excel.WorkBooks.Open('d:\1.xlsx');
      Excel.Visible := True;
   end;
end;


Как закрыть книгу без сохранения (с подавлением диалогового окна Excel)?

var
  E: OleVariant;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if not VarIsEmpty(E) then
   begin
      E.DisplayAlerts := False;
      E.Quit;
      E := Unassigned;
   end;
end;


Как создать пустую рабочую книгу в Excel?

var
  E: OleVariant;

procedure TForm1.Button1Click(Sender: TObject);
begin
   E.WorkBooks.Add;
end;


Как задать количество листов в новой книге?

var
  E: OleVariant;

procedure TForm1.Button1Click(Sender: TObject);
begin
   E.SheetsInNewWorkbook := 10; // от 1 до 255
   E.WorkBooks.Add;
end;


Как выделить один или несколько листов в книге?

var
  E: OleVariant;

// Способ первый - выделить один лист
procedure TForm1.Button1Click(Sender: TObject);
begin
   E.Sheets[1].Select(True);
end;

// Способ второй - выделить несколько листов 
procedure TForm1.Button1Click(Sender: TObject);
begin
   E.ActiveWorkbook.Sheets[VarArrayOf([1, 2, 3])].Select(False);
end;

// Способ третий - выделить несколько листов в цикле 
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
   for i := 1 to 3 do
      E.Sheets[i].Select(False);
end;

При использовании материала - ссылка на сайт обязательна