<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9002454583040968876</id><updated>2011-11-28T02:39:51.331+03:00</updated><category term='MS SQLServer'/><category term='VBA'/><category term='Delphi 2010'/><category term='Internet'/><category term='DataSet'/><category term='e-mail'/><category term='OLE'/><category term='Delphi'/><category term='RAD Studio'/><category term='размышлизмы'/><category term='новости'/><category term='RTTI'/><category term='Oxygene'/><category term='FastReport'/><category term='COM'/><category term='компоненты'/><category term='юмор'/><category term='IDE'/><category term='Borland'/><category term='Pascal'/><category term='MS Word'/><category term='Embarcadero Technologies'/><category term='советы'/><category term='MS Excel'/><title type='text'>ИТ-записки Чорнага кашака</title><subtitle type='html'>Язык программирования самого высокого уровня содержит всего несколько команд для управления программистами</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2703403676322717357</id><published>2011-10-14T10:34:00.000+03:00</published><updated>2011-10-14T10:34:17.937+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='юмор'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><category scheme='http://www.blogger.com/atom/ns#' term='Borland'/><title type='text'>О нумерации версий Delphi</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: right;" trbidi="on"&gt;&lt;span style="font-family: verdana;"&gt;&lt;table border=0&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td align=left&gt;История развивается по спирали, &lt;br /&gt;а пони бегает по кругу...&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Пятничные размышления, на которые натолкнуло письмо одного моего приятеля. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Сначала разработчики Delphi нумеровали версии просто: 1, 2, 3, 4, 5, 6, 7, 8. Затем, с подачи маркетологов Microsoft перешли на нумерацию версий по годам: 2005, 2006, 2007, 2009, 2010. В 2010 году Embarcadero придумала для всех своих продуктов новый бренд - "XE". "XE" - это не "Express Edition" как у Oracle, а два понятия: "X" - гетерогенность платформы (например, доступ к различным базам данных без дополнительных затрат) и "E" - скромное "Embarcadero". Поэтому с 2010 года началась новая эра в нумерации версий Delphi: Delphi XE, Delphi XE2... Что будет дальше? А дальше:&lt;ul&gt;&lt;li&gt;Delphi XE3&lt;/li&gt;&lt;li&gt;Delphi XE4&lt;/li&gt;&lt;li&gt;Delphi XE5&lt;/li&gt;&lt;li&gt;Delphi XE6&lt;/li&gt;&lt;li&gt;Delphi XE7&lt;/li&gt;&lt;li&gt;Delphi XE8&lt;/li&gt;&lt;li&gt;Delphi XE9&lt;/li&gt;&lt;li&gt;Delphi XEA&lt;/li&gt;&lt;li&gt;Delphi XEB&lt;/li&gt;&lt;li&gt;Delphi XEC&lt;/li&gt;&lt;li&gt;Delphi XED&lt;/li&gt;&lt;li&gt;Delphi XEE&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;О, XEE! Легкой перестановкой букв мы получаем название первой версии Delphi - "Delphi.EXE". Круг замкнулся... :)&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2703403676322717357?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2703403676322717357/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2703403676322717357' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2703403676322717357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2703403676322717357'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/10/delphi.html' title='О нумерации версий Delphi'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2971624280721541786</id><published>2011-09-15T10:47:00.006+03:00</published><updated>2011-09-15T10:52:20.148+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE'/><category scheme='http://www.blogger.com/atom/ns#' term='MS Excel'/><title type='text'>Конвертирование XLS/XLSX/XLSM в XLSB</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;С появлением MS Excel 2007 на смену привычного XLS-файла пришли сразу три формата:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;XLSX - стандартный формат файлов Excel 2007-2010 на основе XML;&lt;/li&gt;&lt;li&gt;XLSM - формат Excel 2007-2010 на основе XML с поддержкой макросов (в отличие от XLSX он позволяет сохранять код макросов MS Visual Basic для приложений (VBA) и листы макросов MS Excel 4.0 (XLM));&lt;/li&gt;&lt;li&gt;XLSB - формат двоичных файлов Excel 2007-2010 (BIFF12).&lt;/li&gt;&lt;/ul&gt;Наиболее интересным из них является формат XLSB - Excel Binary Workbook. В отличие от других форматов Excel 2007-2010, он хранит данные не в виде XML, а является двоичным. Это дает существенные преимущества при работе с большими таблицами, т.к. бинарные файлы занимают меньше места на диске и читаются/записываются быстрее.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Ни одна из библиотек для работы с файлами Excel в Delphi не поддерживает XLSB-формат. Например, XLSReadWrite поддерживает только XLSX, а авторы TMS FlexCel вообще не могут сказать, когда у них будет поддержка формата Excel 2007 и будет ли вообще. Поэтому, что бы конвертировать файлы Excel в XLSB-формат необходимо использовать OLE:&lt;br /&gt;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;xls: OleVariant;&lt;br /&gt;...&lt;br /&gt;Const&lt;br /&gt;&amp;nbsp;&amp;nbsp;// formats in Excel 2007-2010&lt;br /&gt;&amp;nbsp;&amp;nbsp;xlExcel12 = 50; // XLSB&lt;br /&gt;&amp;nbsp;&amp;nbsp;xlOpenXMLWorkbook = 51; // XLSX&lt;br /&gt;&amp;nbsp;&amp;nbsp;xlOpenXMLWorkbookMacroEnabled = 52; // XLSM&lt;br /&gt;&amp;nbsp;&amp;nbsp;xlExcel8 = 56; // XLS (export to Excel 97-2003)&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Procedure XYZ.ConvertFilesToXLSB(slFiles: TStringList);&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;iFile: Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls := CreateOleObject('Excel.Application');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls.DisplayAlerts := False;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If StrToFloat(StringReplace(xls.Version, '.', DecimalSeparator, [])) &amp;lt; 12&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then WriteToLog('Error! Requires Excel 2007/2010')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else for iFile := 0 to slFiles.Count-1 do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ConvertToXLSB(slFiles[iFile]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls := UnAssigned;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteToLog(E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;Где ConvertToXLSB:&lt;br /&gt;&lt;br /&gt;Procedure XYZ.ConvertToXLSB(sFileName: String);&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;sFileNameTo: String;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;sFileName := ExpandFileName(sFileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;sFileNameTo := ChangeFileExt(sFileName, '.xlsb');&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls.Workbooks.Open(sFileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls.ActiveWorkbook.SaveAs(Filename := sFileNameTo, FileFormat := xlExcel12);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xls.Workbooks.Close;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteToLog(E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Думаю, что код простой и комментировать нечего. Остановлюсь только на строке проверки версии MS Excel. xls.Version возвращает номер версии MS Excel в виде строки, где цифры разделены точкой (например, "11.0" для Excel 2003, "12.0" для Excel 2007...), поэтому, чтобы получить номер версии в виде числа его необходимо преобразовать следующим способом:&lt;br /&gt;&lt;br /&gt;StrToFloat(StringReplace(xls.Version, '.', DecimalSeparator, []))&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2971624280721541786?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2971624280721541786/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2971624280721541786' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2971624280721541786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2971624280721541786'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/09/delphi-xlsxlsxxlsm-xlsb.html' title='Конвертирование XLS/XLSX/XLSM в XLSB'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-9126537330870590035</id><published>2011-07-18T09:31:00.001+03:00</published><updated>2011-07-18T09:33:24.232+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><category scheme='http://www.blogger.com/atom/ns#' term='e-mail'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet'/><title type='text'>Проверка корректности адреса электронной почты</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Проверить корректность адреса электронной почты очень просто (не только синтаксис, но и его реальное существование). Для этого можно воспользоваться компонентой &lt;a href="http://clevercomponents.com/products/inetsuite/emailvalidator.asp" target=_blank&gt;&lt;b&gt;clEmailValidator&lt;/b&gt;&lt;/a&gt; из библиотеки &lt;a href="http://clevercomponents.com" target=_blank&gt;Clever Internet Suite&lt;/a&gt;. Напишем с ее использованием простую функцию:&lt;br /&gt;&lt;br /&gt;Function ValidateMail(const sAddress: String): Boolean;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;clEV: TclEmailValidator;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;clEV := TclEmailValidator.Create(nil);&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clEV.ValidationLevel := vlMailbox;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clEV.DnsServer :=  '8.8.8.8';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Result := clEV.Validate(sAddress) = vrMailboxOk&lt;br /&gt;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clEV.Free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;Я задал всего лишь два свойства clEmailValidator (остальные можно пропустить). Первое и основное, это &lt;b&gt;ValidationLevel&lt;/b&gt; - метод (уровень) проверки правильности адреса, их пять:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;vlBlacklist&lt;/b&gt; - проверка на вхождение адреса в ваш "чёрный список" (чёрный список хранится у clEmailValidator в свойстве BlackList типа TStrings);&lt;/li&gt;&lt;li&gt;&lt;b&gt;vlSyntax&lt;/b&gt; - проверка синтаксиса (проверяется при помощи шаблона RegEx);&lt;/li&gt;&lt;li&gt;&lt;b&gt;vlDomain&lt;/b&gt; - проверка существования домена (проверяется запросом DNS-информации для почтового домена);&lt;/li&gt;&lt;li&gt;&lt;b&gt;vlSmtp&lt;/b&gt; - проверка доступности почтового сервера (проверяется попыткой установления SMTP-соединения с хостом, указанным в MX-записи DNS);&lt;/li&gt;&lt;li&gt;&lt;b&gt;vlMailbox&lt;/b&gt; - проверка существования почтового ящика (проверяется попыткой отправить SMTP-запрос почтовому серверу с указанием проверяемого адреса в поле "RCPT TO").&lt;/li&gt;&lt;/ol&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Я расположил эти значения в списке по очереди (в порядке) выполнения. Т.е. если вы хотите проверить существование домена, то clEmailValidator выполнит проверки нижнего уровня - сначала на вхождение в чёрный список, потом проверку синтаксиса адреса, а уж затем проверку существования домена.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Проверка корректности с уровнем vlDomain и выше требует активного internet-подключения и у clEmailValidator необходимо задать значение свойству &lt;b&gt;DnsServer&lt;/b&gt;. DnsServer - это IP-адрес name-сервера вашего internet-провайдера. В примере выше я использовал адрес &lt;a href="http://code.google.com/intl/ru/speed/public-dns" target=_blank&gt;Google Public DNS&lt;/a&gt;. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;При желании для уровня vlSmtp (и выше) можно задать имя которое используется в команде "SMTP HELO" (свойство &lt;b&gt;HostName&lt;/b&gt;). А для уровня vlMailbox можно задать еще и адрес электронной почты, который используется в SMTP-запросе свойство &lt;b&gt;EmailFrom&lt;/b&gt;). Я написал "при желании", т.к. у меня проверка корректности работает и без них.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Метод &lt;b&gt;Validate&lt;/b&gt; возвращает уровень, до которого проверка адреса электронной почты выполнилась корректно (vrBlacklistOk, vrSyntaxOk, vrDomainOk, vrSmtpOk, vrMailboxOk) или, если вы совсем ерунду подсунули clEmailValidator, то "vrInvalid".&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-9126537330870590035?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/9126537330870590035/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=9126537330870590035' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9126537330870590035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9126537330870590035'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/07/blog-post.html' title='Проверка корректности адреса электронной почты'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2183823332583496063</id><published>2011-07-06T01:11:00.003+03:00</published><updated>2011-08-14T12:10:17.678+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><title type='text'>Описание у службы Windows</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;При написании очередной службы для MS Windows, меня посетила мысль: "А почему у &lt;b&gt;TService&lt;/b&gt; нет свойства "&lt;b&gt;Description&lt;/b&gt;"?". При этом из своего опыта знаю, что подобное свойство есть у аналогичных компонент: у &lt;b&gt;TNtService&lt;/b&gt; из библиотеки &lt;b&gt;SvCom&lt;/b&gt; и даже у бесплатной компоненты &lt;b&gt;TDDService&lt;/b&gt; от Arno Garrels, а у стандартного &lt;b&gt;TService&lt;/b&gt; его нет даже под Delphi XE. Я понимаю, что описание - это не важно, но служба без описания выглядит на фоне других как-то неполноценно.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Метода для установки описания у TService я не нашел, поэтому ничего другого не оставалось, как добавить описание службе самому.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Оказалось, у MS Windows для этого есть специальная функция - &lt;b&gt;ChangeServiceConfig2&lt;/b&gt; (в advapi32.dll), которая изменяет дополнительные параметры конфигурации службы. Вместо реализации вызова ChangeServiceConfig2 на Delphi я сделал проще – в событии TService.ServiceAfterInstall записал описание службы напрямую в реестр:&lt;/div&gt;&lt;br /&gt;procedure TxyzSvc.ServiceAfterInstall(Sender: TService);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;With TRegistry.Create(KEY_READ or KEY_WRITE) do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RootKey := HKEY_LOCAL_MACHINE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If OpenKey('\SYSTEM\CurrentControlSet\Services\' + Name, False) then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteString('Description', 'XYZ Service');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CloseKey;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2183823332583496063?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2183823332583496063/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2183823332583496063' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2183823332583496063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2183823332583496063'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/07/description-windows-service.html' title='Описание у службы Windows'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-6359133184800426335</id><published>2011-06-13T19:39:00.001+03:00</published><updated>2011-06-13T19:42:50.836+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><title type='text'>ImageEn – кто не успел, тот опоздал</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Год назад компания HiComponents &lt;a href="http://it-blackcat.blogspot.com/2010/06/imageen.html" target=_blank&gt;сделала бесплатной свою библиотеку компонент для работы с картинками – &lt;b&gt;ImageEn&lt;/b&gt;&lt;/a&gt;. Исходные коды, хоть и было обещано, выложены не были, но любой желающий, после несложной регистрации, мог скачать новую версию библиотеки (3.12), скомпилированную под любую версию Delphi и C++Builder и насладиться её мощным функционалом бесплатно.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Но теперь халява закончилась. Права на &lt;a href="http://imageen.com" target=_blank&gt;ImageEn&lt;/a&gt; переданы новозеландской компании &lt;a href="http://www.xequte.com" target=_blank&gt;Xequte Software&lt;/a&gt; и библиотека снова стала платной. Вот такой поворот в условиях лицензии. Взглянув на список продуктов компании (сплошь утилиты для работы с картинками, видео и музыкой), становится очевидной причина смены хозяина. Предполагаю, что для разработки многих продуктов компании используется ImageEn и, после того как ее автор (итальянец Fabrizio) утратил к библиотеке коммерческий интерес, ей просто не дали умереть.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;По заявлению представителя компании Xequte Software они планируют развивать библиотеку и даже задумываются над 64-х битной версией, а над исходными кодами ImageEn по-прежнему трудится Fabrizio.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Со сменой хозяина и лицензии изменились и цены. У Xequte Software лицензия на исходные коды ImageEn и подписка на их бесплатное 12-ти месячное обновление стоит 299.50$ (на одного разработчика). Эта цена почти вдвое больше, чем у HiComponents (175$)! А лицензия на скомпилированную версию ImageEn не продается(у HiComponents она стоила 59$), но её владельцы могут приобрести новую версию по сниженной цене – за  249.50$.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Если Xequte Software снова не выложит бесплатно скомпилированную  версию ImageEn, то тот, кто не успел её скачать, попал на деньги.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-6359133184800426335?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/6359133184800426335/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=6359133184800426335' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/6359133184800426335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/6359133184800426335'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/06/imageen.html' title='ImageEn – кто не успел, тот опоздал'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-7748607198794493678</id><published>2011-04-15T22:47:00.001+03:00</published><updated>2011-04-15T23:39:45.152+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='FastReport'/><title type='text'>FastReport. Вывод данных в внизу страницы</title><content type='html'>&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Недавно коллега обратился с вопросом "Как в FastReport сделать так, чтобы бэнд с данными выводился внизу страницы?".&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Первая моя мысль была положить SubReport на PageFooter. Но такое решение естественно не сработало, и я стал пробовать управлять положением бэнда на странице с помощью скрипта. В результате я нашел решение данного вопроса с помощью дополнительного бэнда и одной строчки скрипта. Поясню на примере.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Например, вверху отчета нам нужно вывести какую-то информацию (добавляем на страницу бэнд MasterData1) и внизу отчета нам нужно вывести какую-то информацию (добавляем на страницу бэнд MasterData2). А между ними положим еще один бэнд (MasterData3), который заполнит пространство между MasterData1 и MasterData2. Его не будем подключать к  данным, а просто укажем количество строк RowCount = 1.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-bJSy6Z9RTik/TaiaUYPtmDI/AAAAAAAAC-g/h0ZkHbDFNG8/s1600/1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" r6="true" src="http://1.bp.blogspot.com/-bJSy6Z9RTik/TaiaUYPtmDI/AAAAAAAAC-g/h0ZkHbDFNG8/s400/1.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В скрипте, при старте отчета зададим размер MasterData3:&lt;br /&gt;&lt;br /&gt;MasterData3.Height := Engine.PageHeight - MasterData1.Height * MasterData1.RowCount – MasterData2.Height * MasterData2.RowCount&lt;br /&gt;&lt;br /&gt;т.е., от высоты страницы отнимаем высоту бэндов с данными. Высоту бэндов с данными вычисляем следующим образом: высоту одной строки бэнда умножаем на количество строк, которые будут в нём выводиться. У меня здесь в скрипте количество строк – это RowCount, а в примере отчета для моего коллеги я использовал количество строк в запросе (DataSet.RecordCount).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вот такими нехитрыми манипуляциями мне удалось решить поставленную задачу.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-RYvrmIVZF3E/TaiaZny5qjI/AAAAAAAAC-k/RCbDCPtrjd0/s1600/2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" r6="true" src="http://3.bp.blogspot.com/-RYvrmIVZF3E/TaiaZny5qjI/AAAAAAAAC-k/RCbDCPtrjd0/s400/2.jpg" width="322" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;Может быть, вы знаете способ проще?&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-7748607198794493678?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/7748607198794493678/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=7748607198794493678' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/7748607198794493678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/7748607198794493678'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/04/fastreport.html' title='FastReport. Вывод данных в внизу страницы'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-bJSy6Z9RTik/TaiaUYPtmDI/AAAAAAAAC-g/h0ZkHbDFNG8/s72-c/1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-5543714741970712275</id><published>2011-02-16T23:09:00.003+02:00</published><updated>2011-08-14T12:11:21.881+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='Pascal'/><category scheme='http://www.blogger.com/atom/ns#' term='Oxygene'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><title type='text'>Object Pascal для Java и Android</title><content type='html'>&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;На прошедшей в Лас-Вегасе конференции &lt;a href="http://www.dsconf.com" target=_blank&gt;Developer Solutions Conference&lt;/a&gt;, компания &lt;a href="http://remobjects.com" target=_blank&gt;RemObjects Software&lt;/a&gt; впервые представила свой новый проект – "&lt;b&gt;Cooper&lt;/b&gt;". &lt;b&gt;Cooper&lt;/b&gt; – это новый компилятор языка &lt;b&gt;RemObjects Oxygene&lt;/b&gt; для платформ Java и Android (RemObjects Oxygene – это реализация языка Object Pascal для .NET и Mono, третья версия которого была выпущена как Embarcadero Delphi Prism). Cooper подключает стандартные библиотеки Java-классов и создает 100% байт-код для виртуальных машин Java и Dalvik (Dalvik – виртуальная машина Java для Android).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В ролике показано, как под Mac-OS в командной строке скомпилировали паскалевский код консольной программы и калькулятора, использующего swing-контролы, а затем запустили полученные jar-файлы.&lt;br /&gt;&lt;center&gt;&lt;object width="400" height="255"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7oIZ6oiXwS4?fs=1&amp;amp;hl=en_US&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/7oIZ6oiXwS4?fs=1&amp;amp;hl=en_US&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="255"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Планируется интеграция Cooper в Visual Studio и MonoDevelop (аналогично с компилятором для .NET). Обещают выпустить это чудо уже в этом году.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-5543714741970712275?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/5543714741970712275/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=5543714741970712275' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5543714741970712275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5543714741970712275'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/02/object-pascal-java-android.html' title='Object Pascal для Java и Android'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-5948306888580651366</id><published>2011-02-13T23:42:00.000+02:00</published><updated>2011-02-13T23:42:28.896+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='MS SQLServer'/><category scheme='http://www.blogger.com/atom/ns#' term='FastReport'/><title type='text'>Сохранение в базу данных отчета FastReport в формате PDF</title><content type='html'>&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Недавно пришлось писать DLL, одна из функций которой должна была:&lt;blockquote&gt;1. сформировать отчет в FastReport;&lt;br /&gt;2. экспортировать отчет в файл PDF-формата и сохранить его в базе данных;&lt;br /&gt;3. возвратить идентификатор сохраненного в базе данных файла.&lt;/blockquote&gt;Предположим, что исходная структура таблицы для хранения файла в базе данных была такая (MS SQLServer 2000):&lt;br /&gt;&lt;blockquote&gt;CREATE TABLE X.FILES (&lt;br /&gt;&amp;nbsp;&amp;nbsp;ID BIGINT IDENTITY NOT NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;FILE_BODY IMAGE NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;CONSTRAINT PK_FILES PRIMARY KEY (ID)),&lt;/blockquote&gt;где FILE_BODY – это поле, в которое сохраняется файл, а ID – идентификатор файла.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Для начала я создал процедуру, которая будет вставлять файл в базу данных и возвращать идентификатор вставленного файла.&lt;/div&gt;&lt;blockquote&gt;CREATE PROCEDURE X.InsertFile &lt;br /&gt;&amp;nbsp;@FILE image,&lt;br /&gt;&amp;nbsp;@ID bigint OUTPUT&lt;br /&gt;AS&lt;br /&gt;&amp;nbsp;INSERT INTO X.FILES(FILE_BODY) VALUES(@FILE)&lt;br /&gt;&amp;nbsp;SET @ID = SCOPE_IDENTITY()&lt;br /&gt;GO&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Потом сел писать код DLL. В Delphi вся работа с файлами реализована с помощью потоков, поэтому я немного удивился, когда оказалось, что метод Export у TfrxReport экспортирует отчет только в файл (честно сказать, я ожидал увидеть, что-то в стиле ExportToStream). Т.е. вместо прямой передачи отчета через поток в базу данных, необходимо было сначала сохранить отчет во временный файл, а потом этот файл загрузить в базу данных. Мне это не понравилось, т.к. файловые операции (сначала записи, потом чтения) должны были хоть немного, но тормозить работу. Но нужно было срочно отдать DLL, поэтому я не стал разбираться с экспортом и сделал через файл:&lt;/div&gt;&lt;br /&gt;...&lt;br /&gt;&amp;nbsp;db: TSDDatabase; // база данных SQLDirect&lt;br /&gt;&amp;nbsp;spInsertFile: TSDStoredProc; // вызов X.InsertFile&lt;br /&gt;&amp;nbsp;frxReport: TfrxReport;&lt;br /&gt;&amp;nbsp;frxPDFExport: TfrxPDFExport;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Function GetDoc(const sDotName: String; ...): Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;Result := -1;&lt;br /&gt;&amp;nbsp;// загружаем шаблон отчета&lt;br /&gt;&amp;nbsp;If frxReport.LoadFromFile(sDotName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;then begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// устанавливаем параметры отчета&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;If frxReport.PrepareReport&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// получаем имя временного файла&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;frxPDFExport.FileName := GetTempFileName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// экспортируем отчет во временный файл&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;frxReport.Export(frxPDFExport);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// загружаем PDF-файл в параметр процедуры&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// из временного файла&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spInsertFile.Params[1].LoadFromFile(frxPDFExport.FileName, ftBlob);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteErrorMessage(E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// сохраняем PDF-файл в базу данных&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;db.StartTransaction;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spInsertFile.ExecProc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;db.Commit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Result := spInsertFile.Params[2].AsInteger;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: ESDEngineError do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;db.Rollback;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteErrorMessage(E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// удаляем временный файл&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DeleteFile(frxPDFExport.FileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else WriteErrorMessage('Ошибка подготовки отчета')&lt;br /&gt;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;else WriteErrorMessage('Файл шаблона не найден')&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;После передачи DLL другому программисту, мысли о лишних файловых операциях при сохранении отчета в базу через временный файл, не давала мне покоя. Вечером, не найдя решения в документации по FastReport, я, прежде чем смотреть исходный код экспорта, решил еще раз пройтись по методам и свойствам экспорта. Глаз сразу же зацепился за свойство Stream. Я создал для этого свойства поток и метод Export у TfrxReport выгрузил отчет не в файл, а в поток.&lt;/div&gt;&lt;br /&gt;Function GetDoc(const sDotName: String; ...): Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;Result := -1;&lt;br /&gt;&amp;nbsp;// загружаем шаблон отчета&lt;br /&gt;&amp;nbsp;If frxReport.LoadFromFile(sDotName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;then begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// устанавливаем параметры отчета&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;If frxReport.PrepareReport&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// создаём поток в памяти&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;frxPDFExport.Stream := TMemoryStream.Create;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// экспортируем отчет в поток&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;frxReport.Export(frxPDFExport);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// загружаем PDF-файл в параметр процедуры&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// из потока в памяти&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spInsertFile.Params[1].LoadFromStream(frxPDFExport.Stream, ftBlob);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteErrorMessage(E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;frxPDFExport.Stream.Free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// сохраняем PDF-файл в базу данных&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;db.StartTransaction;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spInsertFile.ExecProc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;db.Commit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Result := spInsertFile.Params[2].AsInteger;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: ESDEngineError do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;db.Rollback;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteErrorMessage(E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else WriteErrorMessage('Ошибка подготовки отчета')&lt;br /&gt;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;else WriteErrorMessage('Файл шаблона не найден')&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Часто решение задачи лежит на поверхности и нет нужды копаться в чужом коде. Нужно лишь быть внимательным и никогда не сдавайтесь – "ищите и обрящите".&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-5948306888580651366?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/5948306888580651366/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=5948306888580651366' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5948306888580651366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5948306888580651366'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/02/fastreport-pdf.html' title='Сохранение в базу данных отчета FastReport в формате PDF'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-296983370435345751</id><published>2011-01-30T21:57:00.001+02:00</published><updated>2011-01-30T21:57:35.604+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><title type='text'>Часть антивируса Касперского написана на Delphi</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В конце этой недели в интернет были выложены исходные тексты антивируса Касперского, которые были украдены одним из сотрудников компании в 2008 году (последние изменения датируются декабрём 2007-го года). Как сообщает сайт &lt;a href="http://www.softpedia.com" target=_blank&gt;Softpedia&lt;/a&gt;, часть антивируса написано на Delphi :-)&lt;br /&gt;&lt;br /&gt;Ссылки по теме:&lt;br /&gt;1. &lt;a href="http://anti-malware.ru/node/3571" target=_blank&gt;Кому выгодно раскручивать тему утечки кодов из Лаборатории Касперского?&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://news.softpedia.com/news/Kaspersky-Anti-Virus-Source-Code-Leaked-Online-181297.shtml" target=_blank&gt;Kaspersky Anti-Virus Source Code Leaks online&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-296983370435345751?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/296983370435345751/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=296983370435345751' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/296983370435345751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/296983370435345751'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/01/kaspersky-antivirus-is-written-on.html' title='Часть антивируса Касперского написана на Delphi'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-8986247529533773821</id><published>2011-01-28T17:52:00.005+02:00</published><updated>2011-01-31T12:40:06.924+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><title type='text'>Delphi и C++Builder Starter Edition</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;По информации &lt;a href="http://www.sdtimes.com/link/35223" target=_blank&gt;SD Times&lt;/a&gt;, Embarcadero Technologies собирается продавать новую редакцию Delphi и C++Builder – &lt;b&gt;Starter Edition&lt;/b&gt;. Эта редакция будет включать: полноценную IDE с 32-разрядным компилятором, отладчик и библиотеку визуальных компонент (VCL), содержащую сотни компонент для создания пользовательского интерфейса (от стандартных Windows-контролов до контролов в стиле Office Ribbon и touch-интерфейса) и работы с различными Internet протоколами и стандартами. До публикации обновленного "&lt;a href="http://www.embarcadero.com/products/delphi/Delphi-Feature-Matrix.pdf" target=_blank&gt;Delphi Feature Matrix&lt;/a&gt;" трудно, что то понять о функциональных возможностях новой редакции, но по короткому описанию она очень напоминает Professional Edition.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Стоимость Delphi и C++Builder Starter Edition – всего &lt;b&gt;199$&lt;/b&gt; (для сравнения, Professional Edition стоит около 899$)! Пользователи Turbo Edition и других конкурирующих IDE могут получить обновление на Delphi и C++Builder Starter Edition за &lt;b&gt;149$&lt;/b&gt;. Ограничения только юридические: не более пяти подобных лицензий в пределах одной локальной сети и общий доход с сервиса или организации не более 1000$ в год. Кто превысит этот порог или хочет больше возможностей, то должен обновить свой Starter Edition до Professional, Enterprise или Architect со скидкой в 100$.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Думаю, от данного предложения мало радости большинству пользователей Delphi. Но оно вполне подходит тем, кто только учится программировать, для кого программирование – это хобби (например, разработчикам open-source проектов), разработчикам бесплатных продуктов или тем, кто только начинают разработку своего продукта.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Принесет ли этот маркетинговый ход Embarcadero какие-нибудь плоды? Увеличит ли это количество пользователей Delphi и C++Builder? Думаю, что нет. Причина этому то, что Microsoft раздает Visual Studio Express бесплатно. А бесплатно и 199$ – это большая разница.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Конечно, некоторые объемы продаж этой редакции будут. Думаю, что большинство продаж будет только для легализации своих продуктов. Не в каждой стране будут разбираться в тонкостях лицензии, поэтому лицензии на Starter Edition будет достаточно, чтобы узаконить свою деятельность (например, при получении лицензии на разработку ПО чиновнику будет наплевать на редакцию средств разработки).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Остается надеяться, что Embarcadero не будет разочарована в Delphi и C++Builder Starter Edition.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Дополнено 31.01.2011:&lt;/i&gt;&lt;br /&gt;На сайте Embarcadero открыли странички посвященные &lt;a href="http://www.embarcadero.com/products/delphi/starter" target=_blank&gt;Delphi XE Starter Edition&lt;/a&gt; / &lt;a href="http://www.embarcadero.com/products/cbuilder/starter" target=_blank&gt;C++Builder XE Starter Edition&lt;/a&gt; и опубликовали &lt;a href="http://www.embarcadero.com/products/delphi/starter-faq" target=_blank&gt;Delphi XE Starter Edition and C++Builder XE Starter Edition FAQs&lt;/a&gt; (&lt;a href="http://www.gunsmoker.ru/2011/01/delphi-c-builder-starter-faq.html" target=_blank&gt;перевод FAQ&lt;/a&gt;).&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-8986247529533773821?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/8986247529533773821/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=8986247529533773821' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/8986247529533773821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/8986247529533773821'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/01/delphi-cbuilder-starter-edition.html' title='Delphi и C++Builder Starter Edition'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2130506519105663355</id><published>2011-01-25T23:53:00.004+02:00</published><updated>2011-07-15T00:23:10.239+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet'/><title type='text'>Интернет на халяву</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Сегодня заменил свой старый ADSL-модем на новенький с Wi-Fi. Кроме моей точки доступа ноутбук сразу нашел ещё четыре.  Одна из них была помечена, как "Unsecured wireless network". Проверив работу своей точки доступа, я отключил её и проверил "соседскую". Через "соседскую" я без проблем вышел в интернет, открыл для тестирования пару сайтов и отключился. Предположим, что на моём месте оказался бы другой любопытный, но менее честный человек. Что тогда? В лучшем случае, он потихоньку приворовывал бы трафик бороздя просторы интернета, а в худшем - забил бы весь чужой канал каким-нибудь торрентом (если там модем без шейпера). &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"Граждане, храните деньги в сберегательной кассе!", - сказал Жорж Милославский, герой всенародно любимого кинофильма "Иван Васильевич меняет профессию", запихивая в карман пухлую пачку денег, похищенную из квартиры доктора Шпака. Так и я таким же поучительным тоном скажу: "Граждане, защитите свою беспроводную сеть! Хотя бы ограничьте подключения к вашей точке доступа по MAC-адресу устройств".&lt;br /&gt;&lt;br /&gt;P.S. Вечером на кухне ноутбук находил уже 15 точек доступа, две из которых были открыты для общего пользования...&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2130506519105663355?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2130506519105663355/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2130506519105663355' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2130506519105663355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2130506519105663355'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2011/01/internet-on-freebie.html' title='Интернет на халяву'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-9170608695893507333</id><published>2010-11-13T22:17:00.004+02:00</published><updated>2011-02-13T23:15:25.393+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><title type='text'>Delphi Team обидела очередного приверженца Delphi</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Разработчики Delphi все больше ударов наносят по остаткам Delphi-сообщества: постоянные срывы roadmap, кучи багов, минимальное развитие от версии к версии, зашкаливающие цены на обновления... Всем своим поведением они стараются отталкнуть от себя людей. И это им удается!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Например, в начале ноября 2007-го года Питер Моррис (Peter Morris), весьма известный человек в Delphi-сообществе (автор нескольких open-source библиотек (&lt;b&gt;deAudio&lt;/b&gt;, &lt;b&gt;deBold&lt;/b&gt;, &lt;b&gt;DIB Controls&lt;/b&gt; и &lt;b&gt;FastStrings&lt;/b&gt;); автор множества статей по Delphi, Bold и ECO; в феврале 2007-го анонсировал свою книгу, посвященную ECO...), поссорился с CodeGear (Borland) из-за лицензии на Delphi. Менеджеры CodeGear пожадничали, и в результате Питер Моррис закрыл свой сайт (Droopy Eyes Software), отказался от использования Delphi и прекратил поддержку своих open-source проектов.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Сегодня другая известная личность в Delphi Community - Андреас Хаусладен (Andreas Hausladen) опубликовал на своем блоге заметку &lt;a href="http://andy.jgknet.de/blog/2010/11/xe-update-1-the-death-of-ddevextensions" target="_blank"&gt;XE Update 1 the death of DDevExtensions&lt;/a&gt;. Андреас Хаусладен известен своими расширениями для Delphi IDE: &lt;b&gt;DelphiSpeedUp&lt;/b&gt; (ускоряет загрузку IDE), &lt;b&gt;DDevExtensions&lt;/b&gt; (делает более удобной работу в IDE), &lt;b&gt;IDE Fix Pack&lt;/b&gt; (набор патчей для IDE исправляющих баги, до которых у R&amp;amp;D Team нет дела), &lt;b&gt;dcc32Speed&lt;/b&gt; (ускоряет работу компилятора (dcc32.exe)) и прочие. Кроме этого он участвует в &lt;a href="http://www.delphi-jedi.org/" target="_blank"&gt;Project JEDI&lt;/a&gt; и разрабатывает собственные библиотеки (&lt;b&gt;VCL Fix Pack&lt;/b&gt;, &lt;b&gt;Midas Speed Fix&lt;/b&gt;, &lt;b&gt;AsyncCalls&lt;/b&gt; и &lt;b&gt;NvAPI&lt;/b&gt;). Проблема в том, что R&amp;amp;D Team сильно увлеклась защитой от пиратов, тем самым мешает работе разработчиков расширений для Delphi IDE. Пираты и так найдут, как украсть, а страдают, как всегда, честные люди. Delphi XE Update 1, если установлен DDevExtensions, случайным образом останавливает работу и отправляется на &lt;a href="http://www.embarcadero.com/how-to-buy" target="_blank"&gt;http://www.embarcadero.com/how-to-buy&lt;/a&gt;. Думаю, что после прочтения слов Андреаса "Это означает, что DDevExtensions для Delphi XE умер" многочисленные пользователи DDevExtensions по всему миру дружно сказали "фуцк".&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Год от года Delphi-сообщество уменьшается... Только, похоже, что это не волнует ее разработчиков и скоро Delphi, как и Borland, станет достоянием истории.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-9170608695893507333?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/9170608695893507333/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=9170608695893507333' title='Комментарии: 11'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9170608695893507333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9170608695893507333'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/11/delphi-team-delphi.html' title='Delphi Team обидела очередного приверженца Delphi'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-7366371934363910437</id><published>2010-09-16T22:17:00.010+03:00</published><updated>2011-08-14T12:16:29.731+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><category scheme='http://www.blogger.com/atom/ns#' term='FastReport'/><title type='text'>Экономия при покупке FastReport 5</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Компания FastReport уже включила в &lt;a href="http://fast-report.com/ru/partnership/PartnerAgreement-Russia.doc" target=_blank&gt;обновленный для партнеров прайс-лист&lt;/a&gt; цены на 5-ю версию генератора отчетов FastReport. Проанализируем стоимость single-лицензии на FastReport VCL (цены в российских рублях):&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;table border=1&gt;&lt;tr align=center&gt;&lt;td&gt;&lt;b&gt;Редакция&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;FastReport 4&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;FastReport 5&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Рост цены&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align=center&gt;&lt;td align=left&gt;&amp;nbsp;Basic&lt;/td&gt;&lt;td&gt;&amp;nbsp;690&lt;/td&gt;&lt;td&gt;&amp;nbsp;990&lt;/td&gt;&lt;td&gt;1.43&lt;/td&gt;&lt;/tr&gt;&lt;tr align=center&gt;&lt;td align=left&gt;&amp;nbsp;Standard&lt;/td&gt;&lt;td&gt;2590&lt;/td&gt;&lt;td&gt;3590&lt;/td&gt;&lt;td&gt;1.39&lt;/td&gt;&lt;/tr&gt;&lt;tr align=center&gt;&lt;td align=left&gt;&amp;nbsp;Professional&amp;nbsp;&lt;/td&gt;&lt;td&gt;3590&lt;/td&gt;&lt;td&gt;4990&lt;/td&gt;&lt;td&gt;1.39&lt;/td&gt;&lt;/tr&gt;&lt;tr align=center&gt;&lt;td align=left&gt;&amp;nbsp;Enterprise&lt;/td&gt;&lt;td&gt;6990&lt;/td&gt;&lt;td&gt;9790&lt;/td&gt;&lt;td&gt;1.40&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/center&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Как видим, с выходом новой версии цена на FastReport вырастет почти в полтора раза! Для владельцев лицензий на FastReport 3 и FastReport 4 предусмотрены специальные цены на upgrade: владельцы лицензии FastReport 4 могут проапгрейдить ее до 5-й версии за полцены, а владельцы лицензии FastReport 3 за три четвертых от цены. Тем, кто планирует купить FastReport 5, но не имеет лицензии на FastReport 3 или FastReport 4, рост цен вообще не страшен (если конечно не тормозить) – существует законный способ существенно сэкономить, немного "надув" производителя.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Рассказываю. У компании FastReport есть принцип – бесплатное полугодичное обновление продуктов на любую новую версию той же самой редакции (так было в 2006-м  году, когда вышел FastReport 4). Для тех, кто не догадался, рассказываю дальше. Ранее было объявлено, что FastReport 5 будет выпущен осенью 2010 года (т.е. до релиза уже осталось меньше полугода). А это значит, что, купив FastReport 4 сейчас, можно бесплатно получить лицензию на FastReport 5. А это очень существенная экономия :-) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;P.S. Надеюсь, что рост цен на FastReport обусловлен хорошей реализацией &lt;a href="http://fast-report.com/ru/news/fastreport-vcl-5-news.html" target=_blank&gt;нового функционала&lt;/a&gt;, а не тем, что "очень нужны деньги".&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-7366371934363910437?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/7366371934363910437/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=7366371934363910437' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/7366371934363910437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/7366371934363910437'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/09/fastreport-5.html' title='Экономия при покупке FastReport 5'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2908906963773793961</id><published>2010-08-31T00:52:00.003+03:00</published><updated>2010-09-01T12:55:12.251+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><title type='text'>Новые пробники IDE от Embarcadero</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Компания Embarcadero выложила 30 дневные пробные версии &lt;a href="http://altd.embarcadero.com/download/delphicbuilder/xe/radstudio_xe_win_esd.zip" target=_blank&gt;Embarcadero RAD Studio XE Architect&lt;/a&gt;, &lt;a href="http://altd.embarcadero.com/download/delphicbuilder/xe/delphi_xe_win_esd.zip" target=_blank&gt;Delphi XE Architect&lt;/a&gt;, &lt;a href="http://altd.embarcadero.com/download/delphiprism/xe/delphiprism_xe_win_esd.zip" target=_blank&gt;Delphi Prism XE Enterprise&lt;/a&gt;, &lt;a href="http://altd.embarcadero.com/download/delphicbuilder/xe/cbuilder_xe_win_esd.zip" target=_blank&gt;C++Builder XE Architect&lt;/a&gt; и &lt;a href="http://altd.embarcadero.com/download/radphp/xe/radphp_xe_win_esd.zip" target=_blank&gt;RadPHP XE&lt;/a&gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Так же см. &lt;a href="http://edn.embarcadero.com/article/40775" target=_blank&gt;Release Notes for Delphi and C++Builder XE&lt;/a&gt; и &lt;a href="http://edn.embarcadero.com/article/40774" target=_blank&gt;Installation Notes for Delphi and C++Builder XE&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Дополню ссылкой на ISO-образ &lt;a href="http://altd.embarcadero.com/download/delphicbuilder/xe/delphicbuilder_xe_win.iso" target=_blank&gt;DVD с RAD Studio XE&lt;/a&gt;, который содержит Delphi XE и C++Builder XE (редакция (Professional, Enterprise или Architect) определяется серийным номером).&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2908906963773793961?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2908906963773793961/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2908906963773793961' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2908906963773793961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2908906963773793961'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/08/ide-embarcadero.html' title='Новые пробники IDE от Embarcadero'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-6098125122836004416</id><published>2010-08-26T11:23:00.011+03:00</published><updated>2010-08-31T00:52:35.599+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><category scheme='http://www.blogger.com/atom/ns#' term='RAD Studio'/><title type='text'>RAD Studio XE на халяву</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Компания Embarcadero проводит розыгрыш трех лицензий готовящейся к выпуску RAD Studio XE. Разыгрываются лицензии:&lt;br /&gt;• Embarcadero RAD Studio XE Architect (примерная стоимость 4 299$);&lt;br /&gt;• Embarcadero RAD Studio XE Enterprise (примерная стоимость 2 799$);&lt;br /&gt;• Embarcadero RAD Studio XE Professional (примерная стоимость 1 399$).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Победители получат лицензию на RAD Studio XE и ссылку для скачивания продукта еще до начала продаж. Для участия в розыгрыше необходимо до 29 августа 2010 года подать &lt;a href="http://forms.embarcadero.com/forms/AMUSCA1008RADStudioXE" target=_blank&gt;заявку&lt;/a&gt;. Подробнее см. "&lt;a href="http://www.embarcadero.com/rad-studio-xe-preview/rules?elq=00000000000000000000000000000000" target=_blank&gt;Правила участия в розыгрыше&lt;/a&gt;".&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-6098125122836004416?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/6098125122836004416/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=6098125122836004416' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/6098125122836004416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/6098125122836004416'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/08/rad-studio-xe.html' title='RAD Studio XE на халяву'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-3028711135408794471</id><published>2010-08-13T15:41:00.001+03:00</published><updated>2010-08-13T15:42:19.203+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><title type='text'>Delphi. Трудный путь к 64 битам.</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;С каждым годом 64-битных компьютеров становится все больше. Первую 64-х битную версию MS Windows компания Microsoft выпустила 28 марта 2003 (Windows XP 64-bit Edition). Следующий шаг был сделан 25 апреля 2005 – вышла Windows XP Professional x64 Edition. А что у нас с 64-битным компилятором Pascal под Windows? Разработчики &lt;a href="http://www.freepascal.org" target=_blank&gt;FreePascal Compiler&lt;/a&gt; показали свою 64-битную программу "Hello world" под Windows еще в марте 2006 года. А что же разработчики Delphi?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Представители разработчиков Delphi неоднократно говорили, о том, что 64-битная Delphi уже "в пути". Например, в первых числах января 2009-го года Nick Hodges опубликовал статью "&lt;a href="http://edn.embarcadero.com/article/39174" target=_blank&gt;The Future of the Delphi Compiler&lt;/a&gt;", в которой писал: "Мы ожидаем, что 64-битная версия Delphi будет готова в середине 2010. Поскольку компилятор – это первый шаг к полноценному 64-битному продукту, то мы планируем выпустить предварительную версию 64-битного компилятора в середине 2009 года". Уже середина 2010 года прошла, а мы не увидели даже предварительную версию 64-битного компилятора. В готовящемся релизе &lt;a href="http://www.embarcadero.com/rad-studio-xe-preview" target=_blank&gt;RAD Studio XE&lt;/a&gt; (результаты проекта "Fulcrum" – то, что должно было стать Delphi 2011) 64 битами только немного "пахнет" – для упрощения перехода на 64-битную архитектуру добавили типы данных NativeInt и NativeUInt. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Сегодня ночью компания Embarcadero опять обновила "&lt;a href="http://edn.embarcadero.com/article/39934" target=_blank&gt;RAD Studio, Delphi and C++Builder Roadmap&lt;/a&gt;". В него добавили новый проект "Pulsar" и удалили заглядывающий глубоко в будущее проект "Chromium". Теперь у разработчиков RAD Studio четыре отчетные точки по пути к полной поддержке 64-бит:&lt;br /&gt;1. &lt;strong&gt;64 bit Compiler Preview&lt;/strong&gt; – консольная версия 64-битного компилятора;&lt;br /&gt;2. &lt;strong&gt;Pulsar&lt;/strong&gt; – версия Delphi c 64-битным компилятором под Windows;&lt;br /&gt;3. &lt;strong&gt;Wheelhouse&lt;/strong&gt; – версия C++Builder c 64-битным компилятором под Windows;&lt;br /&gt;4. &lt;strong&gt;Commodore&lt;/strong&gt; – версии Delphi и C++Builder с 64-битными компиляторами под Windows, MacOS и Linux.&lt;br /&gt;Опять обещания. А стоит ли им верить?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;С учетом того, что версия Delphi выходит раз в год, то &lt;strong&gt;Delphi XE2&lt;/strong&gt; можно ждать во второй половине 2011 года (а точнее в конце 2011 года). Вероятнее всего (я на это надеюсь) – это будут результаты проекта "Pulsar", что означает: ждать 64-битную Delphi осталось совсем не долго (чуть больше года). Есть надежда, что над проектами "Pulsar" и "Wheelhouse" параллельно будут работать (или уже работают) разные люди. В таком случае, если параллельно с "Pulsar" успеют закончить "Wheelhouse", то в следующем году компания Embarcadero представит полноценную 64-битную версию своей RAD Studio под Windows.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-3028711135408794471?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/3028711135408794471/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=3028711135408794471' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/3028711135408794471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/3028711135408794471'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/08/delphi-64.html' title='Delphi. Трудный путь к 64 битам.'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-3604804770454755751</id><published>2010-06-26T01:00:00.001+03:00</published><updated>2010-06-26T01:02:49.250+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><title type='text'>ImageEn станет бесплатной</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;ImageEn&lt;/b&gt; - это одна из мощнейших библиотек компонент для обработки, просмотра и анализа картинок в программах на Delphi и C++Builder без использования дополнительных DLL или OCX. Она позволяет загружать и сохранять картинки множества форматов, получать их с TWain-сканеров, производить захват видео, применять фильтры, объединять картинки, выделять области изображения (поддерживается инструмент "Волшебная палочка") и многое другое. В 2004 году читатели журнала "Delphi Informant Magazine" выбрали ImageEn  продуктом года в категории "Imaging Tool".&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В конце июля компания &lt;a href="http://www.hi-components.com"&gt;HiComponents&lt;/a&gt; планирует выпустить новую версию ImageEn (3.1.2), исходные тексты которой будут доступны бесплатно! Кроме того, осенью планируется выпустить новый бесплатный плагин для обнаружения объектов и лиц. Желающие уже могут взглянуть на &lt;a href="http://www.hicomponents.com/main"&gt;новый дизайн сайта компании&lt;/a&gt;, который теперь будет иметь форум и систему регистрации ошибок и запросов о новых возможностях.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-3604804770454755751?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/3604804770454755751/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=3604804770454755751' title='Комментарии: 12'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/3604804770454755751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/3604804770454755751'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/06/imageen.html' title='ImageEn станет бесплатной'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-9181633185179096032</id><published>2010-06-14T09:12:00.001+03:00</published><updated>2010-06-26T01:03:02.273+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='FastReport'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><title type='text'>FastReport VCL 5: Объединение дублирующихся значений</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Компания &lt;a href="http://www.fastreport.ru"&gt;Fast Reports&lt;/a&gt; обещает осенью 2010 года выпустить &lt;a href="http://fast-report.com/ru/news/fastreport-vcl-5-news.html"&gt;FastReport VCL 5&lt;/a&gt;. Из всех нововведений пятой версии меня наиболее заинтересовало "объединение дублирующихся значений". Это связано с тем, что за несколько дней до того, как я узнал о возможностях 5-й версии FastReport VCL, я делал отчет, в котором, если ФИО повторялось в соседних строках, то эти строки первого столбца должны были объединяться в одну строку. Думаю, многие делали, что-либо подобное:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_LgmJBoD0CMM/TBVI5nla3aI/AAAAAAAACE8/i3ZDE9TvrDw/s1600/2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="237" qu="true" src="http://4.bp.blogspot.com/_LgmJBoD0CMM/TBVI5nla3aI/AAAAAAAACE8/i3ZDE9TvrDw/s400/2.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В текущей версии FastReport VCL это без скрипта сделать нельзя. У объекта "Текст" есть свойство " SuppressRepeated", но оно только позволяет скрывать повторяющиеся значения. При этом в FastReport.NET у объекта "Текст" есть свойство "Duplicates", которое может иметь одно из следующих значений:&lt;br /&gt;• Показывать (Show) – показывать повторяющиеся значения;&lt;br /&gt;• Прятать (Hide) – прятать объект с повторяющимся значением;&lt;br /&gt;• Очищать (Clear) – очищать текст в объекте, но показывать сам объект;&lt;br /&gt;• Объединять (Merge) – объединять объекты с одинаковыми значениями.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Эта вопиющая несправедливость будет исправлена в &lt;b&gt;FastReport VCL 5&lt;/b&gt;! В пятой версии, по аналогии с .NET, будет несколько режимов SuppressRepeated.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-9181633185179096032?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/9181633185179096032/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=9181633185179096032' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9181633185179096032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9181633185179096032'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/06/fastreport-vcl-5.html' title='FastReport VCL 5: Объединение дублирующихся значений'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_LgmJBoD0CMM/TBVI5nla3aI/AAAAAAAACE8/i3ZDE9TvrDw/s72-c/2.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-5867930874083586487</id><published>2010-06-09T00:17:00.000+03:00</published><updated>2010-06-09T00:17:57.849+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><title type='text'>Проверяйте интервалы</title><content type='html'>&lt;span style="font-family:verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Недавно, когда я платил за электричество через инфокиоск Беларусбанка, я ошибочно ввел текущие показания счетчика на 100 единиц меньше, чем было оплачено в прошлый раз.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_LgmJBoD0CMM/TA6y2-d24SI/AAAAAAAACCM/h4w0wHtvYp4/s1600/P1110937.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="317" qu="true" src="http://2.bp.blogspot.com/_LgmJBoD0CMM/TA6y2-d24SI/AAAAAAAACCM/h4w0wHtvYp4/s400/P1110937.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Результат поразительный – я чуть не оказался должен оплатить 5 760$ за 99 900 киловатт! &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Спрашивается: где "защита от дурака"? Господа программисты, помните, что надпись "ПРОВЕРЯЙТЕ ПРАВИЛЬНОСТЬ ИНФОРМАЦИИ" ни к чему не обязывает пользователя, даже если вы её напишите большими жирными буквами! Лишняя, на первый взгляд, простенькая проверка введенной информации окажется совсем не лишней и спасет вас от подобного казуса.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-5867930874083586487?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/5867930874083586487/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=5867930874083586487' title='Комментарии: 9'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5867930874083586487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5867930874083586487'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/06/blog-post.html' title='Проверяйте интервалы'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_LgmJBoD0CMM/TA6y2-d24SI/AAAAAAAACCM/h4w0wHtvYp4/s72-c/P1110937.JPG' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-5832275973715327270</id><published>2010-05-11T10:12:00.005+03:00</published><updated>2010-05-11T14:09:12.688+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><category scheme='http://www.blogger.com/atom/ns#' term='RAD Studio'/><title type='text'>Обновился "RAD Studio, Delphi/C++Builder и Delphi Prism Roadmap"</title><content type='html'>&amp;nbsp;&amp;nbsp;&amp;nbsp;Компания Embarcadero обновила свой "RAD Studio, Delphi/C++Builder и Delphi Prism Roadmap". Основные направления работ R&amp;D Team в проектах по развитию Delphi/С++Builder теперь такие:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Fulcrum&lt;/b&gt; – разработка кросс-платформенной VCL и компилятора для MacOS;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wheelhouse&lt;/b&gt; – добавление поддержки Linux;&lt;/li&gt;&lt;li&gt;&lt;b&gt;64 bit Compiler Preview&lt;/b&gt; –  консольная версия 64-битного компилятора;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Commodore&lt;/b&gt; – полноценная версия кросс-платформенного 64-битного компилятора, улучшенная поддержка разработки много-ядерных и много-поточных приложений, интеграция с социальными сетями;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Chromium&lt;/b&gt; – ускорение и упрощение процесса разработки за счет улучшения VCL и IDE, поддержка голосового ввода данных, поддержка процессора ARM.&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Мне кажется, компания Embarcadero повторяет ошибку Borland – погналась за кросс-платформенностью. Провал Kylix их так ни чему и не научил. Думаю, все же основным направлением развития Embarcadero RAD Studio должна была оставаться MS Windows, и приоритетной задачей должна была быть разработка 64-битного компилятора.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Пока Embarcadero играет в кросс-платформенность, Microsoft  во всю уже клепает 64-битные приложения. &lt;b&gt;64 bit Compiler Preview&lt;/b&gt; планируется к выпуску только в первой половине 2011 года. А значит &lt;b&gt;Commodore&lt;/b&gt; выйдет еще позже, т.е. ближе к концу 2011 (или в первой половине 2012 года). Успеет ли Embarcadero выпустить свою IDE с полноценным 64-битным компилятором, пока еще есть программисты использующие Delphi?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://edn.embarcadero.com/article/39934" target=_blank&gt;RAD Studio, Delphi/C++Builder и Delphi Prism Roadmap&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-5832275973715327270?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/5832275973715327270/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=5832275973715327270' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5832275973715327270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5832275973715327270'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/05/rad-studio-delphi-and-cbuilder-roadmap.html' title='Обновился &quot;RAD Studio, Delphi/C++Builder и Delphi Prism Roadmap&quot;'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-770382867018013720</id><published>2010-05-05T14:07:00.001+03:00</published><updated>2010-05-05T14:10:00.559+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Вред преждевременной оптимизации</title><content type='html'>&lt;span style="font-family:verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Некто из великих сказал "Преждевременная оптимизация - корень всех зол" ("Premature optimization is the root of all evil"). Точно автор этих мудрых слов не известен, но возможно это был &lt;a href="http://ru.wikipedia.org/wiki/%D0%94%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%B4_%D0%9A%D0%BD%D1%83%D1%82" target=_blank&gt;Дональд Кнут&lt;/a&gt; или  &lt;a href="http://ru.wikipedia.org/wiki/%D0%AD%D0%BD%D1%82%D0%BE%D0%BD%D0%B8_%D0%A5%D0%BE%D0%B0%D1%80" target=_blank&gt;Энтони Хоар&lt;/a&gt; или &lt;a href="http://ru.wikipedia.org/wiki/%D0%AD%D0%B4%D1%81%D0%B3%D0%B5%D1%80_%D0%94%D0%B5%D0%B9%D0%BA%D1%81%D1%82%D1%80%D0%B0" target=_blank&gt;Эдсгер Дейкстра&lt;/a&gt;. Подробнее о исследованиях на эту тему можно посмотреть &lt;a href="http://alenacpp.blogspot.com/2006/08/blog-post.html" target=_blank&gt;тут&lt;/a&gt; или &lt;a href="http://sergeyteplyakov.blogspot.com/2009/12/blog-post_08.html" target=_blank&gt;тут&lt;/a&gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Недавно я сам убедился в правдивости этой фразы. В одном из очень старых модулей на некоторую сумму денег хитрым образом начислялись проценты. На протяжении многих лет это начисление делалось первого числа каждого месяца (ежемесячно), но у руководства компании родилась идея начислять проценты раз в год (ежегодно). Теоретически, если проценты рассчитывать ежемесячно в течение года, то мы должны получить такую же сумму, как и при одном расчете сразу за весь год (из-за округлений можно допустить копеечную разницу). Практически же, попытка сделать ежегодное начисление на тестовом договоре, дала разницу в несколько тысяч рублей.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Начал я разбираться. Сначала проверил заложенную в код логику расчета – все правильно. Потом стал смотреть код под отладчиком. Дошел до куска кода, в котором в цикле подсчитывается, сколько дней действовала каждая процентная ставка (для выбора дальнейшей формулы):&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp;&amp;nbsp;iDayCount1, iDayCount2: Word;&lt;br /&gt;&amp;nbsp;&amp;nbsp;iDayRefCount: Byte;&lt;br /&gt;&amp;nbsp;&amp;nbsp;........&lt;br /&gt;&amp;nbsp;&amp;nbsp;iDayCount1 := 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;iDayRefCount := 0;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// начало цикла&lt;br /&gt;&amp;nbsp;&amp;nbsp;iDayCount2 := ...;&lt;br /&gt;&amp;nbsp;&amp;nbsp;If "правильное условие в этом тесте" then &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Inc(iDayRefCount, iDayCount2);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Inc(iDayCount1, iDayCount2);&lt;br /&gt;&amp;nbsp;&amp;nbsp;// конец цикла&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&lt;br /&gt;Первый проход цикла:&lt;br /&gt;&amp;nbsp;• Ставка действовала 31 день (iDayCount2 = 31)&lt;br /&gt;&amp;nbsp;• Начисление процентов сделано за 31 день (iDayRefCount   = 31)&lt;br /&gt;&amp;nbsp;• Общее количество обработанных дней в периоде – 31 (iDayCount1 = 31)&lt;br /&gt;Второй проход цикла:&lt;br /&gt;&amp;nbsp;• Ставка действовала 327 день (iDayCount2 = 327)&lt;br /&gt;&amp;nbsp;• Начисление процентов сделано за 102 дня (iDayRefCount   = 102)&lt;br /&gt;&amp;nbsp;• Общее количество обработанных дней в периоде – 358 (iDayCount1 = 358)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Стоп! При одинаковых значениях переменных результат выражения Inc(iDayRefCount, iDayCount2) – 102, а результат Inc(iDayCount1, iDayCount2) – 358. Чудеса? Нет! Переменная iDayRefCount объявлена, как Byte (unsigned 8-bit, 0..255), а переменная iDayCount1, как Word (unsigned 16-bit, 0..65535). Оказалось, что когда начисление делалось ежемесячно, размера переменной типа Byte хватало для хранения количества дней, за которые сделано начисление процентов (их было от 0 до 31). А ежегодный расчет вызвал искажение данных за счет её переполнения.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вот так сэкономленный много лет тому назад один байт памяти, мог привести компанию к большим убыткам.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-770382867018013720?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/770382867018013720/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=770382867018013720' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/770382867018013720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/770382867018013720'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/05/blog-post.html' title='Вред преждевременной оптимизации'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-687916365845529945</id><published>2010-04-30T00:37:00.003+03:00</published><updated>2010-05-11T11:34:21.491+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='юмор'/><category scheme='http://www.blogger.com/atom/ns#' term='размышлизмы'/><title type='text'>Шутки округления</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Для IP-телефонии я пользуюсь JustVoip (один из сервисов Betamax). Этот сервис отличается низкими ценами (в 2-3 раза ниже, чем у Skype) и наличием бесплатных звонков во многие страны на стационарный телефон. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Так вот, как-то надо было мне позвонить другу в Германию. Запускаю JustVoip и звоню ему на домашний телефон – не снимает. Набираю ему на мобильный, а программа мне пишет: "Стоимость минуты 0.08€, у вас не хватает средств". Смотрю, точно на счету – 0.07€. Захожу на сайт сервиса, чтобы пополнить счет, а на сайте написано: "На счету 0.08€". А ведь это ровно стоимость минуты!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_LgmJBoD0CMM/S9n6EX5RgJI/AAAAAAAAB7k/IOjToqOjmh4/s1600/justvoip.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="217" src="http://2.bp.blogspot.com/_LgmJBoD0CMM/S9n6EX5RgJI/AAAAAAAAB7k/IOjToqOjmh4/s400/justvoip.jpg" tt="true" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вот наглядный пример, когда округление суммы на счете до центов реализовано разными алгоритмами. Система одна, счет один, а клиентские программы разные и в результате различный баланс :( &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Итак, авторы программ задумайтесь над тем, чтобы алгоритмы обработки данных в рамках одной системы были одинаковыми!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-687916365845529945?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/687916365845529945/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=687916365845529945' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/687916365845529945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/687916365845529945'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/04/blog-post.html' title='Шутки округления'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_LgmJBoD0CMM/S9n6EX5RgJI/AAAAAAAAB7k/IOjToqOjmh4/s72-c/justvoip.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2045361774567922374</id><published>2010-04-27T15:54:00.009+03:00</published><updated>2010-04-27T16:02:44.798+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi 2010'/><title type='text'>Delphi 2010: Ловим ошибки отсроченной загрузки DLL</title><content type='html'>&lt;span style="font-family:verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Как я &lt;a href="http://it-blackcat.blogspot.com/2010/04/delphi-2010-delayed-dynamic-link.html" target=_blank&gt;писал раньше&lt;/a&gt;, Delphi 2010 научилась вызывать функций из DLL новым способом – с помощью отсроченной загрузки DLL.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Одним из недостатков этого способа является то, что если при вызове функции произойдет ошибка, то пользователь не узнает ее причину. В случае если DLL не существует, так же как и если в DLL нет нужной  функции, то сообщение в программе будет однотипным:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_LgmJBoD0CMM/S8WNccQwqDI/AAAAAAAAB1o/rLEsFX4lXvs/s1600/Error4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="114" src="http://1.bp.blogspot.com/_LgmJBoD0CMM/S8WNccQwqDI/AAAAAAAAB1o/rLEsFX4lXvs/s200/Error4.jpg" tt="true" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;События, которые происходят при отложенной загрузке DLL и вызове её функций, можно перехватить и обработать самому. Установить свой обработчик на эти события позволяет функция &lt;b&gt;SetDliNotifyHook&lt;/b&gt;. Эта функция работает с параметрами процедурного типа DelayedLoadHook описанного в юните System:&lt;br /&gt;&lt;br /&gt;DelayedLoadHook = function (dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall;&lt;br /&gt;&lt;br /&gt;где:&lt;br /&gt;• dliNotify – это событие которое происходит с DLL:&lt;br /&gt;&amp;nbsp;&amp;nbsp;- dliNoteStartProcessing – намёк, что будет работа по загрузке DLL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dliNotePreLoadLibrary – идёт загрузка DLL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dliNotePreGetProcAddress – идёт попытка получения адреса вызываемой функции;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dliNoteEndProcessing – окончание работы по загрузке функции из DLL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dliFailLoadLibrary – ошибка при загрузке DLL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dliFailGetProcAddress – ошибка при получении адреса вызываемой функции.&lt;br /&gt;• pdli – указатель на структуру типа TDelayLoadInfo с полями: &lt;br /&gt;&amp;nbsp;&amp;nbsp;– cb – размер структуры;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– pidd – данные в необработанной форме;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– ppfn – указатель на адрес функции, которая загружена;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– szDll – название DLL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dlp – название или номер загружаемой функции;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– hmodCur – информация о DLL (запись типа TDelayLoadProc);&lt;br /&gt;&amp;nbsp;&amp;nbsp;– pfnCur – указатель на адрес функции, которая будет вызвана;&lt;br /&gt;&amp;nbsp;&amp;nbsp;– dwLastError – номер полученной ошибки.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Более подробно о функции SetDliNotifyHook и связанных с ее работой типах вы можете почитать в справке Delphi 2010. А мы приступим к написанию собственного обработчика ошибок при отложенной загрузке DLL и вызове её функций.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Т.к. нас интересует только перехват и обработка ошибок, то воспользуемся урезанной версией функции SetDliNotifyHook – &lt;b&gt;SetDliFailureHook&lt;/b&gt;, которая устанавливает обработчик событий только на события возникающие при ошибке: &lt;b&gt;dliFailLoadLibrary&lt;/b&gt; и &lt;b&gt;dliFailGetProcAddress&lt;/b&gt;. Чтобы не писать перехватчик в каждом новом проекте, вынесем его код в отдельную юниту.&lt;br /&gt;&lt;br /&gt;Unit dliHandler;&lt;br /&gt;&lt;br /&gt;Interface&lt;br /&gt;&lt;br /&gt;Uses&lt;br /&gt;&amp;nbsp;&amp;nbsp;SysUtils;&lt;br /&gt;&lt;br /&gt;Type&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;// Ошибка при работе с отсроченной загрузкой DLL&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;EDliFailure = class(Exception)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ErrorCode: Integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constructor Create(const sMessage: String;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const iErrorCode: Integer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;Implementation&lt;br /&gt;&lt;br /&gt;constructor EDliFailure.Create(const sMessage: String; const iErrorCode: Integer);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;inherited Create(sMessage);&lt;br /&gt;&amp;nbsp;&amp;nbsp;ErrorCode := iErrorCode;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;// Функция возвращает имя или номер импортируемой функции&lt;/i&gt;&lt;br /&gt;function ImportName(const AProc: TDelayLoadProc): String;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;if AProc.fImportByName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then Result := AProc.szProcName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else Result := '#' + IntToStr(AProc.dwOrdinal);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;// Обработчик ошибок генерирующий "красивую" ошибку&lt;/i&gt;&lt;br /&gt;function DelayedLoadHook(dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;If dliNotify = dliFailGetProcAddress&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then Raise EDliFailure.Create('В ' + pdli.szDll + ' не найдена функция ' + ImportName(pdli.dlp), 2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else Raise EDliFailure.Create('Ошибка при загрузке ' + pdli.szDll, 1); //dliFailLoadLibrary}&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;LOldFailureHook: TDelayedLoadHook;&lt;br /&gt;&lt;br /&gt;Initialization&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;// Устанавливаем свой обработчик&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;LOldFailureHook := SetDliFailureHook(DelayedLoadHook);&lt;br /&gt;Finalization&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;i&gt;// На всякий случай вернем старый обработчик&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SetDliFailureHook(LOldFailureHook);&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;Добавляем dliHandler в любой проект и наслаждаемся автоматической обработкой ошибок при работе с отсроченной загрузкой DLL во всем проекте. Теперь вместо непонятного сообщения "External exception" пользователь увидит:&lt;br /&gt;• если не удалось загрузить DLL&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_LgmJBoD0CMM/S9bYroJjXLI/AAAAAAAAB60/imHcqiL-K_4/s1600/Error-2.1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="103" src="http://2.bp.blogspot.com/_LgmJBoD0CMM/S9bYroJjXLI/AAAAAAAAB60/imHcqiL-K_4/s200/Error-2.1.jpg" tt="true" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;• если не удалось получить адрес функции&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_LgmJBoD0CMM/S9bYzY9bX4I/AAAAAAAAB68/K-ue8S156PE/s1600/Error-2.2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="86" src="http://1.bp.blogspot.com/_LgmJBoD0CMM/S9bYzY9bX4I/AAAAAAAAB68/K-ue8S156PE/s200/Error-2.2.jpg" tt="true" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;При необходимости, можно обработать ошибку и для каждого конкретного случая вызова функции  (специально для этого в dliHandler я определил класс EDliFailure):&lt;br /&gt;&lt;br /&gt;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;fFee := CalcFee(1234)&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: EDliFailure do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case E.ErrorCode of&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1: HandleDliFailLoadLibrary;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2: HandleDliFailGetProcAddress;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else Raise&lt;br /&gt;End;&lt;br /&gt;&lt;br /&gt;где, HandleDliFailLoadLibrary и HandleDliFailGetProcAddress  – специфические для данного конкретного случая обработчики ошибок.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Как видите, научить программу выводить понятные пользователю сообщения об ошибке легко.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2045361774567922374?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2045361774567922374/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2045361774567922374' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2045361774567922374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2045361774567922374'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/04/delphi-2010-dll.html' title='Delphi 2010: Ловим ошибки отсроченной загрузки DLL'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_LgmJBoD0CMM/S8WNccQwqDI/AAAAAAAAB1o/rLEsFX4lXvs/s72-c/Error4.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-5961072800728681689</id><published>2010-04-21T15:41:00.002+03:00</published><updated>2010-06-26T01:03:41.825+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='FastReport'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><title type='text'>Fast Reports переманивает клиентов у конкурентов</title><content type='html'>&lt;span style="font-family:verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Когда-то давно, на заре человечества, единственным и неповторимым генератором отчетов для Delphi был QuickReport (про ReportSmith даже вспоминать не будем). Он много лет входил в поставку Delphi и его изначально использовали все. Поработав с QuickReport и устав регулярно вспоминать "матерей его разработчиков" программисты стали искать ему альтернативу. Кто то пытался сам улучшить QuickReport, кто то стал генерировать отчеты в MS Word/Excel (например, я), кто то, в надежде на лучшее, украл или купил другие генераторы Report Builder или Rave Reports (или даже монстра по имени Crystal Reports), а кто то стал писать свой генератор отчетов. Одним из тех, кого не устроил QuickReport и кто начал писать свой генератор, был Александр Цыганенко – автор &lt;a href="http://www.fastreport.ru" target=_blank&gt;FastReport&lt;/a&gt;. Думал ли Александр в далеком 1998 году, что его генератор станет лидером рынка?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;За последние десять лет ситуация изменилась – генераторов отчетов, которые могут быть использованы в Delphi, написано уже много и на любой вкус. Поэтому рынок генераторов отчетов уже насытился и теперь начинается новая стадия борьбы за старых клиентов. Стадия, в которой главная роль отводится не программистам, а маркетологам. Компания Fast Reports, опередив своих конкурентов по функциональным возможностям их генераторов отчетов, решила дожать тех, кто сомневался в его покупке и начала &lt;a href="http://delphiplus.org/articles/press_release/2010/fastreport-action.html" target=_blank&gt;акцию по переманиванию пользователей других коммерческих генераторов отчетов на FastReport&lt;/a&gt;. В обмен на лицензию конкурента они предлагают скидку в 20% на FastReport 4 VCL, FastReport VCL OLAP Pack, FastReport.NET и FastReport Studio. VCL-версию FastReport можно получить в обмен на Report Builder, Rave Reports, Crystal Reports и ActiveReports. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Обидно за QuickReport. Его, классика жанра, вообще обделили вниманием. Но, думаю – это "заслужено", ни кто на просторах бывшего СССР не покупал это убожество программисткой мысли.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-5961072800728681689?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/5961072800728681689/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=5961072800728681689' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5961072800728681689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/5961072800728681689'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/04/fast-reports.html' title='Fast Reports переманивает клиентов у конкурентов'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-7505990957621831319</id><published>2010-04-14T12:52:00.001+03:00</published><updated>2010-04-14T12:55:07.333+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi 2010'/><title type='text'>Delphi 2010: Отсроченная загрузка DLL</title><content type='html'>&lt;span style="font-family: verdana;"&gt;Долгие годы программы на Delphi умели загружать DLL двумя способами: статически и динамически. В Delphi 2010 появился третий способ – отсроченная загрузка.&lt;br /&gt;&lt;br /&gt;Сделаем простенькую DLL, которая экспортирует некую функцию, например, CalcFee:&lt;br /&gt;&lt;br /&gt;library TestDLL;&lt;br /&gt;Function CalcFee(const iID: Integer): Currency;&lt;br /&gt;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Result := ...;&lt;br /&gt;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;Exports&lt;br /&gt;&amp;nbsp;&amp;nbsp;CalcFee;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;и рассмотрим все три способа.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Статическая загрузка.&lt;/b&gt;&lt;br /&gt;Это самый простой способ вызвать функцию из DLL. Для его реализации необходимо всего лишь описать внешнюю функцию:&lt;br /&gt;&lt;br /&gt;Function CalcFee (const iID: Integer): Currency; external 'TestDLL.dll';&lt;br /&gt;&lt;br /&gt;И после этого её можно вызывать:&lt;br /&gt;&lt;br /&gt;fFee := CalcFee(1234)&lt;br /&gt;&lt;br /&gt;Наша DLL загружается при запуске программы и остается загруженной до завершения ее работы. &lt;br /&gt;За этой простотой скрывается большая проблема – если DLL удалить или испортить, то программа просто не запустится.&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_LgmJBoD0CMM/S8WNC_KH4gI/AAAAAAAAB1Y/ht1HcJiVFJg/s1600/Error1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="77" src="http://2.bp.blogspot.com/_LgmJBoD0CMM/S8WNC_KH4gI/AAAAAAAAB1Y/ht1HcJiVFJg/s400/Error1.jpg" width="400" wt="true" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;2. Динамическая загрузка.&lt;/b&gt;&lt;br /&gt;Этот способ – более продвинутый, но требует написания значительно большего количества кода:&lt;br /&gt;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;CalcFee: function(const iID: Integer): Currency;&lt;br /&gt;&amp;nbsp;&amp;nbsp;hDLL: THandle;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;hDLL := LoadLibrary('TestDLL.dll');&lt;br /&gt;&amp;nbsp;&amp;nbsp;If hDLL &amp;lt;&amp;gt; 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@CalcFee := GetProcAddress(hDLL, 'CalcFee');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If @CalcFee = nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then ShowMessage('В TestDLL.dll не найдена функция CalcFee')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else fFee := CalcFee(1234);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FreeLibrary(hDLL);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else ShowMessage('Ошибка при загрузке TestDLL.dll')&lt;br /&gt;&lt;br /&gt;В этом коде используются функции Win32 API из Windows.pas: &lt;br /&gt;&amp;nbsp;&amp;nbsp;- LoadLibrary – загружаем DLL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;- GetProcAddress – получаем адрес функции по её имени;&lt;br /&gt;&amp;nbsp;&amp;nbsp;- FreeLibrary – выгружаем DLL из памяти.&lt;br /&gt;&lt;br /&gt;Динамическая загрузка позволяет загружать DLL только при необходимости и выгружать её, если она больше не нужна. Второе преимущество и более важное – это возможность обработать ошибки при загрузке DLL и вызове функции. Поэтому даже без DLL или с испорченной DLL программа будет работать. Если перед загрузкой DLL ее удалить, то получим нормальное сообщение:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_LgmJBoD0CMM/S8WNObN2VnI/AAAAAAAAB1g/4ACOWIqzmlk/s1600/Error2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="108" src="http://3.bp.blogspot.com/_LgmJBoD0CMM/S8WNObN2VnI/AAAAAAAAB1g/4ACOWIqzmlk/s200/Error2.jpg" width="200" wt="true" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;3. Отсроченная загрузка&lt;/b&gt;&lt;br /&gt;В Delphi 2010 появился третий способ вызова функций из DLL – отсроченная загрузка. Как и динамическая загрузка, она позволяет загружать DLL только при необходимости (например, для экономии ресурсов), но также как при статической загрузке, функцию достаточно лишь описать, добавив директиву &lt;b&gt;delayed&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;Function CalcFee(const iID: Integer): Currency; external 'TestDLL.dll' delayed;&lt;br /&gt;&lt;br /&gt;Недостатки этого способа – это то, что DLL уже нельзя выгрузить и то, что если при вызове функции произойдет ошибка, то пользователь не узнает ее причину. В справке написано "Trying to call a delayed routine that cannot be resolved results in a run-time error (or an exception, if the SysUtils unit is loaded)". Если DLL удалить или если в DLL нет нужной функции, сообщение будет однотипным:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_LgmJBoD0CMM/S8WNccQwqDI/AAAAAAAAB1o/rLEsFX4lXvs/s1600/Error4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="114" src="http://1.bp.blogspot.com/_LgmJBoD0CMM/S8WNccQwqDI/AAAAAAAAB1o/rLEsFX4lXvs/s200/Error4.jpg" width="200" wt="true" /&gt;&lt;/a&gt;&lt;/div&gt;Если функция будет использована в консольной программе, то сообщение об ошибке будет тоже не информативным:&lt;br /&gt;&lt;br /&gt;"Runtime error 255 at 7C812AFB "&lt;br /&gt;&lt;br /&gt;Но спасение есть. При желании ошибки, возникающие во время загрузки DLL или вызове её функций можно перехватить и обработать с помощью процедур SetDliNotifyHook и SetDliFailureHook из юниты System.&lt;br /&gt;&lt;br /&gt;Не знаю, как вам, но мне идея отсроченной загрузки DLL понравилась, и я буду её в будущем использовать.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-7505990957621831319?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/7505990957621831319/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=7505990957621831319' title='Комментарии: 6'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/7505990957621831319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/7505990957621831319'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/04/delphi-2010-delayed-dynamic-link.html' title='Delphi 2010: Отсроченная загрузка DLL'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_LgmJBoD0CMM/S8WNC_KH4gI/AAAAAAAAB1Y/ht1HcJiVFJg/s72-c/Error1.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-9073133282818866066</id><published>2010-04-08T08:18:00.006+03:00</published><updated>2010-04-08T08:29:43.406+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='Pascal'/><title type='text'>TIOBE: Delphi удерживает позиции</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вчера компания TIOBE Software опубликовала апрельский индекс популярности языков программирования - &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" target="_blank"&gt;TIOBE Programming Community Index&lt;/a&gt;. Согласно ему, язык программирования Delphi уверенно удерживает занятое в феврале 2010-го года 9-е место. По сравнению с апрелем прошлого года он поднялся с 11-го на 9-е место. При этом, начиная с 2001-го года, пики популярности Delphi были в 2004-м году: 12-е место в январе и 7-е в августе. &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_LgmJBoD0CMM/S71mi7eR1dI/AAAAAAAAB0o/ViyibE99xgE/s1600/TIOBE_history_Delphi-04-2010.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" nt="true" src="http://4.bp.blogspot.com/_LgmJBoD0CMM/S71mi7eR1dI/AAAAAAAAB0o/ViyibE99xgE/s400/TIOBE_history_Delphi-04-2010.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;По сравнению с апрелем прошлого года рейтинг языка Pascal, опустился с 15-го на 16-е место. При этом в сентябре 2009-го он входил в дюжину лидеров и занимал 12-е место. Жалко прародителя :(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"TIOBE Programming Community Index" обновляется один раз в месяц и основан на количестве квалифицированных инженеров, курсов и разработчиков дополнительного программного обеспечения. Для сбора этой информации используются поисковые машины (Google, MSN, Yahoo!, Wikipedia и YouTube). Для языка Delphi отслеживаются: Delphi, Kylix, Object Pascal, Free Pascal, Chrome (исключая "Google Chrome"), Oxygene, Delphi.NET и Delphi Prism.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-9073133282818866066?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/9073133282818866066/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=9073133282818866066' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9073133282818866066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/9073133282818866066'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/04/tiobe-delphi.html' title='TIOBE: Delphi удерживает позиции'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_LgmJBoD0CMM/S71mi7eR1dI/AAAAAAAAB0o/ViyibE99xgE/s72-c/TIOBE_history_Delphi-04-2010.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-987020995390833751</id><published>2010-04-01T01:18:00.001+03:00</published><updated>2010-04-01T01:19:17.715+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='юмор'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><category scheme='http://www.blogger.com/atom/ns#' term='Borland'/><title type='text'>Embarcadero Technologies покупает бренд "Borland"</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;По сообщению &lt;a href="http://www.businessweek.com" target=_blank&gt;BusinessWeek&lt;/a&gt; компания &lt;a href="http://www.embarcadero.com" target=_blank&gt;Embarcadero Technologies&lt;/a&gt;, крупнейший производитель и поставщик платформенно-независимых инструментов для разработки, управления и оптимизации приложений и баз данных, подписала соглашение с &lt;a href="http://www.microfocus.com" target=_blank&gt;Micro Focus International plc&lt;/a&gt; о приобретении эксклюзивного права на использование торговой марки "&lt;b&gt;Borland&lt;/b&gt;" в названии продуктов линейки "Rapid Application, Web and Java™ Development Tools". &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"Мы возрождаем славное имя Borland! Когда-то "Borland" входил в тройку самых известных в мире брендов. В какой-то степени, использование "Borland" в названии наших продуктов – это возвращение к нашим корням. Borland – это бренд, в будущее которого верят многие ИТ-профессионалы!" – сказал вице-президент по связям с разработчиками и главный евангелист Embarcadero Technologies Дэвид Интерсаймон ("David I").&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;С первого апреля 2010 года, слово "Borland" будет использоваться в названии всех новых версий инструментальных средств для разработки приложений компании Embarcadero Technologies: Borland® RAD Studio, Borland® Delphi, Borland® C++Builder, Borland® Delphi Prism, Borland® JBuilder, Borland® Delphi for PHP.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-987020995390833751?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/987020995390833751/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=987020995390833751' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/987020995390833751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/987020995390833751'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/04/embarcadero-technologies-borland.html' title='Embarcadero Technologies покупает бренд &quot;Borland&quot;'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-1287080622392824667</id><published>2010-03-26T13:20:00.000+02:00</published><updated>2010-03-26T13:20:31.308+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='юмор'/><title type='text'>Пятница. Корректный ответ на жалобу клиента</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_LgmJBoD0CMM/S6yXU9i6LDI/AAAAAAAABvk/JmDjzh8s__o/s1600/correct-answer.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="247" nt="true" src="http://4.bp.blogspot.com/_LgmJBoD0CMM/S6yXU9i6LDI/AAAAAAAABvk/JmDjzh8s__o/s400/correct-answer.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-1287080622392824667?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/1287080622392824667/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=1287080622392824667' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/1287080622392824667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/1287080622392824667'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/blog-post.html' title='Пятница. Корректный ответ на жалобу клиента'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_LgmJBoD0CMM/S6yXU9i6LDI/AAAAAAAABvk/JmDjzh8s__o/s72-c/correct-answer.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-8945152932759328112</id><published>2010-03-24T09:06:00.002+02:00</published><updated>2010-06-26T01:03:50.046+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi 2010'/><category scheme='http://www.blogger.com/atom/ns#' term='компоненты'/><category scheme='http://www.blogger.com/atom/ns#' term='DataSet'/><title type='text'>Delphi 2010: TDataSet.FreeBookmark – рудимент</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Часто бывает полезно отметить текущее положение курсора в DataSet'е так, чтобы позже можно было быстро возвратиться к этому месту. Delphi обеспечивает эту функциональную возможность с помощью закладок (Bookmark), для работы с которыми используются процедуры:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;GetBookmark – устанавливает закладку на текущую запись;&lt;/li&gt;&lt;li&gt;BookmarkValid – проверяет, существует ли запись, на которую ссылается закладка;&lt;/li&gt;&lt;li&gt;GotoBookmark – позиционирует курсор на запись, на которую ссылается закладка;&lt;/li&gt;&lt;li&gt;FreeBookmark – освобождает системные ресурсы, используемые методом GetBookmark.&lt;/li&gt;&lt;/ul&gt;Думаю это знакомая многим конструкция:&lt;br /&gt;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;q: TSDQuery;&lt;br /&gt;&amp;nbsp;&amp;nbsp;bm: TBookmark;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bm := q.GetBookmark; // делаем закладку&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// обрабатываем ds&lt;br /&gt;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If bm &lt;&gt; nil then &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If q.BookmarkValid(bm) then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;q.GotoBookmark(bm);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;q.FreeBookmark(bm);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;В Delphi 7 код FreeBookmark выглядит так:&lt;br /&gt;&lt;br /&gt;procedure TDataSet.FreeBookmark(Bookmark: TBookmark);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;FreeMem(Bookmark);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;В Delphi 2010 он – просто заглушка:&lt;br /&gt;&lt;br /&gt;procedure TDataSet.FreeBookmark(Bookmark: TBookmark);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;// No longer need to free bookmark since it's a TBytes now.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Т.е. FreeBookmark в Delphi 2010 – это уже пережиток прошлого и вызывать его больше не нужно. Таким образом, исходный код становится проще:&lt;br /&gt;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;ds: TSDQuery;&lt;br /&gt;&amp;nbsp;&amp;nbsp;bm: TBookmark;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bm := q.GetBookmark; // делаем закладку&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// обрабатываем ds&lt;br /&gt;&amp;nbsp;&amp;nbsp;Finally&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If (bm &lt;&gt; nil) and q.BookmarkValid(bm) then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;q.GotoBookmark(bm);&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;P.S. А вот справочную систему Delphi 2010 подправить, как всегда, забыли. В ней есть раздел "DB.TDataSet.FreeBookmark" с описанием процедуры и рекомендацией ее использования. А раздел "Marking and Returning to Records" содержит строку "FreeBookmark frees the memory allocated for a specified bookmark when you no longer need it. You should also call DB.TDataSet.FreeBookmark before reusing an existing bookmark." и пример, где используется FreeBookmark :)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-8945152932759328112?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/8945152932759328112/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=8945152932759328112' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/8945152932759328112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/8945152932759328112'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/delphi-2010-tdatasetfreebookmark.html' title='Delphi 2010: TDataSet.FreeBookmark – рудимент'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-461509065287636643</id><published>2010-03-21T01:43:00.003+02:00</published><updated>2010-03-21T01:54:54.762+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='новости'/><category scheme='http://www.blogger.com/atom/ns#' term='Embarcadero Technologies'/><category scheme='http://www.blogger.com/atom/ns#' term='Borland'/><title type='text'>Разработчики Delphi собрали 26 000$ для помощи Гаити</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Anders Ohlsson, сотрудник Embarcadero Technologies (бывший сотрудник компании Borland), организовал на eBay благотворительный аукцион для помощи населению пострадавшего от землетрясения Гаити. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;На аукцион были выставлены старые вещи, связанные с компанией Borland. За 2 025$ был продан Compaq II – компьютер, на котором Anders Hejlsberg разрабатывал Turbo Pascal. За 99$ продали наклейку на бампер "Delphi Developers Do It Faster". С молотка ушли подписанные авторами книги "Delphi 2 Developer's Guide" (Steve Teixeira) и "Delphi Component Design" (Danny Thorpe), старые релизы продуктов в оригинальных упаковках, фирменные футболки компании, эксклюзивная спортивная куртка с большой буквой "B" и прочее. Обед с David Intersimone ("David I", вице-президент по связям с разработчиками и главный евангелист Embarcadero Technologies) оценили в 480$.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Всего поклонниками компании Borland со всех континентов было куплено 177 предметов общей стоимостью 26 000$. Некто то, из Австрии, потратил на этом аукционе почти 4 200$!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Собранные деньги будут переданы фонду "Clinton Bush Haiti Fund".&lt;br /&gt;&lt;div style="text-align: right;"&gt;&lt;i&gt;По информации &lt;a href="http://www.santacruzsentinel.com/business/ci_14715461" target=_blank&gt;Santa Cruz Sentinel&lt;/a&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-461509065287636643?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/461509065287636643/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=461509065287636643' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/461509065287636643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/461509065287636643'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/delphi-26-000.html' title='Разработчики Delphi собрали 26 000$ для помощи Гаити'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-2475655552894999300</id><published>2010-03-16T07:41:00.000+02:00</published><updated>2010-03-16T15:05:16.495+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi 2010'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Delphi 2010: TValue - "тормоз"!</title><content type='html'>&lt;span style="font-family: verdana;"&gt;&lt;i&gt;Перевод. Оригинал "&lt;a href="http://tech.turbu-rpg.com/100/tvalue-is-very-slow" target="_blank"&gt;TValue is very slow&lt;/a&gt;" (© TURBU Tech) дополнен моими тестами и комментариями.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Справочная система Delphi 2010 описывает тип TValue, используемый модулем RTTI для хранения значений произвольных типов, как "облегченная версия типа Variant". Увидев это, я задался вопросом, насколько он легковеснее? Как быстро работает TValue?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;К счастью, среди известных мне новых возможностей Delphi 2010 – модуль диагностики (Diagnostics), который предоставляет нам объект TStopwatch – простой таймер позволяющий засечь время выполнения операций и тем самым облегчить написание простого теста скорости.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Я ожидал, что скорость работы TValue будет сравнима со скоростью Variant, или возможно немного больше. Для проверки, я написал следующую программку:&lt;br /&gt;&lt;br /&gt;program Project1;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;&amp;nbsp;&amp;nbsp;SysUtils, rtti, diagnostics;&lt;br /&gt;&lt;br /&gt;const &lt;br /&gt;&amp;nbsp;&amp;nbsp;HUNDRED_MILLION = 100000000;&lt;br /&gt;&lt;br /&gt;procedure tryTValue;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp;&amp;nbsp;i: integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;j: TValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;value: integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;for I := 1 to HUNDRED_MILLION do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;j := i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value := j.AsInteger;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure tryVariants;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp;&amp;nbsp;i: integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;j: variant;&lt;br /&gt;&amp;nbsp;&amp;nbsp;value: integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;for I := 1 to HUNDRED_MILLION do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;j := i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value := j;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp;&amp;nbsp;stopwatch: TStopWatch;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch := TStopWatch.StartNew;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tryVariants;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Stop;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeln('Variants: ', stopwatch.ElapsedMilliseconds);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch := TStopWatch.StartNew;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tryTValue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Stop;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeln('TValues: ', stopwatch.ElapsedMilliseconds);&lt;br /&gt;&amp;nbsp;&amp;nbsp;except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on E: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Writeln(E.ClassName, ': ', E.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;readln;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Конечно, этот тест - не исчерпывающая проверка возможностей TValue, но результаты поучительны. Когда я запустил его на своем рабочем компьютере (высокопроизводительный ноутбук Alienware), тест Variant выполнился почти мгновенно, а тест TValue выполнялся так долго, что я решил, что он завис и остановил его.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Затем я запустил тест снова и получил следующие результаты (в миллисекундах):&lt;br /&gt;&lt;blockquote&gt;Variants: 717&lt;br /&gt;TValues: 31131&lt;/blockquote&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;По крайней мере, для этой конкретной операции, &lt;b&gt;TValue в 43.52167832167832 раза медленнее, чем Variant&lt;/b&gt;!&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;От меня.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вообще то 31131 поделить на 717 будет равно 43.41841004 ;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Что бы проверить результат, я запустил несколько тестов на своей домашней "dev machine".&lt;br /&gt;&lt;br /&gt;Тест #1. Запустил исходный тест и получил такую же разницу скорости - в 43.17657992 раза:&lt;br /&gt;&lt;blockquote&gt;Variants: 538&lt;br /&gt;TValues: 23229.&lt;/blockquote&gt;Тест #2. Переставил местами вызов tryTValue и tryVariants и снова получил 43.376404494:&lt;br /&gt;&lt;blockquote&gt;TValues: 23163&lt;br /&gt;Variants: 534.&lt;/blockquote&gt;Тест #3. Закомментировав обратное присвоение TValue и Variant целой переменной ("value := j.AsInteger" и "value := j") я получил для TValue более "веселый" результат:&lt;br /&gt;&lt;blockquote&gt;Variants: 535&lt;br /&gt;TValues: 5168&lt;/blockquote&gt;Присвоение целого значения TValue медленнее присвоения целого значения Variant всего в 9.65981308 раза. А значит основное падение скорости вызвано AsInteger.&lt;br /&gt;&lt;br /&gt;Тест #4. В процедуре tryTValue я заменил "value := j.AsInteger" на "value := j.AsOrdinal"&lt;br /&gt;&lt;blockquote&gt;Variants: 536&lt;br /&gt;TValues: 5862&lt;/blockquote&gt;В результате общее падение скорости всего в 10.93656716 раза!&lt;br /&gt;&lt;br /&gt;Тест #5. AsOrdinal возвращает значение типа Int64, поэтому в процедуре tryTValue я заменил "value := j.AsInteger" на "value := j.AsInt64" и получил падение скорости в 54,25981308 раза!!!&lt;br /&gt;&lt;blockquote&gt;Variants: 535&lt;br /&gt;TValues: 29029&lt;/blockquote&gt;&lt;i&gt;&lt;b&gt;Вывод&lt;/b&gt;&lt;/i&gt;: "value := j.AsOrdinal" у TValue работает почти так же быстро, как и "value := j" для Variant. А методы AsInteger и AsInt64 – лучше не использовать. Но все равно, главный вывод: TValue – "тормоз"!&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Напоследок, я проверил с помощью функции SizeOf число байт, которые занимали переменные: переменная типа Variant занимала – 24 байта, а TValue – всего 16. Может в этом проявляется "облегченность" типа TValue? Тогда, храните числа в integer – они будут занимать 4 байта ;)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-2475655552894999300?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/2475655552894999300/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=2475655552894999300' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2475655552894999300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/2475655552894999300'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/delphi-2010-tvalue.html' title='Delphi 2010: TValue - &quot;тормоз&quot;!'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-3376384720092488782</id><published>2010-03-15T08:04:00.000+02:00</published><updated>2010-03-15T08:04:00.509+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS Word'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><title type='text'>Использование полей и закладок при работе с MS Word из Delphi</title><content type='html'>&lt;span style="font-family:verdana;"&gt;&lt;div align="justify"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В предыдущей заметке "&lt;a href="http://it-blackcat.blogspot.com/2010/03/ms-word-delphi.html"&gt;Поиск и замена текста в документе MS Word из Delphi&lt;/a&gt;" я рассказывал, как дорабатывал старый модуль, который генерирует клиентам компании письма в формате MS Word с помощью поиска и замены текста. Сдав модуль заказчикам, я в свободное от работы время, переделал его. Вместо поиска и замены  использовал поля с переменными (DocVariable).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В шаблон письма с помощью макроса добавил переменные&lt;br /&gt;&lt;br /&gt;Sub AddFields()&lt;br /&gt;&amp;nbsp;&amp;nbsp;ThisDocument.Variables.Add "FIO", "FIO"&lt;br /&gt;&amp;nbsp;&amp;nbsp;ThisDocument.Variables.Add "ADDRESS", "ADDRESS"&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;и расставил поля по тексту шаблона. В макросе у метода Add первый параметр – название переменной, а второй – ее значение. Я специально сделал их одинаковыми, чтобы пользователям было  проще и нагляднее редактировать шаблоны.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Затем  внес изменения в методы модуля работающие с MS Word.  Если опустить все детали и различную логику, то упрощенно работа с MS Word выглядит так:&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;wa: WordApplication;&lt;br /&gt;&amp;nbsp;&amp;nbsp;ovDotName, ovFileName: OleVariant;&lt;br /&gt;&amp;nbsp;&amp;nbsp;i: Integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;q: TSDQuery;&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;wa := CreateComObject(CLASS_WordApplication) as _Application;&lt;br /&gt;&amp;nbsp;&amp;nbsp;ovDotName := 'какой то шаблон.dot';&lt;br /&gt;&amp;nbsp;&amp;nbsp;wa.Documents.Add(ovDotName, EmptyParam, EmptyParam, EmptyParam);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;For i := 0 to q.FieldCount-1 do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MSWordSetVariable(q.Fields[i].FieldName, q.Fields[i].AsString);&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;ovFileName := 'письмо любимому клиенту.doc';&lt;br /&gt;&amp;nbsp;&amp;nbsp;wa.ActiveDocument.SaveAs(ovFileName, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Где MSWordSetVariable – процедура, которая присваивает значение переменной в документе MS Word.&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;procedure MSWordSetVariable(ovVariable: OleVariant; const sValue: String);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;If sValue = ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then wa.ActiveDocument.Variables.Item(ovVariable).Value := ' '&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else wa.ActiveDocument.Variables.Item(ovVariable).Value := sValue&lt;br /&gt;end;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Если переменной MS Word присвоить пустую строчку, то в поле выводится текст 'Ошибка! Переменная документа не указана.', поэтому вместо пустого значения я присваиваю ей пробел (так же делает и сам MS Word). Это связано со странной работой MS Word с коллекцией переменных. Если переменной присвоить пустую строку, то количество переменных в коллекции (Variables.Count) уменьшается на единицу, а попытка удалить переменную (Variables.Item(ovVariable).Delete) дает ошибку 'Объект был удален', т.е. присвоение пустой строки равносильно удалению. При этом после удаления переменной из коллекции переменных, присвоение ей непустого значения выполняется успешно и количество переменных в коллекции увеличивается на единицу, т.е. присвоение непустого значения равносильно вызову метода добавления переменной в коллекцию переменных.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Продемонстрирую вышесказанное примером кода, по которому видно как изменяется количество переменных (iCount):&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;iCount := wa.ActiveDocument.Variables.Count; // iCount  = 3&lt;br /&gt;wa.ActiveDocument.Variables.Item(ovVariable).Value := '';&lt;br /&gt;iCount := wa.ActiveDocument.Variables.Count; // iCount  = 2&lt;br /&gt;wa.ActiveDocument.Variables.Item(ovVariable).Value := 'не пусто';&lt;br /&gt;iCount := wa.ActiveDocument.Variables.Count; // iCount  = 3&lt;br /&gt;wa.ActiveDocument.Variables.Item(ovVariable).Delete;&lt;br /&gt;iCount := wa.ActiveDocument.Variables.Count; // iCount  = 2&lt;br /&gt;wa.ActiveDocument.Variables.Item(ovVariable).Value := 'не пусто';&lt;br /&gt;iCount := wa.ActiveDocument.Variables.Count; // iCount  = 3&lt;br /&gt;wa.ActiveDocument.Variables.Item(ovVariable).Value := '';&lt;br /&gt;iCount := wa.ActiveDocument.Variables.Count; // iCount  = 2&lt;br /&gt;wa.ActiveDocument.Variables.Item(ovVariable).Delete; // ошибка 'Объект был удален'&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вот такая логика у индусов, писавших этот кусок MS Word.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;После присвоения значений всем переменным, осталось только дать команду полям обновиться новыми значениями переменных. Для этого в VBA у коллекции объектов полей (Fields) есть метод Update:&lt;br /&gt;&lt;br /&gt;wa.ActiveDocument.Fields.Update&lt;br /&gt;&lt;br /&gt;А для того, чтобы избежать дальнейшего обновления полей, избавимся от их связи с переменными:&lt;br /&gt;&lt;br /&gt;wa.ActiveDocument.Fields.Unlink&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;У каждого структурного элемента документа (заметки, колонтитула, сноски и т.д.)  своя коллекция объектов полей, поэтому, если документ, как у меня, состоит из разных структурных элементов, то методы Update и Unlink необходимо вызвать для каждого из этих элементов. Для этого перебираем все элементы коллекции StoryRanges.&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;procedure MSWordUpdateStoryRanges;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRanges: Word2000.StoryRanges;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange: Word2000.Range;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;iStoryIndex: integer;&lt;br /&gt;Begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;StoryRanges := wa.ActiveDocument.StoryRanges;&lt;br /&gt;&amp;nbsp;&amp;nbsp;For iStoryIndex := wdMainTextStory to wdFirstPageFooterStory do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange := StoryRanges.Item(iStoryIndex);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If StoryRange &lt;&gt; nil then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange.Fields.Update;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange.Fields.Unlink;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;While (StoryRange.NextStoryRange &lt;&gt; nil) do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange := StoryRange.NextStoryRange;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange.Fields.Update;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange.Fields.Unlink;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange := nil;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;End;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Т.к. в моем шаблоне есть только основной текст и одна заметка, то вместо процедуры, которая перебирает все элементы коллекции StoryRanges, я сделал процедуру, которая работает только с одним ее элементом:&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;procedure MSWordUpdateStoryRange(const iStoryIndex: integer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange: Word2000.Range;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange := wa.ActiveDocument.StoryRanges.Item(iStoryIndex);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If StoryRange &lt;&gt; nil then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange.Fields.Update;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StoryRange.Fields.Unlink;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;br /&gt;end;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;И вызываю ее перед сохранением документа.&lt;br /&gt;&lt;br /&gt;MSWordUpdateStoryRange(wdMainTextStory);&lt;br /&gt;MSWordUpdateStoryRange(wdTextFrameStory);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Все бы ничего, но часть текста передаваемого из программы в MS Word необходимо было выводить жирным шрифтом. А это через переменные не сделать :( В подобном случае "поиск и замену текста" можно заменить на "переход к закладке и вывод текста". Например, в шаблон вставляем закладку с именем 'писать текст сюда', а в программе пишем:&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;ovBookmarkName, ovWhat: OLEVariant;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;ovWhat := wdGoToBookmark;&lt;br /&gt;&amp;nbsp;&amp;nbsp;ovBookmarkName := 'писать текст сюда';&lt;br /&gt;&amp;nbsp;&amp;nbsp;Try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If wa.Selection.GoTo_(ovWhat, EmptyParam, EmptyParam, ovBookmarkName) &lt;&gt; nil then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wa.Selection.TypeText('просто текст ');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wa.Selection.Font.Bold := 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wa.Selection.TypeText('жирный текст');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wa.Selection.Font.Bold := 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wa.Selection.TypeText(' просто текст');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Except&lt;br /&gt;&amp;nbsp;&amp;nbsp;End;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вот и все :)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Раннее связывание и использование полей/закладок дало существенный рост скорости генерации писем. Если на 500-х различных документах этого было почти не заметно, то при генерации 15 000 документов, прирост скорости составил 30% (специально проверил несколько раз на одних и тех же исходных данных).&lt;br /&gt;&lt;br /&gt;P.S. При работе с ранним связыванием мне не нравится только одно – многие параметры в методах объявлены, как VAR (даже индекс элемента коллекции!), поэтому приходится заводить для них специальную переменную типа OleVariant.&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-3376384720092488782?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/3376384720092488782/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=3376384720092488782' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/3376384720092488782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/3376384720092488782'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/ms-word-delphi_15.html' title='Использование полей и закладок при работе с MS Word из Delphi'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-8996331186106562477</id><published>2010-03-09T06:54:00.002+02:00</published><updated>2010-03-14T21:27:33.461+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS Word'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><title type='text'>Поиск и замена текста в документе MS Word из Delphi</title><content type='html'>&lt;div align="justify"&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Попросили меня доработать старый модуль, который генерирует клиентам компании письма в формате MS Word. Пользователи создают шаблоны, в которых расставляют названия полей, заключенные в служебные символы (например, #CONTRACT_NUM#, #FIO#, #ADDRESS#...). Программа по заданным критериям выбирает информацию о клиентах из базы и генерирует письма, находя в тексте шаблонов названия полей и заменяя их фактическими значениями.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Если опустить все детали и различную логику, то упрощенно это выглядит так:&lt;br /&gt;&lt;span style="font-size: 90%;"&gt;&lt;br /&gt;Var&lt;br /&gt;&amp;nbsp;&amp;nbsp;MSWord: OleVariant;&lt;br /&gt;&amp;nbsp;&amp;nbsp;i: Integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;q: TSDQuery;&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;MSWord := CreateOleObject('Word.Application');&lt;br /&gt;&amp;nbsp;&amp;nbsp;MSWord.Documents.Add('какой то шаблон.dot');&lt;br /&gt;&amp;nbsp;&amp;nbsp;For i := 0 to q.FieldCount-1 do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MSWord.Selection.Find.Execute(FindText := '#' + q.Fields[i].FieldName + '#', ReplaceWith := q.Fields[i].AsString);&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;MSWord.ActiveDocument.SaveAs('письмо любимому клиенту.doc');&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Первое, с чем я столкнулся, это то, что длина значения параметра ReplaceWith не должна превышать 255 символов. Но это я обошел легко, заменив "поиск и замену текста" на "поиск и вывод текста":&lt;br /&gt;&lt;span style="font-size: 90%;"&gt;&lt;br /&gt;If MSWord.Selection.Find.Execute(FindText := '#' + q.Fields[i].FieldName + '#') then&lt;br /&gt;&amp;nbsp;&amp;nbsp;MSWord.Selection.TypeText(q.Fields[i].AsString);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Вторая задачка оказалась сложнее. Внизу листа в фиксированное место необходимо было вывести фамилию и адрес получателя. Сначала я думал поместить его в нижний колонтитул, но оказалось, что письмо может быть на двух листах. Тогда ничего не оставалось, как использовать объект "заметка". Вставил "заметку". Красота! Документ генерируется, текст сдвигается, заметка остается на месте... Но радость была недолгой, т.к. поля #FIO# и #ADDRESS#, помещенные в заметку, так и остались незамененными :(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Оказалось, что MSWord.Selection.Find.Execute ищет текст только в основной части документа, а в документе, состоящем из разных структурных элементов (заметок, колонтитулов, сносок и т.д.), поиск необходимо производить отдельно в каждом из этих элементов. Все эти структурные элементы документа являются элементами коллекции StoryRanges. Т.к. дело было к ночи, а модуль должен был быть готов к утру, я не стал разбираться, как работать со StoryRanges через OLE из Delphi, и просто добавил в тестовый шаблон письма макрос на VBA, в котором перебираются все структурные элементы активного документа, в которых ведется поиск:&lt;br /&gt;&lt;span style="font-size: 90%;"&gt;&lt;br /&gt;Sub ReplaceText(sFindText As String, sReplaceText As String)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Dim rngStory As Range&lt;br /&gt;&amp;nbsp;&amp;nbsp;For Each rngStory In ActiveDocument.StoryRanges&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;With rngStory.Find&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Text = sFindText&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Replacement.Text = sReplaceText&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Wrap = wdFindContinue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Execute Replace:=wdReplaceAll&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End With&lt;br /&gt;&amp;nbsp;&amp;nbsp;Next rngStory&lt;br /&gt;End Sub&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;А в программе я только написал вызов макроса:&lt;br /&gt;&lt;span style="font-size: 90%;"&gt;&lt;br /&gt;MSWord.Application.Run('ReplaceText', '#FIO#', 'Иванов Иван Иванович');&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Работает как часы :)&lt;br /&gt;&lt;br /&gt;P.S. После окончания генерации документа, если MS Word вам больше не нужен, то не забывайте закрывать его и высвобождать память&lt;br /&gt;&lt;span style="font-size: 90%;"&gt;&lt;br /&gt;MSWord.Quit;&lt;br /&gt;MSWord := UnAssigned;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;P.P.S. Для подобной задачи генерации писем в формат MS Word больше подходит не поиск и замена текста, использование полей с переменными (DocVariable) и закладок (Bookmark). А как это сделать, я расскажу в следующий раз.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-8996331186106562477?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/8996331186106562477/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=8996331186106562477' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/8996331186106562477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/8996331186106562477'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/ms-word-delphi.html' title='Поиск и замена текста в документе MS Word из Delphi'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9002454583040968876.post-271550454482767474</id><published>2010-03-04T12:29:00.010+02:00</published><updated>2010-03-07T21:38:44.759+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi 2010'/><title type='text'>Delphi 2010: Сносим назойливый Code Formatter</title><content type='html'>&lt;div align="justify"&gt;&lt;span style="font-family:verdana;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;В далекие школьные годы у нас в школе стоял компьютер ДВК-2М. По сравнению с общераспространенными БК - это было чудо техники, с нормальным монитором и даже с винчестером. На нем я писал свои первые программки. Однажды, когда я писал очередной "шедевр", в соседний кабинет вошла уборщица и включила свет. Этот щелчок включателя я запомнил надолго. При включении света, компьютер моргнул экраном и начал перезагружаться, унеся с собой больше часа моей работы. Это послужило для меня уроком. С тех пор, я регулярно сохраняюсь и, раз в несколько минут, мои руки автоматически жмут Ctrl+S.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Когда я начал писать свою первую программу на Delphi 2010, я случайно промахнулся и нажал Ctrl+D вместо Ctrl+S. Каково было мое изумление, когда я заметил, что код программы стал выглядеть совсем не так, как я привык его форматировать за свои 14 лет работы с Delphi.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Я вспомнил, что одним из нововведений Delphi 2010 является "&lt;strong&gt;Code Formatter&lt;/strong&gt;" - встроенный модуль для форматирования исходного кода. Больше часа я бился над его настройкой, но все равно не смог настроить его под себя - он упорно переносил строчки не так как мне нужно. Решив его больше не трогать, я продолжил работать, пока снова, случайно не нажал Ctrl+D...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Поиски настройки, отключающей это чудо программисткой мысли Embarcadero, ничего не дали и, как я понял, мирным способом договориться с Delphi IDE не форматировать мои исходники не получится.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Значит, мы пойдем другим путем! Возможности Delphi IDE расширяется за счет отдельных модулей, поэтому существует большая вероятность того, что этот форматер вынесен в отдельную BPL или DLL. Подумав так, я не ошибся - в каталоге "RAD Studio\7.0\bin" я нашел &lt;strong&gt;Embarcadero.Modeling.Formatter.dll&lt;/strong&gt;, в свойствах которой было написано "Embarcadero RAD Studio Formatter". В реестре среди "Known IDE Packages" форматера я не заметил, поэтому, выбрав Embarcadero.Modeling.Formatter.dll, я безжалостно нажал Shift+Delete. С тех пор форматер кода меня больше в Delphi 2010 не беспокоит :)&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9002454583040968876-271550454482767474?l=it-blackcat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://it-blackcat.blogspot.com/feeds/271550454482767474/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9002454583040968876&amp;postID=271550454482767474' title='Комментарии: 13'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/271550454482767474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9002454583040968876/posts/default/271550454482767474'/><link rel='alternate' type='text/html' href='http://it-blackcat.blogspot.com/2010/03/delphi-2010-code-formatter.html' title='Delphi 2010: Сносим назойливый Code Formatter'/><author><name>Чорны кашак</name><uri>http://www.blogger.com/profile/16771614324716527749</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://1.bp.blogspot.com/_LgmJBoD0CMM/ShUSAb5ksJI/AAAAAAAAAZY/NUQ9to1urxY/S220/BlackCat.jpg'/></author><thr:total>13</thr:total></entry></feed>
