Имя: Пароль:
1C
1C 7.7
v7: Как открыть не сохраненный но заполненный новый документ
0 picom
 
03.09.11
07:24
Не понимаю как это сделать в семерке:
Нужно открыть программно новый документы с предзаполненными из обработки  данными.
ОткрытьФорму(НовДок.ТекущийДокумент())
ведь работает если документ записан.
А мне его запись не нужна, только открытие с заполненными данными
1 МастерВопросов
 
03.09.11
07:41
стандартно  никак, это старый баян. Либо заполнять данными из модуля самой формы, куда передавать данные из обработки, либо Формекс.
2 1Сергей
 
03.09.11
07:42
Конт="";
ОткрытьФорму("Документ.Накладная",Конт);
Конт.НоваяСтрока();
...
3 Рэйв
 
03.09.11
07:42
>>новый документы
..
Ты свой "новый документы " запиши перед отурытием..а то ссылки не будет
4 picom
 
03.09.11
07:45
(3) не могу записать
этот документ носит информативный зарактер и как только он зареган в базе тут-же начинается движуха
например отправка писем или смс
надо открывать его без записи
5 Рэйв
 
03.09.11
07:46
(4)Тогда ->(2)
6 skunk
 
03.09.11
07:46
открыть можно ... даже можно заполнить после открытия все кроме табличной части
7 picom
 
03.09.11
07:47
(2) не понятно
8 Рэйв
 
03.09.11
07:47
Открытие формы нового документа

ОткрытьФорму(<ОписательОбъекта>, <КонтекстФормы>, <ДокументОснование>)

<ОписательОбъекта>    Строковое выражение."Документ.ХХХХХ", где ХХХХХ — идентификатор вида документа;
<ДокументОснование>    Необязательный параметр. Выражение типа «документ», задающий документ-основание для открытия формы ввода нового документа в режиме ввода на основании.
9 Рэйв
 
03.09.11
07:48
(7)СП купишь по сходной цене?
10 picom
 
03.09.11
07:49
(6) жаль, а таб часть ой как надо заполнить
хотя ее то можно и заполнить как раз в форме документа при открытии
11 МастерВопросов
 
03.09.11
07:49
(4) передавай параметры при ОткрытьФорму , а в модуле формы документа в процедуре ПриОткрытии пиши заполнение полей формы данными из параметра.
12 Dump
 
03.09.11
08:09
А не проще сделать, чтобы "движуха" начиналась не когда документ "зареган в базе", а при его проведении? Кучу проблем зараз решишь
13 picom
 
03.09.11
08:14
(12) Примерно так и сделал, добавил галку, не начинать движуху)
14 mishaPH
 
03.09.11
08:15
(12) + 100. или по флагу некому "ДвижухаПошла".
Вот придумают себе проблем.

Завел бы 1 технический док себе и грузил его.
15 mishaPH
 
03.09.11
08:15
(13) бугагашечка
16 zak555
 
03.09.11
08:22
записать в транзакции, заполнить, отменить транзакцию =)
17 Рэйв
 
03.09.11
08:26
Я так понял (8) опять никто не читал.
18 Banned
 
03.09.11
08:28
(17) а кому оно надо? Читать СП - удел задротов и ботанов....
19 picom
 
03.09.11
08:43
(17) СП не всегда понятен, объясните своими словами, возможно ваше решение и будет самым правильным
20 Хряк
 
03.09.11
09:03
самое правильное добавить строку загрузки формэкс и продолжать работать как ни в чём не бывало
21 Мимохожий Однако
 
03.09.11
09:18
А еще можно сделать обработку с реквизитами документа. Закрыл - не сохранилось. ОК - записал и провел документ.
22 GreyK
 
03.09.11
12:00
//******************************************************************************
Процедура МояПроцедура()
   Перем Докум;
   ОткрытьФорму("Документ.ПоступлениеТМЦ",Докум);
;
   Докум.ОткрытьПодбор("Обработка.МояОбработкаЗаполнения",,Докум);
КонецПроцедуры
23 МастерВопросов
 
03.09.11
12:06
(19) видимо он тебе рекомендует открывать форму в режиме ввода на основании. Но почему бы просто параметры не передать в открываемую форму.
24 Torquader
 
03.09.11
22:50
(23) Для передачи параметров форму нужно модифицировать, а вот для ввода на основании всё уже написано.
25 Torquader
 
03.09.11
23:11
Для (16):
// здесь мы бдуем создавать документ с табличной частью
// будем использовать метод "Транзакция"
d=CreateObject("Document.Создаваемый");
d.New();
d.ЗагРек1="Уст.Загол.";
d.NewLine();
d.СтрРек1="Стр1";
d.СтрРек2="Уст1";
d.NewLine();
d.СтрРек1="Стр2";
d.СтрРек2="Уст2";
// теперь выполняем сохранение в транзакции
BeginTransaction();
d.Write();
OpenForm(d.CurrentDocument());
// отменяем транзакцию
RollBackTransaction();
// и о чудо - мы видим на экране заполненный документ
// а в журнале его нет, то есть он не сохранён.


Однако, так делать нельзя ни в коем случае!!!
Почему ?
Во-первых, мы видим документ, у которого нет пометки изменения, то есть по мнению системы он не только сохранён, но ещё и не изменён. Первое, к чему это приводит - это то, что при закрытии документа пользователь не получает сообщения о том, что документ нужно сохранить - 1С считает, что мы его уже сохранили.
Во-вторых, если мы вызовем у этого документа функцию Selected (Выбран), то мы получим возвращаемое значение 1, хотя должно быть ноль. Но это не самое страшное.
Самое страшное в том, что у этого документа есть внутренний идентификатор (можно спросить ValueToStringInternal(CurrentDocument()) и увидеть его.
Более того, при нескольких несохранениях мы получаем одинаковый идентификатор, что говорит о том, что он присвоился, но счётчик идентификаторов не увеличивается.
И основное:
Теперь пробуем создать новы документ любого типа - ему присвоится тот же самый идентификатор и при сохранении система скажет, что "Запись заблокирована" - и слава богу - иначе - задвоение идентификатора нам бы было обеспечено.
(Если, конечно, какой-то документ удастся сохранить, то будет печально).
То есть решение через транзакцию - это однозначная порча информации в базе данных.
26 Torquader
 
03.09.11
23:15
+(25) После экспериментов с сохранением был потерян номер документа (то есть в тестовой  базе создавался только один документ номер 1 и не сохранялся в транзакции, а потом оказалось, что нумерация идёт с номера 2).
27 Torquader
 
03.09.11
23:24
(23) Ваш способ - ввод на основании:

// создаём документ и заполняем его
d=CreateObject("Document.Создаваемый");
d.New();
d.ЗагРек1="Уст.Загол.";
d.NewLine();
d.СтрРек1="Стр1";
d.СтрРек2="Уст1";
d.NewLine();
d.СтрРек1="Стр2";
d.СтрРек2="Уст2";
// открываем форму нового документа и передаём в качестве
// параметра сформированный нами документ
OpenForm("Document.Создаваемый",,d);
// форма открылась, но нас подстерегает сюрприз

В форме документа в процедуре InputNew(ВводНового) есть флаг признака копирования - он не установился в 1, а процедура InputCausedBy(ВводНаОсновании) вообще не вызвалась
То есть в качестве основания нужно передавать сохранённый документ - вот тут-то мы и вспоминаем про транзакцию (то есть про то, что мы делали до этого)
28 Torquader
 
03.09.11
23:34
Собмещаем:

// то есть делаем и транзакцию и ввод на основании
d=CreateObject("Document.Создаваемый");
d.New();
d.ЗагРек1="Уст.Загол.";
d.NewLine();
d.СтрРек1="Стр1";
d.СтрРек2="Уст1";
d.NewLine();
d.СтрРек1="Стр2";
d.СтрРек2="Уст2";
// открываем транзакцию
BeginTransaction();
// записываем документ
d.Write();
// передаём его в форму
// она отработает создание нового документа на основании
// переданного ей значения сохранённого документа
// который какое-то время существует
OpenForm("Document.Создаваемый",,d.CurrentDocument());
// после отработки создания документа его форма ещё
// не открыта, а ссылка на переданный параметр
// уже использована и больше она не нужна
// теперь мы отменяем транзакцию и наш "фиктивный" документ
// разрушается и система больше не знает о том
// что он вообще существовал
RollBackTransaction();

Такой способ позволяет избежать проблем, так как пользователь видит новый документ, и для 1С он тоже новый
Единственная проблема в том, что в модуле формы документа
должна быть описана процедура ввода на основании другого документа такого же вида.
Если этого нет, то все наши старания были бессмысленны.
29 Cthulhu
 
03.09.11
23:54
(28): а вот вопрос. по реинжинирингу. м.б. сможешь попробовать как-то отловить - что и как вызывается при F9 в форме журнала, ммм?.. я не компетентен ни полраза именно в этом, но может быть как-то хитро можно инициировать открытие формы нового документа таким образом, чтобы она "подумала" что выполняется копирование (с "подсовыванием" флага копирования и ссылки на копируемый документ)?..
30 Torquader
 
04.09.11
00:09
Дело в том, что "умная" 1С при копировании выполняет загрузку в память выбранного объекта и вытирание у него идентификатора, а потом для полученного объекта открывает форму с вызовом функции копирования, но при вызове процедуры копирования объект уже заполнен скопированными данными.
Имитацию копирования сделать сложнее, так как новый документ должен появится в журнале, а для этого откаченной транзакции недостаточно.
А F9 смело можно через SendKey "нажать".
31 Cthulhu
 
04.09.11
00:24
(30): а чем инициируется весь этот процесс... вот про то я. м.б. можно какую-то байду вызвать с передачей в ней ИД копируемого объекта данных - и там уже пойдет молотить все ч то ты сказал... никак?..
(а сендкей и ф9 - некомильфо, в терминале у меня, например, далеко не обязательно всх в службах сессии будет запущен, например; да и гарантировано открыть журнал спозиционироваться на том что надо потом закрыть журнал и т.п. - ой как муторно на самом деле)
32 Torquader
 
04.09.11
00:48
(31) В меню этот пункт называется копирование.
При вызове меню система получает идентификатор активной формы (в данном случае журнал документов) и в нём находит активный документ, то есть то, что возвращает CurrentDocument в журнале.
Кроме того, в процедуре InputNew во втором параметре мы получаем значение спозиционированного документа (ValueToStringInternal показывает нам именно ссылку, а не объект документ), то есть если даже мы научимся выполнять копирование, то у нас будут опять проблемы с тем, как сделать ссылку на то, чего в системе нет.
33 Torquader
 
04.09.11
00:56
Интересно ещё то, что в случае нового документа в процедуру InputNew передаётся ссылка на пустой документ, как ни странно.
То есть ссылка есть всегда, а первый флаг, видимо, это есть Selected от этой ссылки.
34 Torquader
 
04.09.11
01:03
А через SendKey можно спокойно вводить строки и задавать значения, только для этого приходится использовать Form.IdleProcessing, чтобы дождаться обработки клавиши именно тогда, когда это нужно - но такой способ разумным назвать сложно.
При открытии формы мы можем получить от неё контекст, но это будет контекст формы, через который можно вызывать какие-то функции модуля формы и иметь доступ к части реквизитов - например, установить значения реквизитов табличной части для активной строки можно, но создать или поменять активную строку - нет.
35 Cthulhu
 
04.09.11
01:42
и никак не подсунуть во ВводНового ссылку?.. ВК-шку на крайняк слепить?..
36 Voronve
 
04.09.11
08:11
(0) Чего паримся ? Делаем все проще, например, в ТиС, во многих документах есть код вида:
[code]
   Парам = Форма.Параметр;
   Если ТипЗначенияСтр(Парам)="СписокЗначений" Тогда
       Если ПустоеЗначение(Парам.Получить("Команда"))=1 Тогда
           Сообщить("В форму документа "+Вид()+" передан неверный параметр!","I");
           СтатусВозврата(0);Возврат;
       КонецЕсли;
       Если Парам.Получить("Команда") = "ПечатьНаПринтер" Тогда
           КолЭкз = Макс(Число(Парам.Получить("КолЭкз")),1);
           ПоКнопкеПечать(1,КолЭкз);
           СтатусВозврата(0);Возврат;
       ИначеЕсли Парам.Получить("Команда") = "ПечатьНаЭкран" Тогда
           ПоКнопкеПечать(0);                
           СтатусВозврата(0);Возврат;
       Иначе
           Сообщить("В форму документа "+Вид()+" передана неверная команда "+Парам.Получить("Команда")+"!","I");
           СтатусВозврата(0);Возврат;
       КонецЕсли;
   КонецЕсли;        
[/code]

В эту мешанину добавляем:
[code]
ИначеЕсли Парам.Получить("Команда") = "ЗаполнитьИзОбработки" Тогда
ОткрытьФорму("Обработка.МояОбработкаПоЗаполнению", Контекст);
[/code]

Документ открываем так:
[code]
спПараметры = СоздатьОбъект("СписокЗначений");
спПараметры.Установить("Команда", "ЗаполнитьИзОбработки");

ОткрытьФорму("Документ.Реализация", спПараметры);
[/code]

Имеем заполненную как надо, открытую, но не записанную форму документа.
37 Voronve
 
04.09.11
08:27
+
Вот так вызываемся если нужно показать юзеру два и более открытых документа одного вида
[code]
спПараметры = СоздатьОбъект("СписокЗначений");
спПараметры.Установить("Команда", "ЗаполнитьИзОбработки");

ОткрытьФорму("Документ.Реализация#" + ИмяПользователя() + "_" + ТекущееВремя(), спПараметры);
[/code]
38 МастерВопросов
 
04.09.11
15:32
(36) можно и не дописывать ничего в эту мешанину, просто " МояОбработкаПоЗаполнению" сделать в виде внешней формы и подключить к документу как печатную форму.
39 Torquader
 
04.09.11
21:53
Ребята!
Разговор шёл о том, что делать, если:
1) Конфигурация написана неизвестно кем и заказчик не даёт разрешение на её изменение.
2) В родной конфигурации в модуле формы документа нет ни обработки переданных параметров ни обработки подбора.
3) Нельзя подключать внешние компоненты.
И нужно из внешней обработки создать и заполнить документ, который будет отображён пользователю, чтобы у него был шанс его или сохранить или не сохранить.
Понятно, что если мы можем открыть обработку подбора, то потом из неё можно вызывать ВыполнитьВыбор (MakeChoice).
40 Кукуев
 
