What I need to do is read table details from excel file and want to create .pas file from it.
For the read-write purpose, I've used record type in delphi 7.
Here is the code what I've tried till now:
unit fImportFile;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
tSourceFile: TEdit;
dlgSourceFile: TOpenDialog;
btnImport: TButton;
procedure tSourceFileClick(Sender: TObject);
procedure btnImportClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TTableDetails = record
fTableName: String;
end;
TFieldDetails = record
fFieldName: String;
fType: String;
fShortAlias: String;
fLongAlias: String;
fDomainName: String;
fFieldAttributes:TStringList;
fComments: String;
end;
var
Form1: TForm1;
implementation
uses ComObj, uFileGeneration;
{$R *.dfm}
procedure TForm1.tSourceFileClick(Sender: TObject);
begin
with dlgSourceFile do
begin
FileName := tSourceFile.Text;
if ExtractFilePath(FileName) <> '' then
InitialDir := ExtractFilePath(FileName);
if Execute then
if FileName <> '' then
tSourceFile.Text := FileName;
end;
end;
procedure TForm1.btnImportClick(Sender: TObject);
const
cEndOfTables = '';
cTable = 'Table';
cTableCell = 2;
cTableNameCell = 3; // TableNameField
cFieldName = 'Field Name';
var
Excel: OleVariant;
iRow: Integer;
aTableDetails: TTableDetails;
aFieldDetails: Array of TFieldDetails;
fieldCount: Integer;
iTableName, FldWithChar, FldWithoutChar: String;
FldList, WordList: TStringList;
FieldName: String;
begin
FldList := nil;
WordList := nil;
try
Excel := CreateOleObject('Excel.Application');
Excel.Visible := False;
Excel.Workbooks.Open(tSourceFile.Text);
iRow := 1;
while (Excel.ActiveSheet.Cells[iRow,cTableCell].Value <> '') do //To exit loop when the excel record will read blank TableName
begin
if (Excel.ActiveSheet.Cells[iRow,cTableCell].Value = cTable) then
begin
iTableName := Excel.ActiveSheet.Cells[iRow,cTableNameCell].Value;
if (iTableName = '') then
begin
ShowMessage('Table Name cannot be blank.');
exit;
end;
aTableDetails.fTableName := iTableName;
Inc(iRow);
fieldCount := 0;
FldList := TStringList.Create;
WordList := TStringList.Create;
ShowMessage('1 -- iRow --> ' + IntToStr(iRow));
while (Excel.ActiveSheet.Cells[iRow,cTableCell].Value <> '') AND
(Excel.ActiveSheet.Cells[iRow,cTableCell].Value <> cTable) do //Will create record until another table will found
begin
ShowMessage('2 -- Excel.ActiveSheet.Cells[iRow,cTableNameCell].Value = ' + Excel.ActiveSheet.Cells[iRow,cTableNameCell].Value);
FieldName := Excel.ActiveSheet.Cells[iRow,cTableNameCell].Value;
aFieldDetails[fieldCount].fFieldName := FieldName; //ERROR LINE
ShowMessage('3 -- iRow --> ' + IntToStr(iRow));
FldWithChar := aFieldDetails[fieldCount].fFieldName;
FldWithoutChar := NameWithoutAnyChar(FldWithChar, WordList);
FldList.Add(FldWithChar + '=' + FldWithoutChar);
WordList.Clear;
ShowMessage('4 -- iRow --> ' + IntToStr(iRow));
if (aFieldDetails[fieldCount].fFieldName = '') then
begin
ShowMessage('Field Name cannot be blank. TableName: '+iTableName);
exit;
end;
aFieldDetails[fieldCount].fType := Excel.ActiveSheet.Cells[iRow,3].Value;
aFieldDetails[fieldCount].fShortAlias := Excel.ActiveSheet.Cells[iRow,4].Value;
aFieldDetails[fieldCount].fLongAlias := Excel.ActiveSheet.Cells[iRow,5].Value;
aFieldDetails[fieldCount].fDomainName := Excel.ActiveSheet.Cells[iRow,6].Value;
aFieldDetails[fieldCount].fFieldAttributes.CommaText := Excel.ActiveSheet.Cells[iRow,7].Value;
aFieldDetails[fieldCount].fComments := Excel.ActiveSheet.Cells[iRow,8].Value;
Inc(fieldCount);
Inc(iRow);
end;
//Once new table row will be fouund it will call below method to create a dataview file for current table
ShowMessage('5 -- iRow --> ' + IntToStr(iRow));
GenerateDataviewFiles(aTableDetails, aFieldDetails, FldList, fieldCount-1);
ShowMessage('6 -- iRow --> ' + IntToStr(iRow));
end; //End of If condition
end; //End of outer most while loop
finally
FreeAndNil(WordList);
FreeAndNil(FldList);
Excel.Workbooks.Close;
Excel.Quit;
Excel := Unassigned;
end;
end;
end.
I've commented //ERROR LINE where I'm getting error for access violation.
What I'm doing here is, creating array of TFieldDetails and wanted to loop through it in another file.
Please help me through this as I am a new to delphi.
The problem is that you're trying to access an index of aFieldDetails
which is out of bounds. You should set length of a dynamic array before that. Like this:
...
SetLength(aFieldDetails, fieldCount+1);
aFieldDetails[fieldCount].fFieldName := FieldName; //ERROR LINE
...
However, this has a poor performance unless you know how many total fields you have since the beginning. It's because everytime SetLength
gets called, another block of memory is allocated and the whole array is copied to it.
I suggest you to use TList
which tries to keep performance in a good shape even if you don't know how many items are gonna be added to your list.