Программное заполнение электронного заказа-заявки ЭПД
Здравствуйте,
Задача заполнить новую заказ-заявку ЭПД на форме. Не записать документ, а заполнить форму (в случае отказа документ не будет записан).
Врезаюсь расширением на основную форму и заполняю пока таким образом:
Простые типы таким образом заполняются, а до табличных я ещё не допёр.
Прошу методику заполнения таблиц (груза, сторон договора, адресов загрузки выгрузки)
А так же, оценить вменяемость текущей моей врезки.
Задача заполнить новую заказ-заявку ЭПД на форме. Не записать документ, а заполнить форму (в случае отказа документ не будет записан).
Врезаюсь расширением на основную форму и заполняю пока таким образом:
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьПосле(Команда)
ДанныеССервера = ДанныеССервера();
ДЗ = Новый Соответствие; // Данные заполнения
#Область Грузоотправитель
ДЗ.Вставить("СсылкаТитулГрузоотправителяГрузоотправитель",ДанныеССервера.Клиент);
ДЗ.Вставить("ВариантПоДоверенностиЗаГрузоотправителя",Истина);
ДЗ.Вставить("СсылкаТитулГрузоотправителяСоставитель",ДанныеССервера.Организация);
#КонецОбласти
ДЗ.Вставить("СсылкаТитулГрузоотправителяПеревозчик",ДанныеССервера.Перевозчик);
ДЗ.Вставить("ТитулГрузоотправителяФункция","Заявка");
ДЗ.Вставить("ТитулГрузоотправителяЗаявленныеДатаВремяПодачи",ТекущаяДата());
ДЗ.Вставить("ТитулГрузоотправителяДоговорНаименование","Договор №13/37 от "+Формат(ТекущаяДата(),"ДФ=dd.MM.yyyy"));
ДЗ.Вставить("ТитулГрузоотправителяДоговорНомер","13/37");
ДЗ.Вставить("ТитулГрузоотправителяДоговорДата",ТекущаяДата());
ДЗ.Вставить("ТитулГрузоотправителяДоговорИдентификаторФайла","123");
ДЗ.Вставить("ТитулГрузоотправителяДоговорДополнительныеСведения","321");
ITSP_ЭПД_ОбработатьИзмененияРеквизитов(ДЗ);
КонецПроцедуры
&НаКлиенте
Процедура ITSP_ЭПД_ОбработатьИзмененияРеквизитов(ДЗ)
НомерВерсии = 0;
Для Каждого СтрВерсия Из ВерсииТитулов Цикл
Если СтрВерсия.Титул = Объект.ТекущийТитул И СтрВерсия.НомерВерсии > НомерВерсии Тогда
НомерВерсии = СтрВерсия.НомерВерсии;
КонецЕсли;
КонецЦикла;
СтруктураРеквизитовФормы = Новый Структура(ЭтотОбъект.ОписаниеРеквизитовФормы.ПараметрыФормы);
СтруктураРеквизитовОбъекта = Новый Структура(ЭтотОбъект.ОписаниеРеквизитовФормы.РеквизитыОбъекта);
Для каждого Д ИЗ ДЗ Цикл
ИмяЭлемента = Д.Ключ;
ЗначениеРеквизита = Д.Значение;
Если СтруктураРеквизитовФормы.Свойство(ИмяЭлемента) Тогда
ЭтотОбъект[ИмяЭлемента] = ЗначениеРеквизита;
ИначеЕсли СтруктураРеквизитовОбъекта.Свойство(ИмяЭлемента) Тогда
Объект[ИмяЭлемента] = ЗначениеРеквизита;
КонецЕсли;
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(ЭтотОбъект, ИмяЭлемента, ЗначениеРеквизита, , , Истина);
Если ИмяЭлемента = "СсылкаТитулГрузоотправителяПеревозчик" Тогда
ОбновитьДополнительныеРеквизитыОсновнойФормы();
ИначеЕсли ИмяЭлемента = "ВариантПоДоверенностиЗаГрузоотправителя" Тогда
ОбменСГИСЭПДКлиентСервер.ИзменитьОформлениеФормы(ЭтотОбъект, ИмяЭлемента);
ВариантПоДоверенностиПриИзмененииСервер();
ИначеЕсли ИмяЭлемента = "СсылкаТитулГрузоотправителяСоставитель" Тогда
ИзмененСоставУчастников = Истина;
НаименованиеСоставителя = Строка(Объект.СсылкаТитулГрузоотправителяСоставитель);
Если ЗначениеЗаполнено(НаименованиеСоставителя) Тогда
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(ЭтотОбъект,
"ТитулГрузоотправителяПредставительГрузоотправителя", НаименованиеСоставителя, , , Истина);
Иначе
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(ЭтотОбъект,
"ТитулГрузоотправителяПредставительГрузоотправителя", , , , Истина);
КонецЕсли;
ИначеЕсли ИмяЭлемента = "ТитулГрузоотправителяФункция" Тогда
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецЕсли;
Если Элементы.Найти(ИмяЭлемента)<>Неопределено Тогда
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлемента], ЭтотОбъект);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ITSP_ЭПД_ОбработатьИзмененияРеквизитов()
&НаСервереБезКонтекста
Функция ДанныеССервера()
Рез = Новый Структура;
Рез.Вставить("Организация",Справочники.Организации.НайтиПоРеквизиту("ИНН",""));
Рез.Вставить("Перевозчик",Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",""));
Рез.Вставить("Клиент",Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",""));
Возврат Рез;
КонецФункции
ПоказатьПростые типы таким образом заполняются, а до табличных я ещё не допёр.
Прошу методику заполнения таблиц (груза, сторон договора, адресов загрузки выгрузки)
А так же, оценить вменяемость текущей моей врезки.
Найденные решения
(11) Форму ТитулГрузоотправителяГрузы открывать не нужно вообще — ни настоящую, ни через ОткрытиеФормыПоГиперссылке_Завершение. Всё делается прямо с основной формы.
1. Почему не запускался ЗагрузитьТаблицуВСтруктуруФормы
Посмотрите на её тело: она не «загружает таблицу в форму», а наоборот — выгружает таблицу формы и построчно вызывает УстановитьЗначениеРеквизитаВСтруктуреФормы с ключами ИмяТаблицы__НомерСтроки__ИмяКолонки:
То есть это просто цикл-обёртка. Ей нужен реквизит-таблица на форме, поэтому с основной формы она и не работает: таблицы грузов там нет и быть не должно. А сам метод УстановитьЗначениеРеквизитаВСтруктуреФормы ничего не знает про таблицы — он кладёт в структуру титула любой ключ, который вы дадите. Значит строку таблицы можно записать напрямую, без промежуточной формы.
2. Сквозной пример: заполнение с основной формы
Код целиком лежит в модуле основной формы (ваша врезка), формы ввода не открываются, документ не записывается.
ДанныеЗаполнения — ваша серверная функция (в вашем коде это ДанныеССервера()); ТекущаяДата() на клиенте лучше не использовать — это часы рабочей станции.
Результат на демо-базе ERP 2.5.27.56 (та самая надпись, ради которой всё затевалось):
3. Почему у вас надпись оставалась красной
Цвет и текст гиперссылки не имеют отношения к формам ввода. ИзменитьОформлениеКнопок отдаёт на сервер СтруктураРеквизитов текущей версии титула, там кнопка сопоставляется с узлом схемы формата (для «Описание груза» это //Файл/Документ/СодИнфГО/ОпГруз), и по дереву обязательности проверяются подчинённые узлы. Заголовок «N груз» рисуется потом, из количества строк в структуре — ПолучитьКоличествоОбъектовТабЧасти.
Значит красная надпись означает ровно одно: в строке груза не заполнено что-то обязательное. Для заказа-заявки обязательный минимум такой:
— ОтгрузочноеНаименованиеГруза, СостояниеГруза, ВидТары, КоличествоГрузовыхМест,
МетодОпределенияМассыГруза, ОбъемГруза;
— структура «масса груза» — МассаБрутто;
— структура «размер грузовых мест» — Высота, Длина, Ширина (все три);
— флаги ВозможностьРаспределенияПоДлинеПлатформы и ДелимостьГруза.
Главная грабля — последние два. Это булевы поля, и в структуру их нужно положить явно, даже со значением Ложь. Проверка заполненности читает ключ из структуры: если ключа нет, возвращается Неопределено, а Неопределено — не Булево, поэтому поле считается незаполненным, и вся строка груза остаётся «незаполненной». Через форму ввода эти флажки всегда имеют значение, поэтому руками проблема не воспроизводится — только при программном заполнении. У меня на этом ушло несколько прогонов: в структуре уже лежало 42 ключа, «1 груз» упрямо не появлялся.
Второе место, где легко застрять, — адрес пункта. Обязательны АдресПунктаПогрузкиИндекс и АдресПунктаПогрузкиКодРегиона, но при этом нельзя заполнять АдресПунктаПогрузкиПредставление: это не представление адреса для формы, а АдрТекст из ветки «адрес иностранного государства», и вместе с ним становится обязательным АдресПунктаПогрузкиКодСтраны. Представление для формы — отдельный реквизит ПредставлениеАдресПунктаПогрузки.
4. Как посмотреть, чего именно не хватает
Не подбирать вслепую — спросить у подсистемы:
Выдаёт список вида //Файл/Документ/СодИнфГО/АдрПункт: Не заполнено поле "Адреса пунктов погрузки и выгрузки" — сразу видно, какой узел формата пустой.
5. Мелочи, которые сэкономят время
— Телефон перевозчика. Отдельный код не нужен: ЗаполнитьРеквизитыПоСсылке внутри
сам вызывает ПоказатьОшибкиПоКонтрагенту, а тот проверяет
ПолучитьРеквизитыУчастника(Контрагент).НомераТелефонов и выводит красную подсказку
в декорацию <ИмяЭлемента>_Ошибка. Именно это делает штатный
СсылкаТитулГрузоотправителяПеревозчикПриИзменении, так что в врезке достаточно
вызвать штатный обработчик формы или напрямую ЗаполнитьРеквизитыПоСсылке.
— Грузоотправитель — поле с переменным ограничением типа. При снятом флаге
«По доверенности за грузоотправителя» поле принимает только Организацию,
при установленном — Контрагента (ВариантПоДоверенностиПриИзмененииСервер).
Флаг выставляйте до записи грузоотправителя, иначе значение ляжет в объект,
но в поле не покажется.
— Контейнер версии титула — один на весь пакет. Без него каждый вызов
УстановитьЗначениеРеквизитаВСтруктуреФормы заново копирует структуру реквизитов
формы рекурсивно, а в конце всё равно нужен один СтруктураРеквизитов = ....
— Строка без содержательных колонок молча пропускается. В структуру попадает только
та строка, где заполнено хотя бы одно поле кроме ИдентификаторСтроки и
ИдентификаторСтрокиРодителя.
— НомерВерсии в вашей врезке вычисляется, но нигде не используется — либо передавайте
его в КонтейнерОтображаемойВерсииРеквизита, либо уберите расчёт.
1. Почему не запускался ЗагрузитьТаблицуВСтруктуруФормы
Посмотрите на её тело: она не «загружает таблицу в форму», а наоборот — выгружает таблицу формы и построчно вызывает УстановитьЗначениеРеквизитаВСтруктуреФормы с ключами ИмяТаблицы__НомерСтроки__ИмяКолонки:
Таблица = Форма[ИмяТаблицы].Выгрузить();
...
СтруктураСтроки.Вставить(ИмяТаблицы + "__" + Строка(НомерСтроки) + "__" + Колонка.Имя, ЗначениеКолонки);То есть это просто цикл-обёртка. Ей нужен реквизит-таблица на форме, поэтому с основной формы она и не работает: таблицы грузов там нет и быть не должно. А сам метод УстановитьЗначениеРеквизитаВСтруктуреФормы ничего не знает про таблицы — он кладёт в структуру титула любой ключ, который вы дадите. Значит строку таблицы можно записать напрямую, без промежуточной формы.
2. Сквозной пример: заполнение с основной формы
Код целиком лежит в модуле основной формы (ваша врезка), формы ввода не открываются, документ не записывается.
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьВсё(Команда)
// Контейнер отображаемой версии титула берём ОДИН раз и передаём во все вызовы.
// Без него каждый вызов заново копирует всю структуру реквизитов формы —
// на полусотне ключей это заметно.
КонтейнерВерсииТитула = ОбменСГИСЭПДКлиентСервер.КонтейнерОтображаемойВерсииРеквизита(
ЭтотОбъект, "ТитулГрузоотправителяГрузы");
// --- 1. однократные реквизиты титула ---
ЗначенияПростыхРеквизитов = Новый Структура;
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузоотправитель", ДанныеЗаполнения.Клиент);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяСоставитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяПеревозчик", ДанныеЗаполнения.Перевозчик);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФункция", "Заявка");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказНомер", "13/37");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказДата", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаявленныеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорНаименование", "Договор перевозки груза");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорНомер", "13/37");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорДата", ДанныеЗаполнения.ДатаСеанса);
Для Каждого ОписаниеРеквизита Из ЗначенияПростыхРеквизитов Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ОписаниеРеквизита.Ключ, ОписаниеРеквизита.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 2. груз: строка 1 таблицы ТитулГрузоотправителяГрузы ---
ИдентификаторСтрокиГруза = Строка(Новый УникальныйИдентификатор);
ЗначенияГруза = Новый Структура;
ЗначенияГруза.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиГруза);
ЗначенияГруза.Вставить("ОтгрузочноеНаименованиеГруза", "Мёд липовый");
ЗначенияГруза.Вставить("СостояниеГруза", "Исправное");
ЗначенияГруза.Вставить("ВидТары", "BA");
ЗначенияГруза.Вставить("КоличествоГрузовыхМест", 100);
ЗначенияГруза.Вставить("МетодОпределенияМассыГруза", "01");
ЗначенияГруза.Вставить("ОбъемГруза", 48);
ЗначенияГруза.Вставить("МассаБрутто", 25000);
ЗначенияГруза.Вставить("МассаНетто", 24000);
ЗначенияГруза.Вставить("Высота", 2);
ЗначенияГруза.Вставить("Длина", 12);
ЗначенияГруза.Вставить("Ширина", 2);
ЗначенияГруза.Вставить("ВозможностьРаспределенияПоДлинеПлатформы", Ложь);
ЗначенияГруза.Вставить("ДелимостьГруза", Ложь);
Для Каждого ЗначениеКолонки Из ЗначенияГруза Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузы__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 3. подчинённые таблицы груза: связь по идентификатору родителя ---
ЗначенияПунктаГруза = Новый Структура;
ЗначенияПунктаГруза.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияПунктаГруза.Вставить("ПунктПогрузки", "1");
ЗначенияПунктаГруза.Вставить("ПунктВыгрузки", "2");
ЗначенияПунктаГруза.Вставить("КоличествоГрузовыхМест", 100);
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеПодчиненнойСтрокиВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки",
ИдентификаторСтрокиГруза, ЗначенияПунктаГруза, Истина, КонтейнерВерсииТитула);
// --- 4. адреса пунктов погрузки и выгрузки ---
ЗначенияАдресов = Новый Массив;
СтрокаПогрузки = Новый Структура;
СтрокаПогрузки.Вставить("Операция", "Погрузка");
СтрокаПогрузки.Вставить("НомерПп", 1);
СтрокаПогрузки.Вставить("ДатаИВремяПогрузкиВыгрузки", ДанныеЗаполнения.ДатаСеанса);
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиИндекс", "125009");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиКодРегиона", "77");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиГород", "Москва");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиУлица", "Тверская");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиДом", "1");
СтрокаПогрузки.Вставить("ПредставлениеАдресПунктаПогрузки", "125009, г Москва, ул Тверская, д 1");
ЗначенияАдресов.Добавить(СтрокаПогрузки);
СтрокаВыгрузки = Новый Структура;
СтрокаВыгрузки.Вставить("Операция", "Выгрузка");
СтрокаВыгрузки.Вставить("НомерПп", 2);
СтрокаВыгрузки.Вставить("ДатаИВремяПогрузкиВыгрузки", ДанныеЗаполнения.ДатаСеанса + 86400);
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиИндекс", "191025");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиКодРегиона", "78");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиГород", "Санкт-Петербург");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиУлица", "Невский пр-кт");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиДом", "10");
СтрокаВыгрузки.Вставить("ПредставлениеАдресПунктаПогрузки", "191025, г Санкт-Петербург, Невский пр-кт, д 10");
ЗначенияАдресов.Добавить(СтрокаВыгрузки);
НомерСтрокиАдреса = 0;
Для Каждого ЗначенияСтрокиАдреса Из ЗначенияАдресов Цикл
НомерСтрокиАдреса = НомерСтрокиАдреса + 1;
ЗначенияСтрокиАдреса.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
Для Каждого ЗначениеКолонкиАдреса Из ЗначенияСтрокиАдреса Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект,
"ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки__" + НомерСтрокиАдреса + "__" + ЗначениеКолонкиАдреса.Ключ,
ЗначениеКолонкиАдреса.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
КонецЦикла;
// --- 5. стороны договора с перевозчиком (без них договор остаётся «Заполнить») ---
ЗначенияСторонДоговора = Новый Массив;
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН", ДанныеЗаполнения.ИННКлиента));
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН", ДанныеЗаполнения.ИННПеревозчика));
НомерСтороныДоговора = 0;
Для Каждого ЗначенияСтороныДоговора Из ЗначенияСторонДоговора Цикл
НомерСтороныДоговора = НомерСтороныДоговора + 1;
ЗначенияСтороныДоговора.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
Для Каждого ЗначениеКолонкиСтороны Из ЗначенияСтороныДоговора Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект,
"ТитулГрузоотправителяДоговорРеквизитыСторон__" + НомерСтороныДоговора + "__" + ЗначениеКолонкиСтороны.Ключ,
ЗначениеКолонкиСтороны.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
КонецЦикла;
// --- 6. фиксируем структуру на форме (один раз в конце) ---
ЭтотОбъект.СтруктураРеквизитов = ОбменСГИСЭПДКлиентСервер.СкопироватьВФиксированноеЗначенияРекурсивно(
КонтейнерВерсииТитула.СтруктураРеквизитовЗаполнение);
// --- 7. клиентские механизмы участников ---
// подтягивает реквизиты участника из справочника (наименование, ИНН, адрес, телефоны)
// и рисует красную подсказку «Не заполнен номер телефона контрагента» рядом с полем
ИменаЭлементовУчастников = "СсылкаТитулГрузоотправителяГрузоотправитель,СсылкаТитулГрузоотправителяСоставитель,СсылкаТитулГрузоотправителяПеревозчик";
Для Каждого ИмяЭлементаУчастника Из СтрРазделить(ИменаЭлементовУчастников, ",") Цикл
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлементаУчастника], ЭтотОбъект);
КонецЦикла;
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры ПоказатьДанныеЗаполнения — ваша серверная функция (в вашем коде это ДанныеССервера()); ТекущаяДата() на клиенте лучше не использовать — это часы рабочей станции.
Результат на демо-базе ERP 2.5.27.56 (та самая надпись, ради которой всё затевалось):
Описание груза: 1 груз (синим)
Адреса пунктов погрузки/выгрузки: 2 адреса (синим)
Договор на перевозку груза: Договор перевозки груза 13/37 от 10.08.2026 (синим)
Грузоотправитель / Перевозчик: Не заполнен номер телефона контрагента (красным)3. Почему у вас надпись оставалась красной
Цвет и текст гиперссылки не имеют отношения к формам ввода. ИзменитьОформлениеКнопок отдаёт на сервер СтруктураРеквизитов текущей версии титула, там кнопка сопоставляется с узлом схемы формата (для «Описание груза» это //Файл/Документ/СодИнфГО/ОпГруз), и по дереву обязательности проверяются подчинённые узлы. Заголовок «N груз» рисуется потом, из количества строк в структуре — ПолучитьКоличествоОбъектовТабЧасти.
Значит красная надпись означает ровно одно: в строке груза не заполнено что-то обязательное. Для заказа-заявки обязательный минимум такой:
— ОтгрузочноеНаименованиеГруза, СостояниеГруза, ВидТары, КоличествоГрузовыхМест,
МетодОпределенияМассыГруза, ОбъемГруза;
— структура «масса груза» — МассаБрутто;
— структура «размер грузовых мест» — Высота, Длина, Ширина (все три);
— флаги ВозможностьРаспределенияПоДлинеПлатформы и ДелимостьГруза.
Главная грабля — последние два. Это булевы поля, и в структуру их нужно положить явно, даже со значением Ложь. Проверка заполненности читает ключ из структуры: если ключа нет, возвращается Неопределено, а Неопределено — не Булево, поэтому поле считается незаполненным, и вся строка груза остаётся «незаполненной». Через форму ввода эти флажки всегда имеют значение, поэтому руками проблема не воспроизводится — только при программном заполнении. У меня на этом ушло несколько прогонов: в структуре уже лежало 42 ключа, «1 груз» упрямо не появлялся.
Второе место, где легко застрять, — адрес пункта. Обязательны АдресПунктаПогрузкиИндекс и АдресПунктаПогрузкиКодРегиона, но при этом нельзя заполнять АдресПунктаПогрузкиПредставление: это не представление адреса для формы, а АдрТекст из ветки «адрес иностранного государства», и вместе с ним становится обязательным АдресПунктаПогрузкиКодСтраны. Представление для формы — отдельный реквизит ПредставлениеАдресПунктаПогрузки.
4. Как посмотреть, чего именно не хватает
Не подбирать вслепую — спросить у подсистемы:
СтруктураПоТитулу = ОбменСГИСЭПДКлиентСервер.ПолучитьСтруктуруПоТитулуИВерсии(ЭтотОбъект);
ОписанияОшибок = ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД(
СтруктураПоТитулу, Объект.ТекущийТитул, Объект.ВидДокумента);
Для Каждого ОписаниеОшибки Из ОписанияОшибок Цикл
Сообщить(Строка(ОписаниеОшибки.Узел) + ": " + СтрСоединить(ОписаниеОшибки.Текст, " "));
КонецЦикла;Выдаёт список вида //Файл/Документ/СодИнфГО/АдрПункт: Не заполнено поле "Адреса пунктов погрузки и выгрузки" — сразу видно, какой узел формата пустой.
5. Мелочи, которые сэкономят время
— Телефон перевозчика. Отдельный код не нужен: ЗаполнитьРеквизитыПоСсылке внутри
сам вызывает ПоказатьОшибкиПоКонтрагенту, а тот проверяет
ПолучитьРеквизитыУчастника(Контрагент).НомераТелефонов и выводит красную подсказку
в декорацию <ИмяЭлемента>_Ошибка. Именно это делает штатный
СсылкаТитулГрузоотправителяПеревозчикПриИзменении, так что в врезке достаточно
вызвать штатный обработчик формы или напрямую ЗаполнитьРеквизитыПоСсылке.
— Грузоотправитель — поле с переменным ограничением типа. При снятом флаге
«По доверенности за грузоотправителя» поле принимает только Организацию,
при установленном — Контрагента (ВариантПоДоверенностиПриИзмененииСервер).
Флаг выставляйте до записи грузоотправителя, иначе значение ляжет в объект,
но в поле не покажется.
— Контейнер версии титула — один на весь пакет. Без него каждый вызов
УстановитьЗначениеРеквизитаВСтруктуреФормы заново копирует структуру реквизитов
формы рекурсивно, а в конце всё равно нужен один СтруктураРеквизитов = ....
— Строка без содержательных колонок молча пропускается. В структуру попадает только
та строка, где заполнено хотя бы одно поле кроме ИдентификаторСтроки и
ИдентификаторСтрокиРодителя.
— НомерВерсии в вашей врезке вычисляется, но нигде не используется — либо передавайте
его в КонтейнерОтображаемойВерсииРеквизита, либо уберите расчёт.
(14)(18)(19) Разобрался с обоими вопросами: и со ссылками на ХранимыеДанныеЭПД, и с «красными пунктами погрузки». В конце — процедура для ЭлектроннаяТранспортнаяНакладная, как просили.
1. «Встроенное заполнение» ХранимыеДанныеЭПД существует — искать больше не нужно
Мария, вы написали «нужно пошукать по общим модулям, может есть где-нить встроенное заполнение» — есть, и оно одно на все виды данных:
Именно её вызывает любая форма ввода («Сторона, подписавшая документ», «Параметры транспортного средства», «Транспортное средство», «Водитель»…) при нажатии «Сохранить» — см. ОбменСГИСЭПДКлиент.СохранитьПараметрыПодчиненнойФормы. Устройство элемента справочника простое: шапка (Тип, ГруппаДанных, ИмяОбъекта, Организация, Контрагент) плюс табличная часть Данные — пары «Имя реквизита формы ввода → Значение». Наименование руками собирать не нужно: в ПередЗаписью справочника оно строится само из значимых полей (ОбменСГИСЭПД.ПредставлениеХранимыхДанныхЭПД) — поэтому у стороны получается «ИНН: 7784897167 (Юр. лицо)», а у параметров ТС «86м3, 20т (Полуприцеп)».
Создание стороны договора (серверная часть, кладу в ту же ДанныеЗаполнения):
Три обязательных требования к ОписаниеДанных (иначе упадёт внутри):
- ИмяФормы — по нему функция берёт и имя объекта, и описание группы данных;
- ОписаниеРеквизитовФормы.Представления — структура с теми же ключами, что и в данных (читается по каждому ключу);
- ДанныеЗаполненияТаблицФормы — хотя бы пустая структура.
Параметры транспортного средства ЭЗЗ создаются той же функцией, меняются только группа, форма и набор полей:
2. Куда подставлять ссылку
Тут два разных случая, и оба проще, чем кажется.
Одиночная группа (параметры ТС, «Сведения о транспортном средстве» в ЭТрН). На основной форме это реквизит формы ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре дства. Заполняем его и зовём штатный обработчик — тот самый, который срабатывает, когда пользователь выбирает элемент в поле руками:
ХранимыеДанныеПриИзменении сам вычислит группу данных из имени элемента, развернёт содержимое элемента справочника в ключи структуры титула (ТитулГрузоотправителяПараметрыТранспортногоСредстваТип, ...Грузоподъемность, …), положит ссылку в ключ ХранимыеДанные<ГруппаДанных> и перерисует оформление. Ваш блок из сообщения 18 с ручным ВходящийКонтекст + ОткрытиеФормыПоГиперссылке_Завершение делает то же самое — можно оставить, но штатная обёртка короче и не требует знать состав контекста. Последний параметр Ложь — «не записывать структуру после каждого вызова», раз в конце процедуры всё равно есть общий СтруктураРеквизитов = СкопироватьВФиксированное....
Строки таблиц (стороны договора). Сторона в строке — это два ключа: значимые поля плюс ссылка в колонке ХранимыеДанныеСторонаПодписавшаяДокумент (колонка составного типа: ссылка на справочник или строка). В цикле из сообщения 13 достаточно добавить ссылку в структуру строки:
После этого форма договора показывает стороны представлениями элементов справочника — «как при ручном заполнении», что и требовалось в сообщении 18. Скриншот с демо-базы прилагаю.
Почему у вас «данные в структуре есть, а в форме не отражаются»: колонка таблицы в форме договора — это именно ХранимыеДанные..., а не ЮЛ_ИНН. Пока в строке лежит только ИНН, для XML и проверки заполненности всё в порядке (договор синеет и без ссылки), но видимая колонка пуста — ей нечего показать.
3. Мария, про «пункты погрузки и выгрузки горят красным» (14)
Смотрим макет соответствий (Документ.ЭлектронныйЗаказЗаявка.Макет.СоответствиеИменРеквизитов, он же — источник дерева обязательности):
То есть сам узел «Пункты погрузки-выгрузки» груза — необязательный, но у начатой строки обязательны все три поля. Отсюда и разница: при ручном заполнении вы просто не трогаете эту таблицу — узел пуст и не проверяется; при программном — как только в строке появился хотя бы один содержательный ключ, механизм требует заполнить ПунктПогрузки, ПунктВыгрузки и КоличествоГрузовыхМест целиком. Заполняйте все три (как в примере сообщения 13) — или не заполняйте таблицу вовсе, для заявки она не обязательна.
Чтобы не гадать, какой именно узел «начат и недозаполнен» — самодиагностика из сообщения 13 (ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД) называет узел схемы и текст прямо списком.
4. Поправка к сообщению 13
В блоке 7 у меня опечатка в имени модуля: ЗаполнитьРеквизитыПоСсылке живёт в ОбменСГИСЭПДКлиентСервер, а не в ОбменСГИСЭПДКлиент:
ЕСТЬNULL, в вашей врезке из сообщения 18 эта строка скопирована как была — поправьте и у себя.
5. ЭлектроннаяТранспортнаяНакладная: ITSP_ЭПД_ЗаполнитьВсё для титула грузоотправителя
Механика ровно та же (это одна подсистема), отличается состав обязательного минимума. Прежде чем показать код — три грабли, на которые я наступил при прогоне:
- Телефоны грузополучателя и перевозчика (СвГП/.../Тлф, СвПер/Контакт/Тлф) кладите после вызовов ЗаполнитьРеквизитыПоСсылке: та перечитывает контактные данные участника из справочника и перетирает ваши значения (у контрагента без телефона — пустотой). И раз общий контейнер к этому моменту уже устарел, вызов делается без него, но с шестым параметром Записать = Истина — иначе вставка не доедет до СтруктураРеквизитов формы.
- Каждая записанная дата автоматически взводит парный флаг <Имя>ИспользуетсяUTC = Истина (это делает сам УстановитьЗначениеРеквизитаВСтруктуреФормы). Флаги-«ИспользуетсяUTC» из обязательного минимума можно не заполнять вовсе — но если заполняете, кладите их после даты.
- Грузополучатель из заказа-заявки не переносится не из-за бага (19): в титуле ЭЗЗ грузополучателя нет вообще — ни одного поля с таким именем в макете соответствий. Переносить неоткуда, источник — только ваши данные (заказ клиента, договор и т.п.).
Сама процедура (врезка в модуль основной формы ЭТрН; ДанныеЗаполнения — ваша серверная структура: Организация, Грузополучатель, Перевозчик, СсылкаТС из раздела 1):
6. Результат прогона на демо-базе
ЭЗЗ: «1 груз», «2 адреса», «Договор перевозки груза 13/37 от 11.08.2026» — синие; поле «Параметры транспортного средства» = «86м3, 20т (Полуприцеп)»; в форме договора обе стороны видны представлениями («ИНН: 7784897167 (Юр. лицо)», «ИНН: 7731343528 (Юр. лицо)»).
ЭТрН: «Мёд липовый на 0 RUB», водители «Пётр Иванов», погрузка и указания «Сведения заполнены», «Сведения о транспортном средстве» = «А123ВС716 КАМАЗ 54901 86м3, 20т (Тягач седельный)».
ПроверитьЗаполнениеДокументаЭПД по обоим документам оставляет только служебные узлы файла обмена (ИдФайл, ВерсПрог, ВерсФорм, КНД, дата/время формирования) и подписанта — они заполняются при выгрузке и подписании, из формы их трогать не нужно.
1. «Встроенное заполнение» ХранимыеДанныеЭПД существует — искать больше не нужно
Мария, вы написали «нужно пошукать по общим модулям, может есть где-нить встроенное заполнение» — есть, и оно одно на все виды данных:
ОбменСГИСЭПДВызовСервера.ЗаписатьХранимыеДанныеЭПД(ГруппаДанных, Организация, Контрагент, ДополнительныйОтбор, ОписаниеДанных)Именно её вызывает любая форма ввода («Сторона, подписавшая документ», «Параметры транспортного средства», «Транспортное средство», «Водитель»…) при нажатии «Сохранить» — см. ОбменСГИСЭПДКлиент.СохранитьПараметрыПодчиненнойФормы. Устройство элемента справочника простое: шапка (Тип, ГруппаДанных, ИмяОбъекта, Организация, Контрагент) плюс табличная часть Данные — пары «Имя реквизита формы ввода → Значение». Наименование руками собирать не нужно: в ПередЗаписью справочника оно строится само из значимых полей (ОбменСГИСЭПД.ПредставлениеХранимыхДанныхЭПД) — поэтому у стороны получается «ИНН: 7784897167 (Юр. лицо)», а у параметров ТС «86м3, 20т (Полуприцеп)».
Создание стороны договора (серверная часть, кладу в ту же ДанныеЗаполнения):
&НаСервере
Функция ITSP_ЭПД_СторонаПоИНН(ИННСтороны, Организация, Контрагент)
// не плодим дубли: сначала ищем существующий элемент этого типа с тем же ИНН
ЗапросПоиска = Новый Запрос;
ЗапросПоиска.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 ХранимыеДанные.Ссылка КАК Ссылка
|ИЗ Справочник.ХранимыеДанныеЭПД КАК ХранимыеДанные
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ХранимыеДанныеЭПД.Данные КАК СтрокиДанных
| ПО СтрокиДанных.Ссылка = ХранимыеДанные.Ссылка
|ГДЕ ХранимыеДанные.Тип = ""СторонаПодписавшаяДокумент""
| И СтрокиДанных.Имя = ""ЮЛ_ИНН""
| И СтрокиДанных.Значение = &ЗначениеИНН";
ЗапросПоиска.УстановитьПараметр("ЗначениеИНН", ИННСтороны);
ВыборкаПоиска = ЗапросПоиска.Выполнить().Выбрать();
Если ВыборкаПоиска.Следующий() Тогда
Возврат ВыборкаПоиска.Ссылка;
КонецЕсли;
// данные — с именами реквизитов ФОРМЫ ВВОДА (как заполнила бы рука)
ЗначенияСтороны = Новый Структура;
ЗначенияСтороны.Вставить("ОбщееПолеВводаИНН", ИННСтороны);
ЗначенияСтороны.Вставить("ЮЛ_ИНН", ИННСтороны); // 12 цифр — в ФЛ_ИНН
ПредставленияСтороны = Новый Структура;
Для Каждого ОписаниеПоля Из ЗначенияСтороны Цикл
ПредставленияСтороны.Вставить(ОписаниеПоля.Ключ, Строка(ОписаниеПоля.Значение));
КонецЦикла;
ОписаниеДанных = Новый Структура;
ОписаниеДанных.Вставить("ИмяФормы", "Документ.ЭлектронныйЗаказЗаявка.Форма.СторонаПодписавшаяДокумент");
ОписаниеДанных.Вставить("ДанныеЗаполненияРеквизитовФормы", ЗначенияСтороны);
ОписаниеДанных.Вставить("ОписаниеРеквизитовФормы", Новый Структура("Представления", ПредставленияСтороны));
ОписаниеДанных.Вставить("ДанныеЗаполненияТаблицФормы", Новый Структура);
Возврат ОбменСГИСЭПД.ЗаписатьХранимыеДанныеЭПД(
"СторонаПодписавшаяДокумент", Организация, Контрагент, "", ОписаниеДанных);
КонецФункции ПоказатьТри обязательных требования к ОписаниеДанных (иначе упадёт внутри):
- ИмяФормы — по нему функция берёт и имя объекта, и описание группы данных;
- ОписаниеРеквизитовФормы.Представления — структура с теми же ключами, что и в данных (читается по каждому ключу);
- ДанныеЗаполненияТаблицФормы — хотя бы пустая структура.
Параметры транспортного средства ЭЗЗ создаются той же функцией, меняются только группа, форма и набор полей:
ЗначенияПараметров = Новый Структура;
ЗначенияПараметров.Вставить("Тип", "Полуприцеп");
ЗначенияПараметров.Вставить("Грузоподъемность", 20);
ЗначенияПараметров.Вставить("Вместимость", 86);
ЗначенияПараметров.Вставить("ТипКузова", "Тентованный");
ЗначенияПараметров.Вставить("ТипПогрузки", "Задняя");
ЗначенияПараметров.Вставить("ИныеПараметры", "Гидроборт");
// ... Представления и ОписаниеДанных так же, ИмяФормы =
// "Документ.ЭлектронныйЗаказЗаявка.Форма.ПараметрыТранспортногоСредства"
СсылкаПараметров = ОбменСГИСЭПД.ЗаписатьХранимыеДанныеЭПД(
"ТитулГрузоотправителяПараметрыТранспортногоСредства", Организация, Контрагент, "", ОписаниеДанных); Показать2. Куда подставлять ссылку
Тут два разных случая, и оба проще, чем кажется.
Одиночная группа (параметры ТС, «Сведения о транспортном средстве» в ЭТрН). На основной форме это реквизит формы ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре
ЭтотОбъект.ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСредства = ДанныеЗаполнения.ПараметрыТС;
ОбменСГИСЭПДКлиент.ХранимыеДанныеПриИзменении(ЭтотОбъект, ДанныеЗаполнения.ПараметрыТС,
Элементы.ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре дства,
, КонтейнерВерсииТитула, Ложь);ХранимыеДанныеПриИзменении сам вычислит группу данных из имени элемента, развернёт содержимое элемента справочника в ключи структуры титула (ТитулГрузоотправителяПараметрыТранспортногоСредстваТип, ...Грузоподъемность, …), положит ссылку в ключ ХранимыеДанные<ГруппаДанных> и перерисует оформление. Ваш блок из сообщения 18 с ручным ВходящийКонтекст + ОткрытиеФормыПоГиперссылке_Завершение делает то же самое — можно оставить, но штатная обёртка короче и не требует знать состав контекста. Последний параметр Ложь — «не записывать структуру после каждого вызова», раз в конце процедуры всё равно есть общий СтруктураРеквизитов = СкопироватьВФиксированное....
Строки таблиц (стороны договора). Сторона в строке — это два ключа: значимые поля плюс ссылка в колонке ХранимыеДанныеСторонаПодписавшаяДокумент (колонка составного типа: ссылка на справочник или строка). В цикле из сообщения 13 достаточно добавить ссылку в структуру строки:
ЗначенияСторонДоговора = Новый Массив;
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН, ХранимыеДанныеСторонаПодписавшаяДокумент",
ДанныеЗаполнения.ИННКлиента, ДанныеЗаполнения.СторонаКлиента));
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН, ХранимыеДанныеСторонаПодписавшаяДокумент",
ДанныеЗаполнения.ИННПеревозчика, ДанныеЗаполнения.СторонаПеревозчика));
// дальше цикл с "ТитулГрузоотправителяДоговорРеквизитыСторон__N__..." без измененийПосле этого форма договора показывает стороны представлениями элементов справочника — «как при ручном заполнении», что и требовалось в сообщении 18. Скриншот с демо-базы прилагаю.
Почему у вас «данные в структуре есть, а в форме не отражаются»: колонка таблицы в форме договора — это именно ХранимыеДанные..., а не ЮЛ_ИНН. Пока в строке лежит только ИНН, для XML и проверки заполненности всё в порядке (договор синеет и без ссылки), но видимая колонка пуста — ей нечего показать.
3. Мария, про «пункты погрузки и выгрузки горят красным» (14)
Смотрим макет соответствий (Документ.ЭлектронныйЗаказЗаявка.Макет.СоответствиеИменРеквизитов, он же — источник дерева обязательности):
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки //...ОпГруз/Пункт обязательный: НЕТ
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.ПунктПогрузки /Пункт/Погр обязательный: ДА
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.ПунктВыгрузки /Пункт/Выгр обязательный: ДА
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.КоличествоГрузовыхМест /Пункт/КолГрМест обязательный: ДАТо есть сам узел «Пункты погрузки-выгрузки» груза — необязательный, но у начатой строки обязательны все три поля. Отсюда и разница: при ручном заполнении вы просто не трогаете эту таблицу — узел пуст и не проверяется; при программном — как только в строке появился хотя бы один содержательный ключ, механизм требует заполнить ПунктПогрузки, ПунктВыгрузки и КоличествоГрузовыхМест целиком. Заполняйте все три (как в примере сообщения 13) — или не заполняйте таблицу вовсе, для заявки она не обязательна.
Чтобы не гадать, какой именно узел «начат и недозаполнен» — самодиагностика из сообщения 13 (ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД) называет узел схемы и текст прямо списком.
4. Поправка к сообщению 13
В блоке 7 у меня опечатка в имени модуля: ЗаполнитьРеквизитыПоСсылке живёт в ОбменСГИСЭПДКлиентСервер, а не в ОбменСГИСЭПДКлиент:
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлементаУчастника], ЭтотОбъект);ЕСТЬNULL, в вашей врезке из сообщения 18 эта строка скопирована как была — поправьте и у себя.
5. ЭлектроннаяТранспортнаяНакладная: ITSP_ЭПД_ЗаполнитьВсё для титула грузоотправителя
Механика ровно та же (это одна подсистема), отличается состав обязательного минимума. Прежде чем показать код — три грабли, на которые я наступил при прогоне:
- Телефоны грузополучателя и перевозчика (СвГП/.../Тлф, СвПер/Контакт/Тлф) кладите после вызовов ЗаполнитьРеквизитыПоСсылке: та перечитывает контактные данные участника из справочника и перетирает ваши значения (у контрагента без телефона — пустотой). И раз общий контейнер к этому моменту уже устарел, вызов делается без него, но с шестым параметром Записать = Истина — иначе вставка не доедет до СтруктураРеквизитов формы.
- Каждая записанная дата автоматически взводит парный флаг <Имя>ИспользуетсяUTC = Истина (это делает сам УстановитьЗначениеРеквизитаВСтруктуреФормы). Флаги-«ИспользуетсяUTC» из обязательного минимума можно не заполнять вовсе — но если заполняете, кладите их после даты.
- Грузополучатель из заказа-заявки не переносится не из-за бага (19): в титуле ЭЗЗ грузополучателя нет вообще — ни одного поля с таким именем в макете соответствий. Переносить неоткуда, источник — только ваши данные (заказ клиента, договор и т.п.).
Сама процедура (врезка в модуль основной формы ЭТрН; ДанныеЗаполнения — ваша серверная структура: Организация, Грузополучатель, Перевозчик, СсылкаТС из раздела 1):
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьВсё(Команда)
КонтейнерВерсииТитула = ОбменСГИСЭПДКлиентСервер.КонтейнерОтображаемойВерсииРеквизита(
ЭтотОбъект, "ТитулГрузоотправителяГрузы");
// --- 1. однократные реквизиты титула ---
ЗначенияПростыхРеквизитов = Новый Структура;
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузоотправитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяСоставитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузополучатель", ДанныеЗаполнения.Грузополучатель);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяПеревозчик", ДанныеЗаполнения.Перевозчик);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяСодержаниеОперации", "Перевозка груза");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяТранспортнаяНакладнаяНомер", "42/2026");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяТранспортнаяНакладнаяДата", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказДата", ДанныеЗаполнения.ДатаСеанса);
// сведения о погрузке: заявленные и фактические даты; булевы — ЯВНО, даже Ложь
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаявленныеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФактическиеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса + 3600);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФактическиеДатаВремяУбытия", ДанныеЗаполнения.ДатаСеанса + 7200);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяМассаБруттоГруза", 25000);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяКоличествоГрузовыхМест", 100);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЛицоОсуществляющееПогрузкуЯвляетсяГруз оотправителем", Истина);
// фактический адрес погрузки
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиИндекс", "125009");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиКодРегиона", "77");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиГород", "Москва");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиУлица", "Тверская");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиДом", "1");
ЗначенияПростыхРеквизитов.Вставить("ПредставлениеТитулГрузоотправителяАдресПогрузки", "125009, г Москва, ул Тверская, д 1");
// адрес доставки грузополучателя
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиИндекс", "191025");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиКодРегиона ", "78");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиГород", "Санкт-Петербург");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиУлица", "Невский пр-кт");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиДом", "10");
ЗначенияПростыхРеквизитов.Вставить("ПредставлениеТитулГрузоотправителяГрузополучательАдресДоста вки", "191025, г Санкт-Петербург, Невский пр-кт, д 10");
// указания грузоотправителя: сведения о переадресовке
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЛицоИмеющееПолномочияПереадресовки", "Грузоотправитель");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяСпособПередачиУказанияНаПереадресовку" , "Телефонограмма");
Для Каждого ОписаниеРеквизита Из ЗначенияПростыхРеквизитов Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ОписаниеРеквизита.Ключ, ОписаниеРеквизита.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 2. телефон ответственного за переадресовку (таблица, строка 1) ---
ЗначенияТелефона = Новый Структура;
ЗначенияТелефона.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияТелефона.Вставить("Телефон", "+7 495 123-45-67");
Для Каждого ЗначениеКолонки Из ЗначенияТелефона Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяОтветственныйЗаПереадресовкуНомераТеле фонов__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 3. груз (в ЭТрН к минимуму ЭЗЗ добавляется СпособУпаковки) ---
ИдентификаторСтрокиГруза = Строка(Новый УникальныйИдентификатор);
ЗначенияГруза = Новый Структура;
ЗначенияГруза.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиГруза);
ЗначенияГруза.Вставить("ОтгрузочноеНаименованиеГруза", "Мёд липовый");
ЗначенияГруза.Вставить("СостояниеГруза", "Исправное");
ЗначенияГруза.Вставить("СпособУпаковки", "Бочки");
ЗначенияГруза.Вставить("ВидТары", "BA");
ЗначенияГруза.Вставить("КоличествоГрузовыхМест", 100);
ЗначенияГруза.Вставить("МассаБрутто", 25000);
ЗначенияГруза.Вставить("МассаНетто", 24000);
Для Каждого ЗначениеКолонки Из ЗначенияГруза Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузы__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 4. водитель + телефон (телефоны — подчинённая таблица по идентификатору родителя) ---
ИдентификаторСтрокиВодителя = Строка(Новый УникальныйИдентификатор);
ЗначенияВодителя = Новый Структура;
ЗначенияВодителя.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиВодителя);
ЗначенияВодителя.Вставить("Фамилия", "Иванов");
ЗначенияВодителя.Вставить("Имя", "Пётр");
ЗначенияВодителя.Вставить("Отчество", "Сергеевич");
ЗначенияВодителя.Вставить("СерияВУ", "9911");
ЗначенияВодителя.Вставить("НомерВУ", "123456");
ЗначенияВодителя.Вставить("ДатаВыдачиВУ", ДанныеЗаполнения.ДатаСеанса - 86400 * 365);
Для Каждого ЗначениеКолонки Из ЗначенияВодителя Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяВодители__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
ЗначенияТелефонаВодителя = Новый Структура;
ЗначенияТелефонаВодителя.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияТелефонаВодителя.Вставить("Телефон", "+7 917 000-11-22");
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеПодчиненнойСтрокиВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяВодительНомераТелефонов",
ИдентификаторСтрокиВодителя, ЗначенияТелефонаВодителя, Истина, КонтейнерВерсииТитула);
// --- 5. транспортное средство: ссылка на ХранимыеДанныеЭПД + штатный обработчик ---
ЭтотОбъект.ХранимыеДанныеТитулГрузоотправителяТранспортноеСредство = ДанныеЗаполнения.СсылкаТС;
ОбменСГИСЭПДКлиент.ХранимыеДанныеПриИзменении(ЭтотОбъект, ДанныеЗаполнения.СсылкаТС,
Элементы.ХранимыеДанныеТитулГрузоотправителяТранспортноеСредство,
, КонтейнерВерсииТитула, Ложь);
// --- 6. фиксация структуры, участники ---
ЭтотОбъект.СтруктураРеквизитов = ОбменСГИСЭПДКлиентСервер.СкопироватьВФиксированноеЗначенияРекурсивно(
КонтейнерВерсииТитула.СтруктураРеквизитовЗаполнение);
ИменаЭлементовУчастников = "СсылкаТитулГрузоотправителяГрузоотправитель,СсылкаТитулГрузоотправителяСоставитель,СсылкаТитулГрузоотправителяГрузополучатель,СсылкаТитулГрузоотправителяПеревозчик";
Для Каждого ИмяЭлемента Из СтрРазделить(ИменаЭлементовУчастников, ",") Цикл
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлемента], ЭтотОбъект);
КонецЦикла;
// --- 7. телефоны участников — строго ПОСЛЕ ЗаполнитьРеквизитыПоСсылке (см. грабли выше) ---
ИменаТаблицТелефонов = "ТитулГрузоотправителяГрузополучательНомераТелефонов,ТитулГрузоотправителяПеревозчикНомераТелефонов";
Для Каждого ИмяТаблицы Из СтрРазделить(ИменаТаблицТелефонов, ",") Цикл
СтрокаТелефона = Новый Структура;
СтрокаТелефона.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
СтрокаТелефона.Вставить("Телефон", "+7 495 765-43-21");
Для Каждого ЗначениеКолонки Из СтрокаТелефона Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ИмяТаблицы + "__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, , Истина);
КонецЦикла;
КонецЦикла;
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры Показать6. Результат прогона на демо-базе
ЭЗЗ: «1 груз», «2 адреса», «Договор перевозки груза 13/37 от 11.08.2026» — синие; поле «Параметры транспортного средства» = «86м3, 20т (Полуприцеп)»; в форме договора обе стороны видны представлениями («ИНН: 7784897167 (Юр. лицо)», «ИНН: 7731343528 (Юр. лицо)»).
ЭТрН: «Мёд липовый на 0 RUB», водители «Пётр Иванов», погрузка и указания «Сведения заполнены», «Сведения о транспортном средстве» = «А123ВС716 КАМАЗ 54901 86м3, 20т (Тягач седельный)».
ПроверитьЗаполнениеДокументаЭПД по обоим документам оставляет только служебные узлы файла обмена (ИдФайл, ВерсПрог, ВерсФорм, КНД, дата/время формирования) и подписанта — они заполняются при выгрузке и подписании, из формы их трогать не нужно.
Прикрепленные файлы:
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
3.
nedomolkov.ivan
104
04.08.26 11:37
Сейчас в теме
(1) По ЭПД конкретно не работал, поэтому только методика — зато она даёт точные имена вместо угадывания.
1. Снимите структуру формы, а не подбирайте реквизиты. Пройдите ЭтотОбъект.ПолучитьРеквизиты() рекурсивно (у каждого элемента есть Имя, ТипЗначения и Путь) и выгрузите дерево в сообщение. Титулы ЭПД собираются программно, в конфигураторе этих реквизитов нет, и глазами таблицы вы не найдёте — а так получите и имена таблиц, и состав колонок.
2. Эталон берите с руками заполненного документа. Заполните заказ-заявку вручную, не записывая, и той же командой выгрузите значения всех реквизитов из п.1. Дальше вы не «заполняете форму», а воспроизводите зафиксированное состояние: сразу видно, какие таблицы реально участвуют и какие колонки обязательны.
3. Таблицы заполняются как обычная коллекция: НоваяСтрока = ЭтотОбъект[ИмяТаблицы].Добавить(), затем колонки. Две вещи, на которых спотыкаются: у строк есть собственный идентификатор, по которому на них ссылаются другие таблицы (грузы и адреса привязаны к сторонам) — его заполняете вы, форма сама этого не сделает; и после заполнения нужно прогнать ЗаполнитьРеквизитыПоСсылке, как вы уже делаете для элементов.
4. По врезке. Лишнее — двойная запись: сначала ЭтотОбъект[ИмяЭлемента] = ЗначениеРеквизита, следом УстановитьЗначениеРеквизитаВСтруктуреФормы с тем же значением. Оставьте только вызов подсистемы: он пишет значение и держит служебную структуру формы в согласии с ним. Прямое присваивание в обход ломает ровно то, ради чего этот метод написан, и всплывает это не сразу, а на титуле, который вы не трогали.
5. Устойчивее к обновлениям — не врезаться в форму, а открывать её на уже заполненном незаписанном объекте (значения заполнения или основание). Тогда штатная логика отработает сама. Проверьте по коду ПриСозданииНаСервере, собираются ли титулы из объекта: если да, путь рабочий и снимает половину вашего кода вместе с зависимостью от внутренних процедур.
1. Снимите структуру формы, а не подбирайте реквизиты. Пройдите ЭтотОбъект.ПолучитьРеквизиты() рекурсивно (у каждого элемента есть Имя, ТипЗначения и Путь) и выгрузите дерево в сообщение. Титулы ЭПД собираются программно, в конфигураторе этих реквизитов нет, и глазами таблицы вы не найдёте — а так получите и имена таблиц, и состав колонок.
2. Эталон берите с руками заполненного документа. Заполните заказ-заявку вручную, не записывая, и той же командой выгрузите значения всех реквизитов из п.1. Дальше вы не «заполняете форму», а воспроизводите зафиксированное состояние: сразу видно, какие таблицы реально участвуют и какие колонки обязательны.
3. Таблицы заполняются как обычная коллекция: НоваяСтрока = ЭтотОбъект[ИмяТаблицы].Добавить(), затем колонки. Две вещи, на которых спотыкаются: у строк есть собственный идентификатор, по которому на них ссылаются другие таблицы (грузы и адреса привязаны к сторонам) — его заполняете вы, форма сама этого не сделает; и после заполнения нужно прогнать ЗаполнитьРеквизитыПоСсылке, как вы уже делаете для элементов.
4. По врезке. Лишнее — двойная запись: сначала ЭтотОбъект[ИмяЭлемента] = ЗначениеРеквизита, следом УстановитьЗначениеРеквизитаВСтруктуреФормы с тем же значением. Оставьте только вызов подсистемы: он пишет значение и держит служебную структуру формы в согласии с ним. Прямое присваивание в обход ломает ровно то, ради чего этот метод написан, и всплывает это не сразу, а на титуле, который вы не трогали.
5. Устойчивее к обновлениям — не врезаться в форму, а открывать её на уже заполненном незаписанном объекте (значения заполнения или основание). Тогда штатная логика отработает сама. Проверьте по коду ПриСозданииНаСервере, собираются ли титулы из объекта: если да, путь рабочий и снимает половину вашего кода вместе с зависимостью от внутренних процедур.
4.
nedomolkov.ivan
104
04.08.26 11:39
Сейчас в теме
(3) Дополню свой же предыдущий ответ тремя мелочами по коду врезки — они мимо табличных частей, но всплывут обязательно.
1. НомерВерсии вычисляется и нигде не используется. Титул версионный, так что либо передавайте версию дальше, либо уберите расчёт: сейчас он создаёт ложное ощущение, что версия учтена.
2. ТекущаяДата() на клиенте - это часы рабочей станции. Для заявленной даты подачи и даты договора берите ТекущуюДатуСеанса() с сервера, иначе содержимое документа зависит от того, у кого сбились часы.
3. Порядок обхода Соответствия у вас значим: Перевозчик обновляет дополнительные реквизиты, ВариантПоДоверенности перерисовывает форму. А Соответствие обходится не в порядке вставки. Если последовательность важна - берите массив структур, иначе поймаете плавающий баг при добавлении очередного ключа.
И по табличным частям, коротко к пункту 3 предыдущего сообщения: соответствие «имя - значение» для них не работает в принципе, у таблицы нет одного значения. Строку добавили, колонки заполнили, и только после этого - вызов метода подсистемы, который дёргается в штатном ПриИзменении строки. Без него адреса погрузки и выгрузки останутся пустыми, хотя визуально в таблице всё встанет.
1. НомерВерсии вычисляется и нигде не используется. Титул версионный, так что либо передавайте версию дальше, либо уберите расчёт: сейчас он создаёт ложное ощущение, что версия учтена.
2. ТекущаяДата() на клиенте - это часы рабочей станции. Для заявленной даты подачи и даты договора берите ТекущуюДатуСеанса() с сервера, иначе содержимое документа зависит от того, у кого сбились часы.
3. Порядок обхода Соответствия у вас значим: Перевозчик обновляет дополнительные реквизиты, ВариантПоДоверенности перерисовывает форму. А Соответствие обходится не в порядке вставки. Если последовательность важна - берите массив структур, иначе поймаете плавающий баг при добавлении очередного ключа.
И по табличным частям, коротко к пункту 3 предыдущего сообщения: соответствие «имя - значение» для них не работает в принципе, у таблицы нет одного значения. Строку добавили, колонки заполнили, и только после этого - вызов метода подсистемы, который дёргается в штатном ПриИзменении строки. Без него адреса погрузки и выгрузки останутся пустыми, хотя визуально в таблице всё встанет.
Всё это очень здорово, но я предоставил готовый код, который конкретно заполняет документ. Прошу код, который заполняет табличные части. Надеюсь на людей делающих аналогичную задачу или имеющих доступ к документации от их какой-то новой методики сохранения реквизитов. То, что получилось - вырезки из стандартного кода, чуть переделанные, дающие результат. Я там мало что придумал.
Пока ответа не получил, спасибо за добрые советы, но нужен конкретный код.
Пока ответа не получил, спасибо за добрые советы, но нужен конкретный код.
6.
nedomolkov.ivan
104
04.08.26 17:20
Сейчас в теме
(5) Справедливо: методика без имён — половина ответа. Точных имён таблиц ЭПД не назову, вашей конфигурации у меня нет, а выдуманные имена хуже молчания. Зато код, который вытащит их за минуту и превратит в готовую врезку, — вот он.
1. Снять реальную структуру формы (таблицы и их колонки):
Всё, у чего есть вложенные реквизиты, — ваши таблицы, вложенные — колонки. Титулы собираются программно, в конфигураторе их нет, поэтому только так.
2. Снять эталон. Заполните заявку руками, не записывая, и выгрузите найденные таблицы:
Это и есть недостающая документация: фактический состав колонок и, главное, чем строки связаны между таблицами — грузы и адреса ссылаются на стороны по идентификатору строки, и заполнять его придётся вам.
3. Само заполнение — таблица на управляемой форме это обычная коллекция:
Вызов:
4. Чего этому коду не хватит. Присваивание колонок не дёргает обработчики, на которых держатся связи между таблицами. Откройте модуль основной формы, найдите ПриИзменении колонок нужной таблицы — они зовут процедуры ОбменСГИСЭПД...; ровно эти вызовы поставьте после добавления строки. Для простых реквизитов эту работу делает УстановитьЗначениеРеквизитаВСтруктуреФормы, для строк она её не сделает: у таблицы нет одного значения.
5. Проверка. После врезки прогоните дамп из п.2 и сравните с эталоном. Совпало построчно — можно отдавать пользователю. Без этой сверки адреса погрузки и выгрузки уходят пустыми, хотя визуально в таблице всё стоит.
1. Снять реальную структуру формы (таблицы и их колонки):
&НаСервере
Процедура ITSP_ЭПД_ДампСтруктуры()
Текст = "";
Для Каждого Р Из ПолучитьРеквизиты() Цикл
Текст = Текст + Р.Имя + " : " + Строка(Р.ТипЗначения) + Символы.ПС;
Для Каждого К Из ПолучитьРеквизиты(Р.Имя) Цикл
Текст = Текст + " " + Р.Имя + "." + К.Имя + " : " + Строка(К.ТипЗначения) + Символы.ПС;
КонецЦикла;
КонецЦикла;
Сообщить(Текст);
КонецПроцедуры ПоказатьВсё, у чего есть вложенные реквизиты, — ваши таблицы, вложенные — колонки. Титулы собираются программно, в конфигураторе их нет, поэтому только так.
2. Снять эталон. Заполните заявку руками, не записывая, и выгрузите найденные таблицы:
&НаСервере
Процедура ITSP_ЭПД_ДампТаблицы(ИмяТаблицы)
Т = ЭтотОбъект[ИмяТаблицы].Выгрузить();
Для Каждого С Из Т Цикл
Стр = "";
Для Каждого К Из Т.Колонки Цикл
Стр = Стр + К.Имя + " = " + Строка(С[К.Имя]) + "; ";
КонецЦикла;
Сообщить(ИмяТаблицы + " | " + Стр);
КонецЦикла;
КонецПроцедуры ПоказатьЭто и есть недостающая документация: фактический состав колонок и, главное, чем строки связаны между таблицами — грузы и адреса ссылаются на стороны по идентификатору строки, и заполнять его придётся вам.
3. Само заполнение — таблица на управляемой форме это обычная коллекция:
&НаКлиенте
Процедура ITSP_ЭПД_ДобавитьСтроки(ИмяТаблицы, МассивСтруктур)
Таблица = ЭтотОбъект[ИмяТаблицы];
Для Каждого Данные Из МассивСтруктур Цикл
НоваяСтрока = Таблица.Добавить();
Для Каждого КЗ Из Данные Цикл
НоваяСтрока[КЗ.Ключ] = КЗ.Значение;
КонецЦикла;
КонецЦикла;
КонецПроцедуры ПоказатьВызов:
Грузы = Новый Массив;
Грузы.Добавить(Новый Структура("Наименование, Количество, Масса", "Паллета", 3, 750));
ITSP_ЭПД_ДобавитьСтроки(ИмяТаблицыИзПункта1, Грузы);4. Чего этому коду не хватит. Присваивание колонок не дёргает обработчики, на которых держатся связи между таблицами. Откройте модуль основной формы, найдите ПриИзменении колонок нужной таблицы — они зовут процедуры ОбменСГИСЭПД...; ровно эти вызовы поставьте после добавления строки. Для простых реквизитов эту работу делает УстановитьЗначениеРеквизитаВСтруктуреФормы, для строк она её не сделает: у таблицы нет одного значения.
5. Проверка. После врезки прогоните дамп из п.2 и сравните с эталоном. Совпало построчно — можно отдавать пользователю. Без этой сверки адреса погрузки и выгрузки уходят пустыми, хотя визуально в таблице всё стоит.
Спасибо за старания, но догадки не нужны. Есть конкретный документ в конкретной конфигурации. Методика - не нужна, нужно конкретное, человеческое решение от тех, кто работает конкретно с ЭПД (это сейчас популярно). Конфигурация - БП 3.0, модуль ЭПД есть во всех основных конфигурациях. Если у вас нет опыта конкретно с ЭПД - не тратьте время.
(7) решение простое - внедряете Контур.Логистика а там кастомизируете что хотите и без программирования а только визуальными настройками мэппинга документов учетной системы в контуровские доки и справочники. Из коробки уже все настроено для БП3 в т.ч. и это легко "затюнинговать". А 1с-ная ЭДО подсистема сложна, негибка и нужно обновлять постоянно релизы - в Контур.Логистике достаточно обновить расширение.
(7) Конкретика будет, но начну с причины, по которой поиск не давал результата.
1. Табличных частей, которые вы ищете, у документа нет
У Документ.ЭлектронныйЗаказЗаявка ровно одна табличная часть — ДокументыОснования. Грузы, адреса пунктов погрузки и выгрузки, стороны договора, водители не являются ни реквизитами объекта, ни обычными реквизитами формы, поэтому подобрать их имя перебором нельзя в принципе.
Содержимое титула хранится в регистре сведений ЗначенияРеквизитовДокументовЭПД. В измерениях, кроме документа, организации, титула и номера версии, есть ещё три ключевых: ИмяТабличнойЧасти, НомерСтрокиРеквизита и ИмяРеквизита. Значение кладётся в один из трёх ресурсов по типу: ЗначениеРеквизитаСтрока, ЗначениеРеквизита (булево, дата, число) или ЗначениеРеквизитаСсылка.
Одна строка «табличной части» — это набор записей регистра с общими ИмяТабличнойЧасти и НомерСтрокиРеквизита, различающихся ИмяРеквизита. Это и есть та «новая методика сохранения реквизитов», о которой вы писали.
2. Как форма и документ обмениваются данными
Форма кладёт в ДополнительныеСвойства объекта плоскую структуру СтруктураРеквизитов, а ПриЗаписи документа разбирает каждый её ключ:
Ключ строки таблицы — ИмяТаблицы__НомерСтроки__ИмяРеквизита, разделитель из двух подчёркиваний. Тип значения подсистема определяет сама, раскладывая его по нужному ресурсу.
3. Что менять в вашей врезке
Заполнять надо не структуру руками, а таблицу формы — и отдать её подсистеме одним вызовом:
Сигнатура: ЗагрузитьТаблицуВСтруктуруФормы(Форма, ИмяТаблицы, Перезаписывать = Истина, КонтейнерОтображаемойВерсии = Неопределено). Внутри она выгружает таблицу формы, нумерует строки с единицы и на каждую колонку вызывает УстановитьЗначениеРеквизитаВСтруктуреФормы — тот самый метод, которым вы уже пишете простые реквизиты. Документ при этом не записывается, то есть ваш сценарий «заполнили форму, а пользователь может отказаться» сохраняется.
Важное: строка попадает в структуру только если в ней заполнена хотя бы одна колонка кроме ИдентификаторСтроки и ИдентификаторСтрокиРодителя — внутри этой функции стоит проверка на содержательность строки. Строка с одними идентификаторами пропускается молча, и номер строки на неё не тратится. Со стороны это выглядит как «строки исчезли после записи».
4. Если понадобится создать заявку целиком программно, без формы
Форма не нужна вовсе, достаточно тех же ДополнительныеСвойства:
Прогнал этот код на ERP 2.5.27.56: в регистре появились записи с ИмяТабличнойЧасти = ТитулГрузоотправителяГрузы, номерами строк 1 и 2, у подчинённой таблицы ИдентификаторСтрокиРодителя совпал с идентификатором первой строки грузов, а однократный реквизит договора лёг с пустым именем таблицы и нулевым номером строки. Тестовый документ и записи после проверки удалил.
5. Имена таблиц титула заказа-заявки
Они совпадают с именами форм редактирования у документа, так что полный список виден прямо в конфигураторе. Основные: ТитулГрузоотправителяГрузы, внутри неё ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки (связь по ИдентификаторСтрокиРодителя), ТитулГрузоотправителяГрузыИнформационныеПоля и ТитулГрузоотправителяГрузыДополнительнаяИнформация. Дальше ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки, ТитулГрузоотправителяДоговор, ТитулГрузоотправителяДоговораНаВыполнениеУслуг, ТитулГрузоотправителяУказанияГрузоотправителя, ТитулГрузоотправителяУполномоченныеЛица, ТитулГрузоотправителяДокументПодтвержденияПолномочий, ТитулГрузоотправителяОснованиеРасчетовИнымЛицом, а по титулу перевозчика — ТитулПеревозчикаВодители, ТитулПеревозчикаДоверенность, ТитулПеревозчикаРазмерПлатыИПорядокРасчетов.
Состав колонок конкретной таблицы смотрится в реквизитах соответствующей формы. У ТитулГрузоотправителяГрузы это ИдентификаторСтроки, ОтгрузочноеНаименованиеГруза, СостояниеГруза, ВидТары, КоличествоГрузовыхМест, МассаБрутто, МассаНетто, ОбъемГруза, блок ДОПОГ и далее.
Проверялось на ERP 2.5.27.56. У вас БП 3.0, но подсистема ЭПД поставляется во все типовые единым блоком, состав объектов совпадает — имена таблиц у себя сверьте по списку форм документа.
1. Табличных частей, которые вы ищете, у документа нет
У Документ.ЭлектронныйЗаказЗаявка ровно одна табличная часть — ДокументыОснования. Грузы, адреса пунктов погрузки и выгрузки, стороны договора, водители не являются ни реквизитами объекта, ни обычными реквизитами формы, поэтому подобрать их имя перебором нельзя в принципе.
Содержимое титула хранится в регистре сведений ЗначенияРеквизитовДокументовЭПД. В измерениях, кроме документа, организации, титула и номера версии, есть ещё три ключевых: ИмяТабличнойЧасти, НомерСтрокиРеквизита и ИмяРеквизита. Значение кладётся в один из трёх ресурсов по типу: ЗначениеРеквизитаСтрока, ЗначениеРеквизита (булево, дата, число) или ЗначениеРеквизитаСсылка.
Одна строка «табличной части» — это набор записей регистра с общими ИмяТабличнойЧасти и НомерСтрокиРеквизита, различающихся ИмяРеквизита. Это и есть та «новая методика сохранения реквизитов», о которой вы писали.
2. Как форма и документ обмениваются данными
Форма кладёт в ДополнительныеСвойства объекта плоскую структуру СтруктураРеквизитов, а ПриЗаписи документа разбирает каждый её ключ:
МассивЧастей = ОбменСГИСЭПДКлиентСервер.РазделитьСтрокуСоСложнымРазделителем(КиЗ.Ключ, "__");
Если МассивЧастей.Количество() = 3 Тогда
ИмяТабличнойЧасти = МассивЧастей[0];
НомерСтрокиРеквизита = Число(МассивЧастей[1]);
ИмяРеквизита = МассивЧастей[2];
Иначе
ИмяТабличнойЧасти = ""; НомерСтрокиРеквизита = 0; ИмяРеквизита = КиЗ.Ключ;
КонецЕсли;Ключ строки таблицы — ИмяТаблицы__НомерСтроки__ИмяРеквизита, разделитель из двух подчёркиваний. Тип значения подсистема определяет сама, раскладывая его по нужному ресурсу.
3. Что менять в вашей врезке
Заполнять надо не структуру руками, а таблицу формы — и отдать её подсистеме одним вызовом:
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьГрузы(Команда)
НоваяСтрокаГруза = ТитулГрузоотправителяГрузы.Добавить();
НоваяСтрокаГруза.ИдентификаторСтроки = Строка(Новый УникальныйИдентификатор);
НоваяСтрокаГруза.ОтгрузочноеНаименованиеГруза = "Мебель корпусная";
НоваяСтрокаГруза.КоличествоГрузовыхМест = 12;
НоваяСтрокаГруза.МассаБрутто = 850.5;
// подчинённая таблица связывается с родителем идентификатором, а не индексом строки
НоваяСтрокаПункта = ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.Добавить();
НоваяСтрокаПункта.ИдентификаторСтроки = Строка(Новый УникальныйИдентификатор);
НоваяСтрокаПункта.ИдентификаторСтрокиРодителя = НоваяСтрокаГруза.ИдентификаторСтроки;
НоваяСтрокаПункта.КоличествоГрузовыхМест = 12;
ОбменСГИСЭПДКлиентСервер.ЗагрузитьТаблицуВСтруктуруФормы(ЭтотОбъект,
"ТитулГрузоотправителяГрузы");
ОбменСГИСЭПДКлиентСервер.ЗагрузитьТаблицуВСтруктуруФормы(ЭтотОбъект,
"ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки");
КонецПроцедуры ПоказатьСигнатура: ЗагрузитьТаблицуВСтруктуруФормы(Форма, ИмяТаблицы, Перезаписывать = Истина, КонтейнерОтображаемойВерсии = Неопределено). Внутри она выгружает таблицу формы, нумерует строки с единицы и на каждую колонку вызывает УстановитьЗначениеРеквизитаВСтруктуреФормы — тот самый метод, которым вы уже пишете простые реквизиты. Документ при этом не записывается, то есть ваш сценарий «заполнили форму, а пользователь может отказаться» сохраняется.
Важное: строка попадает в структуру только если в ней заполнена хотя бы одна колонка кроме ИдентификаторСтроки и ИдентификаторСтрокиРодителя — внутри этой функции стоит проверка на содержательность строки. Строка с одними идентификаторами пропускается молча, и номер строки на неё не тратится. Со стороны это выглядит как «строки исчезли после записи».
4. Если понадобится создать заявку целиком программно, без формы
Форма не нужна вовсе, достаточно тех же ДополнительныеСвойства:
ДокументЗаявкаОбъект = Документы.ЭлектронныйЗаказЗаявка.СоздатьДокумент();
ДокументЗаявкаОбъект.Дата = ТекущаяДатаСеанса();
ДокументЗаявкаОбъект.СсылкаТитулГрузоотправителяГрузоотправитель = ОрганизацияПоУмолчанию;
ДокументЗаявкаОбъект.ТитулГрузоотправителяФункция = "Заявка";
ДокументЗаявкаОбъект.ТитулГрузоотправителяЗаказНомер = "ТЕСТ-ЭПД-1";
ДокументЗаявкаОбъект.ТекущийТитул = Перечисления.ТипыЭлементовРегламентаЭДО.ЭЗЗ_Титул1;
ИдентификаторСтрокиПервогоГруза = Строка(Новый УникальныйИдентификатор);
СтруктураРеквизитовТитула = Новый Структура;
СтруктураРеквизитовТитула.Вставить("ТитулГрузоотправителяДоговорНомер", "13/37");
СтруктураРеквизитовТитула.Вставить("ТитулГрузоотправителяГрузы__1__ИдентификаторСтроки",
ИдентификаторСтрокиПервогоГруза);
СтруктураРеквизитовТитула.Вставить("ТитулГрузоотправителяГрузы__1__ОтгрузочноеНаименованиеГруза ",
"Мебель корпусная");
СтруктураРеквизитовТитула.Вставить("ТитулГрузоотправителяГрузы__1__КоличествоГрузовыхМест", 12);
СтруктураРеквизитовТитула.Вставить("ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки__1__Иденти фикаторСтрокиРодителя",
ИдентификаторСтрокиПервогоГруза);
ВерсияТитулаСтруктура = Новый Структура;
ВерсияТитулаСтруктура.Вставить("Титул", Перечисления.ТипыЭлементовРегламентаЭДО.ЭЗЗ_Титул1);
ВерсияТитулаСтруктура.Вставить("НомерВерсии", 0);
ВерсияТитулаСтруктура.Вставить("ИдентификаторФайла", "");
ВерсияТитулаСтруктура.Вставить("ДатаВерсии", ТекущаяДатаСеанса());
ДокументЗаявкаОбъект.ДополнительныеСвойства.Вставить("ВерсияТитула", ВерсияТитулаСтруктура);
ДокументЗаявкаОбъект.ДополнительныеСвойства.Вставить("НомерВерсии", 0);
ДокументЗаявкаОбъект.ДополнительныеСвойства.Вставить("СтруктураРеквизитов", СтруктураРеквизитовТитула);
ДокументЗаявкаОбъект.Записать(); ПоказатьПрогнал этот код на ERP 2.5.27.56: в регистре появились записи с ИмяТабличнойЧасти = ТитулГрузоотправителяГрузы, номерами строк 1 и 2, у подчинённой таблицы ИдентификаторСтрокиРодителя совпал с идентификатором первой строки грузов, а однократный реквизит договора лёг с пустым именем таблицы и нулевым номером строки. Тестовый документ и записи после проверки удалил.
5. Имена таблиц титула заказа-заявки
Они совпадают с именами форм редактирования у документа, так что полный список виден прямо в конфигураторе. Основные: ТитулГрузоотправителяГрузы, внутри неё ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки (связь по ИдентификаторСтрокиРодителя), ТитулГрузоотправителяГрузыИнформационныеПоля и ТитулГрузоотправителяГрузыДополнительнаяИнформация. Дальше ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки, ТитулГрузоотправителяДоговор, ТитулГрузоотправителяДоговораНаВыполнениеУслуг, ТитулГрузоотправителяУказанияГрузоотправителя, ТитулГрузоотправителяУполномоченныеЛица, ТитулГрузоотправителяДокументПодтвержденияПолномочий, ТитулГрузоотправителяОснованиеРасчетовИнымЛицом, а по титулу перевозчика — ТитулПеревозчикаВодители, ТитулПеревозчикаДоверенность, ТитулПеревозчикаРазмерПлатыИПорядокРасчетов.
Состав колонок конкретной таблицы смотрится в реквизитах соответствующей формы. У ТитулГрузоотправителяГрузы это ИдентификаторСтроки, ОтгрузочноеНаименованиеГруза, СостояниеГруза, ВидТары, КоличествоГрузовыхМест, МассаБрутто, МассаНетто, ОбъемГруза, блок ДОПОГ и далее.
Проверялось на ERP 2.5.27.56. У вас БП 3.0, но подсистема ЭПД поставляется во все типовые единым блоком, состав объектов совпадает — имена таблиц у себя сверьте по списку форм документа.
Здравствуйте,
(10)
Я врезаюсь в ОсновнаяФорма этого документа, а таблица грузов находится в форме ТитулГрузоотправителяГрузы. На основной форме нельзя ТитулГрузоотправителяГрузы.Добавить() и врезаться в каждую форму для заполнения таблиц - не комильфо.
Получил форму без проблем (взял ОбменСГИСЭПДКлиент.ВывестиФормуВводаДанных, сделал из неё ITSP_ЭПД_ПолучитьФормуВводаДанных), попробовал выполнить ваш код в полученной форме, но метод
ЗагрузитьТаблицуВСтруктуруФормы не запускается с Клиентского контекста (в серверный передать полученную форму - тоже нельзя).
Пока ломлюсь через ОбменСГИСЭПДКлиент.ОткрытиеФормыПоГиперссылке_Завершение, таким образом:
1,2,4,5 - Да, в регистре, да их видно в конфигураторе, в любом случае огромное спасибо за очень полезный код и богатый расклад.
Задача - именно подготовить форму. Помимо заполнения данных (без занесения в БД), преследуется цель отработать соответствующие клиентские механизмы. Например, при установке перевозчика, нужно подсветить, есть ли у него телефон. После корректного заполнения груза, надпись напротив "Описание груза" должна быть синего цвета "1 груз". Сейчас, при заполнении последним куском кода, надпись красная - "Заполнить". Продолжаю ломать голову, задача не решена.
(10)
3. Что менять в вашей врезке
Заполнять надо не структуру руками, а таблицу формы — и отдать её подсистеме одним вызовом:
Заполнять надо не структуру руками, а таблицу формы — и отдать её подсистеме одним вызовом:
Я врезаюсь в ОсновнаяФорма этого документа, а таблица грузов находится в форме ТитулГрузоотправителяГрузы. На основной форме нельзя ТитулГрузоотправителяГрузы.Добавить() и врезаться в каждую форму для заполнения таблиц - не комильфо.
Получил форму без проблем (взял ОбменСГИСЭПДКлиент.ВывестиФормуВводаДанных, сделал из неё ITSP_ЭПД_ПолучитьФормуВводаДанных), попробовал выполнить ваш код в полученной форме, но метод
ЗагрузитьТаблицуВСтруктуруФормы не запускается с Клиентского контекста (в серверный передать полученную форму - тоже нельзя).
ФормаГрузы = ОбменСГИСЭПДКлиент.ITSP_ЭПД_ПолучитьФормуВводаДанных(ЭтотОбъект, "ЗаполнитьТитулГрузоотправителяГрузы");
ITSP_ЭПД_ЗаполнитьГрузы(ФормаГрузы);
ФормаГрузы.Открыть();
КонецПроцедуры
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьГрузы(ФормаГрузы)
НоваяСтрокаГруза = ФормаГрузы.ТитулГрузоотправителяГрузы.Добавить();
НоваяСтрокаГруза.ИдентификаторСтроки = Строка(Новый УникальныйИдентификатор);
НоваяСтрокаГруза.ОтгрузочноеНаименованиеГруза = "Мебель корпусная";
НоваяСтрокаГруза.КоличествоГрузовыхМест = 12;
НоваяСтрокаГруза.МассаБрутто = 850.5;
// подчинённая таблица связывается с родителем идентификатором, а не индексом строки
НоваяСтрокаПункта = ФормаГрузы.ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.Добавить();
НоваяСтрокаПункта.ИдентификаторСтроки = Строка(Новый УникальныйИдентификатор);
НоваяСтрокаПункта.ИдентификаторСтрокиРодителя = НоваяСтрокаГруза.ИдентификаторСтроки;
НоваяСтрокаПункта.КоличествоГрузовыхМест = 12;
ОбменСГИСЭПДКлиентСервер.ЗагрузитьТаблицуВСтруктуруФормы(ФормаГрузы,
"ТитулГрузоотправителяГрузы");
ОбменСГИСЭПДКлиентСервер.ЗагрузитьТаблицуВСтруктуруФормы(ФормаГрузы,
"ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки");
ПоказатьПока ломлюсь через ОбменСГИСЭПДКлиент.ОткрытиеФормыПоГиперссылке_Завершение, таким образом:
ГруппаДанных = "ТитулГрузоотправителяГрузы";
ОРФ = ITSP_ЭПД_ОписаниеРеквизитовФормы(ГруппаДанных);
СТ = ITSP_ЭПД_ВернутьСтруктуруТаблицПоОписанию(ОРФ);
НС = Новый Структура(СТ.ПоляТаблиц.Получить(ГруппаДанных));
НС.ОтгрузочноеНаименованиеГруза = "Мёд липовый";
НС.ВидТары = "BA";
НС.Описание = "Сладкий, вкусный";
НС.МетодОпределенияМассыГруза = "01";
НС.КоличествоГрузовыхМест = 100;
НС.МассаБрутто = 25000;
НС.Длина = 12;
НС.Ширина = 2;
НС.Высота = 2;
НС.ОбъемГруза = 48;
СТ.ДанныеЗаполненияТаблицФормы.ТитулГрузоотправителяГрузы.Добавить(НС);
РезультатВыбора = Новый Структура;
РезультатВыбора.Вставить("Ключ",ПустаяЭЗЗ());
РезультатВыбора.Вставить("ОписаниеРеквизитовФормы", ОРФ);
РезультатВыбора.Вставить("ИмяФормы","ТитулГрузоотправителяГрузы");
РезультатВыбора.Вставить("Модифицированность", Истина);
РезультатВыбора.Вставить("ДанныеЗаполненияРеквизитовФормы", Новый Структура);
РезультатВыбора.Вставить("ДанныеЗаполненияТаблицФормы", СТ.ДанныеЗаполненияТаблицФормы);
ВходящийКонтекст = Новый Структура;
ВходящийКонтекст.Вставить("ЗапретитьИзменение", Ложь);
ВходящийКонтекст.Вставить("Форма", ЭтотОбъект);
ВходящийКонтекст.Вставить("ГруппаДанных", ГруппаДанных);
//ВходящийКонтекст.Вставить("КонтейнерОтображаемойВерсии", КонтейнерОтображаемойВерсии);
//ВходящийКонтекст.Вставить("Записывать", Записывать);
//ВходящийКонтекст.Вставить("ТекущиеДанные", Неопределено);
ОбменСГИСЭПДКлиент.ОткрытиеФормыПоГиперссылке_Завершение(РезультатВыбора, ВходящийКонтекст);
&НаКлиенте
Функция ITSP_ЭПД_ВернутьСтруктуруТаблицПоОписанию(ОРФ)
ПоляТаблиц = Новый Соответствие;
ДанныеЗаполненияТаблицФормы = Новый Структура;
Для каждого Т ИЗ ОРФ.ОписаниеТаблицФормы Цикл
ДанныеЗаполненияТаблицФормы.Вставить(Т.Ключ, Новый Массив);
ПоляТаблиц.Вставить(Т.Ключ,Т.Значение);
КонецЦикла;
Рез = Новый Структура;
Рез.Вставить("ДанныеЗаполненияТаблицФормы",ДанныеЗаполненияТаблицФормы);
Рез.Вставить("ПоляТаблиц",ПоляТаблиц);
Возврат Рез;
КонецФункции
// Тут дамп описания, его можно получить, но пока я не хочу вообще создавать форму ТитулГрузоотправителяГрузы (а структура данных считывается из формы)
Функция ITSP_ЭПД_ОписаниеРеквизитовФормы(ГруппаДанных = Неопределено)
Если ГруппаДанных = "ТитулГрузоотправителяГрузы" Тогда
Возврат ЗначениеИзСтрокиВнутр("{""#"",3ee983d7-ace7-40f9-bb7e-2e916fcddd56,
|{12,
|{
|{""S"",""ПараметрыФормы""},
|{""S"",""""}
|},
|{
|{""S"",""ИменаТаблиц""},
|{""S"",""ТитулГрузоотправителяГрузы,ТитулГрузоотправителяЗаказчикАвтоматизация,ТитулГрузоотправителяЗаказчикАдресФИАСЗдание,ТитулГрузоотправителяЗаказчикНомераТелефонов,ТитулГрузоотправителяЗаказчикАдресаЭлектроннойПочты,ТитулГрузоотправителяСтороныДоговораНаВыполнениеУслуг,ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки,ТитулГрузоотправителяГрузыИнформационныеПоля,ТитулГрузоотправителяГрузыДополнительнаяИнформация,ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки""}
|},
|{
|{""S"",""ТаблицыСписки""},
|{""#"",4500381b-db30-4a10-9db4-990038032acf,
|{2,
|{""S"",""ТитулГрузоотправителяЗаказчикНомераТелефонов""},
|{""S"",""ТитулГрузоотправителяЗаказчикАдресаЭлектроннойПочты""}
|}
|}
|},
|{
|{""S"",""Представления""},
|{""#"",3ee983d7-ace7-40f9-bb7e-2e916fcddd56,
|{0}
|}
|},
|{
|{""S"",""ЕстьОбъект""},
|{""B"",0}
|},
|{
|{""S"",""ЕстьСтруктураРеквизитов""},
|{""B"",0}
|},
|{
|{""S"",""ПрефиксТитула""},
|{""S"",""ТитулГрузоотправителя""}
|},
|{
|{""S"",""НеСтроковыеТипы""},
|{""#"",3ee983d7-ace7-40f9-bb7e-2e916fcddd56,
|{0}
|}
|},
|{
|{""S"",""ОписаниеТаблицФормы""},
|{""#"",3ee983d7-ace7-40f9-bb7e-2e916fcddd56,
|{10,
|{
|{""S"",""ТитулГрузоотправителяГрузы""},
|{""S"",""ИдентификаторСтроки,ОтгрузочноеНаименованиеГруза,СостояниеГруза,ВидТары,ДругаяИнформация,КоличествоГрузовыхМест,МетодОпределенияМассыГруза,ОбъемГруза,ВозможностьРаспределенияПоДлинеПлатформы,ДелимостьГруза,УчастиеВодителяВПогрузкеГрузаВКонтейнер,ПриемГруженогоКонтейнера,МассаНетто,МассаБрутто,КоличествоПаллет,МассаТары,Высота,Длина,Ширина,СсылкаСведенияОбОпасномГрузе,НомерООН,НадлежащееОтгрузочноеНаименование,ТехническоеНаименование,Описание,Класс,КлассификационныйКод,ГруппаУпаковки,ЗнакОпасности,КодОграниченияПроездаЧерезТуннели,НазваниеИлиСимволКаждогоРадионуклида,ОписаниеФизическойИХимическойФормы,МаксимальнаяАктивностьРадиоактивногоСодержимого,КатегорияУпаковкиТранспортногоПакетаИлиКонтейнера,ТранспортныйИндекс,ИндексБезопасностиПоКритичностиДляГрузовСодержащихДелящийсяМ атериал,ОпознавательныйЗнакДляКаждогоСертификата,ПолнаяАктивностьГруза,МассаВзрывчатогоСодержимогоИмеющегоОтдельныйНомерООН,МассаВзрывчатогоСодержимогоДляВсехВеществ,ПроцентныйПоОбъемуИлиМассеСоставСмеси,ДатаИстеченияВремениУдержания,КонтрольнаяТемператураВГрадусах,АварийнаяТемператураВГрадусах,СсылкаТитулГрузоотправителяЗаказчик,ТитулГрузоотправителяЗаказчикИП_ИНН,ТитулГрузоотправителяЗаказчикОГРНИП,ТитулГрузоотправителяЗаказчикИПИныеСведения,ТитулГрузоотправителяЗаказчикИПФамилия,ТитулГрузоотправителяЗаказчикИПИмя,ТитулГрузоотправителяЗаказчикИПОтчество,ТитулГрузоотправителяЗаказчикЮЛНаименование,ТитулГрузоотправителяЗаказчикЮЛ_ИНН,ТитулГрузоотправителяЗаказчикЮЛ_КПП,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаСтатусИО_ИГ,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаСтрана,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаНаименование,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаИдентификатор ,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаИныеСведения,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаВидУдостовере ния,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаНомерУдостове рения,ТитулГрузоотправителяЗаказчикИнострЛицоБезУчетаДатаУдостовер ения,ТитулГрузоотправителяЗаказчикФЛ_ИНН,ТитулГрузоотправителяЗаказчикФЛИныеСведения,ТитулГрузоотправителяЗаказчикФЛФамилия,ТитулГрузоотправителяЗаказчикФЛИмя,ТитулГрузоотправителяЗаказчикФЛОтчество,ТитулГрузоотправителяЗаказчикАдресИндекс,ТитулГрузоотправителяЗаказчикАдресКодРегиона,ТитулГрузоотправителяЗаказчикАдресРайон,ТитулГрузоотправителяЗаказчикАдресГород,ТитулГрузоотправителяЗаказчикАдресНаселенныйПункт,ТитулГрузоотправителяЗаказчикАдресУлица,ТитулГрузоотправителяЗаказчикАдресДом,ТитулГрузоотправителяЗаказчикАдресКорпус,ТитулГрузоотправителяЗаказчикАдресКвартира,ТитулГрузоотправителяЗаказчикАдресИныеСведения,ТитулГрузоотправителяЗаказчикАдресФИАСКодГАР,ТитулГрузоотправителяЗаказчикАдресФИАСКодСубъекта,ТитулГрузоотправителяЗаказчикАдресФИАСРайонВид,ТитулГрузоотправителяЗаказчикАдресФИАСРайонНаименование,ТитулГрузоотправителяЗаказчикАдресФИАСГородВид,ТитулГрузоотправителяЗаказчикАдресФИАСГородНаименование,ТитулГрузоотправителяЗаказчикАдресФИАСНаселенныйПунктВид,ТитулГрузоотправителяЗаказчикАдресФИАСНаселенныйПунктНаимено вание,ТитулГрузоотправителяЗаказчикАдресФИАССтруктураТип,ТитулГрузоотправителяЗаказчикАдресФИАССтруктураНаименование,ТитулГрузоотправителяЗаказчикАдресФИАСДорожнаяСетьТип,ТитулГрузоотправителяЗаказчикАдресФИАСДорожнаяСетьНаименован ие,ТитулГрузоотправителяЗаказчикАдресФИАСПомещениеТип,ТитулГрузоотправителяЗаказчикАдресФИАСПомещениеНомер,ТитулГрузоотправителяЗаказчикАдресФИАСКомнатаТип,ТитулГрузоотправителяЗаказчикАдресФИАСКомнатаНомер,ТитулГрузоотправителяЗаказчикАдресКодСтраны,ТитулГрузоотправителяЗаказчикАдресПредставление,ТитулГрузоотправителяЗаказчикИныеКонтактныеДанные,ЗаполнитьТитулГрузоотправителяДоговораНаВыполнениеУслуг,НаименованиеДокумента,НомерДокумента,ДатаДокумента,ИдентификаторФайла,ДополнительныеСведения,ЗаполнитьТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки,СсылкаВидТары""}
|},
|{
|{""S"",""ТитулГрузоотправителяЗаказчикАвтоматизация""},
|{""S"",""ИдентификаторСтроки,ИдентификаторСтрокиРодителя,ИНН,Содержание""}
|},
|{
|{""S"",""ТитулГрузоотправителяЗаказчикАдресФИАСЗдание""},
|{""S"",""ИдентификаторСтроки,ИдентификаторСтрокиРодителя,ТитулГрузоотправителяЗаказчикАдресФИАСЗданиеТип,ТитулГрузоотправителяЗаказчикАдресФИАСЗданиеНомер""}
|},
|{
|{""S"",""ТитулГрузоотправителяЗаказчикНомераТелефонов""},
|{""S"",""ИдентификаторСтрокиРодителя,Телефон""}
|},
|{
|{""S"",""ТитулГрузоотправителяЗаказчикАдресаЭлектроннойПочты""},
|{""S"",""ИдентификаторСтрокиРодителя,АдресЭлектроннойПочты""}
|},
|{
|{""S"",""ТитулГрузоотправителяСтороныДоговораНаВыполнениеУслуг""},
|{""S"",""ИдентификаторСтроки,ИдентификаторСтрокиРодителя,ХранимыеДанныеСторонаПодписавшаяДокумент,ЮЛ_ИНН,ФЛ_ИНН,ИнострЛицоБезУчетаДатаВыдачиУдостоверения,ИнострЛицоБезУчетаНомерУдостоверения,ИнострЛицоБезУчетаВидУдостоверения,ИнострЛицоБезУчетаИныеСведения,ИнострЛицоБезУчетаИдентификатор,ИнострЛицоБезУчетаНаименование,ИнострЛицоБезУчетаСтрана,ИнострЛицоБезУчетаСтатусИО_ИГ,ОрганВластиВыдавшийДокумент""}
|},
|{
|{""S"",""ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки""},
|{""S"",""ИдентификаторСтроки,ИдентификаторСтрокиРодителя,ПунктПогрузки,ПунктВыгрузки,КоличествоГрузовыхМест""}
|},
|{
|{""S"",""ТитулГрузоотправителяГрузыИнформационныеПоля""},
|{""S"",""ИдентификаторСтроки,ИдентификаторСтрокиРодителя,ИдентификаторФайла""}
|},
|{
|{""S"",""ТитулГрузоотправителяГрузыДополнительнаяИнформация""},
|{""S"",""ИдентификаторСтроки,ИдентификаторСтрокиРодителя,ИдентификаторИнформации,Значение""}
|},
|{
|{""S"",""ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки""},
|{""S"",""ИдентификаторСтроки,Операция,НомерПп,ДатаИВремяПогрузкиВыгрузки,ДатаИВремяПогрузкиВыгрузкиПрименениеUTC,КрайнееВремяПодачиТС,КрайнееВремяПодачиТСПрименениеUTC,АдресПунктаПогрузкиВыгрузкиКомментарий,АдресПунктаПогрузкиВыгрузкиGLN,АдресПунктаПогрузкиВыгрузкиШирота,АдресПунктаПогрузкиВыгрузкиДолгота,ПредставлениеАдресПунктаПогрузки,АдресПунктаПогрузкиИндекс,АдресПунктаПогрузкиКодРегиона,АдресПунктаПогрузкиРайон,АдресПунктаПогрузкиГород,АдресПунктаПогрузкиНаселенныйПункт,АдресПунктаПогрузкиУлица,АдресПунктаПогрузкиДом,АдресПунктаПогрузкиКорпус,АдресПунктаПогрузкиКвартира,АдресПунктаПогрузкиИныеСведения,АдресПунктаПогрузкиФИАСКодГАР,АдресПунктаПогрузкиФИАСКодСубъекта,АдресПунктаПогрузкиФИАСРайонВид,АдресПунктаПогрузкиФИАСРайонНаименование,АдресПунктаПогрузкиФИАСГородВид,АдресПунктаПогрузкиФИАСГородНаименование,АдресПунктаПогрузкиФИАСНаселенныйПунктВид,АдресПунктаПогрузкиФИАСНаселенныйПунктНаименование,АдресПунктаПогрузкиФИАССтруктураТип,АдресПунктаПогрузкиФИАССтруктураНаименование,АдресПунктаПогрузкиФИАСДорожнаяСетьТип,АдресПунктаПогрузкиФИАСДорожнаяСетьНаименование,АдресПунктаПогрузкиФИАСПомещениеТип,АдресПунктаПогрузкиФИАСПомещениеНомер,АдресПунктаПогрузкиФИАСКомнатаТип,АдресПунктаПогрузкиФИАСКомнатаНомер,АдресПунктаПогрузкиКодСтраны,АдресПунктаПогрузкиПредставление,ВладелецПунктаПогрузкиНаименование,ВладелецПунктаПогрузкиИНН""}
|}
|}
|}
|},
|{
|{""S"",""ХранимыеДанныеФормы""},
|{""#"",4500381b-db30-4a10-9db4-990038032acf,
|{0}
|}
|},
|{
|{""S"",""ПодчиненныеТаблицы""},
|{""#"",3ee983d7-ace7-40f9-bb7e-2e916fcddd56,
|{2,
|{
|{""S"",""ТитулГрузоотправителяГрузы""},
|{""#"",4500381b-db30-4a10-9db4-990038032acf,
|{7,
|{""S"",""ТитулГрузоотправителяЗаказчикАвтоматизация""},
|{""S"",""ТитулГрузоотправителяЗаказчикАдресФИАСЗдание""},
|{""S"",""ТитулГрузоотправителяЗаказчикНомераТелефонов""},
|{""S"",""ТитулГрузоотправителяЗаказчикАдресаЭлектроннойПочты""},
|{""S"",""ТитулГрузоотправителяСтороныДоговораНаВыполнениеУслуг""},
|{""S"",""ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки""},
|{""S"",""ТитулГрузоотправителяГрузыИнформационныеПоля""}
|}
|}
|},
|{
|{""S"",""ТитулГрузоотправителяГрузыИнформационныеПоля""},
|{""#"",4500381b-db30-4a10-9db4-990038032acf,
|{1,
|{""S"",""ТитулГрузоотправителяГрузыДополнительнаяИнформация""}
|}
|}
|}
|}
|}
|},
|{
|{""S"",""ОписаниеДопРеквизитов""},
|{""#"",3ee983d7-ace7-40f9-bb7e-2e916fcddd56,
|{0}
|}
|}
|}
|}");
КонецЕсли;
КонецФункции
Показать1,2,4,5 - Да, в регистре, да их видно в конфигураторе, в любом случае огромное спасибо за очень полезный код и богатый расклад.
Задача - именно подготовить форму. Помимо заполнения данных (без занесения в БД), преследуется цель отработать соответствующие клиентские механизмы. Например, при установке перевозчика, нужно подсветить, есть ли у него телефон. После корректного заполнения груза, надпись напротив "Описание груза" должна быть синего цвета "1 груз". Сейчас, при заполнении последним куском кода, надпись красная - "Заполнить". Продолжаю ломать голову, задача не решена.
(11) Форму ТитулГрузоотправителяГрузы открывать не нужно вообще — ни настоящую, ни через ОткрытиеФормыПоГиперссылке_Завершение. Всё делается прямо с основной формы.
1. Почему не запускался ЗагрузитьТаблицуВСтруктуруФормы
Посмотрите на её тело: она не «загружает таблицу в форму», а наоборот — выгружает таблицу формы и построчно вызывает УстановитьЗначениеРеквизитаВСтруктуреФормы с ключами ИмяТаблицы__НомерСтроки__ИмяКолонки:
То есть это просто цикл-обёртка. Ей нужен реквизит-таблица на форме, поэтому с основной формы она и не работает: таблицы грузов там нет и быть не должно. А сам метод УстановитьЗначениеРеквизитаВСтруктуреФормы ничего не знает про таблицы — он кладёт в структуру титула любой ключ, который вы дадите. Значит строку таблицы можно записать напрямую, без промежуточной формы.
2. Сквозной пример: заполнение с основной формы
Код целиком лежит в модуле основной формы (ваша врезка), формы ввода не открываются, документ не записывается.
ДанныеЗаполнения — ваша серверная функция (в вашем коде это ДанныеССервера()); ТекущаяДата() на клиенте лучше не использовать — это часы рабочей станции.
Результат на демо-базе ERP 2.5.27.56 (та самая надпись, ради которой всё затевалось):
3. Почему у вас надпись оставалась красной
Цвет и текст гиперссылки не имеют отношения к формам ввода. ИзменитьОформлениеКнопок отдаёт на сервер СтруктураРеквизитов текущей версии титула, там кнопка сопоставляется с узлом схемы формата (для «Описание груза» это //Файл/Документ/СодИнфГО/ОпГруз), и по дереву обязательности проверяются подчинённые узлы. Заголовок «N груз» рисуется потом, из количества строк в структуре — ПолучитьКоличествоОбъектовТабЧасти.
Значит красная надпись означает ровно одно: в строке груза не заполнено что-то обязательное. Для заказа-заявки обязательный минимум такой:
— ОтгрузочноеНаименованиеГруза, СостояниеГруза, ВидТары, КоличествоГрузовыхМест,
МетодОпределенияМассыГруза, ОбъемГруза;
— структура «масса груза» — МассаБрутто;
— структура «размер грузовых мест» — Высота, Длина, Ширина (все три);
— флаги ВозможностьРаспределенияПоДлинеПлатформы и ДелимостьГруза.
Главная грабля — последние два. Это булевы поля, и в структуру их нужно положить явно, даже со значением Ложь. Проверка заполненности читает ключ из структуры: если ключа нет, возвращается Неопределено, а Неопределено — не Булево, поэтому поле считается незаполненным, и вся строка груза остаётся «незаполненной». Через форму ввода эти флажки всегда имеют значение, поэтому руками проблема не воспроизводится — только при программном заполнении. У меня на этом ушло несколько прогонов: в структуре уже лежало 42 ключа, «1 груз» упрямо не появлялся.
Второе место, где легко застрять, — адрес пункта. Обязательны АдресПунктаПогрузкиИндекс и АдресПунктаПогрузкиКодРегиона, но при этом нельзя заполнять АдресПунктаПогрузкиПредставление: это не представление адреса для формы, а АдрТекст из ветки «адрес иностранного государства», и вместе с ним становится обязательным АдресПунктаПогрузкиКодСтраны. Представление для формы — отдельный реквизит ПредставлениеАдресПунктаПогрузки.
4. Как посмотреть, чего именно не хватает
Не подбирать вслепую — спросить у подсистемы:
Выдаёт список вида //Файл/Документ/СодИнфГО/АдрПункт: Не заполнено поле "Адреса пунктов погрузки и выгрузки" — сразу видно, какой узел формата пустой.
5. Мелочи, которые сэкономят время
— Телефон перевозчика. Отдельный код не нужен: ЗаполнитьРеквизитыПоСсылке внутри
сам вызывает ПоказатьОшибкиПоКонтрагенту, а тот проверяет
ПолучитьРеквизитыУчастника(Контрагент).НомераТелефонов и выводит красную подсказку
в декорацию <ИмяЭлемента>_Ошибка. Именно это делает штатный
СсылкаТитулГрузоотправителяПеревозчикПриИзменении, так что в врезке достаточно
вызвать штатный обработчик формы или напрямую ЗаполнитьРеквизитыПоСсылке.
— Грузоотправитель — поле с переменным ограничением типа. При снятом флаге
«По доверенности за грузоотправителя» поле принимает только Организацию,
при установленном — Контрагента (ВариантПоДоверенностиПриИзмененииСервер).
Флаг выставляйте до записи грузоотправителя, иначе значение ляжет в объект,
но в поле не покажется.
— Контейнер версии титула — один на весь пакет. Без него каждый вызов
УстановитьЗначениеРеквизитаВСтруктуреФормы заново копирует структуру реквизитов
формы рекурсивно, а в конце всё равно нужен один СтруктураРеквизитов = ....
— Строка без содержательных колонок молча пропускается. В структуру попадает только
та строка, где заполнено хотя бы одно поле кроме ИдентификаторСтроки и
ИдентификаторСтрокиРодителя.
— НомерВерсии в вашей врезке вычисляется, но нигде не используется — либо передавайте
его в КонтейнерОтображаемойВерсииРеквизита, либо уберите расчёт.
1. Почему не запускался ЗагрузитьТаблицуВСтруктуруФормы
Посмотрите на её тело: она не «загружает таблицу в форму», а наоборот — выгружает таблицу формы и построчно вызывает УстановитьЗначениеРеквизитаВСтруктуреФормы с ключами ИмяТаблицы__НомерСтроки__ИмяКолонки:
Таблица = Форма[ИмяТаблицы].Выгрузить();
...
СтруктураСтроки.Вставить(ИмяТаблицы + "__" + Строка(НомерСтроки) + "__" + Колонка.Имя, ЗначениеКолонки);То есть это просто цикл-обёртка. Ей нужен реквизит-таблица на форме, поэтому с основной формы она и не работает: таблицы грузов там нет и быть не должно. А сам метод УстановитьЗначениеРеквизитаВСтруктуреФормы ничего не знает про таблицы — он кладёт в структуру титула любой ключ, который вы дадите. Значит строку таблицы можно записать напрямую, без промежуточной формы.
2. Сквозной пример: заполнение с основной формы
Код целиком лежит в модуле основной формы (ваша врезка), формы ввода не открываются, документ не записывается.
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьВсё(Команда)
// Контейнер отображаемой версии титула берём ОДИН раз и передаём во все вызовы.
// Без него каждый вызов заново копирует всю структуру реквизитов формы —
// на полусотне ключей это заметно.
КонтейнерВерсииТитула = ОбменСГИСЭПДКлиентСервер.КонтейнерОтображаемойВерсииРеквизита(
ЭтотОбъект, "ТитулГрузоотправителяГрузы");
// --- 1. однократные реквизиты титула ---
ЗначенияПростыхРеквизитов = Новый Структура;
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузоотправитель", ДанныеЗаполнения.Клиент);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяСоставитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяПеревозчик", ДанныеЗаполнения.Перевозчик);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФункция", "Заявка");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказНомер", "13/37");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказДата", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаявленныеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорНаименование", "Договор перевозки груза");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорНомер", "13/37");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорДата", ДанныеЗаполнения.ДатаСеанса);
Для Каждого ОписаниеРеквизита Из ЗначенияПростыхРеквизитов Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ОписаниеРеквизита.Ключ, ОписаниеРеквизита.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 2. груз: строка 1 таблицы ТитулГрузоотправителяГрузы ---
ИдентификаторСтрокиГруза = Строка(Новый УникальныйИдентификатор);
ЗначенияГруза = Новый Структура;
ЗначенияГруза.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиГруза);
ЗначенияГруза.Вставить("ОтгрузочноеНаименованиеГруза", "Мёд липовый");
ЗначенияГруза.Вставить("СостояниеГруза", "Исправное");
ЗначенияГруза.Вставить("ВидТары", "BA");
ЗначенияГруза.Вставить("КоличествоГрузовыхМест", 100);
ЗначенияГруза.Вставить("МетодОпределенияМассыГруза", "01");
ЗначенияГруза.Вставить("ОбъемГруза", 48);
ЗначенияГруза.Вставить("МассаБрутто", 25000);
ЗначенияГруза.Вставить("МассаНетто", 24000);
ЗначенияГруза.Вставить("Высота", 2);
ЗначенияГруза.Вставить("Длина", 12);
ЗначенияГруза.Вставить("Ширина", 2);
ЗначенияГруза.Вставить("ВозможностьРаспределенияПоДлинеПлатформы", Ложь);
ЗначенияГруза.Вставить("ДелимостьГруза", Ложь);
Для Каждого ЗначениеКолонки Из ЗначенияГруза Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузы__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 3. подчинённые таблицы груза: связь по идентификатору родителя ---
ЗначенияПунктаГруза = Новый Структура;
ЗначенияПунктаГруза.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияПунктаГруза.Вставить("ПунктПогрузки", "1");
ЗначенияПунктаГруза.Вставить("ПунктВыгрузки", "2");
ЗначенияПунктаГруза.Вставить("КоличествоГрузовыхМест", 100);
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеПодчиненнойСтрокиВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки",
ИдентификаторСтрокиГруза, ЗначенияПунктаГруза, Истина, КонтейнерВерсииТитула);
// --- 4. адреса пунктов погрузки и выгрузки ---
ЗначенияАдресов = Новый Массив;
СтрокаПогрузки = Новый Структура;
СтрокаПогрузки.Вставить("Операция", "Погрузка");
СтрокаПогрузки.Вставить("НомерПп", 1);
СтрокаПогрузки.Вставить("ДатаИВремяПогрузкиВыгрузки", ДанныеЗаполнения.ДатаСеанса);
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиИндекс", "125009");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиКодРегиона", "77");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиГород", "Москва");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиУлица", "Тверская");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиДом", "1");
СтрокаПогрузки.Вставить("ПредставлениеАдресПунктаПогрузки", "125009, г Москва, ул Тверская, д 1");
ЗначенияАдресов.Добавить(СтрокаПогрузки);
СтрокаВыгрузки = Новый Структура;
СтрокаВыгрузки.Вставить("Операция", "Выгрузка");
СтрокаВыгрузки.Вставить("НомерПп", 2);
СтрокаВыгрузки.Вставить("ДатаИВремяПогрузкиВыгрузки", ДанныеЗаполнения.ДатаСеанса + 86400);
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиИндекс", "191025");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиКодРегиона", "78");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиГород", "Санкт-Петербург");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиУлица", "Невский пр-кт");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиДом", "10");
СтрокаВыгрузки.Вставить("ПредставлениеАдресПунктаПогрузки", "191025, г Санкт-Петербург, Невский пр-кт, д 10");
ЗначенияАдресов.Добавить(СтрокаВыгрузки);
НомерСтрокиАдреса = 0;
Для Каждого ЗначенияСтрокиАдреса Из ЗначенияАдресов Цикл
НомерСтрокиАдреса = НомерСтрокиАдреса + 1;
ЗначенияСтрокиАдреса.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
Для Каждого ЗначениеКолонкиАдреса Из ЗначенияСтрокиАдреса Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект,
"ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки__" + НомерСтрокиАдреса + "__" + ЗначениеКолонкиАдреса.Ключ,
ЗначениеКолонкиАдреса.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
КонецЦикла;
// --- 5. стороны договора с перевозчиком (без них договор остаётся «Заполнить») ---
ЗначенияСторонДоговора = Новый Массив;
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН", ДанныеЗаполнения.ИННКлиента));
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН", ДанныеЗаполнения.ИННПеревозчика));
НомерСтороныДоговора = 0;
Для Каждого ЗначенияСтороныДоговора Из ЗначенияСторонДоговора Цикл
НомерСтороныДоговора = НомерСтороныДоговора + 1;
ЗначенияСтороныДоговора.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
Для Каждого ЗначениеКолонкиСтороны Из ЗначенияСтороныДоговора Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект,
"ТитулГрузоотправителяДоговорРеквизитыСторон__" + НомерСтороныДоговора + "__" + ЗначениеКолонкиСтороны.Ключ,
ЗначениеКолонкиСтороны.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
КонецЦикла;
// --- 6. фиксируем структуру на форме (один раз в конце) ---
ЭтотОбъект.СтруктураРеквизитов = ОбменСГИСЭПДКлиентСервер.СкопироватьВФиксированноеЗначенияРекурсивно(
КонтейнерВерсииТитула.СтруктураРеквизитовЗаполнение);
// --- 7. клиентские механизмы участников ---
// подтягивает реквизиты участника из справочника (наименование, ИНН, адрес, телефоны)
// и рисует красную подсказку «Не заполнен номер телефона контрагента» рядом с полем
ИменаЭлементовУчастников = "СсылкаТитулГрузоотправителяГрузоотправитель,СсылкаТитулГрузоотправителяСоставитель,СсылкаТитулГрузоотправителяПеревозчик";
Для Каждого ИмяЭлементаУчастника Из СтрРазделить(ИменаЭлементовУчастников, ",") Цикл
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлементаУчастника], ЭтотОбъект);
КонецЦикла;
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры ПоказатьДанныеЗаполнения — ваша серверная функция (в вашем коде это ДанныеССервера()); ТекущаяДата() на клиенте лучше не использовать — это часы рабочей станции.
Результат на демо-базе ERP 2.5.27.56 (та самая надпись, ради которой всё затевалось):
Описание груза: 1 груз (синим)
Адреса пунктов погрузки/выгрузки: 2 адреса (синим)
Договор на перевозку груза: Договор перевозки груза 13/37 от 10.08.2026 (синим)
Грузоотправитель / Перевозчик: Не заполнен номер телефона контрагента (красным)3. Почему у вас надпись оставалась красной
Цвет и текст гиперссылки не имеют отношения к формам ввода. ИзменитьОформлениеКнопок отдаёт на сервер СтруктураРеквизитов текущей версии титула, там кнопка сопоставляется с узлом схемы формата (для «Описание груза» это //Файл/Документ/СодИнфГО/ОпГруз), и по дереву обязательности проверяются подчинённые узлы. Заголовок «N груз» рисуется потом, из количества строк в структуре — ПолучитьКоличествоОбъектовТабЧасти.
Значит красная надпись означает ровно одно: в строке груза не заполнено что-то обязательное. Для заказа-заявки обязательный минимум такой:
— ОтгрузочноеНаименованиеГруза, СостояниеГруза, ВидТары, КоличествоГрузовыхМест,
МетодОпределенияМассыГруза, ОбъемГруза;
— структура «масса груза» — МассаБрутто;
— структура «размер грузовых мест» — Высота, Длина, Ширина (все три);
— флаги ВозможностьРаспределенияПоДлинеПлатформы и ДелимостьГруза.
Главная грабля — последние два. Это булевы поля, и в структуру их нужно положить явно, даже со значением Ложь. Проверка заполненности читает ключ из структуры: если ключа нет, возвращается Неопределено, а Неопределено — не Булево, поэтому поле считается незаполненным, и вся строка груза остаётся «незаполненной». Через форму ввода эти флажки всегда имеют значение, поэтому руками проблема не воспроизводится — только при программном заполнении. У меня на этом ушло несколько прогонов: в структуре уже лежало 42 ключа, «1 груз» упрямо не появлялся.
Второе место, где легко застрять, — адрес пункта. Обязательны АдресПунктаПогрузкиИндекс и АдресПунктаПогрузкиКодРегиона, но при этом нельзя заполнять АдресПунктаПогрузкиПредставление: это не представление адреса для формы, а АдрТекст из ветки «адрес иностранного государства», и вместе с ним становится обязательным АдресПунктаПогрузкиКодСтраны. Представление для формы — отдельный реквизит ПредставлениеАдресПунктаПогрузки.
4. Как посмотреть, чего именно не хватает
Не подбирать вслепую — спросить у подсистемы:
СтруктураПоТитулу = ОбменСГИСЭПДКлиентСервер.ПолучитьСтруктуруПоТитулуИВерсии(ЭтотОбъект);
ОписанияОшибок = ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД(
СтруктураПоТитулу, Объект.ТекущийТитул, Объект.ВидДокумента);
Для Каждого ОписаниеОшибки Из ОписанияОшибок Цикл
Сообщить(Строка(ОписаниеОшибки.Узел) + ": " + СтрСоединить(ОписаниеОшибки.Текст, " "));
КонецЦикла;Выдаёт список вида //Файл/Документ/СодИнфГО/АдрПункт: Не заполнено поле "Адреса пунктов погрузки и выгрузки" — сразу видно, какой узел формата пустой.
5. Мелочи, которые сэкономят время
— Телефон перевозчика. Отдельный код не нужен: ЗаполнитьРеквизитыПоСсылке внутри
сам вызывает ПоказатьОшибкиПоКонтрагенту, а тот проверяет
ПолучитьРеквизитыУчастника(Контрагент).НомераТелефонов и выводит красную подсказку
в декорацию <ИмяЭлемента>_Ошибка. Именно это делает штатный
СсылкаТитулГрузоотправителяПеревозчикПриИзменении, так что в врезке достаточно
вызвать штатный обработчик формы или напрямую ЗаполнитьРеквизитыПоСсылке.
— Грузоотправитель — поле с переменным ограничением типа. При снятом флаге
«По доверенности за грузоотправителя» поле принимает только Организацию,
при установленном — Контрагента (ВариантПоДоверенностиПриИзмененииСервер).
Флаг выставляйте до записи грузоотправителя, иначе значение ляжет в объект,
но в поле не покажется.
— Контейнер версии титула — один на весь пакет. Без него каждый вызов
УстановитьЗначениеРеквизитаВСтруктуреФормы заново копирует структуру реквизитов
формы рекурсивно, а в конце всё равно нужен один СтруктураРеквизитов = ....
— Строка без содержательных колонок молча пропускается. В структуру попадает только
та строка, где заполнено хотя бы одно поле кроме ИдентификаторСтроки и
ИдентификаторСтрокиРодителя.
— НомерВерсии в вашей врезке вычисляется, но нигде не используется — либо передавайте
его в КонтейнерОтображаемойВерсииРеквизита, либо уберите расчёт.
14.
afanaseva_maria
10.08.26 18:35
Сейчас в теме
(13) Спасибо, все удалось заполнить программно по Вашей инструкции!
Подскажите, как заполнять поля типа "СправочникСсылка.ХранимыеДанныеЭПД"
Это реквизиты:
ТитулГрузоотправителяДоговорРеквизитыСторон__1__ХранимыеДанн ыеСторонаПодписавшаяДокумент
ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре дства
И еще непонятно:
Когда заполняю Описание груза вручную, пункты погрузки и выгрузки устанавливаются как необязательные, а при программном заполнении горят красным - что на это влияет?
Заранее спасибо за ответ.
Подскажите, как заполнять поля типа "СправочникСсылка.ХранимыеДанныеЭПД"
Это реквизиты:
ТитулГрузоотправителяДоговорРеквизитыСторон__1__ХранимыеДанн
ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре
И еще непонятно:
Когда заполняю Описание груза вручную, пункты погрузки и выгрузки устанавливаются как необязательные, а при программном заполнении горят красным - что на это влияет?
Заранее спасибо за ответ.
(13)
Здравствуйте,
Безупречно, спасибо огромное! Поставленную задачу, по заполнению таблиц вы решили.
Как написала Мария, не заполняются Параметры ТС и стороны в договоре (+адрес подачи ТС, который отдельно).
Адрес подачи заполнил, параметры ТС тоже, а вот со сторонами пока не разобрался.(код ниже)
Хотя, скорее всего, необходимые данные помещены в структуру (ИННКлиента, ИННПеревозчика), но в 1С форме не отражаются, так как для этого должен быть создан объект справочника CW_ХранимыеДанныеЭПД и являлся основанием для заполнения дочерних полей. Нужно, чтобы заполнение сторон происходило ссылкам на CW_ХранимыеДанныеЭПД, и они отражались в форме, как при ручном заполнении.
Прошу озадачить ИИ, в том же контексте, составлением аналогичной процедуры ITSP_ЭПД_ЗаполнитьВсё(Команда) для ЭлектроннаяТранспортнаяНакладная
Здравствуйте,
Безупречно, спасибо огромное! Поставленную задачу, по заполнению таблиц вы решили.
Как написала Мария, не заполняются Параметры ТС и стороны в договоре (+адрес подачи ТС, который отдельно).
Адрес подачи заполнил, параметры ТС тоже, а вот со сторонами пока не разобрался.(код ниже)
Хотя, скорее всего, необходимые данные помещены в структуру (ИННКлиента, ИННПеревозчика), но в 1С форме не отражаются, так как для этого должен быть создан объект справочника CW_ХранимыеДанныеЭПД и являлся основанием для заполнения дочерних полей. Нужно, чтобы заполнение сторон происходило ссылкам на CW_ХранимыеДанныеЭПД, и они отражались в форме, как при ручном заполнении.
Прошу озадачить ИИ, в том же контексте, составлением аналогичной процедуры ITSP_ЭПД_ЗаполнитьВсё(Команда) для ЭлектроннаяТранспортнаяНакладная
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьВсё(ДанныеЗаполнения)
// Контейнер отображаемой версии титула берём ОДИН раз и передаём во все вызовы.
// Без него каждый вызов заново копирует всю структуру реквизитов формы —
// на полусотне ключей это заметно.
КонтейнерВерсииТитула = ОбменСГИСЭПДКлиентСервер.КонтейнерОтображаемойВерсииРеквизита(
ЭтотОбъект, "ТитулГрузоотправителяГрузы");
// --- 1. однократные реквизиты титула ---
ЗначенияПростыхРеквизитов = Новый Структура;
ЗначенияПростыхРеквизитов.Вставить("ВариантПоДоверенностиЗаГрузоотправителя",Истина);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузоотправитель", ДанныеЗаполнения.Клиент);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяСоставитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяПеревозчик", ДанныеЗаполнения.Перевозчик);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФункция", "Заявка");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказНомер", "13/37");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказДата", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаявленныеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорНаименование", "Договор перевозки груза");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорНомер", "13/37");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяДоговорДата", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиИндекс", 125009);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиКодРегиона", "77");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиГород", "Москва");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиУлица", "Тверская");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиДом", "1");
ЗначенияПростыхРеквизитов.Вставить("ПредставлениеТитулГрузоотправителяАдресПогрузки", "125009, г Москва, ул Тверская, д 1");
//ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоС редства =
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредства", ДанныеЗаполнения.ПараметрыТранспортногоСредства);
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредстваВместимо сть", 11);
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредстваГрузопод ъёмность", 29);
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредстваИныеПара метры", "Иные параметры");
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредстваИныеТип" , "Фура");
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредстваТипКузов а", "Прицеп");
//ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяПараметрыТранспортногоСредстваТипПогру зки", "");
Для Каждого ОписаниеРеквизита Из ЗначенияПростыхРеквизитов Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ОписаниеРеквизита.Ключ, ОписаниеРеквизита.Значение, Истина, КонтейнерВерсииТитула);
Если ОписаниеРеквизита.Ключ = "ВариантПоДоверенностиЗаГрузоотправителя" Тогда
ОбменСГИСЭПДКлиентСервер.ИзменитьОформлениеФормы(ЭтотОбъект, ОписаниеРеквизита.Ключ);
ВариантПоДоверенностиПриИзмененииСервер();
КонецЕсли;
КонецЦикла;
// --- 2. груз: строка 1 таблицы ТитулГрузоотправителяГрузы ---
ИдентификаторСтрокиГруза = Строка(Новый УникальныйИдентификатор);
ЗначенияГруза = Новый Структура;
ЗначенияГруза.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиГруза);
ЗначенияГруза.Вставить("ОтгрузочноеНаименованиеГруза", "Мёд липовый");
ЗначенияГруза.Вставить("СостояниеГруза", "Исправное");
ЗначенияГруза.Вставить("ВидТары", "BA");
ЗначенияГруза.Вставить("КоличествоГрузовыхМест", 100);
ЗначенияГруза.Вставить("МетодОпределенияМассыГруза", "01");
ЗначенияГруза.Вставить("ОбъемГруза", 48);
ЗначенияГруза.Вставить("МассаБрутто", 25000);
ЗначенияГруза.Вставить("МассаНетто", 24000);
ЗначенияГруза.Вставить("Высота", 2);
ЗначенияГруза.Вставить("Длина", 12);
ЗначенияГруза.Вставить("Ширина", 2);
ЗначенияГруза.Вставить("ВозможностьРаспределенияПоДлинеПлатформы", Ложь);
ЗначенияГруза.Вставить("ДелимостьГруза", Ложь);
Для Каждого ЗначениеКолонки Из ЗначенияГруза Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузы__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 3. подчинённые таблицы груза: связь по идентификатору родителя ---
ЗначенияПунктаГруза = Новый Структура;
ЗначенияПунктаГруза.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияПунктаГруза.Вставить("ПунктПогрузки", "1");
ЗначенияПунктаГруза.Вставить("ПунктВыгрузки", "2");
ЗначенияПунктаГруза.Вставить("КоличествоГрузовыхМест", 100);
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеПодчиненнойСтрокиВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки",
ИдентификаторСтрокиГруза, ЗначенияПунктаГруза, Истина, КонтейнерВерсииТитула);
// --- 4. адреса пунктов погрузки и выгрузки ---
ЗначенияАдресов = Новый Массив;
СтрокаПогрузки = Новый Структура;
СтрокаПогрузки.Вставить("Операция", "Погрузка");
СтрокаПогрузки.Вставить("НомерПп", 1);
СтрокаПогрузки.Вставить("ДатаИВремяПогрузкиВыгрузки", ДанныеЗаполнения.ДатаСеанса);
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиИндекс", "125009");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиКодРегиона", "77");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиГород", "Москва");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиУлица", "Тверская");
СтрокаПогрузки.Вставить("АдресПунктаПогрузкиДом", "1");
СтрокаПогрузки.Вставить("ПредставлениеАдресПунктаПогрузки", "125009, г Москва, ул Тверская, д 1");
ЗначенияАдресов.Добавить(СтрокаПогрузки);
СтрокаВыгрузки = Новый Структура;
СтрокаВыгрузки.Вставить("Операция", "Выгрузка");
СтрокаВыгрузки.Вставить("НомерПп", 2);
СтрокаВыгрузки.Вставить("ДатаИВремяПогрузкиВыгрузки", ДанныеЗаполнения.ДатаСеанса + 86400);
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиИндекс", "191025");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиКодРегиона", "78");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиГород", "Санкт-Петербург");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиУлица", "Невский пр-кт");
СтрокаВыгрузки.Вставить("АдресПунктаПогрузкиДом", "10");
СтрокаВыгрузки.Вставить("ПредставлениеАдресПунктаПогрузки", "191025, г Санкт-Петербург, Невский пр-кт, д 10");
ЗначенияАдресов.Добавить(СтрокаВыгрузки);
НомерСтрокиАдреса = 0;
Для Каждого ЗначенияСтрокиАдреса Из ЗначенияАдресов Цикл
НомерСтрокиАдреса = НомерСтрокиАдреса + 1;
ЗначенияСтрокиАдреса.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
Для Каждого ЗначениеКолонкиАдреса Из ЗначенияСтрокиАдреса Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект,
"ТитулГрузоотправителяАдресаПунктовПогрузкиИВыгрузки__" + НомерСтрокиАдреса + "__" + ЗначениеКолонкиАдреса.Ключ,
ЗначениеКолонкиАдреса.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
КонецЦикла;
// --- 5. стороны договора с перевозчиком (без них договор остаётся «Заполнить») ---
ЗначенияСторонДоговора = Новый Массив;
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН", ДанныеЗаполнения.ИННКлиента));
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН", ДанныеЗаполнения.ИННПеревозчика));
НомерСтороныДоговора = 0;
Для Каждого ЗначенияСтороныДоговора Из ЗначенияСторонДоговора Цикл
НомерСтороныДоговора = НомерСтороныДоговора + 1;
ЗначенияСтороныДоговора.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
Для Каждого ЗначениеКолонкиСтороны Из ЗначенияСтороныДоговора Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект,
"ТитулГрузоотправителяДоговорРеквизитыСторон__" + НомерСтороныДоговора + "__" + ЗначениеКолонкиСтороны.Ключ,
ЗначениеКолонкиСтороны.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
КонецЦикла;
// --- 6. фиксируем структуру на форме (один раз в конце) ---
ЭтотОбъект.СтруктураРеквизитов = ОбменСГИСЭПДКлиентСервер.СкопироватьВФиксированноеЗначенияРекурсивно(
КонтейнерВерсииТитула.СтруктураРеквизитовЗаполнение);
// --- 7. клиентские механизмы участников ---
// подтягивает реквизиты участника из справочника (наименование, ИНН, адрес, телефоны)
// и рисует красную подсказку «Не заполнен номер телефона контрагента» рядом с полем
ИменаЭлементовУчастников = "СсылкаТитулГрузоотправителяГрузоотправитель,СсылкаТитулГрузоотправителяСоставитель,СсылкаТитулГрузоотправителяПеревозчик";
Для Каждого ИмяЭлементаУчастника Из СтрРазделить(ИменаЭлементовУчастников, ",") Цикл
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлементаУчастника], ЭтотОбъект);
КонецЦикла;
// ----------------------- Параметры ТС ---------------------------------
ВходящийКонтекст = Новый Структура;
ВходящийКонтекст.Вставить("ЗапретитьИзменение", Ложь);
ВходящийКонтекст.Вставить("Форма", ЭтотОбъект);
ВходящийКонтекст.Вставить("ГруппаДанных", "ТитулГрузоотправителяПараметрыТранспортногоСредства");
ВходящийКонтекст.Вставить("КонтейнерОтображаемойВерсии", КонтейнерВерсииТитула);
ВходящийКонтекст.Вставить("Записывать", Истина);
ОбменСГИСЭПДКлиент.ОткрытиеФормыПоГиперссылке_Завершение(ДанныеЗаполнения.ПараметрыТранспортногоСредства, ВходящийКонтекст);
// ----------------------- Параметры ТС ---------------------------------
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры
Показать
19.
afanaseva_maria
11.08.26 09:03
Сейчас в теме
(18) В результате программно заполнила справочник ХранимыеДанныеЭПД (посмотрела редактором реквизитов, как заполняет).
Нужно пошукать по общим модулям, может есть где-нить встроенное заполнение.
Конечно подстава, что грузополучатель из ЭЗЗ в ЭТРН не заполняется, теперь еще с ЭТрН разбираться.
Нужно пошукать по общим модулям, может есть где-нить встроенное заполнение.
Конечно подстава, что грузополучатель из ЭЗЗ в ЭТРН не заполняется, теперь еще с ЭТрН разбираться.
Кстати ИИ пишет свою работу на видео и я подготовил ролик в разделе Видеозаписи. Представляю как модераторы чешут репу, выкладывать или нет его :-) Первую половину делал Опус 5, сейчас заканчивает Фейбл 5 и тоже пишет видео. Так же ИИ готовит статью по мотивам этой задачи. Ответ выложит скоро сам ИИ.
Коллеги, вам за свою работу не страшно?
Коллеги, вам за свою работу не страшно?
(14)(18)(19) Разобрался с обоими вопросами: и со ссылками на ХранимыеДанныеЭПД, и с «красными пунктами погрузки». В конце — процедура для ЭлектроннаяТранспортнаяНакладная, как просили.
1. «Встроенное заполнение» ХранимыеДанныеЭПД существует — искать больше не нужно
Мария, вы написали «нужно пошукать по общим модулям, может есть где-нить встроенное заполнение» — есть, и оно одно на все виды данных:
Именно её вызывает любая форма ввода («Сторона, подписавшая документ», «Параметры транспортного средства», «Транспортное средство», «Водитель»…) при нажатии «Сохранить» — см. ОбменСГИСЭПДКлиент.СохранитьПараметрыПодчиненнойФормы. Устройство элемента справочника простое: шапка (Тип, ГруппаДанных, ИмяОбъекта, Организация, Контрагент) плюс табличная часть Данные — пары «Имя реквизита формы ввода → Значение». Наименование руками собирать не нужно: в ПередЗаписью справочника оно строится само из значимых полей (ОбменСГИСЭПД.ПредставлениеХранимыхДанныхЭПД) — поэтому у стороны получается «ИНН: 7784897167 (Юр. лицо)», а у параметров ТС «86м3, 20т (Полуприцеп)».
Создание стороны договора (серверная часть, кладу в ту же ДанныеЗаполнения):
Три обязательных требования к ОписаниеДанных (иначе упадёт внутри):
- ИмяФормы — по нему функция берёт и имя объекта, и описание группы данных;
- ОписаниеРеквизитовФормы.Представления — структура с теми же ключами, что и в данных (читается по каждому ключу);
- ДанныеЗаполненияТаблицФормы — хотя бы пустая структура.
Параметры транспортного средства ЭЗЗ создаются той же функцией, меняются только группа, форма и набор полей:
2. Куда подставлять ссылку
Тут два разных случая, и оба проще, чем кажется.
Одиночная группа (параметры ТС, «Сведения о транспортном средстве» в ЭТрН). На основной форме это реквизит формы ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре дства. Заполняем его и зовём штатный обработчик — тот самый, который срабатывает, когда пользователь выбирает элемент в поле руками:
ХранимыеДанныеПриИзменении сам вычислит группу данных из имени элемента, развернёт содержимое элемента справочника в ключи структуры титула (ТитулГрузоотправителяПараметрыТранспортногоСредстваТип, ...Грузоподъемность, …), положит ссылку в ключ ХранимыеДанные<ГруппаДанных> и перерисует оформление. Ваш блок из сообщения 18 с ручным ВходящийКонтекст + ОткрытиеФормыПоГиперссылке_Завершение делает то же самое — можно оставить, но штатная обёртка короче и не требует знать состав контекста. Последний параметр Ложь — «не записывать структуру после каждого вызова», раз в конце процедуры всё равно есть общий СтруктураРеквизитов = СкопироватьВФиксированное....
Строки таблиц (стороны договора). Сторона в строке — это два ключа: значимые поля плюс ссылка в колонке ХранимыеДанныеСторонаПодписавшаяДокумент (колонка составного типа: ссылка на справочник или строка). В цикле из сообщения 13 достаточно добавить ссылку в структуру строки:
После этого форма договора показывает стороны представлениями элементов справочника — «как при ручном заполнении», что и требовалось в сообщении 18. Скриншот с демо-базы прилагаю.
Почему у вас «данные в структуре есть, а в форме не отражаются»: колонка таблицы в форме договора — это именно ХранимыеДанные..., а не ЮЛ_ИНН. Пока в строке лежит только ИНН, для XML и проверки заполненности всё в порядке (договор синеет и без ссылки), но видимая колонка пуста — ей нечего показать.
3. Мария, про «пункты погрузки и выгрузки горят красным» (14)
Смотрим макет соответствий (Документ.ЭлектронныйЗаказЗаявка.Макет.СоответствиеИменРеквизитов, он же — источник дерева обязательности):
То есть сам узел «Пункты погрузки-выгрузки» груза — необязательный, но у начатой строки обязательны все три поля. Отсюда и разница: при ручном заполнении вы просто не трогаете эту таблицу — узел пуст и не проверяется; при программном — как только в строке появился хотя бы один содержательный ключ, механизм требует заполнить ПунктПогрузки, ПунктВыгрузки и КоличествоГрузовыхМест целиком. Заполняйте все три (как в примере сообщения 13) — или не заполняйте таблицу вовсе, для заявки она не обязательна.
Чтобы не гадать, какой именно узел «начат и недозаполнен» — самодиагностика из сообщения 13 (ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД) называет узел схемы и текст прямо списком.
4. Поправка к сообщению 13
В блоке 7 у меня опечатка в имени модуля: ЗаполнитьРеквизитыПоСсылке живёт в ОбменСГИСЭПДКлиентСервер, а не в ОбменСГИСЭПДКлиент:
ЕСТЬNULL, в вашей врезке из сообщения 18 эта строка скопирована как была — поправьте и у себя.
5. ЭлектроннаяТранспортнаяНакладная: ITSP_ЭПД_ЗаполнитьВсё для титула грузоотправителя
Механика ровно та же (это одна подсистема), отличается состав обязательного минимума. Прежде чем показать код — три грабли, на которые я наступил при прогоне:
- Телефоны грузополучателя и перевозчика (СвГП/.../Тлф, СвПер/Контакт/Тлф) кладите после вызовов ЗаполнитьРеквизитыПоСсылке: та перечитывает контактные данные участника из справочника и перетирает ваши значения (у контрагента без телефона — пустотой). И раз общий контейнер к этому моменту уже устарел, вызов делается без него, но с шестым параметром Записать = Истина — иначе вставка не доедет до СтруктураРеквизитов формы.
- Каждая записанная дата автоматически взводит парный флаг <Имя>ИспользуетсяUTC = Истина (это делает сам УстановитьЗначениеРеквизитаВСтруктуреФормы). Флаги-«ИспользуетсяUTC» из обязательного минимума можно не заполнять вовсе — но если заполняете, кладите их после даты.
- Грузополучатель из заказа-заявки не переносится не из-за бага (19): в титуле ЭЗЗ грузополучателя нет вообще — ни одного поля с таким именем в макете соответствий. Переносить неоткуда, источник — только ваши данные (заказ клиента, договор и т.п.).
Сама процедура (врезка в модуль основной формы ЭТрН; ДанныеЗаполнения — ваша серверная структура: Организация, Грузополучатель, Перевозчик, СсылкаТС из раздела 1):
6. Результат прогона на демо-базе
ЭЗЗ: «1 груз», «2 адреса», «Договор перевозки груза 13/37 от 11.08.2026» — синие; поле «Параметры транспортного средства» = «86м3, 20т (Полуприцеп)»; в форме договора обе стороны видны представлениями («ИНН: 7784897167 (Юр. лицо)», «ИНН: 7731343528 (Юр. лицо)»).
ЭТрН: «Мёд липовый на 0 RUB», водители «Пётр Иванов», погрузка и указания «Сведения заполнены», «Сведения о транспортном средстве» = «А123ВС716 КАМАЗ 54901 86м3, 20т (Тягач седельный)».
ПроверитьЗаполнениеДокументаЭПД по обоим документам оставляет только служебные узлы файла обмена (ИдФайл, ВерсПрог, ВерсФорм, КНД, дата/время формирования) и подписанта — они заполняются при выгрузке и подписании, из формы их трогать не нужно.
1. «Встроенное заполнение» ХранимыеДанныеЭПД существует — искать больше не нужно
Мария, вы написали «нужно пошукать по общим модулям, может есть где-нить встроенное заполнение» — есть, и оно одно на все виды данных:
ОбменСГИСЭПДВызовСервера.ЗаписатьХранимыеДанныеЭПД(ГруппаДанных, Организация, Контрагент, ДополнительныйОтбор, ОписаниеДанных)Именно её вызывает любая форма ввода («Сторона, подписавшая документ», «Параметры транспортного средства», «Транспортное средство», «Водитель»…) при нажатии «Сохранить» — см. ОбменСГИСЭПДКлиент.СохранитьПараметрыПодчиненнойФормы. Устройство элемента справочника простое: шапка (Тип, ГруппаДанных, ИмяОбъекта, Организация, Контрагент) плюс табличная часть Данные — пары «Имя реквизита формы ввода → Значение». Наименование руками собирать не нужно: в ПередЗаписью справочника оно строится само из значимых полей (ОбменСГИСЭПД.ПредставлениеХранимыхДанныхЭПД) — поэтому у стороны получается «ИНН: 7784897167 (Юр. лицо)», а у параметров ТС «86м3, 20т (Полуприцеп)».
Создание стороны договора (серверная часть, кладу в ту же ДанныеЗаполнения):
&НаСервере
Функция ITSP_ЭПД_СторонаПоИНН(ИННСтороны, Организация, Контрагент)
// не плодим дубли: сначала ищем существующий элемент этого типа с тем же ИНН
ЗапросПоиска = Новый Запрос;
ЗапросПоиска.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 ХранимыеДанные.Ссылка КАК Ссылка
|ИЗ Справочник.ХранимыеДанныеЭПД КАК ХранимыеДанные
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ХранимыеДанныеЭПД.Данные КАК СтрокиДанных
| ПО СтрокиДанных.Ссылка = ХранимыеДанные.Ссылка
|ГДЕ ХранимыеДанные.Тип = ""СторонаПодписавшаяДокумент""
| И СтрокиДанных.Имя = ""ЮЛ_ИНН""
| И СтрокиДанных.Значение = &ЗначениеИНН";
ЗапросПоиска.УстановитьПараметр("ЗначениеИНН", ИННСтороны);
ВыборкаПоиска = ЗапросПоиска.Выполнить().Выбрать();
Если ВыборкаПоиска.Следующий() Тогда
Возврат ВыборкаПоиска.Ссылка;
КонецЕсли;
// данные — с именами реквизитов ФОРМЫ ВВОДА (как заполнила бы рука)
ЗначенияСтороны = Новый Структура;
ЗначенияСтороны.Вставить("ОбщееПолеВводаИНН", ИННСтороны);
ЗначенияСтороны.Вставить("ЮЛ_ИНН", ИННСтороны); // 12 цифр — в ФЛ_ИНН
ПредставленияСтороны = Новый Структура;
Для Каждого ОписаниеПоля Из ЗначенияСтороны Цикл
ПредставленияСтороны.Вставить(ОписаниеПоля.Ключ, Строка(ОписаниеПоля.Значение));
КонецЦикла;
ОписаниеДанных = Новый Структура;
ОписаниеДанных.Вставить("ИмяФормы", "Документ.ЭлектронныйЗаказЗаявка.Форма.СторонаПодписавшаяДокумент");
ОписаниеДанных.Вставить("ДанныеЗаполненияРеквизитовФормы", ЗначенияСтороны);
ОписаниеДанных.Вставить("ОписаниеРеквизитовФормы", Новый Структура("Представления", ПредставленияСтороны));
ОписаниеДанных.Вставить("ДанныеЗаполненияТаблицФормы", Новый Структура);
Возврат ОбменСГИСЭПД.ЗаписатьХранимыеДанныеЭПД(
"СторонаПодписавшаяДокумент", Организация, Контрагент, "", ОписаниеДанных);
КонецФункции ПоказатьТри обязательных требования к ОписаниеДанных (иначе упадёт внутри):
- ИмяФормы — по нему функция берёт и имя объекта, и описание группы данных;
- ОписаниеРеквизитовФормы.Представления — структура с теми же ключами, что и в данных (читается по каждому ключу);
- ДанныеЗаполненияТаблицФормы — хотя бы пустая структура.
Параметры транспортного средства ЭЗЗ создаются той же функцией, меняются только группа, форма и набор полей:
ЗначенияПараметров = Новый Структура;
ЗначенияПараметров.Вставить("Тип", "Полуприцеп");
ЗначенияПараметров.Вставить("Грузоподъемность", 20);
ЗначенияПараметров.Вставить("Вместимость", 86);
ЗначенияПараметров.Вставить("ТипКузова", "Тентованный");
ЗначенияПараметров.Вставить("ТипПогрузки", "Задняя");
ЗначенияПараметров.Вставить("ИныеПараметры", "Гидроборт");
// ... Представления и ОписаниеДанных так же, ИмяФормы =
// "Документ.ЭлектронныйЗаказЗаявка.Форма.ПараметрыТранспортногоСредства"
СсылкаПараметров = ОбменСГИСЭПД.ЗаписатьХранимыеДанныеЭПД(
"ТитулГрузоотправителяПараметрыТранспортногоСредства", Организация, Контрагент, "", ОписаниеДанных); Показать2. Куда подставлять ссылку
Тут два разных случая, и оба проще, чем кажется.
Одиночная группа (параметры ТС, «Сведения о транспортном средстве» в ЭТрН). На основной форме это реквизит формы ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре
ЭтотОбъект.ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСредства = ДанныеЗаполнения.ПараметрыТС;
ОбменСГИСЭПДКлиент.ХранимыеДанныеПриИзменении(ЭтотОбъект, ДанныеЗаполнения.ПараметрыТС,
Элементы.ХранимыеДанныеТитулГрузоотправителяПараметрыТранспортногоСре дства,
, КонтейнерВерсииТитула, Ложь);ХранимыеДанныеПриИзменении сам вычислит группу данных из имени элемента, развернёт содержимое элемента справочника в ключи структуры титула (ТитулГрузоотправителяПараметрыТранспортногоСредстваТип, ...Грузоподъемность, …), положит ссылку в ключ ХранимыеДанные<ГруппаДанных> и перерисует оформление. Ваш блок из сообщения 18 с ручным ВходящийКонтекст + ОткрытиеФормыПоГиперссылке_Завершение делает то же самое — можно оставить, но штатная обёртка короче и не требует знать состав контекста. Последний параметр Ложь — «не записывать структуру после каждого вызова», раз в конце процедуры всё равно есть общий СтруктураРеквизитов = СкопироватьВФиксированное....
Строки таблиц (стороны договора). Сторона в строке — это два ключа: значимые поля плюс ссылка в колонке ХранимыеДанныеСторонаПодписавшаяДокумент (колонка составного типа: ссылка на справочник или строка). В цикле из сообщения 13 достаточно добавить ссылку в структуру строки:
ЗначенияСторонДоговора = Новый Массив;
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН, ХранимыеДанныеСторонаПодписавшаяДокумент",
ДанныеЗаполнения.ИННКлиента, ДанныеЗаполнения.СторонаКлиента));
ЗначенияСторонДоговора.Добавить(Новый Структура("ЮЛ_ИНН, ХранимыеДанныеСторонаПодписавшаяДокумент",
ДанныеЗаполнения.ИННПеревозчика, ДанныеЗаполнения.СторонаПеревозчика));
// дальше цикл с "ТитулГрузоотправителяДоговорРеквизитыСторон__N__..." без измененийПосле этого форма договора показывает стороны представлениями элементов справочника — «как при ручном заполнении», что и требовалось в сообщении 18. Скриншот с демо-базы прилагаю.
Почему у вас «данные в структуре есть, а в форме не отражаются»: колонка таблицы в форме договора — это именно ХранимыеДанные..., а не ЮЛ_ИНН. Пока в строке лежит только ИНН, для XML и проверки заполненности всё в порядке (договор синеет и без ссылки), но видимая колонка пуста — ей нечего показать.
3. Мария, про «пункты погрузки и выгрузки горят красным» (14)
Смотрим макет соответствий (Документ.ЭлектронныйЗаказЗаявка.Макет.СоответствиеИменРеквизитов, он же — источник дерева обязательности):
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки //...ОпГруз/Пункт обязательный: НЕТ
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.ПунктПогрузки /Пункт/Погр обязательный: ДА
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.ПунктВыгрузки /Пункт/Выгр обязательный: ДА
ТитулГрузоотправителяГрузыПунктыПогрузкиВыгрузки.КоличествоГрузовыхМест /Пункт/КолГрМест обязательный: ДАТо есть сам узел «Пункты погрузки-выгрузки» груза — необязательный, но у начатой строки обязательны все три поля. Отсюда и разница: при ручном заполнении вы просто не трогаете эту таблицу — узел пуст и не проверяется; при программном — как только в строке появился хотя бы один содержательный ключ, механизм требует заполнить ПунктПогрузки, ПунктВыгрузки и КоличествоГрузовыхМест целиком. Заполняйте все три (как в примере сообщения 13) — или не заполняйте таблицу вовсе, для заявки она не обязательна.
Чтобы не гадать, какой именно узел «начат и недозаполнен» — самодиагностика из сообщения 13 (ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД) называет узел схемы и текст прямо списком.
4. Поправка к сообщению 13
В блоке 7 у меня опечатка в имени модуля: ЗаполнитьРеквизитыПоСсылке живёт в ОбменСГИСЭПДКлиентСервер, а не в ОбменСГИСЭПДКлиент:
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлементаУчастника], ЭтотОбъект);ЕСТЬNULL, в вашей врезке из сообщения 18 эта строка скопирована как была — поправьте и у себя.
5. ЭлектроннаяТранспортнаяНакладная: ITSP_ЭПД_ЗаполнитьВсё для титула грузоотправителя
Механика ровно та же (это одна подсистема), отличается состав обязательного минимума. Прежде чем показать код — три грабли, на которые я наступил при прогоне:
- Телефоны грузополучателя и перевозчика (СвГП/.../Тлф, СвПер/Контакт/Тлф) кладите после вызовов ЗаполнитьРеквизитыПоСсылке: та перечитывает контактные данные участника из справочника и перетирает ваши значения (у контрагента без телефона — пустотой). И раз общий контейнер к этому моменту уже устарел, вызов делается без него, но с шестым параметром Записать = Истина — иначе вставка не доедет до СтруктураРеквизитов формы.
- Каждая записанная дата автоматически взводит парный флаг <Имя>ИспользуетсяUTC = Истина (это делает сам УстановитьЗначениеРеквизитаВСтруктуреФормы). Флаги-«ИспользуетсяUTC» из обязательного минимума можно не заполнять вовсе — но если заполняете, кладите их после даты.
- Грузополучатель из заказа-заявки не переносится не из-за бага (19): в титуле ЭЗЗ грузополучателя нет вообще — ни одного поля с таким именем в макете соответствий. Переносить неоткуда, источник — только ваши данные (заказ клиента, договор и т.п.).
Сама процедура (врезка в модуль основной формы ЭТрН; ДанныеЗаполнения — ваша серверная структура: Организация, Грузополучатель, Перевозчик, СсылкаТС из раздела 1):
&НаКлиенте
Процедура ITSP_ЭПД_ЗаполнитьВсё(Команда)
КонтейнерВерсииТитула = ОбменСГИСЭПДКлиентСервер.КонтейнерОтображаемойВерсииРеквизита(
ЭтотОбъект, "ТитулГрузоотправителяГрузы");
// --- 1. однократные реквизиты титула ---
ЗначенияПростыхРеквизитов = Новый Структура;
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузоотправитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяСоставитель", ДанныеЗаполнения.Организация);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяГрузополучатель", ДанныеЗаполнения.Грузополучатель);
ЗначенияПростыхРеквизитов.Вставить("СсылкаТитулГрузоотправителяПеревозчик", ДанныеЗаполнения.Перевозчик);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяСодержаниеОперации", "Перевозка груза");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяТранспортнаяНакладнаяНомер", "42/2026");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяТранспортнаяНакладнаяДата", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаказДата", ДанныеЗаполнения.ДатаСеанса);
// сведения о погрузке: заявленные и фактические даты; булевы — ЯВНО, даже Ложь
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЗаявленныеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФактическиеДатаВремяПодачи", ДанныеЗаполнения.ДатаСеанса + 3600);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяФактическиеДатаВремяУбытия", ДанныеЗаполнения.ДатаСеанса + 7200);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяМассаБруттоГруза", 25000);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяКоличествоГрузовыхМест", 100);
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЛицоОсуществляющееПогрузкуЯвляетсяГруз оотправителем", Истина);
// фактический адрес погрузки
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиИндекс", "125009");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиКодРегиона", "77");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиГород", "Москва");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиУлица", "Тверская");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяАдресПогрузкиДом", "1");
ЗначенияПростыхРеквизитов.Вставить("ПредставлениеТитулГрузоотправителяАдресПогрузки", "125009, г Москва, ул Тверская, д 1");
// адрес доставки грузополучателя
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиИндекс", "191025");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиКодРегиона ", "78");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиГород", "Санкт-Петербург");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиУлица", "Невский пр-кт");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяГрузополучательАдресДоставкиДом", "10");
ЗначенияПростыхРеквизитов.Вставить("ПредставлениеТитулГрузоотправителяГрузополучательАдресДоста вки", "191025, г Санкт-Петербург, Невский пр-кт, д 10");
// указания грузоотправителя: сведения о переадресовке
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяЛицоИмеющееПолномочияПереадресовки", "Грузоотправитель");
ЗначенияПростыхРеквизитов.Вставить("ТитулГрузоотправителяСпособПередачиУказанияНаПереадресовку" , "Телефонограмма");
Для Каждого ОписаниеРеквизита Из ЗначенияПростыхРеквизитов Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ОписаниеРеквизита.Ключ, ОписаниеРеквизита.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 2. телефон ответственного за переадресовку (таблица, строка 1) ---
ЗначенияТелефона = Новый Структура;
ЗначенияТелефона.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияТелефона.Вставить("Телефон", "+7 495 123-45-67");
Для Каждого ЗначениеКолонки Из ЗначенияТелефона Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяОтветственныйЗаПереадресовкуНомераТеле фонов__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 3. груз (в ЭТрН к минимуму ЭЗЗ добавляется СпособУпаковки) ---
ИдентификаторСтрокиГруза = Строка(Новый УникальныйИдентификатор);
ЗначенияГруза = Новый Структура;
ЗначенияГруза.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиГруза);
ЗначенияГруза.Вставить("ОтгрузочноеНаименованиеГруза", "Мёд липовый");
ЗначенияГруза.Вставить("СостояниеГруза", "Исправное");
ЗначенияГруза.Вставить("СпособУпаковки", "Бочки");
ЗначенияГруза.Вставить("ВидТары", "BA");
ЗначенияГруза.Вставить("КоличествоГрузовыхМест", 100);
ЗначенияГруза.Вставить("МассаБрутто", 25000);
ЗначенияГруза.Вставить("МассаНетто", 24000);
Для Каждого ЗначениеКолонки Из ЗначенияГруза Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяГрузы__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
// --- 4. водитель + телефон (телефоны — подчинённая таблица по идентификатору родителя) ---
ИдентификаторСтрокиВодителя = Строка(Новый УникальныйИдентификатор);
ЗначенияВодителя = Новый Структура;
ЗначенияВодителя.Вставить("ИдентификаторСтроки", ИдентификаторСтрокиВодителя);
ЗначенияВодителя.Вставить("Фамилия", "Иванов");
ЗначенияВодителя.Вставить("Имя", "Пётр");
ЗначенияВодителя.Вставить("Отчество", "Сергеевич");
ЗначенияВодителя.Вставить("СерияВУ", "9911");
ЗначенияВодителя.Вставить("НомерВУ", "123456");
ЗначенияВодителя.Вставить("ДатаВыдачиВУ", ДанныеЗаполнения.ДатаСеанса - 86400 * 365);
Для Каждого ЗначениеКолонки Из ЗначенияВодителя Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяВодители__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, КонтейнерВерсииТитула);
КонецЦикла;
ЗначенияТелефонаВодителя = Новый Структура;
ЗначенияТелефонаВодителя.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
ЗначенияТелефонаВодителя.Вставить("Телефон", "+7 917 000-11-22");
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеПодчиненнойСтрокиВСтруктуреФормы(
ЭтотОбъект, "ТитулГрузоотправителяВодительНомераТелефонов",
ИдентификаторСтрокиВодителя, ЗначенияТелефонаВодителя, Истина, КонтейнерВерсииТитула);
// --- 5. транспортное средство: ссылка на ХранимыеДанныеЭПД + штатный обработчик ---
ЭтотОбъект.ХранимыеДанныеТитулГрузоотправителяТранспортноеСредство = ДанныеЗаполнения.СсылкаТС;
ОбменСГИСЭПДКлиент.ХранимыеДанныеПриИзменении(ЭтотОбъект, ДанныеЗаполнения.СсылкаТС,
Элементы.ХранимыеДанныеТитулГрузоотправителяТранспортноеСредство,
, КонтейнерВерсииТитула, Ложь);
// --- 6. фиксация структуры, участники ---
ЭтотОбъект.СтруктураРеквизитов = ОбменСГИСЭПДКлиентСервер.СкопироватьВФиксированноеЗначенияРекурсивно(
КонтейнерВерсииТитула.СтруктураРеквизитовЗаполнение);
ИменаЭлементовУчастников = "СсылкаТитулГрузоотправителяГрузоотправитель,СсылкаТитулГрузоотправителяСоставитель,СсылкаТитулГрузоотправителяГрузополучатель,СсылкаТитулГрузоотправителяПеревозчик";
Для Каждого ИмяЭлемента Из СтрРазделить(ИменаЭлементовУчастников, ",") Цикл
ОбменСГИСЭПДКлиентСервер.ЗаполнитьРеквизитыПоСсылке(Элементы[ИмяЭлемента], ЭтотОбъект);
КонецЦикла;
// --- 7. телефоны участников — строго ПОСЛЕ ЗаполнитьРеквизитыПоСсылке (см. грабли выше) ---
ИменаТаблицТелефонов = "ТитулГрузоотправителяГрузополучательНомераТелефонов,ТитулГрузоотправителяПеревозчикНомераТелефонов";
Для Каждого ИмяТаблицы Из СтрРазделить(ИменаТаблицТелефонов, ",") Цикл
СтрокаТелефона = Новый Структура;
СтрокаТелефона.Вставить("ИдентификаторСтроки", Строка(Новый УникальныйИдентификатор));
СтрокаТелефона.Вставить("Телефон", "+7 495 765-43-21");
Для Каждого ЗначениеКолонки Из СтрокаТелефона Цикл
ОбменСГИСЭПДКлиентСервер.УстановитьЗначениеРеквизитаВСтруктуреФормы(
ЭтотОбъект, ИмяТаблицы + "__1__" + ЗначениеКолонки.Ключ,
ЗначениеКолонки.Значение, Истина, , Истина);
КонецЦикла;
КонецЦикла;
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры Показать6. Результат прогона на демо-базе
ЭЗЗ: «1 груз», «2 адреса», «Договор перевозки груза 13/37 от 11.08.2026» — синие; поле «Параметры транспортного средства» = «86м3, 20т (Полуприцеп)»; в форме договора обе стороны видны представлениями («ИНН: 7784897167 (Юр. лицо)», «ИНН: 7731343528 (Юр. лицо)»).
ЭТрН: «Мёд липовый на 0 RUB», водители «Пётр Иванов», погрузка и указания «Сведения заполнены», «Сведения о транспортном средстве» = «А123ВС716 КАМАЗ 54901 86м3, 20т (Тягач седельный)».
ПроверитьЗаполнениеДокументаЭПД по обоим документам оставляет только служебные узлы файла обмена (ИдФайл, ВерсПрог, ВерсФорм, КНД, дата/время формирования) и подписанта — они заполняются при выгрузке и подписании, из формы их трогать не нужно.
Прикрепленные файлы:
Уважаемы коллеги, огромная благодарность за ваш труд.
Подскажите, пожалуйста - Документ ЭТрН
Заполнение произвожу при вводе на основании Расходной накладной
Форма Основная в серверной процедуре ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Заполняю Сведения о грузе, Водители, Сведения о приеме груза перевозчиком
Сведения о транспортном средстве, основываясь на ваших примерах
В мое случае есть еще реквизиты ХранимыеДанныеВодитель, ХранимыеДанныеГруз
добавляю
ЗначенияВодитель.Вставить("ХранимыеДанныеВодитель", СсылкаВодитель);
ЗначенияГруза.Вставить("ХранимыеДанныеГруз", СсылкаНаГруз);
При открытии формы вижу только Сведения о транспортном средстве
Гиперссылки Сведения о грузе, Водители, Сведения о приеме груза перевозчиком в состоянии Заполнить.
Нажимаю Заполнить - и в открывшейся форме вижу свои данные, ОК - гиперссылка перерисовалась в Сведения заполнены.
Исключение только сведения о грузе - в той форме нужно перевыбрать ХранимыеДанныеГруз, ОК и только тогда на Основной форме красивая гиперссылка.
Добавил
&НаКлиенте
Процедура Этн1_ПриОткрытииПосле(Отказ)
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры
Водитель становится заполненным, остальное все равно нужно перещелкивать, как выше описал.
Что я не учел?
Подскажите, пожалуйста - Документ ЭТрН
Заполнение произвожу при вводе на основании Расходной накладной
Форма Основная в серверной процедуре ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Заполняю Сведения о грузе, Водители, Сведения о приеме груза перевозчиком
Сведения о транспортном средстве, основываясь на ваших примерах
В мое случае есть еще реквизиты ХранимыеДанныеВодитель, ХранимыеДанныеГруз
добавляю
ЗначенияВодитель.Вставить("ХранимыеДанныеВодитель", СсылкаВодитель);
ЗначенияГруза.Вставить("ХранимыеДанныеГруз", СсылкаНаГруз);
При открытии формы вижу только Сведения о транспортном средстве
Гиперссылки Сведения о грузе, Водители, Сведения о приеме груза перевозчиком в состоянии Заполнить.
Нажимаю Заполнить - и в открывшейся форме вижу свои данные, ОК - гиперссылка перерисовалась в Сведения заполнены.
Исключение только сведения о грузе - в той форме нужно перевыбрать ХранимыеДанныеГруз, ОК и только тогда на Основной форме красивая гиперссылка.
Добавил
&НаКлиенте
Процедура Этн1_ПриОткрытииПосле(Отказ)
// --- 8. перерисовка гиперссылок ---
ИзменитьОформлениеКнопок(Новый ФиксированнаяСтруктура("ИмяКнопки, ИдентификаторСтроки"));
КонецПроцедуры
Водитель становится заполненным, остальное все равно нужно перещелкивать, как выше описал.
Что я не учел?
(23) ПС
в Сведения о грузе добавил ЗначенияГруза.Вставить("СпособУпаковки", "Коробки");
и эта гиперссылка стала "красивая", до этого было так -> ЗначенияГруза.Вставить("СпособУпаковки", "");
Осталось выяснить чего не хватает в Сведениях о приеме груза перевозчиком
в Сведения о грузе добавил ЗначенияГруза.Вставить("СпособУпаковки", "Коробки");
и эта гиперссылка стала "красивая", до этого было так -> ЗначенияГруза.Вставить("СпособУпаковки", "");
Осталось выяснить чего не хватает в Сведениях о приеме груза перевозчиком
25.
nedomolkov.ivan
104
13.08.26 15:48
Сейчас в теме
(23)
(23) Симптом "нажал Заполнить, ничего не менял, нажал ОК - и стало синим" читается однозначно:
данные в структуре титула так и не появились, их туда кладёт штатный обработчик в момент ОК.
ХранимыеДанные<Группа> это не обычный ключ строки. Когда вы пишете его через
УстановитьЗначениеРеквизитаВСтруктуреФормы, в структуру ложится только ссылка на элемент
справочника. Содержимое элемента (Фамилия, СерияВУ, ОтгрузочноеНаименованиеГруза и прочее)
в структуру не разворачивается, а дерево обязательности проверяет именно его - ссылку оно
не смотрит. Разворачивает ОбменСГИСЭПДКлиент.ХранимыеДанныеПриИзменении, и она же кладёт
ссылку в нужный ключ. Ровно её и дёргает форма ввода по кнопке ОК.
Отсюда и второе: заполняете вы из ПриСозданииНаСервереПосле, а ХранимыеДанныеПриИзменении
клиентская. С сервера её не вызвать, поэтому шаг разворачивания у вас просто не выполняется.
Перенесите заполнение в клиентскую процедуру (ПриОткрытииПосле подходит), с сервера берите
только данные - ссылки, даты сеанса, реквизиты основания.
Почему ТС заработало, а водитель и груз нет: ТС это одиночная группа, у неё есть реквизит
формы ХранимыеДанныеТитулГрузоотправителяТранспортноеСредство, и присваивание в него
плюс обработчик отрабатывают целиком. Водители и грузы это строки таблиц, там ссылка живёт
колонкой, и одной ссылки для проверки заполненности мало.
ИзменитьОформлениеКнопок вам помог только с водителем не случайно: это перерисовка, она
показывает то, что уже лежит в структуре. Где данных нет, перерисовывать нечего.
(24) Ваша находка про пустой СпособУпаковки из той же серии. Пустая строка и отсутствие ключа
для проверки одно и то же, а строка считается начатой, как только в ней заполнено хоть одно
поле кроме идентификаторов. Начатая и недозаполненная строка держит весь узел красным.
С булевыми та же ловушка: Ложь надо класть явно, иначе читается Неопределено.
Чтобы не гадать, какой узел недозаполнен, спросите подсистему:
СтруктураПоТитулу = ОбменСГИСЭПДКлиентСервер.ПолучитьСтруктуруПоТитулуИВерсии(ЭтотОбъект);
ОписанияОшибок = ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД(
СтруктураПоТитулу, Объект.ТекущийТитул, Объект.ВидДокумента);
Для Каждого ОписаниеОшибки Из ОписанияОшибок Цикл
Сообщить(Строка(ОписаниеОшибки.Узел) + ": " + СтрСоединить(ОписаниеОшибки.Текст, " "));
КонецЦикла;
Она назовёт узел схемы и поле, а не заставит перещёлкивать формы руками.
Форма Основная в серверной процедуре ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
(23) Симптом "нажал Заполнить, ничего не менял, нажал ОК - и стало синим" читается однозначно:
данные в структуре титула так и не появились, их туда кладёт штатный обработчик в момент ОК.
ХранимыеДанные<Группа> это не обычный ключ строки. Когда вы пишете его через
УстановитьЗначениеРеквизитаВСтруктуреФормы, в структуру ложится только ссылка на элемент
справочника. Содержимое элемента (Фамилия, СерияВУ, ОтгрузочноеНаименованиеГруза и прочее)
в структуру не разворачивается, а дерево обязательности проверяет именно его - ссылку оно
не смотрит. Разворачивает ОбменСГИСЭПДКлиент.ХранимыеДанныеПриИзменении, и она же кладёт
ссылку в нужный ключ. Ровно её и дёргает форма ввода по кнопке ОК.
Отсюда и второе: заполняете вы из ПриСозданииНаСервереПосле, а ХранимыеДанныеПриИзменении
клиентская. С сервера её не вызвать, поэтому шаг разворачивания у вас просто не выполняется.
Перенесите заполнение в клиентскую процедуру (ПриОткрытииПосле подходит), с сервера берите
только данные - ссылки, даты сеанса, реквизиты основания.
Почему ТС заработало, а водитель и груз нет: ТС это одиночная группа, у неё есть реквизит
формы ХранимыеДанныеТитулГрузоотправителяТранспортноеСредство, и присваивание в него
плюс обработчик отрабатывают целиком. Водители и грузы это строки таблиц, там ссылка живёт
колонкой, и одной ссылки для проверки заполненности мало.
ИзменитьОформлениеКнопок вам помог только с водителем не случайно: это перерисовка, она
показывает то, что уже лежит в структуре. Где данных нет, перерисовывать нечего.
(24) Ваша находка про пустой СпособУпаковки из той же серии. Пустая строка и отсутствие ключа
для проверки одно и то же, а строка считается начатой, как только в ней заполнено хоть одно
поле кроме идентификаторов. Начатая и недозаполненная строка держит весь узел красным.
С булевыми та же ловушка: Ложь надо класть явно, иначе читается Неопределено.
Чтобы не гадать, какой узел недозаполнен, спросите подсистему:
СтруктураПоТитулу = ОбменСГИСЭПДКлиентСервер.ПолучитьСтруктуруПоТитулуИВерсии(ЭтотОбъект);
ОписанияОшибок = ОбменСГИСЭПДВызовСервера.ПроверитьЗаполнениеДокументаЭПД(
СтруктураПоТитулу, Объект.ТекущийТитул, Объект.ВидДокумента);
Для Каждого ОписаниеОшибки Из ОписанияОшибок Цикл
Сообщить(Строка(ОписаниеОшибки.Узел) + ": " + СтрСоединить(ОписаниеОшибки.Текст, " "));
КонецЦикла;
Она назовёт узел схемы и поле, а не заставит перещёлкивать формы руками.
(25) Благодарю!
Касательно Сведения о приеме груза перевозчиком Показало ошибку
//Файл/Документ/СодИнфГО/СвПогруз/ФАдресПогр: Не заполнено поле "Адрес места погрузки"
При открытии формы ТитулГрузоотправителяПогрузка, если не ошибаюсь, это заполняется автоматом вот таким образом (Грузоотправитель уже заполнен в Основоной форме):
ОбменСГИСЭПДКлиентСервер.ЗаполнениеСпискаСохраненныхАдресов(ЭтотОбъект,
СсылкаТитулГрузоотправителяГрузоотправитель,
Элементы.ПредставлениеТитулГрузоотправителяАдресПогрузки,
Элементы.ПредставлениеТитулГрузоотправителяАдресПогрузки.СписокВыбора,
Не ЗначениеЗаполнено(ЭтотОбъект.ПредставлениеТитулГрузоотправителяАдресПогрузки));
Как сделать из Основной формы пока не сообразил, а вручную на первый взгляд там прилично реквизитов
ТитулГрузоотправителяАдресПогрузки***
Касательно Сведения о приеме груза перевозчиком Показало ошибку
//Файл/Документ/СодИнфГО/СвПогруз/ФАдресПогр: Не заполнено поле "Адрес места погрузки"
При открытии формы ТитулГрузоотправителяПогрузка, если не ошибаюсь, это заполняется автоматом вот таким образом (Грузоотправитель уже заполнен в Основоной форме):
ОбменСГИСЭПДКлиентСервер.ЗаполнениеСпискаСохраненныхАдресов(ЭтотОбъект,
СсылкаТитулГрузоотправителяГрузоотправитель,
Элементы.ПредставлениеТитулГрузоотправителяАдресПогрузки,
Элементы.ПредставлениеТитулГрузоотправителяАдресПогрузки.СписокВыбора,
Не ЗначениеЗаполнено(ЭтотОбъект.ПредставлениеТитулГрузоотправителяАдресПогрузки));
Как сделать из Основной формы пока не сообразил, а вручную на первый взгляд там прилично реквизитов
ТитулГрузоотправителяАдресПогрузки***
27.
nedomolkov.ivan
104
15.08.26 13:26
Сейчас в теме
(26) Из основной формы эту процедуру не дёрнуть, и дело не в доступности модуля. Ей на вход идут Элементы.ПредставлениеТитулГрузоотправителяАдресПогрузки и его СписокВыбора, то есть элементы ТОЙ формы. В основной их нет, подсунуть нечего.
Второе, что мешает: представление это витрина. В XML уезжает структурированный адрес внутри титула, строка представления туда не попадает вообще. Поэтому даже если вы её аккуратно проставите, ФАдресПогр останется пустым и проверка скажет ровно то же самое.
Как я бы это разматывал, без угадывания реквизитов. Путь из ошибки //Файл/Документ/СодИнфГО/СвПогруз/ФАдресПогр один в один ложится на узлы структуры, которую отдаёт ПолучитьСтруктуруПоТитулуИВерсии. Снимите её дважды: на своём документе как есть и на нём же после того, как руками открыли форму погрузки и нажали ОК. Разница по ветке СвПогруз и будет полным списком того, что надо заполнить программно, включая поля, про которые вы сейчас не знаете.
И проверьте источник, прежде чем лезть в код. Процедура называется ЗаполнениеСпискаСохраненныхАдресов и берёт адрес из сохранённых адресов грузоотправителя. Если у контрагента там пусто, она и в своей форме ничего не подставит, а вы будете искать ошибку у себя.
Второе, что мешает: представление это витрина. В XML уезжает структурированный адрес внутри титула, строка представления туда не попадает вообще. Поэтому даже если вы её аккуратно проставите, ФАдресПогр останется пустым и проверка скажет ровно то же самое.
Как я бы это разматывал, без угадывания реквизитов. Путь из ошибки //Файл/Документ/СодИнфГО/СвПогруз/ФАдресПогр один в один ложится на узлы структуры, которую отдаёт ПолучитьСтруктуруПоТитулуИВерсии. Снимите её дважды: на своём документе как есть и на нём же после того, как руками открыли форму погрузки и нажали ОК. Разница по ветке СвПогруз и будет полным списком того, что надо заполнить программно, включая поля, про которые вы сейчас не знаете.
И проверьте источник, прежде чем лезть в код. Процедура называется ЗаполнениеСпискаСохраненныхАдресов и берёт адрес из сохранённых адресов грузоотправителя. Если у контрагента там пусто, она и в своей форме ничего не подставит, а вы будете искать ошибку у себя.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот