Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Програмное копирование документов (число прочтений - 9927 )
slider26
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 256
Зарегистрирован: 01. Июня 2006
Програмное копирование документов
23. Ноября 2007 :: 03:42
Печать  
Потребовалось реализовать програмное копирование документов в конфигурации, имея только ссылку на документ.
Так как мной используется различное заполнение реквизитов в форме документа в процедуре
"ВводНового(Скопирован,Источник)" в зависимости от признака "Скопирован", а процедура должна быть универсальной, то просто заполнение всех реквизитов формы после открытии формы нового документа не подходит, так как процедуры ВводНового(), ПриОткрытии() и ПослеОткрытия() на этот момент уже отработали Печаль
Поэтому Вопрос:
Можно ли средствами 1С++ достучаться до процедуры копирования документа (Например, перегрузить ОткрытьФорму())?
И кто как решает подобные задачи?
Please help!
  
Наверх
 
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #1 - 23. Ноября 2007 :: 04:08
Печать  
Я правильно тебя понял? :

1. Не открывая форму, воспользоваться процедурой из МодуляФормыДокумента.
2. Применить её к объекту док = СоздатьОбъект( "Документ.НужногоВида" )
3. док.Записать()

Да?
  
Наверх
ICQ  
IP записан
 
slider26
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 256
Зарегистрирован: 01. Июня 2006
Re: Програмное копирование документов
Ответ #2 - 23. Ноября 2007 :: 06:03
Печать  
dnp писал(а) 23. Ноября 2007 :: 04:08:
Я правильно тебя понял? :

1. Не открывая форму, воспользоваться процедурой из МодуляФормыДокумента.
2. Применить её к объекту док = СоздатьОбъект( "Документ.НужногоВида" )
3. док.Записать()

Да?

Не совсем - задача стоит следующая:
Пишем журнал документов на базе ТП.
Нужно сделать кнопки, аналогичные кнопкам в общем журнале:
Для "Новый":
Код
Выбрать все
ОткрытьФорму("Документ."+ВыбраныйВид) 


Для "Изменить":
Код
Выбрать все
ОткрытьФорму(Док, , флТолькоПросмотр); 


Для "Просмотр":
Код
Выбрать все
ОткрытьФорму(Док, , 1); 


Для "Ввести на основании":
Код
Выбрать все
ОткрытьФорму("Документ."+ВыбраныйВид, ,Док); 


Для "Скопировать":
???????
Хотелось бы иметь подходящий вид процедуры "ОткрытьФорму()" Печаль
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #3 - 23. Ноября 2007 :: 06:26
Печать  
У acsent'a есть класс Расширенный журнал 2. Там сделано так:
Код
Выбрать все
Процедура КопироватьДокумент(_Источник, _Приемник)
	Для ъ = 1 По Метаданные.ОбщийРеквизитДокумента() Цикл
		Реквизит = Метаданные.ОбщийРеквизитДокумента(ъ).Идентификатор;
		_Приемник.УстановитьАтрибут(Реквизит, _Источник.ПолучитьАтрибут(Реквизит));
	КонецЦикла;

	Для ъ = 1 По Метаданные.Документ(_Источник.Вид()).РеквизитШапки() Цикл
		Реквизит = Метаданные.Документ(_Источник.Вид()).РеквизитШапки(ъ).Идентификатор;
		_Приемник.УстановитьАтрибут(Реквизит, _Источник.ПолучитьАтрибут(Реквизит));
	КонецЦикла;

	_Источник.ВыбратьСтроки();
	Пока _Источник.ПолучитьСтроку() = 1 Цикл
		_Приемник.НоваяСтрока();
		Для ъъ = 1 По Метаданные.Документ(_Источник.Вид()).РеквизитТабличнойЧасти() Цикл
			Реквизит = Метаданные.Документ(_Источник.Вид()).РеквизитТабличнойЧасти(ъъ).Идентификатор;
			_Приемник.УстановитьАтрибут(Реквизит, _Источник.ПолучитьАтрибут(Реквизит));
		КонецЦикла;
	КонецЦикла;
КонецПроцедуры	// КопироватьДокумент


Процедура Копировать() Экспорт
	Док = ПолучитьТекущийДокумент();
	Если ПустоеЗначение(Док) = 1 Тогда
		Возврат;
	КонецЕсли;

	Конт = ТабличноеПоле;

	ОткрытьФорму("Документ." + Док.Вид(), Конт);
	КопироватьДокумент(Док, Конт);
	Конт.Форма.Обновить();

	Попытка
		Конт.ВводНового(1);
	Исключение
	КонецПопытки;
КонецПроцедуры 


(по кнопке вызывается "Копировать()")
  
Наверх
 
IP записан
 
slider26
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 256
Зарегистрирован: 01. Июня 2006
Re: Програмное копирование документов
Ответ #4 - 23. Ноября 2007 :: 07:02
Печать  
JohnyDeath писал(а) 23. Ноября 2007 :: 06:26:
У acsent'a есть класс Расширенный журнал 2. Там сделано так...

Вот этот класс я сейчас для себя и переделываю Улыбка... Уже очень многое переписал. Например, отсутствие хинтов (NOLOCK)...
Этот метод для меня не подходит - причина описана в первом посте Улыбка
  
Наверх
 
IP записан
 
slider26
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 256
Зарегистрирован: 01. Июня 2006
Re: Програмное копирование документов
Ответ #5 - 23. Ноября 2007 :: 07:47
Печать  
Механизм ведь уже реализован в платформе Улыбка Вот бы вынести его на пользовательский уровень...
Например так:
ОткрытьФорму("Копия",Контекст,СсылкаНаКопируемыйДокументИлиЭлементСправочника);
Улыбка
  
Наверх
 
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #6 - 23. Ноября 2007 :: 08:57
Печать  
С помощью Перехватчика я получил такой порядок вызова обработчиков :

Код
Выбрать все
Выполнение: ОткрытьФорму( "Документ.НачальныеСобытияДока", кф );
ПЕРЕХВАТЧИК::СобытиеГМ_ВводНового( ГрупповойКонтекст, 0,  )
ПЕРЕХВАТЧИК::СобытиеГМ_ВводНового: Выполнение: ВыполнитьОригинальноеСобытиеГК( "ВводНового", 1, "<ПередаёмСсылку>" );
ДОКУМЕНТ::ВводНового( 1, <ПередаёмСсылку> )
ПЕРЕХВАТЧИК::СобытиеГМ_ВводНового: Выход из : "ВыполнитьОригинальноеСобытиеГК(...)"
ПЕРЕХВАТЧИК::СобытиеГМ_ВводНового:  ВОЗВРАТ 1; // 0- нельзя, форма не откроется
ДОКУМЕНТ::ВводНового( 0,  )
ДОКУМЕНТ::ПриОткрытии()
Вышли из "ОткрытьФорму(...)" 



Если придумаешь, как задушить второй "ВводНового" (точнее, вызваться он стопудово должен, главное, чтобы результат предыдущего не испортил), то вариант -- твой
Улыбка
  
Наверх
ICQ  
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #7 - 23. Ноября 2007 :: 16:12
Печать  
dnp писал(а) 23. Ноября 2007 :: 08:57:
Если придумаешь, как задушить второй "ВводНового" (точнее, вызваться он стопудово должен, главное, чтобы результат предыдущего не испортил), то вариант -- твой
Улыбка


В документе ВводНового запустится только при вызове ВыполнитьОригинальноеСобытиеГК. Не запускай его - не будет второго ВводНового...
  
Наверх
 
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #8 - 23. Ноября 2007 :: 17:35
Печать  
Arta писал(а) 23. Ноября 2007 :: 16:12:
dnp писал(а) 23. Ноября 2007 :: 08:57:
Если придумаешь, как задушить второй "ВводНового" (точнее, вызваться он стопудово должен, главное, чтобы результат предыдущего не испортил), то вариант -- твой
Улыбка


В документе ВводНового запустится только при вызове ВыполнитьОригинальноеСобытиеГК. Не запускай его - не будет второго ВводНового...


Ммммм... Я оригинальное событие же не зря вызвал, я в нем пытался форму обмануть -- передал туда параметры, которые иначе бы она получила пустыми.

Сейчас перепробую заново Улыбка
  
Наверх
ICQ  
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #9 - 23. Ноября 2007 :: 18:35
Печать  
Получил такой вывод Цитата:
вызывающий код ----> ОткрытьФорму()
КОП::СобытиеГМ_ВводНового()
ДОК::ВводНового( 0,  )
ДОК::ПриОткрытии()
вызывающий код ----> Вышли из ОткрытьФорму(...)

в тестовой конфе (прилагается).

