Разузлование номенклатуры 1с это
Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.
В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "///// echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1.
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.
Собственно сам скрипт:
global $wpdb2;
global $failure;
global $file_hist;
///// echo '
Старт загрузки
';
$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
///// echo '
Файл обмена с сервисными книжками не существует.
';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
>
/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure) ///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '
Попытка вставить запись в лог таблицу
';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '
Возврат в начало.
';
return $failure;
>
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file
///// echo '
Размер файла: '.$m_size_file.'
';
///// echo '
Штамп времени файла: '.$m_mtime_file.'
';
///// echo '
Формирование запроса на выборку из лога
';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);
if ($results)
< foreach ( $results as $r)
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
///echo '
Возврат в начало, т.к. найдена запись в логе.
';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
>
>
>
////если данные новые, пишем в лог запись о начале загрузки
/////echo '
Попытка вставить запись о начале загрузки в лог таблицу
';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));
////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '
Очистка таблицы сервисных книжек
';
if (empty($results))
///// echo '
Ошибка очистки таблицы книжек, завершение.
';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
>
////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='\
Продолжаем цикл статей по нормативной подсистеме в 1С:УПП.
В рамках этого цикла детально рассмотрим, как работают спецификации в УПП – от теории до практики использования.
Итак, 9 статей по нормативной подсистеме УПП:
Параметры выходного изделия в спецификациях
О чем эта статья
В этой статье рассмотрим, каким образом в спецификации для выходного изделия заполняются реквизиты:
- Номенклатура и характеристика выходного изделия
- Количество
- Единица измерения
- Точка маршрута
- Номер операции
- Кратность и минимальная партия.
Номенклатура и характеристика выходного изделия
Обратимся к ранее созданной спецификации «Кресло офисное (эксперимент) Комфорт». Номенклатура выходного изделия указывается как элемент справочника «Номенклатура».
Характеристика указывается как элемент справочника «Характеристики номенклатуры».
Если характеристика в спецификации не указана, то данная спецификация используется с любой характеристикой номенклатуры. Возможна ситуация, когда изделие по одной и той же спецификации выпускается с несколькими характеристиками. В то же время для некоторых характеристик этой номенклатуры могут создаваться отдельные спецификации. Создание спецификаций для серий номенклатуры не предусмотрено.
Количество
В спецификации указывается информация о количестве выходного изделия. Это то количество выходных изделий, для которого определяется норматив расхода исходных комплектующих.
В настоящее время в спецификации «Кресло офисное (эксперимент) Комфорт» для выходного изделия в поле Количество установлена единица. То есть исходные комплектующие и их количество указаны для изготовления одного изделия. Так, для изготовления одного кресла требуется материал «Пятилучье» в количестве 1,000 штуки.
Откроем ранее заготовленный документ «Отчет производства за смену», в котором в табличной части на закладке Продукция и услуги указано «Кресло офисное Комфорт» в количестве 1,000 штуки. В поле Спецификация выбрано значение «Кресло офисное (эксперимент) Комфорт».
Для заполнения табличной части на закладке Материалы воспользуемся сервисом Заполнить по спецификации.
Табличная часть заполняется по нормативам расхода, указанным для спецификации. В частности, для материала «Пятилучье» указано Количество – 1,000.
Укажем в спецификации Количество выходных изделий – 5,000 штук и сохраним внесенные изменения.
Напомним, что в документе «Отчет производства за смену» на закладке Продукция и услуги указано одно кресло, которое должно быть изготовлено.
При заполнении табличной части документа на закладке Материалы с использованием сервиса Заполнить по спецификации для материала «Пятилучье» будет установлено Количество – 0,200. То есть ⅕ часть от значения, указанного в спецификации для 5,000 кресел.
Для большинства инструментов программы не критично, какое количество выходных изделий указано в спецификации. В любом случае программа отработает корректно. Поэтому имеет смысл указывать такое количество изделий, которое удобно для указания норматива расходов. Например, в спецификации для колбасы можно указать нормативы расхода мяса и других ингредиентов на изготовление 1,000 кг. продукта, 1,000 тонны продукта или количества, которое выпускается в ходе одного производственного цикла.
Таким образом, в спецификациях номенклатуры может быть указано любое количество выходных изделий. Когда нормативы расхода очень малы, имеет смысл определять нормативы расхода исходных комплектующих для количества выходных изделий больше единицы. В документе «Отчет производства за смену» количество используемых материалов будет корректно пересчитано в соответствии с количеством продукции, указанным в документе на закладке Продукция и услуги.
Единица измерения
В спецификации номенклатуры в поле Единица для выходного изделия может быть указана любая единица измерения, которая определена для выбранной позиции номенклатуры.
Единицы измерения номенклатуры являются элементами справочника «Единицы измерения», который подчинен справочнику «Номенклатура». Это значит, что для каждой позиции номенклатуры может быть определен свой перечень единиц измерения. Чтобы открыть этот перечень, можно в справочнике «Номенклатура» выделить соответствующую позицию и в командной панели формы в меню Перейти выбрать команду Единицы измерения.
В данном случае для «Кресла офисного Комфорт» перечень единиц измерения состоит из одного элемента.
Единицы измерения номенклатуры можно также увидеть в карточке номенклатуры на соответствующей закладке.
Определим для «Кресла офисного Комфорт» единицу измерения «упаковка». Одна упаковка содержит 10,000 штук. Для этого в командной панели табличной части на закладке Единицы используем кнопку Добавить.
В открывшейся форме создания единицы измерения в качестве значения в поле По классификатору выберем элемент «Классификатора единиц измерения» – «Упаковка».
При этом автоматически заполнится и поле Наименование значением, подставляемым по умолчанию для выбранного элемента «Упаковка». В поле Содержит (шт) установим значение – 10,000.
Теперь в спецификации номенклатуры «Кресло офисное Комфорт» можно определить, что норматив расхода исходных комплектующих задан для одной упаковки.
Сохраним внесенные изменения и в документе «Отчет производства за смену» заново заполним табличную часть Материалы с использованием сервиса Заполнить по спецификации. Поскольку в спецификации для производства 1,000 упаковки изделий (10,000 шт.) требуется исходная составляющая «Пятилучье» в количестве 1,000 штуки, то для производства 1,000 «Кресла офисного Комфорт» в документе «Отчет производства за смену» «Пятилучье» потребуется в количестве 0,100 штуки.
Точка маршрута
В спецификации для выходного изделия заполняется реквизит Точка маршрута. Значение для этого реквизита выбирается как элемент справочника «Точки маршрута».
Для элементов данного справочника может быть указано Подразделение, а также Рабочий центр или Группа рабочих центров (группа заменяемости рабочих центров).
Информация о точках маршрута выходных изделий используется только подсистемой предварительного планирования производства.
Номер операции
В спецификации номенклатуры указывается информация о номере операции для выходного изделия. Для поля № операции определен тип данных не «число», а «строка».
Номер операции указывается из связанной с этой спецификацией технологической карты. Это та операция из технологической карты, по окончании которой получается выходное изделие. Данная информация используется подсистемой посменного планирования для формирования запланированного графика выпуска.
Кратность и минимальная партия
Для выходного изделия в спецификации можно также указать Кратность и Минимальную партию.
Кратность – это технологическое ограничение объема выпуска. Нельзя выпустить количество изделий не кратное указанному значению, так как это невозможно технологически.
Минимальная партия – это экономическое ограничение объема выпуска. Выпуск в меньшем объеме экономически нецелесообразен.
Предположим, что для Кратности установлено значение 3,000, а для Минимальной партии – значение 9,000. Поступил заказ покупателя на 5,000 изделий.
При планировании желаемое к выпуску количество изделий сначала сравнивается с Минимальной партией. Для последующего планирования выбирается большее из этих значений. В данном случае следует выбрать значение 9,000, которое кратно 3,000.
Предположим, что поступил заказ покупателя на 20,000 изделий. При сравнении этого количества изделий с Минимальной партией будет выбрано значение 20,000. Если полученное значение не кратно указанному в спецификации, то следует выбрать первое большее число, удовлетворяющее условию кратности. В данном случае это будет число 21,000.
В системе УПП информация о кратности и минимальной партии выходного изделия является справочной. В алгоритмах работы программы эти реквизиты не используются.
Подробнее нормативная система рассматривается в курсе
УПП от А до Я [Производство, Торговля, Персонал и Управление]
Начинаем цикл статей по нормативной подсистеме в 1С:УПП.
В рамках этого цикла детально рассмотрим, как работают спецификации в УПП – от теории до практики использования.
Итак, 9 статей по нормативной подсистеме УПП:
Для лучшего понимания, рекомендуем последовательное изучение статей :)
Принципы работы спецификаций номенклатуры в 1С:УПП
О чем эта статья
В статье рассмотрим базовую информацию, необходимую для понимания принципов работы нормативной подсистемы.
Теорию нужно прочитать вдумчиво, на ней будут базироваться дальнейшие 8 практических статей по спецификациям.
Введение
Для хранения производственных рецептур в системе УПП используются спецификации номенклатуры и технологические карты производства, описывающие технологические операции и их последовательность.
В спецификациях содержится информация о составе потребления (исходные материальные составляющие или комплектующие) и выпуска. В общем случае на выходе некоторой производственной операции может быть получен не один вид продукции, а несколько, кроме того, могут быть получены возвратные отходы. В соответствии со спецификацией определяются материальные затраты, понесенные при выпуске изделия.
Спецификации номенклатуры используются при решении задач:
- Объемно-календарного планирования производства
- Предварительного планирования производства
- Планирования производства по сменам
- Распределения материалов на выпуск
- Расчета плановой себестоимости номенклатуры.
Кроме того, спецификации номенклатуры используются для автоматизации процесса заполнения производственных документов.
Для хранения спецификаций в системе УПП предназначен специальный справочник «Спецификации номенклатуры».
Используемые термины
Рассмотрим пример, когда от прямоугольного листа металла необходимо отделить кусок в форме треугольника.
Прямоугольный лист – это исходная комплектующая.
Полученный треугольный кусок – это выходное изделие. Вообще, выходное изделие может являться готовой продукцией, полуфабрикатом или работой.
Опилки, которые образовались в процессе резки металла – это возвратные отходы. В дальнейшем они могут быть использованы для каких-то производственных целей или реализованы.
Оставшийся кусок металла – это деловой отход.
Разница между выходным изделием, возвратными отходами и деловым отходом определяется пользователем. С точки зрения УПП разницы между ними нет.
Выходное изделие – это то, ради чего был запущен производственный процесс.
Возвратный отход отличается от всех других результатов производственного процесса тем, что ему назначается себестоимость. То есть он учитывается по фиксированной стоимости.
У выходных изделий и делового отхода себестоимость рассчитывается. Себестоимость выходного изделия формируется из прямых и косвенных (распределяемых) расходов. В себестоимость делового отхода включаются только прямые расходы.
Исходный лист металла имеет определенную стоимость. Из него было получено два выпуска (треугольник и оставшаяся часть). При расчете себестоимости каждой части прямыми расходами является стоимость металла, рассчитанная пропорционально весу или площади полученного куска.
К прямым расходам также относится оплата труда (заработная плата). Оплата труда может быть распределена между выходным изделием и деловым отходом или полностью отнесена на выходное изделие.
После расчета себестоимости выпуска по прямым затратам в системе производится распределение косвенных расходов (общепроизводственных и общехозяйственных) на выходные изделия.
В системе УПП учет деловых отходов не поддерживается. Учитываются исходные комплектующие, выходные изделия и возвратные отходы.
О том, чтобы косвенные расходы не распределялись на деловые отходы, пользователь должен позаботиться сам. Для этого деловые отходы могут быть выделены в отдельные номенклатурные группы. После чего способы распределения косвенных расходов могут быть настроены таким образом, чтобы косвенные расходы не распределялись на номенклатурные группы, предназначенные для учета деловых отходов.
При работе со спецификациями в УПП используются следующие термины:
Выходное изделие – объект выпуска производственного подразделения (продукция, полуфабрикат, работа).
Исходное комплектующее – используемая материальная ценность (сырье, материал, полуфабрикат).
Возвратный отход – остатки материальных ресурсов, образовавшиеся в процессе производства, утратившие потребительские качества исходных ресурсов.
Виды спецификаций
Спецификации в УПП могут быть трех видов:
Сборочные спецификации – это такие спецификации, на выходе которых получается только одно калькулируемое изделие.
На входе такой спецификации указываются исходные комплектующие. На выходе получается одно изделие, себестоимость которого рассчитывается.
По окончании производственного процесса могут также быть получены возвратные отходы, которые могут быть нескольких видов. Для возвратных отходов себестоимость не рассчитывается, а назначается.
Для полных спецификаций в качестве выходных изделий могут указываться несколько изделий с рассчитываемой себестоимостью. На входе спецификации также указываются исходные комплектующие. На выходе также возможно наличие возвратных отходов.
Например, из исходной комплектующей «семена подсолнуха» получаются выходные изделия «масло подсолнечное» и «жмых», себестоимость которых будет рассчитываться.
Полные спецификации используются достаточно часто. Например, из нефти получается целый спектр выходных изделий от керосина до мазута.
Спецификации вида Узел отличаются тем, что у них вообще нет выходных изделий, есть только исходные комплектующие.
Спецификации вида узел используются в качестве исходных комплектующих других спецификаций.
Если система в исходных комплектующих какой-либо спецификации встречает спецификации вида узел, то она разузловывает спецификацию, то есть вместо узлов получает и использует исходные комплектующие этих узлов.
В спецификациях вида узел фиксируются регулярно используемые наборы материальных ценностей, чтобы впоследствии в других спецификациях не перечислять все комплектующие, а сразу указывать целые наборы (узлы).
В дальнейшем, если в нескольких спецификациях, использующих один и тот же узел, необходимо поменять какие-то комплектующие из набора (узла), то достаточно произвести замену комплектующих в самом узле.
В конфигурации «1С:Управление производственным предприятием 1.3» откроем справочник «Спецификации номенклатуры». В Полном интерфейсе справочник открывается с помощью команды Справочники – Номенклатура – Спецификации.
Из открывшейся формы справочника откроем форму создания нового элемента.
Для определения вида спецификации в командной панели карточки спецификации предусмотрено специальное меню. Если определить вид спецификации Сборочная, то для указания выходного изделия будет предусмотрено одно поле Номенклатура.
В карточке спецификации вида Полная для указания выходных изделий предназначена специальная табличная часть.
Для спецификации вида Узел возможности указания выходных изделий не предусмотрено.
Спецификация как уравнение
Спецификация номенклатуры может рассматриваться как своеобразный знак равенства в уравнении расчета себестоимости.
Исходные комплектующие отражают сумму материальных затрат в процессе производства. Эта сумма соответствует себестоимости выходных изделий без учета затрат на оплату труда и косвенных расходов.
Предположим, на входе спецификации имеется материал А стоимостью 100 руб. (по статье затрат «Материалы собственные») и полуфабрикат В стоимостью 400 руб. (по статье затрат «Полуфабрикаты собственные»). На выходе получается некое изделие D.
Если больше ничего нет, то рассматривая спецификацию, как некий знак равенства, можно составить уравнение:
100 руб. + 400 руб. = D
То есть в этой ситуации себестоимость изделия D будет равна 500 руб.
Обычно себестоимость рассматривается в разрезе статей затрат.
Если на выходе спецификации появляется не только готовое изделие, но и возвратный отход, то в правой части уравнения следует добавить стоимость возвратного отхода. Стоимость возвратного отхода фиксированная. Она назначается. Пусть это будет 20 руб.
100 руб. + 400 руб. = D + 20 руб.
Перенесем сумму возвратного отхода в левую часть уравнения.
100 руб. + 400 руб. – 20 руб. = D
В себестоимости изделия D появляется еще одна сумма (– 20 руб.). Так как возвратный отход в данном случае находится на стороне исходных комплектующих (на стороне затрат), то возвратному отходу при выпуске указывается специфичная статья статья затрат «Возвратные отходы», которая уменьшает стоимость выпуска, и для которой устанавливается специальный статус «Возвратные отходы».
Себестоимость изделия D будет 480 руб.
Рассмотрим пример с полной спецификацией. Предположим, что исходные комплектующие те же. Помимо изделия D выпускается еще изделие Е.
Чтобы выполнить разделение затрат между изделиями D и Е программе требуется дополнительная информация.
Эта дополнительная информация вводится как доля стоимости каждого из выходных изделий полной спецификации.
Доля стоимости – это весовые коэффициенты, которые используются при делении затрат между выходными изделиями. Это не проценты. Проценты являются частным случаем весовых коэффициентов. Доля стоимости может быть подобрана таким образом, чтобы суммарно все доли стоимости в одной спецификации равнялись 100.
Установим значения доли стоимости как 2 (для изделия D) и 3 (для изделия Е). В этом случае сумма весовых коэффициентов равна 5. На себестоимость изделия D пойдет ⅖ (40%) от каждой затраты. А на себестоимость изделия Е пойдет ⅗ (60%) от каждой затраты.
Себестоимость изделия D будет равна 192 руб., а изделия Е – 288 руб.
Таким образом мы разобрали основные принципы нормирования в 1С:УПП.
Подробнее нормативная система рассматривается в курсе
УПП от А до Я [Производство, Торговля, Персонал и Управление]
Всем добрый день.
требуется совет
имеется иерархичная структура спецификаций номенклатуры.
у каждой номенклатуры свой состав и свои спецификации до 10 уровней вложенности( пока, возможно и больше)
и нужно отобразить все эти уровни.
мне пришло в голову по каждой номенклатуре нарисовать программно свою группировку в отчете (или таблицу)
но наверняка есть еще варианты, кто бы как это реализовал?
мне будет очень интересно, если поделитесь.
или не поделитесь, тогда не интересно будет.
1с 8.2 вывод номенклатуры
Проблема 1с(2012 год где-то ) дали комп 8.2 не обновленный НЕЛЬЗЯ ОБНОВЛЯТЬ ибо там ппц, не могу.
Характеристика номенклатуры
Здравствуйте. С 1С знаком всего лишь несколько дней. Имеется 1С УПП 8.2.16.352/1.3.26.3 при.
Комплектация номенклатуры
В общем, не знаю как сделать правильнее. Создала справочник Изделия, где в табличной части.
Аналоги номенклатуры
Пытаюсь сделать аналоги номенклатуры. Вот только приступил. В корневом каталоге сделал только.
Остатки номенклатуры
Приветствую! В общем, имеется учебная задачка 1С 8.3. Конфигурация имеет пару справочников для.
Доступность номенклатуры
Добрый день. Помогите с проблемой. Исходные данные: 1. 1С:Предприятие 8.3, УТ11 (11.4.5.82) 2.
Обработка номенклатуры
всем привет, создал обработку касаемо контрагентов, а именно загрузка контрагентов из файла dbf в.
Подбор номенклатуры из списка
Всем привет! Создал форму обработки в нее добавил табполе и кнопку подбор.Суть в том что при.
Группировка одинаковой номенклатуры
Здравствуйте, объясните, пожалуйста, чайнику как реализовать для документов "Приход" и "Продажа".
Загрузка номенклатуры из Excel
Загружаю номенклатуру из Excel в справочник и при этом паралельно должен создаваться новый документ.
Часто, столкнувшись с долгим временем выполнения какого-либо фрагмента кода, мы начинаем искать технологические программные решения: переносить вычисления в СУБД, либо в оперативную память, устранять неявные запросы в циклах, применять другие известные приемы оптимизации или просто ругать платформу. Хотя на самом деле проблема может быть всего лишь в неверно выбранном алгоритме. В статье рассказывается об одном таком случае, возникшем при решении задачи «разузлования». Надеюсь, прочитав эту статью и ознакомившись с текстом варианта программы, построенной по давно известному алгоритму, Вы избежите подобных ошибок. Тем более программа получилась совсем небольшой.
Задача, рассматриваемая в статье, приводится здесь с разрешения ее автора Ish_2. Собственно задача была сформулирована в ходе обсуждения вопроса "Реально написать хитрый запрос" в посте (79) примерно так:
Дана таблица, содержащая три колонки: номенклатура-набор (X), номенклатура-элемент (Y), количество элементов в наборе (Z). В строчках этой таблицы записаны тройки (X, Y, Z):
Всего таблица содержит 61 элемент ("0", А0, . А9, Б0, . , Б9, . , Е0, . , Е9) и 510 строк:
(0, А0, 2) (0, А1, 2) (0, А2, 2) (0, А3, 2) (0, А4, 2) (0, А5, 2) (0, А6, 2) (0, А7, 2) (0, А8, 2) (0, А9, 2)
(А0, Б0, 2) (А0, Б1, 2) (А0, Б2, 2) (А0, Б3, 2) (А0, Б4, 2) (А0, Б5, 2) (А0, Б6, 2) (А0, Б7, 2) (А0, Б8, 2) (А0, Б9, 2)
(А1, Б0, 2) (А1, Б1, 2) (А1, Б2, 2) (А1, Б3, 2) (А1, Б4, 2) (А1, Б5, 2) (А1, Б6, 2) (А1, Б7, 2) (А1, Б8, 2) (А1, Б9, 2)
(Д9, Е0, 2) (Д9, Е1, 2) (Д9, Е2, 2) (Д9, Е3, 2) (Д9, Е4, 2) (Д9, Е5, 2) (Д9, Е6, 2) (Д9, Е7, 2) (Д9, Е8, 2) (Д9, Е9, 2).
Каждая строка таблицы ( X , Y , Z ) интерпретируется следующим образом: объект X содержит элемент Y в количестве Z . Наглядно эта таблица представляется следующим графом (фиг1). Все дуги на фиг1 направлены слева направо и имеют вес, равный двум.
Требуется построить программу, способную посчитать: сколько элементов Е0, Е1, Е2, Е3, Е4, Е5, Е6, Е7, Е8, Е9 содержится в объекте «0». Конечно, программа должна решать подобные задачи в общем случае для всех подобных таблиц. Тогда данный пример будет тестом скорости работы программы, а также правильности алгоритма путем сравнения с очевидным ответом (6 400 000, 6 400 000, … , 6 400 000). В этом общем случае программа также должна исключать ошибочные связи типа Е9 – 0, Д0 – Б9 и другие «обратные» связи, приводящие к «зацикливанию».
Сравнение строк 11 (А0-Б0-2) и 21 (А1-Б0-2) позволяет сделать принципиально важный вывод: структура, описываемая таблицей, не является деревом! Элемент Б0 имеет более одного владельца! Необходимость такой структуры при составлении сборочных спецификаций легко объяснить: если четыре колеса входят в спецификацию автомобиля, а два таких же колеса в спецификацию прицепа, то заводится не две разных, а одна единая спецификация колеса. В результате шина как элемент колеса входит в состав автомобиля с прицепом двумя различными способами: в составе колеса в составе автомобиля и в составе колеса в составе прицепа.
В тестовом примере элемент Е9 входит в состав элемента «0» сто тысячью (100 000) различных способов! Вот тут-то некоторые программисты и делают принципиальную ошибку: они считают, что для подсчета числа вхождений Е9 нужно перечислить все 100 000 способов. (На самом деле это тоже самое, что вычислять 10 х 10 х 10 х 10 х 10 х 10 миллионом сложений единиц!) Источником этой ошибки, видимо, является известный отчет о разузловании, строчки которого соответствуют путям вхождения атомарных деталей в готовое изделие. Отчет для наглядности представляется в виде дерева. В данном случае это дерево отчета будет иметь миллион конечных вершин. Видимо, тут и возникает желание получить результат поставленной задачи группировкой этих путей по виду их конечных элементов. Как же по-другому? – А вот как:
1. Исходная задача разузлования заданного узла разбивается на более простые задачи разузлования отдельных узлов, причем в этих простых задачах считается, что результат разузлования подчиненных узлов уже известен. Тогда результат разузлования узла получается как сумма результатов разузлования подчиненных узлов, взятых с коэффициентом количества для каждого подчиненного узла. Если обозначить результат разузлования узла j как Q ( j ) = ( q 1 j , q 2 j , … , qNj ), где qij обозначает, что узел j транзитивно содержит узел i qij раз, и если как gkl обозначить количество узлов i в спецификации узла k , то получаем простую формулу подсчета результата разузлования узла k
Q(k) = ∑ i=1,N G’(i) * Q(i) = ∑ i=1,N gki * qij. (1)
2. Результат разузлования каждого узла запоминается, чтобы не вычисляться заново. Поэтому в решении тестовой задачи будет всего 51 операция вида (1).
3. Порядок обхода вершин графа, начиная с заданного, определяется рекурсией. Дважды в один и тот же узел для расчетов алгоритм не входит!
Вот конфигурация справочника, в котором хранится таблица (фиг2)
А вот код самой программы (фиг3)
Приведен весь исходный код. Никакого другого кода в решении нет и он не требуется.
Для работы с относительно небольшими структурами достаточно использовать массивы.
В данном случае используется массив массивов Матрица. Измерениями будет номер вершины графа. Для простоты считаем, что коды вершин начинаются с единицы и не содержат пропусков. Это позволяет рассчитать индекс при обращении к массиву как ё = Ссылка.Код – 1. В результате Матрица[ё] будет содержать разузлование узла Ссылка. Если Матрица[ё][0] = Неопределено, значит, этой вершиной еще не занимались. Сначала разузлование обнуляется //процедура Обнулить()//, затем к нему в цикле прибавляются разузлования подчиненных узлов //определяемые рекурсивно процедурой Распаковать()// с соответствующим весом //процедура Добавить()//. После разузлования подчиненных узлов отмечаем единицей текущий узел //Матрица[ё][ё] = 1//. Этой единицей данный узел будет с точки зрения вышележащих уровней.
Если разузлование находится в процессе расчета //Матрица[ё][0] <> Неопределено//, но не закончено, то Матрица[ё][ё] = 0. Это дает возможность проверить зацикливание. Правда диагностический вывод «слабоват» - мы отмечаем только вершину, в которую попали в результате «зацикливания».
Запрос в начале работы программы нужен только для построения таблицы, куда потом будут помещены результаты работы метода, для определения терминальных узлов, а также для определения количества узлов, которое также определяет размерность массива.
Для того, чтобы работать со структурами, не помещающимися в массив или сильно разреженными, нужно хранить промежуточные разузлования в массиве не как вложенные массивы, а как таблицы значений и переписать процедуры Обнулить() и Добавить(). Выполнение, возможно, даже не замедлится. Опытным путем можно попробовать установить, что и для каких размерностей лучше.
Сейчас тестовая задача выполняется примерно 0,122 секунды (использовалась платформа 8.1 и ноутбук). При этом «неправильные» методы дают на два-три порядка большие значения!
Сформировав структуру степени 10 из 33 уровней (331 вершина), получим время разузлования всего 3,666 секунды!
К статье прилагается конфигурация, содержащая справочник описанной структуры и отчет с исходным кодом решения (в варианте использования массива). Кроме того, конфигурация содержит обработку, позволяющую формировать тестовые структуры по заданному алфавиту и степени графа (числа ветвей в разветвлении). Там же имеется отчет, позволяющий нарисовать структуру графа, тип которого рассматривается в статье.
Если никто не вспомнит, где уже встречалось такое решение, мне будет нетрудно перевести его на 77. Там всего лишь несколько более длинный код. Также возможно будет интересным показать, как решается эта задача с использованием техники «одного запроса».
Читайте также: