Открытие формы еще незаписанного документа 1С 8.2 Управляемое приложение

Недавно столкнулся с проблемой открытия формы еще не записанного в БД документа, много возился с этим. Решил обобщить все найденное, может кому-то сэкономит время.

Итак вопрос №1: Как открыть форму еще не записанного документа (не заполнить на основании) ?

Ответ: Чтобы открыть форму нам нужно связать ее с ссылкой объекта, но объект еще не записан. Многие пытаются использовать метод УстановитьСсылкуНового() но это не прокатывает. После долгих чтений я сделал вот так:

&НаКлиенте
Процедура Команда(Команда)

Форма = ПолучитьФорму(«Документ.НашДокумент.ФормаОбъекта»);
ДанныеФормы = Форма.Объект; // Получаем объект формы в переменную
ЗаполнитьДокументНаСервере(ДанныеФормы); // Заполняем документ на сервере
КопироватьДанныеФормы(ДанныеФормы, Форма.Объект); // копируем наш объект в объект формы и далее открываем ее
Форма.Открыть();

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

// Можно использовать безконтекстный вызов, оптимизируем передачу данных

&НаСервереБезКонтекста

Функция ЗаполнитьДокументНаСервере(ДанныеФормы);

Док = ДанныеФормыВЗначение(ДанныеФормы, Тип(«ДокументОбъект.НашДокумент»)); // Получаем объект из данных формы ИЛИ

Док = Документы.НашДокумент.СоздатьДокумент();

// Заполняем реквизиты объекта или другие действия ********

ЗначениеВДанныеФормы(Док,ДанныеФормы); // Кладем обратно в объект формы уже созданный документ

КонецФункции

2. Как открыть форму уже записанного документа?

Здесь есть два метода ОткрытьФорму() или ОткрытьЗначение(). В обоих случаях нужно передавать ссылку на записанный документ.

 

&НаКлиенте
Процедура Команда(Команда)

СсылкаОбъекта = СоздатьНаСервере();
//1.
ОткрытьФорму(«Документ.НашДокумент.Егоформа», Новый Стурктура(«Ключ», СсылкаОбъекта)); // Через параметры мы передаем ссылку документа

//2.

ОткрытьЗначение(СсылкаОбъекта);

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

&НаСервере
Функция ЗаполнитьДокументНаСервере()

// Используем метод создать

НовыйОбъект = Документы.НашДокумент.СоздатьДокумент();

 // Заполняем его 

НовыйОбъект.Записать(); // Обязательно записываем

Возврат НовыйОбъект.Ссылка; //Возвращаем ссылку

КонецФункции

На уникальность материла не претендую, сам только «начинающий» так что если что не так  — критикуйте!


50 Comments

  1. bulpi

    Для того, чтобы открыть форму нового документа, достаточно использовать метод ОткрытьФорму. Все , что Вы написали, не нужно. Другое дело, если нужно ЗАПОЛНИТЬ эту форму. Так заголовок публикации тогда нужно поменять.

    Reply
  2. M-Mark-76

    Спасибо, вся описаная методика работает

    Reply
  3. serg_gres

    А я сделал через временное хранилище.

    Reply
  4. bulas

    Заполняем документ программно, а затем:

    ФормаДокумента = ДокументОбъект.ПолучитьФорму();

    ФормаДокумента.ОткрытьМодально();

    Оставили в открытом документе еще «следы» и записываем(проводим).

    Reply
  5. Igoryany4

    При выполнении строки:

    Форма = ПолучитьФорму(«Документы.НашДокумент.ФормаОбъекта»);

    возникает ошибка, исправленный вариант:

    Форма = ПолучитьФорму(«Документ.НашДокумент.ФормаОбъекта»);
    Reply
  6. via64

    (5) bulas,

    Это работает только в толстом клиенте.

    Reply
  7. nick_krsk

    Статья помогла решить задачу, спасибо!

    Reply
  8. M.Shalimov
    Функция ЗаполнитьДокументНаСервере(ДанныеФормы);
    

    В Вашем примере функция ничего не возвращает и «;» при определении излишни.

    Reply
  9. leemuar

    (9) nixel, на какой из 500 страниц?

    Reply
  10. nixel

    (11) leemuar, из 600 🙂

    Извиняюсь, сейчас проглядел книгу, действительно там этого нет. Видимо идею брал из какого-то другого печатного источника.

    В работе дабы не гонять большие массивы данных между клиентом и сервером использую такой подход:

    Форма, с которой мы открываем незаписанную форму.

    &НаКлиенте
    Процедура ОткрытьЗаполненныйДокумент(Команда)
    Адрес = ПолучитьАдресНовогоДокумента(ЭтаФорма.УникальныйИдентификатор);
    Параметры = Новый Структура(“АдресХранилища”, Адрес);
    ОткрытьФорму(”Документ.Приказ.ФормаОбъекта”, Параметры, ЭтаФорма);
    КонецПроцедуры
    
    &НаСервереБезКонтекста
    Функция ПолучитьАдресНовогоДокумента(УИД)
    ДокументОбъект = Документы.НашДокумент.СоздатьДокумент();
    …
    code code code
    …
    АдресХранилища  = ПоместитьВоВременноеХранилище(ДокументОбъект, УИД);
    
    Возврат АдресХранилища;
    КонецФункции
    

    Показать

    Форма открываемого объекта

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

    Да, приходится незначительно залезать в форму объекта, но получается большой выигрыш по производительности и клиент-серверному взаимодействию.

    Reply
  11. dachnik

    Спасибо, хоть ваш пример у меня и не сработал, но навел на правильную мысль.

    Reply
  12. Elvisnya

    (12) nixel, спасибо за совет. В 8.3 скорее всего не будет работать, т.к. в 8.3 при помещении несериализуемого значения во временное хранилище возникает модульная ошибка, а ДокументОбъект как раз несереализуемый. Как вариант можно использовать структуру, взамен ДокументОбъект.

    Reply
  13. Kuklachel

    Спасибо lobster, очень помогли разобраться!

    Reply
  14. t278

    в моём случае, нужно было открывать

    мФорма= ПолучитьФорму(«Документ.ПоступлениеТоваровУслуг.Форма.ФормаДокументаТовары«);

    Reply
  15. kraynev-navi

    Подозреваю, что у последней функции в статье название должно быть все-таки СоздатьНаСервере()

    Reply
  16. volha-77

    Спасибо, очень нужная статья, все сработало и в 8.3

    Reply
  17. hiexe

    Спасибо, помогли

    Reply
  18. Sergus

    До недавнего времени все так и работало но вот сегодня все стало работать так как написал t278, нужно создавать конкретную форму.

    Reply
  19. mirrr

    Отсутствует отображение для типа ‘ДанныеФормыЭлементКоллекции’

    Эта ошибка на строку ЗаполнитьДокументНаСервере(ДанныеФормы);

    Версия 8.3. В чем причина?

    Reply
  20. sonGodv

    В моей ситуации не проходит не первый ни второй вариант.

    В первом, документ Установки цен номенклатуры, не заполняется табличная часть, видимо надо вызывать еще процедуры из общих модулей

    Во втором Документ можно записать, только если у пользователя есть полные права.

    Мне нравиться больше второй вариант, но не нашел как обойти контроль прав пока.

    Может кто сталкивался при записи программно с ограничениям по правам?

    Reply
  21. korppinen

    (23) sonGodv,

    УстановитьПривилегированныйРежим(Истина);

    Reply
  22. alexa191

    Благодарю, помогла статья

    Reply
  23. SunnyGirl

    Спасибо, статья помогла.

    Reply
  24. nikiforovvn

    Большое спасибо!

    Reply
  25. KNM.Work

    Спасибо!

    Reply
  26. tindir
    &НаКлиенте
    Процедура Команда(Команда)
    
    Форма = ПолучитьФорму(«Документ.НашДокумент.ФормаОбъекта»);
    ДанныеФормы = Форма.Объект; // Получаем объект формы в переменную
    ЗаполнитьДокументНаСервере(ДанныеФормы); // Заполняем документ на сервере
    КопироватьДанныеФормы(ДанныеФормы, Форма.Объект); // копируем наш объект в объект формы и далее открываем ее
    Форма.Открыть();
    
    КонецПроцедуры
    
    // Можно использовать безконтекстный вызов, оптимизируем передачу данных
    
    &НаСервереБезКонтекста
    
    Функция ЗаполнитьДокументНаСервере(ДанныеФормы);
    
    Док = ДанныеФормыВЗначение(ДанныеФормы, Тип(«ДокументОбъект.НашДокумент»)); // Получаем объект из данных формы ИЛИ
    
    Док = Документы.НашДокумент.СоздатьДокумент();
    
    // Заполняем реквизиты объекта или другие действия ********
    
    ЗначениеВДанныеФормы(Док,ДанныеФормы); // Кладем обратно в объект формы уже созданный документ
    
    КонецФункции
    

    Показать

    В коде теперь ошибка — Нельзя изменять поле, содержащее объект данных формы….

    Как на этом вывихе мозга можно разрабатывать….

    Reply
  27. sergoqwe

    (29) tindir,

    &НаКлиенте
    Процедура Команда1(Команда)
    
    ЭлементыОтбора = Новый Структура(«ВидОперации», ВидОперацииДокумента());
    ПараметрыФормы = Новый Структура(«ЗначенияЗаполнения», ЭлементыОтбора);
    ФормаДокумента = ОткрытьФорму(«Документ.РеализацияТоваровУслуг.ФормаОбъекта», ПараметрыФормы);
    ДанныеФормы = ФормаДокумента.Объект;
    ЗаполнитьДокументНаСервере(ДанныеФормы);
    КопироватьДанныеФормы(ДанныеФормы, ФормаДокумента.Объект);
    
    КонецПроцедуры
    
    &НаСервере
    Функция ЗаполнитьДокументНаСервере(ДанныеФормы);
    Док = ДанныеФормыВЗначение(ДанныеФормы, Тип(«ДокументОбъект.РеализацияТоваровУслуг»));
    Док = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
    Док.Дата = НачалоМесяца(ТекущаяДата());
    СтрДок = Док.Товары.Добавить();
    СтрДок.Количество = 1000;
    ЗначениеВДанныеФормы(Док,ДанныеФормы);
    КонецФункции
    
    &НаСервере
    Функция ВидОперацииДокумента ()
    Возврат Перечисления.ВидыОперацийРеализацияТоваров.Товары;
    КонецФункции
    
    

    Показать

    Поправьте если что не правильно, только разбираюсь с этим выносом мозга 8.3

    Reply
  28. Meson
    Док = ДанныеФормыВЗначение(ДанныеФормы, Тип(«ДокументОбъект.РеализацияТоваровУслуг»));

    Док = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

    В чем смысл этих двух строк?

    Reply
  29. user657734_YGREEN

    Все просто:

    &НаКлиенте
    Процедура СоздатьЗаявку(Команда)
    ПараметрыФормы = новый Структура(«Основание, Объект.Ссылка);
    ОткрытьФорму(«Документ.ЗаказМатериалов.Форма.ФормаДокумента», ПараметрыФормы);
    КонецПроцедуры

    а теперь на сервере при открытии действуем как обычно при создании документа на основании:

    Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

    // ДанныеЗаполнения — это основание переданное в параметрах формы.

    ЗЫ: см. справку 1с: Интерфейс (управляемый)->УправляемаяФорма

    Reply
  30. apostal86

    (32) спасибо, этот вариант мне подошел

    Reply
  31. ui69

    (1) Считаю, что заголовок соответствует. Нашел и понял суть именно по тожу заголовку который указан сейчас: Открытие формы еще незаписанного документа.

    Reply
  32. LavinVadik

    вот еще один рабочий вариант,

    взято от сюда http://devtrainingforum.v8.1c.ru/forum/thread.jsp?id=625538

    &НаКлиенте
    Процедура ОткрытьФормуНового(Команда)
    
    Форма = ПолучитьФорму(«Документ.ПродажаТоваровУслуг.Форма.ФормаДокумента»);
    ДанныеФормы = Форма.Объект;
    ЗаполнитьНаСервере(ДанныеФормы);
    КопироватьДанныеФормы(ДанныеФормы, Форма.Объект);
    Форма.Открыть();
    
    КонецПроцедуры
    
    &НаСервере
    Процедура ЗаполнитьНаСервере(НовыйОбъект)
    НовыйОбъект.Контрагент = Справочники.Контрагенты.НайтиПоКоду(«000000005»);
    КонецПроцедуры
    
    

    Показать

    Reply
  33. bobster123456

    (35) если нужный (основной) реквизит формы называется не «Объект», то кирдык. Зашёл сюда как раз в поисках решения.

    Reply
  34. mukhina

    Большое спасибо! Очень помогло при решении задачи по переводу внешней обработки по созданию нового документа ПТУ с 8.2 на 8.3.

    Пример для Бухгалтерии 3.0 вместо

    Форма = ПолучитьФорму(«Документ.НашДокумент.ФормаОбъекта»);

    надо

    Форма = ПолучитьФорму(«Документ.ПоступлениеТоваровУслуг.Форма.ФормаДокументаТовары»);

    В этой форме есть реквизит Объект.

    Reply
  35. CratosX

    Для Расширения (тонкий клиент, клиент-сервер) помог такой код, взятый отсюда:

    &НаКлиенте
    Процедура ОткрытьФормуНового(Команда)
    
    Форма = ПолучитьФорму(«Документ.ПродажаТоваровУслуг.Форма.ФормаДокумента»);
    ДанныеФормы = Форма.Объект;
    
    ЗаполнитьНаСервере(ДанныеФормы);
    
    КопироватьДанныеФормы(ДанныеФормы, Форма.Объект);
    Форма.Открыть();
    
    КонецПроцедуры
    
    &НаСервере
    Процедура ЗаполнитьНаСервере(НовыйОбъект)
    
    НовыйОбъект.Контрагент = Справочники.Контрагенты.НайтиПоКоду(«000000005»);
    
    КонецПроцедуры

    Показать

    Reply
  36. user789071

    Пост, помог спасибо.

    Reply
  37. SvetaS2014
    Reply
  38. Xershi

    (14) так и есть:

    АдресХранилища = ПоместитьВоВременноеХранилище(НовыйОбъект, УникальныйИд);

    Ошибка при вызове метода контекста (ПоместитьВоВременноеХранилище)

    АдресХранилища = ПоместитьВоВременноеХранилище(НовыйОбъект, УникальныйИд);

    по причине:

    Переданное значение не может быть помещено во временное хранилище

    1С:Предприятие 8.3 (8.3.10.2466)

    А метод автора сработал!

    В своей публикации не знал как решить проблему не записанного битого объекта: https://infostart.ru/public/608150/

    А теперь это стало возможно!

    Reply
  39. Xershi

    (41) после тестов пришел к мнению, что открыть форму битой ссылки на УФ не возможно. Единственный вариант создавать произвольную форму, но смысла в этом нет, проще записать и открыть уже элемент!

    Reply
  40. rutadmeen

    Действительно работает. Спасибо!

    Reply
  41. Xershi

    (40) вам не нужны танцы с бубном. Получайте новую ссылку о чем автор писал ранее! Это все для УФ нужно!

    Reply
  42. micha26
    ЗаполнитьДокументНаСервере(ДанныеФормы); // Заполняем документ на сервере

    Если я правильно понимаю — НаКлиенте будет ругаться на отсутствие переменной ДанныеФормы.

    Reply
  43. user623969_dusa

    все равно идет обращение к серверу так почему сразу не предложить записать объект если надо открыть его форму как рекомендуется в универсальном решении, выигрыша нет — данные формы туда сюда гоняются если документ будет записываться еще раз на сервер полетят данные формы

    можно использовать директиву НаСервере и не передавать параметром)

    Reply
  44. micha26

    (45)а нет, это я ступил. Не будет ругаться.

    Reply
  45. serg-lom89

    (23)

    Добрый

    точно с таким же столкнулся((

    не подскажете почему не заполняются ТЧ?

    Reply
  46. Vida

    (21) Зачем пугаете?

    ПолучитьФорму (GetForm)

    Доступность:

    Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение(клиент).

    Вызов метода выполняет обращение к серверу.

    Reply
  47. Vida

    (16)

    У меня заработало и как у вас и как у автора.

    Странно…

    Теперь проблема выбора.

    ЧЯДНТ?

    Автору СПАСИБО!

    Reply
  48. Vida

    (20)

    А что у вас изменилось? У меня работают оба варианта.

    Платформа 8.3.13.1644

    УНФ 1.5

    Reply
  49. hydro2588_2015

    Может кому пригодится. Пункт 2. ОткрытьЗначение(Ссылка). У меня не работало в web (хотя справка говорила что все должно быть норм, ругалось на модальность окна), версия платформы 8.12. ОткрытьФорму() отработало как надо. Открывал документ ЗаказКлиента.

    Reply
  50. olbir

    Спасибо!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *