Имя: Пароль:
1C
1С v8
БСП: создание связанных объектов
0 triviumfan
 
01.06.18
12:36
Доброго дня, коллеги.
Нужно минимальными усилиями позволить создавать некий документ на основании другого. Выбор упал на внешнюю обработку типа "создание связанных объектов". Но загвоздка в том, что УТ11.3 ругается - "Для создании на основании требуется провести документ. Выполнить проведение и продолжить?". А у меня задача как раз в том, чтобы сначала создать связанный объект (перемещение между организациями), а затем уже сделать возможность проводить текущий объект (реализация).

Кто-нибудь сталкивался с этим? Как обойти?
1 PiotrLoginov
 
01.06.18
13:32
Никак. В том значении понятия "Создании на основании", в каком оно применяется разработчиками 1С, никакими способами нельзя создать что-то на основании еще незаписанного объекта.
2 PiotrLoginov
 
01.06.18
13:39
Поправлюсь:  если объект-основание хотя бы записан, таких проблем быть не должно. Вариант запуска в параметрах регистрации внешней обработки какой?
3 triviumfan
 
01.06.18
13:39
*рыдает*
4 triviumfan
 
01.06.18
13:40
(2) так он записан...

Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    ПараметрыРегистрации.Информация = НСтр("ru = 'Создание документа ""Передача товаров между организациями"".'");
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиСозданиеСвязанныхОбъектов();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Назначение.Добавить(Метаданные.Документы.РеализацияТоваровУслуг.ПолноеИмя());
    
    Команда = ПараметрыРегистрации.Команды.Добавить();
    Команда.Представление = НСтр("ru = 'Сформировать передачу товара между организациями.'");
    Команда.Идентификатор = "ИТМ_СозданиеПередачиТоваровМеждуОрганизациями";
    Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
    Команда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
КонецФункции
5 PiotrLoginov
 
01.06.18
13:43
(3) не стоит

(4) так.  теперь: что в экспортной процедуре ВыполнитьКоманду() ?
6 triviumfan
 
01.06.18
13:44
(5) Украдено из примера БСП 2.4

// Обработчик серверных команд.
//
// Параметры:
//   ИдентификаторКоманды - Строка - Имя команды, определенное в функции СведенияОВнешнейОбработке().
//   ОбъектыНазначения    - Массив - Ссылки объектов, для которых вызвана команда.
//   СозданныеОбъекты     - Массив - Ссылки новых объектов, созданных в результате выполнения команды.
//   ПараметрыВыполнения  - Структура - Контекст выполнения команды.
//       * ДополнительнаяОбработкаСсылка - СправочникСсылка.ДополнительныеОтчетыИОбработки - Ссылка обработки.
//           Может использоваться для чтения параметров обработки.
//           Пример см. в комментарии к функции ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы().
//
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, СозданныеОбъекты, ПараметрыВыполнения) Экспорт
    ДатаНачалаВМиллисекундах = ТекущаяУниверсальнаяДатаВМиллисекундах();
    МестоХраненияПриемник = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыВыполнения, "МестоХраненияПриемник");
    
    СозданныеОбъекты = Новый Массив;
    Для Каждого Основание Из ОбъектыНазначения Цикл
        ОбъектОснование = Основание.ПолучитьОбъект();
        Если ИдентификаторКоманды = "ИТМ_СозданиеПередачиТоваровМеждуОрганизациями" Тогда
            НовыйОбъект = СозданиеПередачиТоваровМеждуОрганизациями(Основание, ОбъектОснование);
        Иначе
            ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                НСтр("ru = 'Команда ""%1"" не поддерживается обработкой ""%2""'"),
                ИдентификаторКоманды,
                Метаданные().Представление());
        КонецЕсли;
        НовыйОбъект.Записать();
        СозданныеОбъекты.Добавить(НовыйОбъект.Ссылка);
    КонецЦикла;
    
    // Имитация длительной операции.
    ГСЧ = Новый ГенераторСлучайныхЧисел;
    ДатаЗавершенияВМиллисекундах = ДатаНачалаВМиллисекундах + 1000*ГСЧ.СлучайноеЧисло(2, 4);
    Пока ТекущаяУниверсальнаяДатаВМиллисекундах() < ДатаЗавершенияВМиллисекундах Цикл
    КонецЦикла;
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Выполнение соответствующей команды.
Функция СозданиеПередачиТоваровМеждуОрганизациями(Основание, ОбъектОснование)
    
    НовыйОбъект = Документы.ПередачаТоваровМеждуОрганизациями.СоздатьДокумент();
    ЗаполнитьДокументНаОснованииДругого(НовыйОбъект, Основание, ОбъектОснование);
    НовыйОбъект.Товары.Загрузить(ОбъектОснование.Товары.Выгрузить());
    Возврат НовыйОбъект;    
    
КонецФункции
    
// Общая механика.
Процедура ЗаполнитьДокументНаОснованииДругого(НовыйОбъект, Основание, ОбъектОснование)
    ЗаполнитьЗначенияСвойств(НовыйОбъект, ОбъектОснование, , "Номер, Ответственный");
    НовыйОбъект.Дата = ТекущаяДатаСеанса();
    НовыйОбъект.Комментарий = СтрЗаменить(НСтр("ru = 'Введен на основании ""%1"".'"), "%1", Строка(Основание))
        + ?(ЗначениеЗаполнено(НовыйОбъект.Комментарий), " " + СокрЛП(НовыйОбъект.Комментарий), "");
КонецПроцедуры
7 PiotrLoginov
 
01.06.18
13:48
Имхо, не стоило "красть". Для начала попробовать создать нужный объект кодом попроще. Лучше - не использовать механизмы создания на основании. Очень может быть, что проверка на проведенность основания заложена в один из типовых обработчиков. Здесь подсистема создания связанных объектов посредством подключенной внешней обработки совершенно ни при чем.
8 PiotrLoginov
 
01.06.18
13:48
Вот это вот: "ЗаполнитьДокументНаОснованииДругого"  - очень меня смущает.
9 triviumfan
 
01.06.18
14:00
(8) Тупо копирование свойств) нечему тут смущать.
Да, разумеется, проблема с типовым обработчиком, только он все же входит в состав БСП.
https://yadi.sk/i/duIbMhr73WoxHd

доп параметры изначально так формируются...

ДополнительныеПараметры = Новый Структура;
    ДополнительныеПараметры.Вставить("ОписаниеКоманды", ОписаниеКоманды);
    ДополнительныеПараметры.Вставить("Форма", Форма);
    ДополнительныеПараметры.Вставить("Источник", Источник);
10 PiotrLoginov
 
01.06.18
14:11
На скрине вижу, что выполнение команды внешней обработки выполняется обработчиком "Подключаемый_ВыполнитьКомандуСоздатьНаОсновании()

Т.е. команда "СозданиеСвязанныхОбъектов", а обработчик - "создание на основании"? Надо понять, почему так.
11 triviumfan
 
01.06.18
14:35
(10) Такое поведение создания команд БСП.
Прикол в том, что при регистрации обработки я не могу явно указать, делать проверку проведения или нет, как это обычно делается в модуле менеджера при добавлении команд:

Функция ДобавитьКомандуСоздатьНаОсновании(КомандыСоздатьНаОсновании) Экспорт

    
    Если ПравоДоступа("Добавление", Метаданные.Документы.ОтборРазмещениеТоваров) Тогда
        КомандаСоздатьНаОсновании = КомандыСоздатьНаОсновании.Добавить();
        КомандаСоздатьНаОсновании.Идентификатор = Метаданные.Документы.ОтборРазмещениеТоваров.ПолноеИмя();
        КомандаСоздатьНаОсновании.Представление = ВводНаОсновании.ПредставлениеОбъекта(Метаданные.Документы.ОтборРазмещениеТоваров);
        КомандаСоздатьНаОсновании.ПроверкаПроведенияПередСозданиемНаОсновании = Истина;
        КомандаСоздатьНаОсновании.ФункциональныеОпции = "ИспользоватьАдресноеХранение";
    

        Возврат КомандаСоздатьНаОсновании;
    КонецЕсли;

    Возврат Неопределено;
КонецФункции
12 triviumfan
 
01.06.18
15:15
Проблема тут:
ВводНаОснованииПереопределяемый.ПередДобавлениемКомандСоздатьНаОсновании()


Процедура ПередДобавлениемКомандСоздатьНаОсновании(ИмяФормы, КомандыСоздатьНаОсновании, СтандартнаяОбработка) Экспорт
    
    МассивПолей = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИмяФормы,".");
    
    Если ПравоДоступа("Просмотр", Метаданные.Обработки.ИнтеграцияС1СДокументооборот) Тогда
        КомандаСозданияНаОсновании = КомандыСоздатьНаОсновании.Добавить();
        КомандаСозданияНаОсновании.Обработчик = "ВводНаОснованииУТКлиент.ИнтеграцияС1СДокументооборотСоздатьПисьмо";
        КомандаСозданияНаОсновании.Идентификатор = "ИнтеграцияС1СДокументооборотСоздатьПисьмо";
        КомандаСозданияНаОсновании.Представление = НСтр("ru = 'Документооборот: Письмо'");
        КомандаСозданияНаОсновании.ПроверкаПроведенияПередСозданиемНаОсновании = Истина;
        КомандаСозданияНаОсновании.ФункциональныеОпции = "ИспользоватьЭлектроннуюПочту1СДокументооборота";
        КомандаСозданияНаОсновании.Порядок = 98;
        
        КомандаСозданияНаОсновании = КомандыСоздатьНаОсновании.Добавить();
        КомандаСозданияНаОсновании.Обработчик = "ВводНаОснованииУТКлиент.ИнтеграцияС1СДокументооборотСоздатьБизнесПроцесс";
        КомандаСозданияНаОсновании.Идентификатор = "ИнтеграцияС1СДокументооборотСоздатьБизнесПроцесс";
        КомандаСозданияНаОсновании.Представление = НСтр("ru = 'Документооборот: Процесс...'");
        КомандаСозданияНаОсновании.ПроверкаПроведенияПередСозданиемНаОсновании = Истина;
        КомандаСозданияНаОсновании.ФункциональныеОпции = "ИспользоватьПроцессыИЗадачи1СДокументооборота";
        КомандаСозданияНаОсновании.Порядок = 99;
    КонецЕсли;
    
    Если (ПолучитьФункциональнуюОпцию("ИспользоватьДополнительныеОбработкиСозданияСвязанныхОбъектов",
                Новый Структура("ДополнительныеОтчетыИОбработкиОбъектНазначения,ДополнительныеОтчетыИОбработкиТипФормы",
                Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("ПолноеИмя",МассивПолей[0]+"."+МассивПолей[1]), МассивПолей[3]))
            или ПолучитьФункциональнуюОпцию("ИспользоватьДополнительныеОбработкиСозданияСвязанныхОбъектов",
                Новый Структура("ДополнительныеОтчетыИОбработкиОбъектНазначения,ДополнительныеОтчетыИОбработкиТипФормы",
                Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("ПолноеИмя",МассивПолей[0]+"."+МассивПолей[1]),
                ?(СтрНайти(МассивПолей[3], "ФормаСписка") <> 0,ДополнительныеОтчетыИОбработкиКлиентСервер.ТипФормыСписка(),
                ДополнительныеОтчетыИОбработкиКлиентСервер.ТипФормыОбъекта()))))
            и СтрНайти(ИмяФормы,"ЖурналДокументов") = 0 Тогда
        
        КомандаСозданияНаОсновании = КомандыСоздатьНаОсновании.Добавить();
        КомандаСозданияНаОсновании.Обработчик = "ВводНаОснованииУТКлиент.СозданиеСвязанныхОбъектов";
        КомандаСозданияНаОсновании.Идентификатор = "СозданиеСвязанныхОбъектов";
        КомандаСозданияНаОсновании.Представление = НСтр("ru = 'Создание связанных объектов...'");
        КомандаСозданияНаОсновании.ПроверкаПроведенияПередСозданиемНаОсновании = Истина;
        КомандаСозданияНаОсновании.Порядок = 100;
    КонецЕсли;
    
КонецПроцедуры
13 triviumfan
 
01.06.18
15:17
По умолчанию команда с проверкой проведения.
Поставил условие на имяформы и уаля!