Отладка расчета себестоимости в ERP - просмотр изменений временных таблиц

Публикация № 1291127 09.09.20

Разработка - Практика программирования

Расчет себестоимости Управление предприятием 2 ERP

Как уследить за изменениями в сотне временных таблиц на различных этапах выполнения расчета себестоимости. Тестировалось на 1С:ERP Агропромышленный комплекс 2 (2.4.12.75)

Перед прочтением рекомендую ознакомиться с выжимкой из описания типовых методов  расчета в этой статье: //infostart.questa.ru/1c/articles/658048/

Для отладки расчета себестоимости будет очень удобно использовать методы сравнения данных в МВТ. Поясню. Весь расчет себестоимости - это формирование и перезапись временных таблиц. Их около 50 штук. Для того чтобы понимать, какие ВТ на каком этапе формируются, и какие данные в них меняются, я написал два метода и положил их в общий модуль.

На протяжении расчета во все методы передаётся структура ПараметрыРасчета, содержащая МенеджерВременныхТаблиц. Именно в нём и меняются ВТ, формируемые в разных этапах расчета. 
 

Функция ПолучитьОписаниеТаблицМВТ(МВТ, Параметры = Неопределено, ИмяПараметра = "") Экспорт
    
    ТаблицыМВТ = Новый ТаблицаЗначений;
    ТаблицыМВТ.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
    ТаблицыМВТ.Колонки.Добавить("КоличествоЗаписей", Новый ОписаниеТипов("Число"));
    ТаблицыМВТ.Колонки.Добавить("ТЗ");
    
    
    Для Каждого цВТ Из МВТ.Таблицы Цикл
        
        новСтрока = ТаблицыМВТ.Добавить();
        новСтрока.Имя = цВТ.ПолноеИмя;
        
        ТЗ = цВТ.ПолучитьДанные().Выгрузить();
        
        новСтрока.КоличествоЗаписей = ТЗ.Количество();
        новСтрока.ТЗ = ТЗ;
        
    КонецЦикла;
    
    ТаблицыМВТ.Сортировать("Имя");
    
    
    Если Параметры <> Неопределено И Не ПустаяСтрока(ИмяПараметра) Тогда
        Параметры.Вставить(ИмяПараметра, ТаблицыМВТ);
    КонецЕсли;
    
    
    Возврат ТаблицыМВТ;
    
