В статье рассказывается о новых оригинальных возможностях по созданию различных форм документов для мебельного производства, реализованных в системе -БАЗИС 2023. В ней приводятся практические примеры, направленные на оптимизацию управления документацией в данной области.
Мебельное производство является важным и динамично развивающимся сектором российской экономики. По данным, озвученным на III Всероссийской конференции производителей мебели (4 июля 2023 г.), производство мебели растет. В частности, за первые пять месяцев 2023 года рост выпуска изделий составил в стоимостном выражении 1,5%, а в натуральном — 5,6% [1].
Мебельный бизнес находится под воздействием множества факторов: изменение трендов в дизайне, новые технологии, материалы, фурнитура и оборудование, повышенное внимание к экологичности, быстро меняющиеся вкусы потребителей. В этом контексте эффективное управление процессом формирования отчетов и документов является немаловажным моментом, способствующим конкурентоспособности предприятий.
Создание, хранение и обмен документами — этим аспектам автоматизации в системе БАЗИС всегда уделялось самое пристальное внимание, поскольку они формируют единую среду для проектирования, технологической подготовки, производства и контроля качества, гарантируя уверенность в соответствии изделий требованиям и стандартам [2, 3]. В этой статье речь пойдет о некоторых «тонких» моментах, связанных с настройками генератора отчетов на специфику документооборота на некотором конкретном предприятии. Грамотное их применение позволит оптимизировать производственные процессы, что, в конечном счете, положительно скажется на общей эффективности всех бизнес-процессов.
Генератор отчетов БАЗИС
С ростом числа вопросов, касающихся различных аспектов работы с генератором отчетов в системе БАЗИС, появляется понимание того, что современный пользователь системы — это мебельщик, не чурающийся программирования и достаточно серьезных вопросов информационных технологий. Именно на такого человека и рассчитан данный материал.
Все примеры кейсов мы будем рассматривать, используя модель, состояющую из шести различных панелей, ряд кромок которых отделан различными облицовочными материалами. Помимо этого к модели добавлено 500 единиц дополнительного материала для демонстрации построения простой, но действенной защиты от возможных некорректных ситуаций.
Внешний вид отчета, сформированного с применением шаблона Общий отчет из библиотеки стандартных шаблонов, входящей в стандартную поставку системы БАЗИС, приведен на рис. 1. Как видно, по умолчанию данные не отсортированы. На отчете виден определенный набор колонок (в том числе и пустых, на печать которых также тратится краска — мелочь, но всё же), а кроме того, в превью есть изображения одинаковых панелей. Вопрос: все ли они так нужны? Попробуем найти ответы на эти и некоторые другие практические вопросы, а также рассмотрим примеры кейсов, которые присылали пользователи системы.
Для начала немного теории. Система Fast Report позволяет работать с различными типами данных. Отметим, что соответствующий модуль входит в дистрибутив системы и не требует дополнительной установки. Начиная с 2021 года в системе БАЗИС проведена работа по типизации данных — выделено понятие «потенциально строковые данные». К ним относятся позиции, обозначения, артикулы и ряд других данных. Соответственно, все операции, применимые к ним, выполняются по правилам работы со строками, даже в том случае, когда они представлены числами. Например, если позиции, как в приведенном примере на рис. 1, записаны цифрами, по умолчанию система будет считать их строками, и в результате сложения позиций 3+1+2+4+5+6 результат будет не 25, а 312456 (конкатенация строк). Казалось бы — зачем? Вроде бы «очевидно», что позиции очень удобно сортировать и обрабатывать именно как числа. Однако при простановке позиций в случае облицовок пласти система к номеру позиции автоматически добавляет символ (рис. 2). Значит, рассмотрение номеров позиций в виде строк имеет какие-то плюсы. Это действительно так: кажущееся «неудобство» строк позволяет находить интересные решения некоторых реальных задач.
Рис. 1. Структура общего отчета
Рис. 2. Фрагмент отчета с облицовкой пласти
Кейс 1. Как выбрать облицованные панели
В набор данных, которые выводятся в отчет по стандартному шаблону, входит избыточное их количество, что позволяет применять различные подходы к решению задачи, обозначенной в заголовке:
- Использовать фильтр, который будет проверять отсутствие данных в конкретных полях у каждого из объектов. В данном случае это такие поля, как «Пластик (лицевая)»,«Пластик (нелицевая)»,«Пластик (лицевая) Арт.»и«Пластик (нелицевая) Арт.».
- Проверять значение определенного пользовательского свойства. Минус этого варианта в том, что для упрощения назначения необходимо использовать скрипты, а это программирование, на которое у многих просто нет времени.
- Использовать стандартную функцию SmartSort (об этом пойдет речь во втором кейсе).
Итак, используем первый подход. Перед решением задачи необходимо обратить внимание на тот факт, что у произвольного материала может отсутствовать либо артикул, либо наименование, но не оба свойства одновременно. Другими словами, если строки «Артикул» и «Наименование» могут быть пустыми, то строка «Артикул+Наименование» не будет пустой никогда.
Соответственно в рассматриваемом случае фильтр будет иметь вид:
<Панели."Пластик (лицевая)"> + <Панели."Пластик (лицевая) Арт."> +
<Панели."Пластик (нелицевая)">+ <Панели."Пластик (нелицевая) Арт."> <> "
Структура запроса в редакторе выражений приведена на рис. 3, а на рис. 4 показан результат работы фильтра. Очевидно, что для нахождения необлицованных панелей в приведенном выше фильтре достаточно заменить знак неравенства на знак равенства: вместо «<>» написать «=».
Рис. 3. Фильтр для отбора облицованных панелей
Рис. 4. Предварительный просмотр отфильтрованного списка панелей
Может возникнуть вопрос: если при облицовке пласти толщина панели увеличивается на одну или две толщины облицовочного материала, то почему бы не использовать в качестве фильтра сравнение толщины детали с облицовкой и ее толщины без облицовки? Причина проста: иногда для удобства или по иным технологическим причинам толщину облицовки ставят равной нулю, что приводит к неустойчивой работе подобного фильтра.
О функциях сортировки
Теперь попробуем отсортировать результаты выдачи по позиции. В генераторе отчетов БАЗИС 2023 реализовано три функции сортировки (Sort, Multisort и SmartSort), которые отличаются как синтаксисом, так и своими возможностями. Кратко можно сказать следующее:
- Функция Sort исторически появилась первой. Она организует алфавитную сортировку по единственному полю и не поддерживает сортировку по нескольким полям одновременно.
- Функция Multisort предназначена для сортировки данных по нескольким полям. Она, как и Sort, чувствительна к типу данных и поддерживает сортировку разных данных в различных направлениях.
- Функция SmartSort реализована как дальнейшее развитие Multisort и частично использует ее синтаксис. Она поддерживает множественную сортировку и всегда обрабатывает данные как смешанные (тип данных Variant, если быть точными с точки зрения программирования). Кроме того, у функции SmartSort появилась возможность фильтрации данных «на лету».
Для текущего набора данных в целом не важно, какую функцию выбрать, однако на больших наборах данных позиция 10 может оказаться выше, чем позиция 9, или ниже ее, в зависимости от типа сортировки. Во избежание ошибок воспользуемся смешанной сортировкой в функции SmartSort, общий синтаксис которой имеет вид:
SmartSort(DatasetUsername: string; Format: string; Condition: string = "),
где DatasetUserName — имя набора данных для сортировки;
Format — колонки для сортировки и порядок ее выполнения (возрастание/убывание);
Condition — необязательный параметр: условие отбора, записанное в виде строки.
Таким образом, для решения кейса 1 и сортировки результата можно воспользоваться следующим кодом:
SmartSort('Панели', 'Позиция', ' «Пластик (лицевая) Арт." + "Пластик (лицевая)" + "Пластик (нелицевая) Арт." + "Пластик (нелицевая)" ' <> ' " ');
Названия столбцов «экранируются» кавычками, пустая строка (два подряд идущих апострофа) также экранируются кавычками, и в целом вся строка заключается в кавычки. Такой вариант решения задачи исключает необходимость настраивать фильтр у бэнда через редактор выражений.
Аналогично можно делать любые фильтры, учитывая при этом тип данных колонок.
Кейс 2. Как скрыть пустую колонку
Продолжим работать с шаблоном и воспользуемся еще одной функцией — HideEmpty. Она позволяет скрыть колонку, в которой отсутствуют данные. В рассматриваемом случае такой колонкой является колонка с названием Паз. Общий синтаксис команды:
HideEmpty(MemoName: string; HeaderName: string ="),
где MemoName — название компонента, хранящего данные, проверяемые на отсутствие;
HeaderName — название компонента, в котором выводится заголовок (для случая, когда необходимо скрыть и заголовок тоже).
Для удобства в инспекторе объектов полезно задать соответствующие имена колонок (свойство Name). К примеру, назовем компонент, содержащий данные, Memo_Paz, а компонент, в котором выводится заголовок столбца, — Header_Paz.
Тогда необходимая команда примет вид:
HideEmpty('Memo_Paz', 'Header_Paz').
Осталось только определиться, в какой момент должно происходить сокрытие объекта. Для этого используется вкладка События инспектора объектов. В данном случае удобным является использование события OnBeforePrint (перед выводом на печать) компонента Page2 (создаваемый отчет изначально состоит из двух страниц), которое генерируется после того, как объект отчета был наполнен данными, с которыми он связан. Результат вызова команды приведен на рис. 5.
Рис. 5. Результат применения команды HideEmpty
Рассмотрим общий порядок обращения к событиям:
- Вызывается событие бэнда OnBeforePrint.
- Вызываются события OnBeforePrint всех объектов, лежащих на бэнде;
- Все объекты заполняются данными, после этого вызываются события OnAfterData всех объектов.
- Выполняется позиционирование объектов на бэнде (если среди них есть масштабируемые объекты), после чего рассчитываются высота бэнда и коэффициент его масштабирования, если бэнд масштабируемый.
- Вызывается событие бэнда OnAfterCalcHeight.
- Если бэнд не может быть размещен на свободном месте страницы, то формируется новая страница.
- Бэнд и все его объекты выводятся на страницу готового отчета.
- Вызывается событие OnAfterPrint всех объектов бэнда.
- Вызывается событие OnAfterPrint самого бэнда.
Для того чтобы «спрятать» пустую колонку, достаточно задать выравнивание у всех объектов (заголовков и данных) по левому или правому краю (свойство Align в Инспекторе объектов).
Кейс 3. Как организовать перебор объектов и проверку на ошибки
Нередко встречаются ситуации, когда имеется готовый рабочий шаблон, но есть подозрения, что данные в него поступают ошибочные, и необходимо произвести дополнительные проверки и правки при выполнении определенных условий, то есть добавить так называемую «защиту от дурака». Например, проверить, а не оказались ли в отчете лишние объекты? Еще вариант: не выходит ли количество или общая стоимость заказа за разумные пределы? Одним словом, для надежности работы шаблона и гарантии корректности формируемых документов весьма желательно организовать определенные проверки и/или обработку данных без изменения самого шаблона.
Рассмотрим способ организации перебора всех объектов отчета и анализа для них определенных показателей в зависимости от некоторых условий. Возьмем конкретный пример: добавим проверку количества объектов на превышение заданного порогового значения, допустим, 100 единиц. В процессе моделирования изделий вполне вероятна ситуация, когда при работе с дополнительными материалами или фурнитурой происходят ошибки — с точки зрения как проектирования, так и расчетов. Реализуем защиту от подобных сбоев. Помимо этого в качестве примера организации вычислений вычислим суммарную длину облицовочного материала. Соответствующий скрипт будет иметь следующий вид:
procedure Page2OnBeforePrint(Sender: TfrxComponent);
begin
HideEmpty('Memo_Paz', 'Header_Paz');
end;
var
DataS: TfrxDataSet; // Переменная, содержащая ссылку на набор данных
Length_Butt: Double; //Суммарная длина кромки
begin
// сортировка и фильтрация записей в наборе данных "Панели"
SmartSort('Панели','Позиция', '"Пластик (лицевая) Арт." + "Пластик (лицевая)" + "Пластик (нелицевая) Арт." + "Пластик (нелицевая)" <> '''' ');
DataS := Report.GetDataset('Фурнитура и покупные изделия'); //указываем текущий активный набор данных
DataS.first; // Принудительно переходим к первой записи
while not DataS.Eof do
begin
if DataS.Value['Количество'] > 100 then //сравнение значения
ShowMessage('Количество объектов больше 100'); // вывод сообщения
DataS.next;
end;
DataS := Report.GetDataset('Дополнительные материалы');
DataS.first; // Принудительно переходим к первой записи
while not DataS.Eof do // ограничения цикла - пока не будут пройдены все записи
begin
if DataS.Value['Количество'] > 100 then //условие проверки. Возможно построение составных условий с использованием AND и OR
ShowMessage('Количество объектов больше 100');
DataS.next; // Переход к следующей записи
end;
// вычисление суммарной длины кромки
DataS := Report.GetDataset('Облицовки кромок');
Length_Butt := 0;
DataS.first;
while not DataS.Eof do
begin
if DataS.Value['Длина'] <> null then
Length_Butt := Length_Butt + Strtofloat(DataS.Value['Длина']);
DataS.next;
end;
ShowMessage('Суммарная длина кромки: ' + FloattoStr(Length_Butt));
end.
При предварительном просмотре отчета можно увидеть соответствующие сообщения (рис. 6 и 7).
Рис. 6. Сообщение об ошибке
Рис. 7. Результат расчета
Кейс 4. Как «подправить» отчет
Как и в любой программе, в генераторе отчетов могут быть ошибки, например во введенных данных может содержаться опечатка. В конце концов иногда возникает необходимость заменить номер страницы или добавить его. Решение таких проблем достаточно простое — не нужно писать ни строчки кода. В генератор встроена функция редактирования страницы, доступная в режиме предпросмотра (рис. 8).
Сделаем несколько небольших замечаний для тех, кто планирует активно использовать программирование при решении задач, связанных с разработкой или доработкой шаблонов документов в системе БАЗИС:
- В случае появления «нетипичных» ошибок лучше сохранить шаблон под другим именем и перезапустить программу (именно программу, а не только генератор отчетов). Вполне возможно, что возникшая ошибка может повлиять на работоспособность всей системы.
- В последнем кейсе использовалось только чтение из набора данных. Запись и редактирование набора данных невозможно, поскольку он доступен только для чтения. Все преобразования данных осуществляются либо посредством использования переменных, либо с помощью графических компонентов на форме.
- Генератор отчетов позволяет использовать различные языки программирования, в частности PascalScript и Jscript. Рекомендуем, но не настаиваем использовать PascalScript — именно из-за его строгой типизации. В частности, попытка адаптировать пример из кейса 3 к Jscript приведет к ошибке приведения к типу (рис. 9) при обращении к любому свойству или методу объекта (Next или First). Обойти эту ошибку на стороне пользователя на данный момент не представляется возможным.
Рис. 8. Доступ к редактору заполненного отчета
Рис. 9. Ошибка приведения типа
Что и где почитать
Для поиска ответов на общие вопросы, связанные с работой генератора отчетов, можно предложить два ресурса:
онлайн-справку, предлагаемую компанией «Быстрые Отчеты»:
https://быстрыеотчеты.рф/public_download/docs/FRVCL/online/ru/index.html;
телеграмм-канал пользователей — энтузиастов системы БАЗИС: https://t.me/Bazis_drawing. Здесь рассматриваются в том числе и нетривиальные задачи, возникающие на мебельных предприятиях, а также разбираются интересные решения, которые наверняка помогут улучшить документацию и начинающему пользователю системы, и профессионалу.
Заключение
С учетом современных реалий мебельной отрасли предприятия должны стремиться к созданию более эффективных систем управления документацией и отчетами. Это позволит им организовать четко работающее производство. Однако автоматизация и управление документацией — сложная и многогранная задача. Очень важно, чтобы используемые автоматизированные системы не просто позволяли работать с шаблонами документов, а давали возможность их доработки и формирования собственных шаблонов. В системе БАЗИС такой инструментарий есть, и он постоянно развивается и совершенствуется.
Литература:
- III Всероссийская конференция производителей мебели // Мебельщик Юга. 2023. № 04-05. С. 16-25.
- Бунаков П.Ю. Как создать идеальную документацию для мебельного производства // САПР и графика. 2023. № 2(318). С. 42-49.
- Бунаков П.Ю., Лопатин А.К. Новые возможности оформления документов в системе БАЗИС // САПР и графика. 2022. № 4(306). С. 56-62.