RAD Studio 10 Seattle Update 1
Delphi 10 Seattle Web Install (includes Update 1)
C++Builder 10 Seattle Web Install (includes Update 1)
RAD Studio 10 Seattle Web Install (includes Update 1)
Как видите, программисты компании Embarcadero трудились над развитием Delphi в стиле «ни дня без строчки», т.е. «ни года без релиза». Для сравнения компания Borland за 13 лет (с 1995-го по 2008-й), если не считать «мертворожденных» Kylix и Delphi 8.NET, были сделаны всего 10 резов Delphi. Хотя авторство Delphi 2009 спорно, т.к. эта версия была выпущена Embarcadero всего через несколько месяцев после покупки компании Borland. По большому счету, не важно, какая компания разрабатывает Delphi (скорбим только о Borland). Важно то, чтобы команда разработчиков Delphi дружной толпой, не снижая набранного темпа, продолжила работу над своим проектом под крышей Idera, а компания Idera уделяла больше внимания и средств на дальнейшее развитие и продвижение Delphi.
Этот способ позволяет программным образом управлять реакцией на щелчок мыши по объектам в предварительном просмотре и ограничивается только фантазией программиста/пользователя и возможностями языка программирования.
Например, если в скрипте написать «Memo.URL := ‘@5’;», то свойство Memo.Kind будет равно hkPageNumber, а Memo.Value равно «5» и по клику мышкой по нему в предварительном просмотре отчета будет сделан переход на 5-ю страницу.
В приведенном выше списке варианты экспорта расположены в порядке возрастания размера получаемого файла, а значит в порядке убывания ценности в рамках поставленной задачи. Поэтому мой выбор тогда пал на RareFind FastReport Export Filters. Но к моему сожалению, эта библиотека повторила судьбу многих библиотек для Delphi — она давно «умерла» (последняя версия вышла в феврале 2006). Я думаю, что в наше время и на перспективу стоит рассматривать только экспорт входящий в поставку FastReport, т.к. он «умрет» только вместе с FastReport.
Версия FastReport | EmbeddedFonts=False | EmbeddedFonts=True | Увеличение в, раз |
4.11 | 2 367 | 520 294 | 220 |
4.15 | 2 357 | 80 933 | 34 |
5.04 | 2 351 | 77 905 | 33 |
Размер полученного файла очень сильно зависит от встраиваемого шрифта. Например, если в этом шаблоне «Arial» заменить на «Times New Roman», то размер PDF-файла вырастет на 1%, а если «Arial» заменить на «Forte», то уменьшится в 10 раз.
Версия FastReport | EmbeddedFonts=False | EmbeddedFonts=True | Увеличение в, раз |
4.11 | 13 316 | 9 762 210 | 733 |
4.15 | 13 386 | 750 136 | 56 |
5.04 | 13 307 | 730 183 | 55 |
Потом у FastReports, Inc был договор с Embarcadero Technologies, Inc о включении FastReport в качестве штатного генератора в Embarcadero RAD Studio XE2. Затем последовали выпуск FastReport RAD Edition, FastReport FMX, FastReport Mono и других продуктов… Итак, не сложно догадаться, разработчикам компании было не до FastReport VCL 5. И вот, согласно народной мудрости «Обещанного три года ждут» (с 2011-го по 2014-й), читаю:Мы приняли решение перенести релиз FastReport VCL 5 на начало 2011-го года. Работы над FastReport VCL v.5 и FastCube VCL v.2 повлекли за собой серьёзные внутренние архитектурные изменения обоих продуктов (в том числе — для обеспечения бесшовной совместимости), в силу которых альфа-версия FastReport VCL v.5 отправлена на доработку. Мы приносим извинения за перенос сроков выпуска продукта.
Надеюсь, что «Новые иконки в окне предпросмотра и в Дизайнере отчетов» — это не основное новшество в FastReport VCL 5. На следующей неделе обновлю свою версию FastReport 4 до 5-ки и узнаю, так ли это. Обещаю написать об этом в апреле (год на всякий случай не называю).«Рады сообщить вам, что новая долгожданная версия FastReport VCL 5 выпущена!
Рассылка специально идёт 2 апреля — ведь это не шутка!
Обратите внимание на полный список нововведений:
…
Если вы ещё не попробовали FastReport 5 — воспользуйтесь нашим спецпредложением для наших клиентов на обновление до 5й версии: http://cp.fast-report.com/upgrades
P.S. FastReports, Inc, спасибо за долгожданный релиз FastReport VCL 5! Извините, если слишком резко высказал свои мысли.
qInsertResearchData.Params[5].SetBlobData(aData, Length(aData) * SizeOf(aData[0]))
Чтение массива из поля типа TBlobField тоже можно записать коротко:
// Установка размера динамического массива aData
SetLength(aData, qResearchDATA.BlobSize div SizeOf(aData[0]));
// Запись содержимого поля qResearchDATA типа TBlobField в массив aData
qResearch.GetBlobFieldData(qResearchDATA.FieldNo, TBlobByteData(aData))
Т.к. размер массива я устанавливаю равным размеру содержимого BLOB-поля, то для исключения лишних проверок в GetBlobFieldData я заменил вызов этого метода на свой код и теперь запись содержимого поля qResearchDATA типа TBlobField в массив aData выглядит так:
With qResearch.CreateBlobStream(qResearchDATA, bmRead) do
Try
ReadBuffer(aData[0], qResearchDATA.BlobSize);
Finally
Free;
End;
Var
aData: Array of Integer;
Процедура записи динамического массива в базу данных получилась примерно такая:
Var
ms: TMemoryStream;
…
begin
…
Try
ms := TMemoryStream.Create;
// Запись содержимого массива aData в поток ms
ms.WriteBuffer(aData[0], Length(aData) * SizeOf(aData[0]));
// Запись содержимого потока ms в параметр query для вставки данных
qInsertResearch.Params[5].LoadFromStream(ms, ftBlob);
Finally
ms.Free;
End;
…
А процедура чтения массива из базы данных не сложнее процедуры записи:
Var
ms: TMemoryStream;
…
begin
…
Try
ms := TMemoryStream.Create;
// Запись содержимого поля qResearchDATA типа TBlobField в поток ms
qResearchDATA.SaveToStream(ms);
// Установка размера динамического массива aData
SetLength(aData, ms.Size div SizeOf(aData[0]));
ms.Position := 0;
// Запись содержимого потока ms в массив aData
ms.ReadBuffer(aData[0], ms.Size);
Finally
ms.Free;
End;
…
Теперь на запись/чтение нескольких миллионов записей моя программа тратит секунду. Вместо размера первого элемента массива SizeOf(aData[0]) вы можете использовать размер типа элементов массива (для приведенного мной примера — SizeOf(Integer)). Но такой вариант кода будет менее универсальным, т.к. будет зависеть от используемого типа данных.
P.S. При использовании такого способа хранения данных не забывайте, что размер некоторых типов данных зависит от операционной системы, для которой скомпилирована программа. Иначе информация, которую прочтет из базы данных ваша 64-битная программа перекомпилированная из 32-битной, вас неприятно удивит.
История развивается по спирали, а пони бегает по кругу… |
О, XEE! Легкой перестановкой букв мы получаем название первой версии Delphi — «Delphi.EXE». Круг замкнулся… 🙂
С появлением MS Excel 2007 на смену привычного XLS-файла пришли сразу три формата:
Наиболее интересным из них является формат XLSB — Excel Binary Workbook. В отличие от других форматов Excel 2007-2010, он хранит данные не в виде XML, а является двоичным. Это дает существенные преимущества при работе с большими таблицами, т.к. бинарные файлы занимают меньше места на диске и читаются/записываются быстрее.
Ни одна из библиотек для работы с файлами Excel в Delphi не поддерживает XLSB-формат. Например, XLSReadWrite поддерживает только XLSX, а авторы TMS FlexCel вообще не могут сказать, когда у них будет поддержка формата Excel 2007 и будет ли вообще. Поэтому, что бы конвертировать файлы Excel в XLSB-формат необходимо использовать OLE:
Var
xls: OleVariant;
…
Const
// formats in Excel 2007-2010
xlExcel12 = 50; // XLSB
xlOpenXMLWorkbook = 51; // XLSX
xlOpenXMLWorkbookMacroEnabled = 52; // XLSM
xlExcel8 = 56; // XLS (export to Excel 97-2003)
…
Procedure XYZ.ConvertFilesToXLSB(slFiles: TStringList);
Var
iFile: Integer;
begin
Try
Try
xls := CreateOleObject(‘Excel.Application’);
xls.DisplayAlerts := False;
If StrToFloat(StringReplace(xls.Version, ‘.’, DecimalSeparator, [])) < 12
then WriteToLog(‘Error! Requires Excel 2007/2010’)
else for iFile := 0 to slFiles.Count-1 do
ConvertToXLSB(slFiles[iFile]);
Finally
xls.Quit;
xls := UnAssigned;
End;
Except
on E: Exception do
WriteToLog(E.Message);
End;
end;
Где ConvertToXLSB:
Procedure XYZ.ConvertToXLSB(sFileName: String);
Var
sFileNameTo: String;
begin
sFileName := ExpandFileName(sFileName);
sFileNameTo := ChangeFileExt(sFileName, ‘.xlsb’);
Try
Try
xls.Workbooks.Open(sFileName);
xls.ActiveWorkbook.SaveAs(Filename := sFileNameTo, FileFormat := xlExcel12);
Finally
xls.Workbooks.Close;
End;
Except
on E: Exception do
WriteToLog(E.Message);
End;
end;
Думаю, что код простой и комментировать нечего. Остановлюсь только на строке проверки версии MS Excel. xls.Version возвращает номер версии MS Excel в виде строки, где цифры разделены точкой (например, «11.0» для Excel 2003, «12.0» для Excel 2007…), поэтому, чтобы получить номер версии в виде числа его необходимо преобразовать следующим способом:
StrToFloat(StringReplace(xls.Version, ‘.’, DecimalSeparator, []))