КонецФункции
Функция СравнитьОписанияВТ(Описание1, Описание2, ТолькоОтличия = Истина) Экспорт
    
    ОтличияОписаний = Новый ТаблицаЗначений;
    ОтличияОписаний.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
    ОтличияОписаний.Колонки.Добавить("КоличествоЗаписей1", Новый ОписаниеТипов("Число"));
    ОтличияОписаний.Колонки.Добавить("КоличествоЗаписей2", Новый ОписаниеТипов("Число"));
    ОтличияОписаний.Колонки.Добавить("ЕстьВОписании1", Новый ОписаниеТипов("Булево"));
    ОтличияОписаний.Колонки.Добавить("ЕстьВОписании2", Новый ОписаниеТипов("Булево"));
    ОтличияОписаний.Колонки.Добавить("ДанныеОтличаются", Новый ОписаниеТипов("Булево"));
    ОтличияОписаний.Колонки.Добавить("ТЗ1");
    ОтличияОписаний.Колонки.Добавить("ТЗ2");
    
    Для Каждого цСтрокаОписания1 Из Описание1 Цикл
        
        новСтрока = ОтличияОписаний.Добавить();
        новСтрока.Имя = цСтрокаОписания1.Имя;
        новСтрока.ТЗ1 = цСтрокаОписания1.ТЗ;
        новСтрока.КоличествоЗаписей1 = цСтрокаОписания1.ТЗ.Количество();;
        новСтрока.ЕстьВОписании1 = Истина;
        
        СтрокиВ2Описании = Описание2.НайтиСтроки(Новый Структура("Имя", цСтрокаОписания1.Имя));
        
        Если СтрокиВ2Описании.Количество() = 0 Тогда
            новСтрока.ДанныеОтличаются = Истина;
        Иначе
            
            новСтрока.ЕстьВОписании2 = Истина;
            новСтрока.ТЗ2 = СтрокиВ2Описании[0].ТЗ;
            новСтрока.КоличествоЗаписей2 = новСтрока.ТЗ2.Количество();;
            
            
            Если новСтрока.КоличествоЗаписей1 <> новСтрока.КоличествоЗаписей2 Тогда
                новСтрока.ДанныеОтличаются = Истина;
                Продолжить;
            КонецЕсли;
            
            
            Для Каждого цКолонкаТЗ1 Из новСтрока.ТЗ1.Колонки Цикл
                Если новСтрока.ТЗ2.Колонки.Найти(цКолонкаТЗ1.Имя) = Неопределено Тогда
                    новСтрока.ДанныеОтличаются = Истина;
                    прервать;
                КонецЕсли;
            КонецЦикла;
            
            Для Каждого цКолонкаТЗ2 Из новСтрока.ТЗ2.Колонки Цикл
                Если новСтрока.ТЗ1.Колонки.Найти(цКолонкаТЗ2.Имя) = Неопределено Тогда
                    новСтрока.ДанныеОтличаются = Истина;
                    прервать;
                КонецЕсли;
            КонецЦикла;
            
            Если Не новСтрока.ДанныеОтличаются Тогда
                новСтрока.ДанныеОтличаются = Не ОбщегоНазначения.КоллекцииИдентичны(новСтрока.ТЗ1, новСтрока.ТЗ2);
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
    Для Каждого цСтрокаОписания2 Из Описание2 Цикл
        
        СтрокиВОписании = ОтличияОписаний.НайтиСтроки(Новый Структура("Имя", цСтрокаОписания2.Имя));
        
        Если СтрокиВОписании.Количество() = 0 Тогда
            новСтрока = ОтличияОписаний.Добавить();
            новСтрока.Имя = цСтрокаОписания2.Имя;
            новСтрока.ТЗ2 = цСтрокаОписания2.ТЗ;
            новСтрока.КоличествоЗаписей2 = цСтрокаОписания2.ТЗ.Количество();;
            новСтрока.ЕстьВОписании2 = Истина;
            новСтрока.ДанныеОтличаются = Истина;
        КонецЕсли;
        
    КонецЦикла;
    
    Если ТолькоОтличия Тогда
        ОтличияОписаний = ОтличияОписаний.Скопировать(Новый Структура("ДанныеОтличаются", Истина));
    КонецЕсли;
    
    ОтличияОписаний.Сортировать("Имя");
    
    Возврат ОтличияОписаний;
    
КонецФункции

Первый метод читает все ВТ из менеджера и возвращает таблицу значений с колонками:

  • Имя (имя временной таблицы), 
  • КоличествоЗаписей, 
  • ТЗ (непосредственно данные из временной таблицы).

Кроме того, этот метод может положить сформированную таблицу с описанием ВТ в любую структуру с произвольным ключом (параметры метода: Параметры, ИмяПараметра). Таким образом мы можем на любом этапе расчета создать "слепок" содержимого менеджера ВТ и положить его, например, в структуру "ПараметрыРасчета".

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

  • Имя (имя временной таблицы), 
  • КоличествоЗаписей1, 
  • КоличествоЗаписей2, 
  • ТЗ1 (непосредственно данные из таблицы первого слепка).
  • ТЗ2 (непосредственно данные из таблицы второго слепка).
  • ЕстьВОписании1 (признак того, что ВТ присутствует в первом слепке)
  • ЕстьВОписании1 (признак того, что ВТ присутствует во втором слепке)
  • ДанныеОтличаются (признак того, что Данные в таблицах с одинаковым именем отличаются - по количеству записей, или по значению полей, или по наличию таблиц)

Как этим пользоваться.
1. Запускаем расчет. Можно накидать внешнюю обработку для запуска

&НаСервере
Процедура ЗапуститьРасчетССНаСервере()
    ПараметрыЗапуска = Новый Структура;
    ПараметрыЗапуска.Вставить("АвтоматическоеТестирование", Ложь);
    ПараметрыЗапуска.Вставить("ВыполняетсяЗакрытиеМесяца", Ложь);
    ПараметрыЗапуска.Вставить("Дата", НачалоМесяца(Период));
    ПараметрыЗапуска.Вставить("МассивОрганизаций", ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Организация));
    ПараметрыЗапуска.Вставить("МестоВызоваРасчета", "РасчетСебестоимостиКорректировкаСтоимости.Выполнить_РасчетПартийИСебестоимости");
        
    СхемаРасчета = РасчетСебестоимостиПрикладныеАлгоритмы.СхемаРасчетаПартий(ПараметрыЗапуска.Дата, ПараметрыЗапуска.МассивОрганизаций);
    Если СхемаРасчета.Количество() = 0 Тогда
        новСтрока = СхемаРасчета.Добавить();
        новстрока.Дата = КонецМесяца(ПараметрыЗапуска.Дата);
        новстрока.ИзмененоДокументов = 1;
        новстрока.Организации = ПараметрыЗапуска.МассивОрганизаций;
    КонецЕсли;
    ПараметрыЗапуска.Вставить("СхемаРасчета", СхемаРасчета);
    
    РасчетСебестоимости.РассчитатьВсе(ПараметрыЗапуска);

КонецПроцедуры


Обработка во вложении, там она ещё перепроводит проблемный документ перед расчетом.
2. Тормозим отладку перед интересующим нас методом.
3. В табло пишем:

НашОбщийМодуль.ПолучитьОписаниеТаблицМВТ(ПараметрыРасчета.МенеджерВременныхТаблиц, ПараметрыРасчета, "ТаблицыПередВыполнениемЭтапа")


4. После того как выражение вычислилось, в структуре ПараметрыЗапуска появились данные с ключом "ТаблицыПередВыполнениемЭтапа", комментим (или удаляем из табло) выражение из пункта №3, чтобы данные не перезаписались при следующих шагах
5. Выполняем интересующий нас этап и кладём его данные в структуру с новым ключом. Для этого опять пишем выражение в табло:

НашОбщийМодуль.ПолучитьОписаниеТаблицМВТ(ПараметрыРасчета.МенеджерВременныхТаблиц, ПараметрыРасчета, "ТаблицыПослеВыполненияЭтапа")


6. Сравниваем эти описания, выполняя в табло код: 

НашОбщийМодуль.СравнитьОписанияВТ(ПараметрыРасчета.ТаблицыПередВыполнениемЭтапа, ПараметрыРасчета.ТаблицыПослеВыполненияЭтапа)


В результате имеем Таблицу, содержащую отличия. Открыть её можно прямо из табло, нажав F2.
Также можно вместо этапов 5,6 просто идти по коду, вычисляя в табло выражение:
 

НашОбщийМодуль.СравнитьОписанияВТ(ПараметрыРасчета.ТаблицыПередВыполнениемЭтапа, НашОбщийМодуль.ПолучитьОписаниеТаблицМВТ(ПараметрыРасчета.МенеджерВременныхТаблиц))

Таким образом можно на любом этапе понять, какие ВТ сформировались или изменились.

Скачать файлы

Наименование Файл Версия Размер
Обработка для запуска расчета себестоимости с перепроведением проблемного документа

.epf 6,81Kb
14
.epf 6,81Kb 14 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Date 8 07.09.21 05:18 Сейчас в теме
Добрый день. Интересная задумка. Вот только я столкнулся с тем, что функция "СравнитьОписанияВТ()" ничего не возвращает, а структура "ПараметрыРасчета" меняет тип на что-то не понятное. Не сталкивались с таким?
Прикрепленные файлы:
2. doom2good 45 07.09.21 10:04 Сейчас в теме
(1)
функция "СравнитьОписанияВТ()" ничего не возвращает

Сталкивался. У вас ооочень много данных, на сравнение таблиц требуется много времени. Просто ждите, когда появится значение (произойдёт вычисление выражения). И имейте в виду, если сделаете шаг, то вычисляться будет заново. Так что комментируйте //выражение, чтобы не подвисать на ненужных шагах.
Можете доработать метод чтобы сравнивалось например только количество строк, это значительно ускорит выполнение.

(1)
структура "ПараметрыРасчета" меняет тип на что-то не понятное

С таким не сталкивался
Оставьте свое сообщение

См. также

Публикаций не найдено

Попробуйте расширить область поиска, проверьте поисковый запрос и повторите попытку.

Или закажите индивидуальную разработку вашего решения.

Создать заказ на разработку