Как из приложения Delphi сформировать счет

01.07.2020

Говоря о приложениях Delphi мы понимаем, что речь идет о приложениях, реализованных на библиотеке VCL (Visual Component Library) для операционной системы Windows. С появлением языка программирования C# и платформы .Net популярность Delphi VCL несколько угасла, но тем не менее по всему миру остается огромное количество Delphi программистов. Множество программ, написано на библиотеке VCL и требует модернизации. 

Если вы реализуете информационную систему учета товарооборота, вам понадобится формировать некоторые документы из программы. Это могут быть отчеты, товарные и кассовые чеки, счет. В этой статье мы рассмотрим весь процесс вывода счета на печать от создания приложения до вывода отчета.

Для создания приложения мы будем использовать среду разработки Delphi 7, а для создания отчета – генератор отчетов FastReport VCL.

Работа над приложением сводится к добавлению на форму нужных компонентов и их настройке.

На панели компонентов найдем вкладку FastReport и добавим на форму компонент frxReport. Также нам потребуется создать источник данных для отчета. Для примера используем базу данных из поставки FastReport VCL demo.mdb. Из базы данных мы возьмем четыре таблицы: Orders, Customer, Items, Parts.

Из вкладки ADO в палитре компонентов перетягиваем на форму компонент ADOConnection. Настроим подключение к базе данных demo.mdb. Теперь добавим четыре компонента ADOTable. 

Из вкладки DataAccess добавляем четыре компонента DataSource.

Из вкладки FastReport добавляем четыре компонента frxDBDataSet. 

У нас получилось четыре тройки: ADOTable, DataSource, frxDBDataSet. Настраивать их нужно именно такими тройками.

Приступим. 

Первая тройка:

  • Для ADOTable задаем свойства:
  1. Connection – ADOConnection1;
  2. Name – Orders;
  3. TableName – orders.
  • Для DataSource настраиваем свойство:
  1. DataSet – Orders.
  • Для frxDBDataSet настраиваем свойства:
  1. DataSet – Orders;
  2. UserName – Orders.

Вторая тройка:

  • Для ADOTable задаем свойства:
  1. Connection – ADOConnection1;
  2. Name – Customer;
  3. IndexFieldnames – CustNo;
  4. MasterSource – DataSource1;
  5. MasterFields - CustNo
  6. TableName – customer.
  • Для DataSource настраиваем свойство:
  1. DataSet – Customer.
  • Для frxDBDataSet настраиваем свойства:
  1. DataSet – Customer;
  2. UserName – Customer.

Третья тройка:

  • Для ADOTable задаем свойства:
  1. Connection – ADOConnection1;
  2. Name – Items;
  3. IndexFieldnames – OrderNo;
  4. MasterSource – DataSource1;
  5. MasterFields - OrderNo
  6. TableName – items.
  • Для DataSource настраиваем свойство:
  1. DataSet – Items.
  • Для frxDBDataSet настраиваем свойства:
  1. DataSet – items;
  2. UserName – Items.

Четвертая тройка:

  • Для ADOTable задаем свойства:
  1. Connection – ADOConnection1;
  2. Name – Parts;
  3. TableName – parts.
  • Для DataSource настраиваем свойство:
  1. DataSet – Parts.
  • Для frxDBDataSet настраиваем свойства:
  1. DataSet – Parts;
  2. UserName – Parts.

Наверно вы обратили внимание, что таблицы: Customer и Items имеют связь с DataSource1, то есть с первой таблицей Orders. Это означает, что они связаны по ключу связь один ко многим. Один Customer может быть во многих заказах и так далее. Это нужно, чтобы в отчете, при выводе информации по конкретному заказу «подтягивались» данные из связанных таблиц актуальные для этого заказа.

Для упрощения нашей дальнейшей работы с шаблоном отчета, давайте создадим вычислимые поля в ADOTable для таблицы Items. Дважды кликаем по этому объекту и видим окно с полями таблицы. Вернее, изначально оно пусто, но из контекстного меню можно их загрузить, выбрав Add fields…:

 Items ADOTable fields window with Price and Description added

Поля Price и Description будут взяты из таблицы Parts.

В контекстном меню выбираем New field…. И добавляем поле Price:

 Price field adding to Items ADOTable

Таким же способом добавим описание товара – Description:

 Description field adding to Items ADOTable

Таким образом, мы избавились от необходимости задействовать таблицу Parts в своем отчете, все, что нам было нужно мы из нее уже взяли.

Теперь, когда мы создали источник данных, настроили связи между таблицами, давайте добавим на форму пару кнопок: Design Report, и ShowReport.

Как вы уже догадались, первая запускает дизайнер отчета, вторая – отображает отчет.

Для каждой из кнопок добавим событие нажатия. Код обработчика события для отображения дизайнера отчетов:

1
frxReport1.DesignReport();

А для печати готового отчета можно добавить на форму диалог открытия файла чтобы выбрать созданный в дизайнере отчет. Тогда код для вывода отчета на печать будет таким:

1
2
3
4
5
6
7
8
OpenDialog1.Filter := 'FastReport VCL (*.fr3)|*.FR3';
 OpenDialog1.Execute();
 if Length(OpenDialog1.FileName)>0 then
 begin
 frxReport1.LoadFromFile(OpenDialog1.FileName);
 frxReport1.PrepareReport();
 frxReport1.Print();
end

А если нужно предварительно посмотреть отчет, то можно заменить функцию печати на отображение отчета:

1
 frxReport1.ShowReport();

Теперь можно запустить приложение, нажать на кнопку Design report и перейти к созданию отчета.

Пришло время поговорить об отчете, который мы собираемся создать. Чтобы документ был понятным и не вызывал вопросов у покупателя нужно наполнить его всей необходимой информацией. Но, в то же время нельзя и перегружать его ей. Попробуем соблюсти этот тонкий баланс. Итак, по нашему мнению, счет на оплату должен содержать следующие информационные блоки:

 Invoice template

На этом рисунке отмечены важные области документа:

  1. Информация о продавце. Любой официальный документ должен содержать информацию о продавце: название, адрес, телефон, электронная почта, возможно что-то еще;
  2. Информация о контактном лице покупателя – необходимо указать реально ответственное за оплату лицо;
  3. Идентификаторы заказа и счета, дата формирования счета и срок оплаты. Эти идентификаторы помогут отыскать счет или заказ в базе данных, в случае возникновения вопросов у клиента;
  4. Информация о составе заказа. Клиент должен понимать за что платит. Нужно указывать наименование и количество товара, а также его стоимость за единицу;
  5. Итоговая сумма. Итоговые суммы необходимы не только для произведения оплаты, но и для понимания расчета;
  6. Реквизиты для платежа. Так как это счет на оплату, конечно тут должны быть реквизиты получателя платежа;
  7. Реквизиты для оплаты из-за рубежа. Даже если, в данном случае покупать не из-за границы, можно оставить эти данные для единообразного бланка;
  8. Разъяснительная информация. Важно указать контактные данные, в случае вопросов. А также нужно сразу предупредить о последствиях несвоевременной оплаты. Это будет мотивировать клиента не затягивать.

Нам предстоит создать такой документ в дизайнере отчетов, который мы уже запустили. Прежде всего выберем данные для отчета.

 Report datasets

Таблица Parts нам не понадобится в этом отчете, поэтому ее можно не выбирать. Перейдем к созданию шаблона. В нашем отчете будет два уровня данных MasterData и DetailData. В первом бэнде данных мы выводим информацию о клиенте:

  • название - Customer.Company;
  • адрес - Customer.Addr1;
  • телефон - Customer.Phone.

 и продавце:

  • номер заказа – Orders.OrderNo;
  • дата заказа - системная переменная [Date];
  • срок оплаты - текущая дата [Date] + нужное количество дней.

Этот бэнд подключен к таблице Orders. В подчиненном бэнде данных будет выводиться информация о содержимом заказа: наименование товара, количество, стоимость за единицу, стоимость указанного количества, налог, который не включен в стоимость в некоторых странах (показан для примера), общая стоимость налога для указанного количества единиц товара.

В подвале бэнда данных будут отображены итоги: итог по стоимости налогов, итог стоимости без налогов, общая стоимость с учетом налогов. Также, здесь будут реквизиты для оплаты заказа.

Report template

В подвал страницы добавим разъяснительную информацию, которая поможет избежать некоторых вопросов клиента:

Invoce additional information 

Промежуточные итоги Net, которые рассчитываются в рамках одной записи таблицы создаются путем перемножения количества и цены единицы товара:

[<Items."Qty">*<Items."Price">]

Стоимость налога рассчитывается по формуле:

количество товара * стоимость единицы товара * процент налога

[<Items."Qty">*<Items."Price">*0.05]

Общая стоимость всех товаров без учета налога:

∑(количество товара * стоимость единицы товара)

[SUM(<Items."Qty">*<Items."Price">)]

Общая стоимость налога:

∑( количество товара * стоимость единицы товара * процент налога)

[SUM(<Items."Qty">*<Items."Price">)*0.05]

Общая стоимость с учетом налога:

∑(количество товара * стоимость единицы товара)+ ∑( количество товара * стоимость единицы товара * процент налога)

[SUM(<Items."Qty">*<Items."Price">) + SUM(<Items."Qty">*<Items."Price">)*0.05]

Вот и все. Сохраняем отчет на локальном диске и закрываем дизайнер отчетов. С помощью второй кнопки выбираем созданный отчет на локальном диске и получаем диалоговое окно печати, либо построенный отчет, если вы в коде кнопки выбрали ShowReport().

Invoice showed in the report

Таким образом мы создали счет на оплату и отобразили его пользователю за каких-то полчаса. Теперь, из окна просмотра отчета мы можете отправить его на печать, или сохранить в один из популярных форматов электронных документов, таких как: PDF, docx, xlsx, rtf и многие другие.

20 ноября 2024

Локализация и смена языков в FastReport VCL

FastReport VCL поддерживает 40 языков для локализации интерфейса и позволяет изменять язык на лету через меню или код, без перекомпиляции.
2 сентября 2024

Обзор облачного решения для создания и управления отчетами

МоиОтчеты Облако — это мощное облачное решение для создания и управления отчетами, обеспечивающее широкий спектр возможностей, от создания документов в различных форматах до интеграции с корпоративными системами.
11 декабря 2023

Новый транспорт S3 (Amazon) в FastReport VCL

В этой статье мы рассмотрим новый транспорт в S3 (Amazon) для FastReport VCL, являющийся объектным хранилищем файлов и бакетов.