05.09.11
06:51
Делал через контекст, как (2) советовал...

Процедура Сформировать()
   
   Перем Парам;
   
   Если ПустоеЗначение(ВыбДок) = 1 Тогда
       Предупреждение("Не выбран документ!!!", 3);
       Возврат;
   КонецЕсли;
   
   ДокОтчет = СоздатьОбъект("Документ.ОтчетКомиссионера");
   ДокБухСпр = СоздатьОбъект("Документ.БухгалтерскаяСправка");
   
   ТЗДвижения = СоздатьОбъект("ТаблицаЗначений");
   ТЗДвижения.Очистить();
   ТЗДвижения.НоваяКолонка("Номенклатура", "Справочник.Номенклатура");
   ТЗДвижения.НоваяКолонка("Комиссионер", "Справочник.Контрагенты");
   ТЗДвижения.НоваяКолонка("Себестоимость", "Число");
   ТЗДвижения.НоваяКолонка("ПродСтоимость", "Число");
   ТЗДвижения.НоваяКолонка("Количество", "Число");
   
   Парам = глВзятьКонтекст(Контекст);
   
   ОткрытьФорму("Документ.БухгалтерскаяСправка", Парам);
   
   ДокОтчет.НайтиДокумент(ВыбДок);
   
   РегПродажи = СоздатьОбъект("Регистр.Продажи");
   РегПродажи.ВыбратьДвиженияДокумента(ДокОтчет);
   Пока РегПродажи.ПолучитьДвижение() = 1 Цикл
       ТЗДвижения.НоваяСтрока();
       .....
       .....
   КонецЦикла;                                      
   //Заполняем шапку документа    
   Парам.ДатаДок = ДокОтчет.ДатаДок;
   Парам.Автор = глПользователь;
   .....
   .....
   
   Парам.Форма.Обновить();
   
   ТЗДвижения.ВыбратьСтроки();
   Пока ТЗДвижения.ПолучитьСтроку() = 1 Цикл
       Парам.НоваяСтрока();
       //Заполняем табличную часть документа
       .....
       .....
   КонецЦикла;
   
КонецПроцедуры

И табличная часть заполняется :)
41 Torquader
 
06.09.11
23:31
У меня (40) не работает (платформа 27).
Если вместо Конт.НоваяСтрока() вставить Конт.Записать, то "умная" система выдаёт ошибку "Данная команда не может выполняться в формуле элемента диалога!" - собственно, по этой причине строки и не создаются.
(А формула элемента диалога, видимо, зависит от типа документа и от вида элементов управления на форме документа).
42 Cthulhu
 
06.09.11
23:38
(40): а теперь попробуй без ВК.
(41): ряд ВК автоматом подключают возможность добавления новых строк в документ через контекст.
43 SiAl-chel
 
07.09.11
03:02
(11) А зачем в ПриОткрытии?() Можено же через КонтекстФормы заполнять.
44 skunk
 
07.09.11
03:03
пробуй
45 Кукуев
 
07.09.11
08:58
(42)Ну да, ВК-шками не брезгую, есть кое-чего  :)
Подозревал, что ВК "оказывает помощь" в этом, но, честно говоря, какая именно - не интересовался. Бум знать, спасибо...
46 Ёпрст
 
07.09.11
09:05
(45) только одна - формекс.
47 Кукуев
 
07.09.11
10:15
(46)Спасиб, запомню :)
48 Cthulhu
 
07.09.11
13:52
(46): а 1с++ ???
49 Ёпрст
 
07.09.11
13:57
(48) нет. Только первые версии, где был встроен формекс.
50 Cthulhu
 
07.09.11
16:43
(49): вспомнил: ещё turbobl (и вроде даже давнее других).
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший