Bruce, I’ve used the Axolot XLSReadWriteII component for going on 10 years now. It’s been very good, and their support forums (while lite on content) seem to be monitored pretty well. The XLSReadWriteII2 version is blindingly fast, and supports all sorts of things like charts and graphics, named ranges, adding formulas on the fly, cell formatting (including borders and shading, merging cells, vertical and horizontal alignment, auto-width column sizing, and so forth).
I haven’t upgraded to the latest version (we’re still using XLSReadWriteII2) because we can still use the Excel XP format files, and I haven’t used the XLSMini at all. I can say really good things about the full product, though; in fact, I just used it for a couple of database export things this past week.
If you decide to go that route, I have a bunch of notes about how to do different things that might be useful; if you want them, drop me a note. I also have a Delphi 2007 app that just shows how to do different formatting and alignments; I actually reproduced an existing, fairly complex report in Excel complete with all of the formats, borders, etc. that I’d be glad to let you have as well.
DISCLAIMER: I have no connection with Axolot or any of their employees. I’m just a very happy customer who learned of the product at a previous job, and was impressed enough to buy it when I started my current one.
unit uRPAvitoImport;
interface
uses
System.SysUtils, System.Classes, IdContext, IdCustomHTTPServer, FireDAC.Stan.Intf,
FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, Data.DB,
FireDAC.Comp.DataSet, FireDAC.Comp.Client,
//
Windows, Messages, Variants, Graphics, Controls, Forms, Dialogs, Grids,
StdCtrls, ComObj;
type
TRPAvitoImport = class(TDataModule)
private
{ Private declarations }
// region
function getRegionID(aName: string): Integer;
function insertRegion(aName: string): integer;
// city
function getCityID(aName: string; aRegionID: integer): Integer;
function insertCity(aName: string; aRegionID: integer): integer;
// category
function getCategoryID(aName: string): Integer;
function insertCategory(aName, aIDParent: string): integer;
function isCategory(aName: string): boolean;
// users
function GetUsersID(aPhone: string): integer;
function GetUserKeyWords(aID: integer): string;
procedure UpdateUserKeyWords(aID: integer; aKeyWords: string);
// users_has_categories
function GetUsersHasCategoriesID(aUsersID, categoriesID: integer): boolean;
procedure InsertUsersHasCategories(aUsersID, categoriesID: integer; aUserDescription: string);
procedure UpdateUsersHasCategories(aUsersID, categoriesID: integer; aUserDescription: string);
public
{ Public declarations }
procedure Execute();
end;
implementation
{%CLASSGROUP ‘Vcl.Controls.TControl’}
{$R *.dfm}
uses
IOUtils, uDB, uCommon;
{ TRPAvitoImport }
const
xlCellTypeLast = $000000B;
procedure TRPAvitoImport.Execute;
procedure parseParams(aParams: string; var aCategory: string; var aSubCategory: string);
var
sa, sa1, sa2: TArray<string>;
begin
sa := aParams.Split([‘=’]);
if length(sa) > 1 then
aCategory := stringReplace(sa[1], ‘, Тип услуги’, », [rfReplaceAll]);
if length(sa) > 2 then
aSubCategory := sa[2];
end;
var
e, sheet: OLEVariant;
r: integer;
c: integer;
j: integer;
i: Integer;
rawPhone: string;
contactName: string;
regionName: string;
cityName: string;
adress: string;
description: string;
params: string;
keywords: string;
subCategoryName: string;
categoryName: string;
phone: string;
idRegion: Integer;
idCity: Integer;
idCategory: integer;
idUser: integer;
currKeyWords: string;
filePath: string;
idSubCategory: Integer;
begin
e := CreateOleObject(‘Excel.Application’);
e.DisplayAlerts := false; //отключаем запросы Excel
e.Visible := false;
filePath := ‘avito_Orenburg_20180420.xls’;
if TFile.Exists(ExtractFilePath(Application.ExeName) + filePath) then
begin
e.Workbooks.Open(ExtractFilePath(Application.ExeName) + filePath);
sheet := e.Workbooks[ExtractFileName(filePath)].WorkSheets[1];
i := 2; // first row
j := e.ActiveCell.SpecialCells(xlCellTypeLast).Row; // last row
while i <> j do
begin
rawPhone := sheet.cells[i, 5];
contactName := sheet.cells[i, 7];
regionName := sheet.cells[i, 8];
cityName := sheet.cells[i, 9];
adress := sheet.cells[i, 12];
description := sheet.cells[i, 13]; //users_has_categories
keywords := sheet.cells[i, 3]; // users_has_categories
params := sheet.cells[i, 18];
parseParams(params, categoryName, subCategoryName);
// ———— INSERTION IN DB
// — region
idRegion := getRegionID(regionName);
if idRegion = —1 then
idRegion := insertRegion(regionName);
// — city
idCity := getCityID(cityName, idRegion);
if idCity = —1 then
idCity := insertCity(cityName, idRegion);
// insert in users
phone := TCommon.TryGetUserPhone(rawPhone);
if (phone <> ») //
then
begin
idUser := getUsersID(phone);
if idUser = —1 then
begin
TCommon.InsertUser( //
phone, //
‘password’, //
3, // aUserStatusCode // with status freezed
2, // aRoleCode
contactName, //
adress, //
1, // Russia
idRegion, //
idCity); //
idUser := db.GetLastID;
end;
end;
// update user keyWords
currKeyWords := GetUserKeyWords(idUser);
if currKeyWords = » then
currKeyWords := keywords
else
currKeyWords := currKeyWords + ‘,’ + keywords;
UpdateUserKeyWords(idUser, currKeyWords);
// insert in categories
idCategory := getCategoryID(categoryName);
if idCategory = —1 then
idCategory := insertCategory(categoryName, »);
//
idSubCategory := getCategoryID(subCategoryName);
if (subCategoryName <> ») and (idSubCategory = —1) then
idSubCategory := insertCategory(subCategoryName, idCategory.toString);
// insert in user_has_categories
if GetUsersHasCategoriesID(idUser, idCategory) then
UpdateUsersHasCategories(idUser, idCategory, description)
else
InsertUsersHasCategories(idUser, idCategory, description);
inc(i);
end;
end;
e.ActiveWorkBook.Close;
e.Quit;
e := Unassigned;
end;
function TRPAvitoImport.getCategoryID(aName: string): Integer;
var
q: TFDquery;
begin
result := —1;
q := TFDquery.Create(Self);
try
with q do
begin
Connection := db.FDConnection;
sql.Text := ‘SELECT * FROM sarafan_db.categories where name=:name;’;
params.ParamValues[‘name’] := aName;
Disconnect();
Open();
if not FieldByName(‘id’).IsNull then
result := FieldByName(‘id’).AsInteger;
Close();
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.getCityID(aName: string; aRegionID: integer): Integer;
var
q: TFDquery;
begin
result := —1;
q := TFDquery.Create(Self);
try
with q do
begin
Connection := db.FDConnection;
sql.Text := ‘SELECT * FROM sarafan_db.city where name=:name and region_id=:region_id;’;
params.ParamValues[‘name’] := aName;
params.ParamValues[‘region_id’] := aRegionID;
Disconnect();
Open();
if not FieldByName(‘id’).IsNull then
result := FieldByName(‘id’).AsInteger;
Close();
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.getRegionID(aName: string): Integer;
var
q: TFDquery;
begin
result := —1;
q := TFDquery.Create(Self);
try
with q do
begin
Connection := db.FDConnection;
sql.Text := ‘SELECT * FROM sarafan_db.region where name=:name and country_id=1; # Russia’;
params.ParamValues[‘name’] := aName;
Disconnect();
Open();
if not FieldByName(‘id’).IsNull then
result := FieldByName(‘id’).AsInteger;
Close();
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.getUserKeyWords(aID: integer): string;
var
q: Tfdquery;
begin
result := »;
q := Tfdquery.Create(nil);
try
with q do
begin
Connection := DB.FDConnection;
sql.Text := ‘SELECT keywords FROM sarafan_db.users where id=:id;’;
params.ParamValues[‘id’] := aID;
Disconnect();
Open();
if not FieldByName(‘keywords’).IsNull then
result := FieldByName(‘keywords’).AsString;
Close();
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.GetUsersHasCategoriesID(aUsersID, categoriesID: integer): boolean;
var
q: Tfdquery;
begin
q := Tfdquery.Create(nil);
try
with q do
begin
Connection := DB.FDConnection;
sql.Text := ‘SELECT * FROM sarafan_db.users_has_categories where users_id=:users_id and categories_id=:categories_id;’;
params.ParamValues[‘users_id’] := aUsersID;
params.ParamValues[‘categories_id’] := categoriesID;
Disconnect();
Open();
result := not IsEmpty;
Close();
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.getUsersID(aPhone: string): integer;
var
q: Tfdquery;
begin
result := —1;
q := Tfdquery.Create(nil);
try
with q do
begin
Connection := DB.FDConnection;
sql.Text := ‘SELECT * FROM sarafan_db.users where phone=:phone;’;
params.ParamValues[‘phone’] := aPhone;
Disconnect();
Open();
if not FieldByName(‘id’).IsNull then
result := FieldByName(‘id’).AsInteger;
Close();
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.insertCategory(aName, aIDParent: string): integer;
var
q: TFDquery;
begin
q := TFDquery.Create(Self);
try
with q do
begin
Connection := db.FDConnection;
if aIDParent = » then
begin
sql.Text := ‘INSERT INTO `sarafan_db`.`categories` (`name`) VALUES (:name);’;
params.ParamValues[‘name’] := aName;
end
else
begin
sql.text := ‘INSERT INTO `sarafan_db`.`categories` (`name`, `idParent`) VALUES (:name, :idParent);’;
params.ParamValues[‘name’] := aName;
params.ParamValues[‘idParent’] := aIDParent;
end;
ExecSQL;
result := db.GetLastID;
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.insertCity(aName: string; aRegionID: integer): integer;
var
q: TFDquery;
begin
q := TFDquery.Create(Self);
try
with q do
begin
Connection := db.FDConnection;
sql.Text := ‘INSERT INTO `sarafan_db`.`city` (`name`, `region_id`) VALUES (:name, :region_id);’;
params.ParamValues[‘name’] := aName;
params.ParamValues[‘region_id’] := aRegionID;
ExecSQL;
result := db.GetLastID;
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.insertRegion(aName: string): integer;
var
q: TFDquery;
begin
q := TFDquery.Create(Self);
try
with q do
begin
Connection := db.FDConnection;
sql.Text := ‘INSERT INTO `sarafan_db`.`region` (`name`, `country_id`) VALUES (:name, ‘‘1’‘);’; // country Russia
params.ParamValues[‘name’] := aName;
ExecSQL;
result := db.GetLastID;
end;
finally
q.Free;
end;
end;
procedure TRPAvitoImport.InsertUsersHasCategories(aUsersID, categoriesID: integer; aUserDescription: string);
var
q: Tfdquery;
begin
q := Tfdquery.Create(nil);
try
with q do
begin
Connection := DB.FDConnection;
sql.Text := ‘INSERT INTO `sarafan_db`.`users_has_categories` ‘ + //
‘(`users_id`, `categories_id`, `userDescription`) ‘ + //
‘VALUES (:users_id, :categories_id, :userDescription);’;
params.ParamValues[‘users_id’] := aUsersID;
params.ParamValues[‘categories_id’] := categoriesID;
params.ParamValues[‘userDescription’] := aUserDescription;
ExecSQL;
end;
finally
q.Free;
end;
end;
function TRPAvitoImport.isCategory(aName: string): boolean;
begin
//
end;
procedure TRPAvitoImport.UpdateUserKeyWords(aID: integer; aKeyWords: string);
var
q: Tfdquery;
begin
q := Tfdquery.Create(nil);
try
with q do
begin
Connection := DB.FDConnection;
sql.Text := ‘UPDATE `sarafan_db`.`users` SET `keywords`=:keywords WHERE `id`=:id;’;
params.ParamValues[‘id’] := aID;
params.ParamValues[‘keywords’] := aKeyWords;
ExecSQL;
end;
finally
q.Free;
end;
end;
//
procedure TRPAvitoImport.UpdateUsersHasCategories(aUsersID, categoriesID: integer; aUserDescription: string);
var
q: Tfdquery;
begin
q := Tfdquery.Create(nil);
try
with q do
begin
Connection := DB.FDConnection;
sql.Text := ‘UPDATE `sarafan_db`.`users_has_categories` SET `userDescription`=:userDescription ‘ + //
‘ WHERE `users_id`=:users_id and`categories_id`=:categories_id;’;
params.ParamValues[‘users_id’] := aUsersID;
params.ParamValues[‘categories_id’] := categoriesID;
params.ParamValues[‘userDescription’] := aUserDescription;
ExecSQL;
end;
finally
q.Free;
end;
end;
end.
Здравствуйте, в этой статье я расскажу Вам, как использовать в своем приложении (программе) на Delphi БД в виде MS Excel. Да да именно MS Excel. Тут ничего сложного нету. Для начала давайте заполним наш лист в MS Excel. Первая строка в каждом столбце всегда будет брать наше приложение как название столбцов, то есть оно не берет название столбцов такое — A, B, C и так далее. Так что в первсой строке столбца А и столбца B я написал ФИО и Оценка соответственно для каждого столбца. Это и будут наши заголовки, затем ниже я заполнил данные, которые будут в моей БД, ну это фамилии и оценки сами напиши. Так БД у нас готова. Теперь создадим к ней подключение. создается подключение похоже как и в MS Access, так что тут ничего сложного нету. На форме у нас старые компоненты это
- TDBGrid
- TADOQuery
- TADOConnection
- TDataSource
Как связывать эти компоненты я расскажу быстро, так как это уже было сказано мною.
- TADOQuery c TADOConnection в свойстве — Connection
- TDataSource с TADOQuery в свойстве DataSet
- TDBGrid c TDataSource в свойстве DataSource
В TADOConnection установим свойство LongPromt в False. Вроде бы небольшую настройку сделали. Теперь приходим к непосредственному подключени. В свойстве TADOConnection — ConnectionString нажимаем на кнопку «…«, далее у нас появляется окно вида
Нажимаем на кнопку «Build…» и появляется следующее окно
В данном окне выбираем следующего провайдера: Microsoft OLE DB Provider for ODBC Drivers и нажимаем кнопку «Далее>>» и видем следующее окно
В этом окне сразу ставим указатель на «Использовать строку подключения» и нажимаем на кнопку «Сборка«, после чего появляется окно
В этом окне переходим на вкладку Источник данных компьютера, в появившемся списке выбираем — Файлы Excel, а точнее жмем левой кнопкой мыши по этой сроке двойным щелчком и в появившемся окне указываем путь к нашей Excel-книги, которую мы создавали. После этого нажимаем на пноку «Ok«. Все подключение у нас готово. Хочу добавить еще, если у Вас файл Excel, где ваша таблица находится лежит в одном каталоге с программой, то в свойстве компонента TADOConnection — ConnectionString будет прописан путь к Вашему Excel-файлу, стерите путь, а оставьте просто имя Вашего Excel файла с расширением, а в свойстве DefaultDataBase этого же компонента, напишите имя вашего Excel-файла с расширением. Тогда при запуске вашего приложения, не будет возникать ошибок с неправильно заданым путем к вашей БД. Далее в TDBGrid нажмем по нему двойным щелчком и в появившемся окне создаим 2 строки, это наши столбцы будут. А создаются они путем нжатия в данном окне на кнопку «Add New (Ins)«. Далее выделив кажду строку в свойстве FieldName для первой строки напишем — ФИО, так как в Excel-файле я именно так написал в первую строку название столбца (для ячейки A1 я так написал), а выделив вторую строку, что создали в TDBGrid, в свойстве FieldName напишем — Оценка, так как именно я такое название столбца написал (в ячейке А2 я так написал). Все теперь нам можно активировать наши данные. Для этого на событие главной формы — OnCreate напишем следующее
procedure TForm1.FormCreate(Sender: TObject); begin try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM [Лист1$]'); ADOQuery1.Active:=True; except on e:Exception do end; end;
Как видите все тот же запрос, только вместо имя таблица, как у нас было в MS Access мы указываем имя листа нашего в Excel, заключив его в квадратные скобки и поставив в конце знак $. Как видите ничего сложного нету. В следующей статье про БД MS Excel я расскажу как вставлять данные, редактировать и так далее.