Обработчик, отписавшийся во второй строке этого вывода, обязан вернуть 1, чтобы форма открылась.
Третья строка вывода указывает на баг? Или я обшибаюсь?
Оригинального события я, в данном случае, не вызывал.

  

HookTest_05.rar ( 11 KB | Загрузки )
Наверх
ICQ  
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #10 - 23. Ноября 2007 :: 19:11
Печать  
Какая последовательность? Что и откуда ты делаешь?
У меня на Ins выдает
ДОК::ВводНового( 0,  )
ДОК::ПриОткрытии()

Или в "нажми меня" нажимаем Открыть форму?
там тоже самое


Брр... посмотрел код и так и не врубился, ЧТО ты хочешь достичь.
Давай еще раз разжуй Улыбка
  
Наверх
 
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #11 - 24. Ноября 2007 :: 19:03
Печать  
Я вчера, когда тест выложил - вырубил комп и лёг спать...

И тут меня осенило - ведь форма открываемого документа, её ГК, ещё не перехвачена. Значит её события ещё летят своим чередом, и остановить это мы не в силах. Перехватить я могу. Желательно сделать это как можно быстрее от начала её жизни. И самое первое событие, где я могу это сделать - это, к сожалению, СобытиеГМ_ВводНового, и это событие ГЛОБАЛЬНОГО модуля. То есть я не могу отменить вызова штатного обработчика ЛОКАЛЬНОГО модуля "ВводНового()" прописанного в МодулеФормы, ГК ведь ещё только *будет* перехвачен. Что и демонстрирует мой тест (хотя выкладывая его, я думал, что демонстрирует он другое Смех  )


Что я хочу достичь? Ищу решение проблемы, поставленой автором топика. Это максимальная цель.

Локальная цель была - подменить штатный вызов 1С-кой ВводНового( 0, "пусто" )
на свой ВыполнитьОригинальноеСобытиеГК( "ВводНового", 1, <ПередаёмСсылку> );
(Кстати, теперь я считаю, что это дыра в 1С++, это событие является неперехватуемым, значит и позволять мне его вызывать *таким образом* - нельзя Улыбка )

Вызвать можно.
Подменить нет.
Если не найти СобытияГМ, возникающего раньше "ВводНового".
  
Наверх
ICQ  
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #12 - 24. Ноября 2007 :: 19:08
Печать  
Arta писал(а) 23. Ноября 2007 :: 19:11:
Какая последовательность? Что и откуда ты делаешь?
....
Или в "нажми меня" нажимаем Открыть форму?
там тоже самое

Да, второй час ночи был, кажется. Скосячил. Нажимать нужно было :
[ Нажми меня ]
[ Вкл.перехват ]
[ ОткрытьФорму(... ]

Хотя теперь это не так важно..
  
Наверх
ICQ  
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #13 - 24. Ноября 2007 :: 20:24
Печать  
Последовательность в теории такая:
СобытиеГМ_ВводНового
ПерехватчикСобытийФормы ВводНового
МодульФормы ВводНового (При условии выполнения в классе ПерехватчикСобытийФормы метода ВыполнитьОригинальноеСобытиеГК)

Так что в классе можно отменить создание документа, вернув 0 в ВводНового.

Или я опять не понял?
Если честно, то я так и не понял как ты хочешь реализовать "проблему поставленую автором топика". Ты пошагово опиши, что ожидаешь от кода.
  
Наверх
 
IP записан
 
dnp
Senior Member
****
Отсутствует


.

Сообщений: 479
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Програмное копирование документов
Ответ #14 - 24. Ноября 2007 :: 21:14
Печать  
Arta! Спасибо за терпение!
Я опять тупил.
Перехватчик мне просто космически нравится!
Сделал!
Можно обмануть ВводНового!
slider26, возрадуйся со мной  Смех

Пошагово :

1. Запоминаю "что копировать", делаю простое ОткрытьФорму( "Документ.НужногоВида" )
2. В СобытиеГМ_ВводНового славливаю контекст этой формы, и цепляю к ней своего ОбработчикГК
3. В ОбработчикГК славливаю (опять) событие ВводНового, на входе в который (естественно) его параметры пусты (флаг копирования не поднят, нет ссылки на копируемый объект).
   3.1. Каким-то образом (нужно подумать) из места действия п.1 извлекаю инфу - "что копировать?", и получив это --
   3.2. Делаю ВызватьОригинальноеСобытиеГК( конт, "ВводНового", 1, <что копировать> )

Всё.
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать