Possible Duplicate:
Is COM broken in XE2, and how might I work around it?
The VCL applications referred to call EXCEL via "early binding" as instructed in Deborah Pate's Automating Excel Pages(http://www.djpate.freeserve.co.uk/AutoExcl.htm). Specifically, the applications modify the font of certain characters of two cells.
The application compiled using Delphi XE runs as expected. However, the application compiled using Delphi XE2 gives access violation in the second iteration of for-loop. I mean, if I do not use for-loop, and modify the two cells manually, the application runs as expected. I have no clue what the cause could be. Any help will be appreciated!
The EXCEL type library .pas files are generated by DXE and DXE2, respectively.
The source codes of the main unit are pasted below for your convenience. The whole directories are packaged into .zip files and can be downloaded here.
http://www.fileserve.com/file/HxyZw9w/TestExcelCharacters_1_DXE.zip
http://www.fileserve.com/file/pd8Q8qm/TestExcelCharacters_1_DXE2.zip
Source code in Delphi XE VCL application
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
ComObj, ActiveX, Excel_TLB;
procedure TForm1.FormCreate(Sender: TObject);
var
lcid: integer;
AppWasRunning: boolean;
Result: HResult;
Unknown: IUnknown;
Excel: _Application;
WBk: _Workbook;
WS: _WorkSheet;
l_RIdxStr, l_CIdxStr: string;
l_CharStartIdx, l_CharLength: Integer;
l_XlsSpinLine: string;
I: Integer;
begin
lcid := LOCALE_USER_DEFAULT;
AppWasRunning := False;
Result := GetActiveObject(CLASS_ExcelApplication, nil, Unknown);
if (Result = MK_E_UNAVAILABLE) then
begin
Excel := CoExcelApplication.Create
end
else
begin
OleCheck(Result);
OleCheck(Unknown.QueryInterface(_Application, Excel));
AppWasRunning := True;
end;
Excel.Visible[lcid] := True;
// Create empty Excel workbook
WBk := Excel.Workbooks.Add(EmptyParam, LCID);
WS := WBk.Worksheets.Item['Sheet1'] as _Worksheet;
WS.Activate(LCID);
WS.Range['D5', 'D5'].Value[xlRangeValueDefault] := 'Ru12.11256 Ru2-1.22587';
WS.Range['D6', 'D6'].Value[xlRangeValueDefault] := 'Ru10.11256 Ru2-0.22587';
WS.Range['D5', 'D5'].EntireColumn.AutoFit;
for I := 0 to 1 do
begin
l_RIdxStr := 'D' + IntToStr(5 + I);
l_CIdxStr := l_RIdxStr;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[1, 2].Font.Superscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[1, 2].Font.Subscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[3, 1].Font.Subscript := True;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[4, 7].Font.Superscript := True;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[11, 1].Font.Superscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[11, 1].Font.Subscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[12, 2].Font.Superscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[12, 2].Font.Subscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[14, 1].Font.Subscript := True;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[15, 8].Font.Superscript := True;
end;
end;
end.
Source code in Delphi XE2 VCL application
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
ComObj, ActiveX, Excel_TLB;
procedure TForm1.FormCreate(Sender: TObject);
var
lcid: integer;
AppWasRunning: boolean;
Result: HResult;
Unknown: IUnknown;
Excel: _Application;
WBk: _Workbook;
WS: _WorkSheet;
l_RIdxStr, l_CIdxStr: string;
l_CharStartIdx, l_CharLength: Integer;
l_XlsSpinLine: string;
I: Integer;
begin
lcid := LOCALE_USER_DEFAULT;
AppWasRunning := False;
Result := GetActiveObject(CLASS_ExcelApplication, nil, Unknown);
if (Result = MK_E_UNAVAILABLE) then
begin
Excel := CoExcelApplication.Create
end
else
begin
OleCheck(Result);
OleCheck(Unknown.QueryInterface(_Application, Excel));
AppWasRunning := True;
end;
Excel.Visible[lcid] := True;
// Create empty Excel workbook
WBk := Excel.Workbooks.Add(EmptyParam, LCID);
WS := WBk.Worksheets.Item['Sheet1'] as _Worksheet;
WS.Activate(LCID);
WS.Range['D5', 'D5'].Value[xlRangeValueDefault] := 'Ru12.11256 Ru2-1.22587';
WS.Range['D6', 'D6'].Value[xlRangeValueDefault] := 'Ru10.11256 Ru2-0.22587';
WS.Range['D5', 'D5'].EntireColumn.AutoFit;
for I := 0 to 1 do
begin
l_RIdxStr := 'D' + IntToStr(5 + I);
l_CIdxStr := l_RIdxStr;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[1, 2].Font.Superscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[1, 2].Font.Subscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[3, 1].Font.Subscript := True;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[4, 7].Font.Superscript := True;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[11, 1].Font.Superscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[11, 1].Font.Subscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[12, 2].Font.Superscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[12, 2].Font.Subscript := False;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[14, 1].Font.Subscript := True;
WS.Range[l_RIdxStr, l_CIdxStr].Characters[15, 8].Font.Superscript := True;
end;
end;
end.