<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Intacta: Бортовой журнал &#187; Программирование</title>
	<atom:link href="http://blog.intacta.ru/category/%d0%9f%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.intacta.ru</link>
	<description></description>
	<lastBuildDate>Mon, 10 Oct 2011 23:54:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Кастомизируем Бизнес Пак</title>
		<link>http://blog.intacta.ru/2009/11/16/custom-business-pack/</link>
		<comments>http://blog.intacta.ru/2009/11/16/custom-business-pack/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 04:52:50 +0000</pubDate>
		<dc:creator>alexf</dc:creator>
				<category><![CDATA[Программирование]]></category>

		<guid isPermaLink="false">http://blog.intacta.ru/?p=360</guid>
		<description><![CDATA[У меня есть несколько новостей по популярной программе Бизнес Пак 7-ой версии. Начнем с хороших. Во-первых, для хранения данных вместо формата DBF (который был известен еще царю Гороху) теперь используется Embedded Firebird. Во-вторых, в программу встроен скриптовый движок, который позволяет изменить или дополнить имеющийся функционал. Плохих новостей тоже две. Во-первых, язык для скриптования &#8212; MzScheme. [...]]]></description>
			<content:encoded><![CDATA[<p>У меня есть несколько новостей по популярной программе <a href="http://pvision.ru/bp.htm">Бизнес Пак</a> 7-ой версии.</p>
<p>Начнем с хороших. Во-первых, для хранения данных вместо формата DBF (который был известен еще царю Гороху) теперь используется Embedded Firebird. Во-вторых, в программу встроен скриптовый движок, который позволяет изменить или дополнить имеющийся функционал.</p>
<p>Плохих новостей тоже две. Во-первых, язык для скриптования &#8212; MzScheme. (Хорошо, что они Forth не выбрали.) Во-вторых, нет никакой документации и уже имеющиеся скрипты не содержат ни одного информативного комментария.<br />
<span id="more-360"></span></p>
<h4>Условия задачи</h4>
<p>Попробуем сделать на базе Бизнес Пак (далее &#8212; БП) свое решение для стола заказов. Стол заказов обслуживает частных клиентов из нескольких населенных пунктов. Обслуживание заключается в выписывании счетов. В счет включаются товары из нескольких групп.</p>
<h4>Фото-отчет</h4>
<p>Чтобы вы поняли, о чем идет речь, &#8212; несколько скриншотов.</p>
<p>Было:<br />
<img src="http://blog.intacta.ru/wp-content/uploads/2009/11/bp1.jpg" alt="bp1" title="bp1" width="821" height="668" class="alignnone size-full wp-image-367" /></p>
<p>Стало:<br />
<img src="http://blog.intacta.ru/wp-content/uploads/2009/11/bp2.jpg" alt="bp2" title="bp2" width="496" height="290" class="alignnone size-full wp-image-369" /></p>
<p><img src="http://blog.intacta.ru/wp-content/uploads/2009/11/bp3.jpg" alt="bp3" title="bp3" width="564" height="349" class="alignnone size-full wp-image-371" /></p>
<p><img src="http://blog.intacta.ru/wp-content/uploads/2009/11/bp4.jpg" alt="bp4" title="bp4" width="460" height="244" class="alignnone size-full wp-image-373" /></p>
<p><img src="http://blog.intacta.ru/wp-content/uploads/2009/11/bp5.jpg" alt="bp5" title="bp5" width="575" height="187" class="alignnone size-full wp-image-375" /></p>
<h4>Just do it</h4>
<p>Системные скрипты БП находятся в каталоге <code>scm</code>. Скрипты, описывающие документы &#8212; в каталоге <code>documents</code>. Шаблоны печатных форм &#8212; в каталоге <code>reports</code>.</p>
<p>Для начала удалим лишние файлы: из каталога <code>documents</code> &#8212; все, кроме файла <code>dictionary.scm</code>, а из каталога <code>reports</code> &#8212; все, кроме файла <code>bpfunc.pas</code>.</p>
<p>Все сущности, хранящиеся в БД, описываются списком <code>tables</code> в файле <code>scm\meta.scm</code>.</p>
<p>Со справочниками все просто. Мы добавим две новые сущности:</p>
<pre class="brush: plain; title: ; notranslate">
      (tables
       ...
       (Settlement
        (desc &quot;Населенные пункты&quot;)
        (fields
         (Name (type LongString) (caption &quot;Наименование&quot;) (tags def desc))
        )
       )
       (Client
        (desc &quot;Клиенты&quot;)
        (fields
         (Settlement (type Settlement) (caption &quot;Населенный пункт&quot;))
         (Name (type LongString) (caption &quot;ФИО&quot;) (tags def desc))
         (Address (type LongString) (caption &quot;Адрес&quot;))
         (Phone (type LongString) (caption &quot;Телефон&quot;))
        )
       )
</pre>
<p>Список <code>fields</code> здесь задает полный перечень атрибутов, а <code>type</code> описывает тип данных. Доступные типы данных и их соответствие SQL-типам можно посмотреть в этом же файле в списке <code>types</code>.</p>
<p>Здесь же в списке <code>indexes</code> можно определить индексы для таблиц базы данных, например так:</p>
<pre class="brush: plain; title: ; notranslate">
      (indexes
       ...
       (Client
         (Name))
       (Settlement
         (Name))
</pre>
<p>При обработке файла <code>meta.scm</code> БП выполнит для наших сущностей такие SQL-операторы:</p>
<pre class="brush: sql; title: ; notranslate">
CREATE TABLE &quot;tSettlement&quot; (
    &quot;fObject&quot;  CHAR(12) NOT NULL,
    &quot;fName&quot;    VARCHAR(250) DEFAULT '' NOT NULL
);
ALTER TABLE &quot;tSettlement&quot; ADD CONSTRAINT PK_SETTLEMENT PRIMARY KEY (&quot;fObject&quot;);
CREATE INDEX I_SETTLEMENT2_N0 ON &quot;tSettlement&quot; (&quot;fName&quot;);
CREATE TABLE &quot;tClient&quot; (
    &quot;fObject&quot;       CHAR(12) NOT NULL,
    &quot;fSettlement&quot;   CHAR(12) DEFAULT '000000000000' NOT NULL,
    &quot;fName&quot;         VARCHAR(250) DEFAULT '' NOT NULL,
    &quot;fAddress&quot;      VARCHAR(250) DEFAULT '' NOT NULL,
    &quot;fPhone&quot;        VARCHAR(250) DEFAULT '' NOT NULL
);
ALTER TABLE &quot;tClient&quot; ADD CONSTRAINT PK_CLIENT PRIMARY KEY (&quot;fObject&quot;);
ALTER TABLE &quot;tClient&quot; ADD CONSTRAINT FK_CLIENT_SETTLEMENT FOREIGN KEY (&quot;fSettlement&quot;) REFERENCES &quot;tSettlement&quot; (&quot;fObject&quot;);
CREATE INDEX I_CLIENT1_N0 ON &quot;tClient&quot; (&quot;fName&quot;);
</pre>
<p>Обратите внимание, БП сам управляется с первичными и внешними ключами.</p>
<p>В файле <code>scm\layout.scm</code> дополним список <code>defaults</code> следующими &laquo;магическими&raquo; элементами:</p>
<pre class="brush: plain; title: ; notranslate">
     (defaults
       ...
       (Settlement
        (dataset ds-settlement-min)
        (form form-settlement-std))
       (Client
        (dataset ds-client-min)
        (form form-client-std))
</pre>
<p>Почему &laquo;магическими&raquo;? Потому, что достоверно установить, что именно они означают, не удалось. Но они нужны.</p>
<p>С документами чуть-чуть иначе. Дело в том, что в БП все документы, вне зависимости от их вида, являются одной сущностью &#8212; <code>Doc</code>. В принципе, наш документ (а это заказ), отличается от прочих документов БП лишь тем, что второй контрагент &#8212; не фирма, а определенный нами выше <code>Client</code>. Самым простым решением будет дополнить описание <code>Doc</code> таким образом:</p>
<pre class="brush: plain; title: ; notranslate">
       (Doc
         ...
         (Client
          (type Client))
</pre>
<p>Такое решение, конечно же, отразиться на всех других документах, но&#8230; Во-первых, в нашей системе других документов и не будет, и, во-вторых, атрибут <code>Client</code> у документа будет отображаться в интерфейсе пользователя только там, где мы явным образом это разрешим.</p>
<p>На этом модификация имеющихся скриптов завершена. Имейте в виду, в БП встроена система обновления через интернет, и вполне может быть, что очередное обновление перепишет модифицированные нами файлы. Со всеми вытекающими&#8230;</p>
<p>Все остальное наше творчество будем записывать в файл <code>documents\order.scm</code>. Почему именно &laquo;order&raquo;? Потому, что в дистрибутиве БП нет файла с таким именем, значит автообновление нам не грозит. И еще, &laquo;order&raquo; &#8212; это &laquo;заказ&raquo; в переводе на великий и могучий.</p>
<p>В файле <code>documents\order.scm</code> находятся скрипты, описывающие интерфейс пользователя. В нашем примере таких скриптов &#8212; четыре, все они перечислены в списке <code>export</code>, что делает их доступными для ядра БП:</p>
<pre class="brush: plain; title: ; notranslate">
(define export '(export
                 (forms form-settlement-dict
                        form-client-dict
                        doc-order
                        arch-order)))
</pre>
<p><code>form-NNN-dict</code> представляет собой скрипт интерфейса пользователя для справочника <code>NNN</code>, а <code>doc-MMM</code> и <code>arch-MMM</code> &#8212; для документа <code>MMM</code> и архива документов <code>MMM</code> соответственно.</p>
<p>Названия скриптов интерфейса пользователя используются в именовании файлов с печатными формами в каталоге <code>reports</code>. Имя файла печатной формы выглядит так: <code>SSS.MMM.fr3</code>, где <code>SSS</code> &#8212; имя скрипта интерфейса пользователя, а <code>MMM</code> &#8212; название печатной формы в интерфейсе пользователя. Например, печатная форма для справочника клиентов в нашем примере может называться <code>form-client-dict.Список клиентов.fr3</code>, а печатная форма для заказа &#8212; <code>doc-order.На кухню.fr3</code>. Самый простой способ создать печатную форму &#8212; отредактировать одну из готовых печатных форм БП.</p>
<p>К сожалению, большую часть того, что я &laquo;накопипастил&raquo; в файл <code>documents\order.scm</code> связно объяснить я не могу. Поэтому предлагаю заинтересовавшимся <a href="http://blog.intacta.ru/wp-content/uploads/2009/11/custombp.zip">скачать</a> мое готовое решение и &laquo;скопипастить&raquo; что-нибудь из него.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intacta.ru/2009/11/16/custom-business-pack/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

