Имя: Пароль:
1C
1С v8
Сделать внешний отчет без СКД и без костылей
0 zelenprog
 
20.03.24
10:47
Добрый день!

Есть простая внешняя обработка, которая формирует табличный документ. СКД не используется.

Как я понимаю, для формирования табличного документа нужно сделать процедуру или функцию, которая должна располагаться в модуле объекта.
Но чтобы показать и вывести табличный документ на печать, это нужно сделать в модуле формы на клиенте.

А это есть проблема, так как из модуля формы обратиться напрямую к модулю объекта нельзя.
Приходится использовать костыль
"    ОбъектОтчет = РеквизитФормыВЗначение("Объект");"

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

Возникает вопрос: а как надо делать? Как правильно?
Подскажите плиз.
1 FIXXXL
 
20.03.24
10:49
перенеси код в модуль формы
2 p-soft
 
20.03.24
10:55
работает? не глючит? чего еще надо? а не нравится - сипипи всегда есть с бесплатным компилятором)
3 Волшебник
 
20.03.24
11:00
>> метод РеквизитФормыВЗначение("Объект") надо использовать только в крайних случаях.

Считайте свой случай именно таким.
4 zelenprog
 
20.03.24
11:25
(3) >> Считайте свой случай именно таким.

Получается, что любой внешний отчет - это крайний случай.
А внешних отчетов - используется приличное количество, на Инфостарте их полным-полно. Значит, такие "крайние" случаи встречаются часто. Что противоречит понятию "крайний".

Следовательно, либо написание внешних отчетов - это нарушение архитектуры 1С.
Либо сама 1С так коряво сделана, что провоцирует использование костылей.
Либо есть какой-то малоизвестный способ "корректного" написания подобных отчетов.
5 zelenprog
 
20.03.24
11:26
(1) >> перенеси код в модуль формы

В коде модуля формы недоступны некоторые методы для формирования ТабличногоДокумента.
6 zelenprog
 
20.03.24
11:27
(2) >> работает? не глючит? чего еще надо?

Надо разобраться и понять: почему приходиться применять такие костыли, и можно ли сделать правильно без костылей.
7 Hmster
 
20.03.24
11:31
(4) В статьях 1С ИТС достаточно часто встречал рекомендацию использовать РеквизитФормыВЗначение("Объект")
Так что не волнуйся, пользуйся
8 p-soft
 
20.03.24
11:33
(6) это не костыли - попытка повернуть программирование бухгалтеру лицом. и тут 1с немного палку перегнули: и херня в коде и бухам уже не разобраться)
9 p-soft
 
20.03.24
11:34
(8) но если разрабов нормальных держать - разработка копейки стоит
10 youalex
 
20.03.24
11:50
(0) > это нужно сделать в модуле формы на клиенте.
Почему именно на клиенте?
11 PLUT
 
20.03.24
11:54
(6) открой пофигуратор

в нем ctrl + shift + F по заклинанию РеквизитФормыВЗначение поищи по типовой пофигурации

в результатах глянь - сколько раз встретишь это магическое заклинание - много думай...

в типовой ERP 2.5.12 найдено более 3 тыс. использований
12 p-soft
 
20.03.24
12:10
из анекдота: вчера читал папкин пейджер. много думал..))
13 Garykom
 
20.03.24
12:23
(12) это он еще мамкин не читал...
14 Valdis2007
 
20.03.24
12:56
(0) метод РеквизитФормыВЗначение("Объект") надо использовать только в крайних случаях.

Если бы это на сайте ИТС прочитал...тогда да
15 zelenprog
 
20.03.24
13:00
(10) >> Почему именно на клиенте?

Мне кажется сервер не сможет показать ТабличныйДокумент и не сможет отправить его на печать.
Принтеры ведь подключены к ПК клиента.
16 Garykom
 
20.03.24
13:26
(15) Эмм кто/что мешает в модуле формы размещать процедуры/функции &НаСервере ?
17 Garykom
 
20.03.24
13:28
Классика это вызвать с клиента функцию, которая на сервере создаст ТабДок и вернет на клиента, чтобы там его показать или напечатать
18 zelenprog
 
20.03.24
16:48
(16),(17) Да, конечно.

Просто в (10) был вопрос "Почему именно на клиенте?".
Этот вопрос он задавал к моему самому первому посту.
Этот вопрос можно расшифровать так: "Почему ... показать и распечатать ТабличныйДокумент можно ... именно на клиенте?".

Ну вот я ему и ответил, что сервер не может показать и распечатать табличный документ.
19 Garykom
 
20.03.24
16:53
(18) Сервер может распечатать
20 Chai Nic
 
20.03.24
16:58
Я вот тоже не понимаю, почему в модуле формы обработки недоступен контекст объекта без этого странного метода РеквизитФормыВЗначение(), который кстати достаточно тяжелый для выполнения.
21 Garykom
 
20.03.24
17:04
(20) Преобразование из одних типов в другие же
22 Шурик71
 
20.03.24
17:15
(0) >> нужно сделать процедуру или функцию, которая должна располагаться в модуле объекта.

Что??

>> В коде модуля формы недоступны некоторые методы для формирования ТабличногоДокумента.

Что??

Оба утверждения - ложь.

1. Как правило, в типовых отчетах/обработках, подключенных к БСП - формирование процедуры производится в модуле обработки. Например, внешняя печатная форма, подключенная с вызовом серверного метода, имеет формирование таб.документа на сервере. Но она не нуждается в форме внешней обработки, т.к. использует форму отчета из конфигурации.

При этом, если используется СВОЯ форма - никто не запрещает иметь формирование табдока в форме.

Если есть своя форма (а она есть, т.е. внешняя обработка работает в режиме "ОткрытиеФормы" или просто через файл-открыть) - то где распологать функцию, возвращающую ТабДок (в форме или в модуле через РеквизитФормыВЗначение) - дело исключительно вкусов и стандартов.

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

2. В коде модуля формы нет недоступных методов. Недоступные методы есть на сервере и на клиенте.

Модуль формы содержит И клиентские И серверные методы, разделенные директивами.
Модуль объекта - только серверные.

На сервере недоступна интерактивная работа. Например, ТабДок.Показать().
На клиенте недоступно обращение к данным и метаданным (и много чего еще).

Но в (17) описан стандартный способ.
23 Hmster
 
20.03.24
17:46
(20) Возможно посчитали, что он не нужен. Ну или не получилось нормально сделать синхронизацию между клиентом и сервером, и пришлось добавить новые сущности
24 youalex
 
20.03.24
18:40
(18) нет мой вопрос был в целом к контексту "для формирования табличного документа..." где было неверное утверждение "нужно сделать процедуру или функцию, которая должна располагаться в модуле объекта" (ключевое Должна)
25 Волшебник
 
20.03.24
19:42
(22) Только оберните всё это в условие
Если УправляемыеФормы Тогда

потому что в обычных формах всё не так.
26 zelenprog
 
21.03.24
08:42
(24) >> ... неверное утверждение "нужно сделать процедуру или функцию, которая должна располагаться в модуле объекта" (ключевое Должна) ...

А где еще может находиться процедура, которая формирует табличный документ, напрямую используя методы типа "ПолучитьМакет"?
27 zelenprog
 
21.03.24
08:53
(22)
>> Что??
>> 2. В коде модуля формы нет недоступных методов. Недоступные методы есть на сервере и на клиенте.
Модуль формы содержит И клиентские И серверные методы, разделенные директивами.

Это все понятно.
Говоря о модуле формы, я и имел ввиду и серверные и клиентские методы, располагающиеся в модуле формы.

Ни из серверного, ни из клиентского метода в модуле формы недоступен метод "ПолучитьМакет". Следовательно, сформировать ТабличныйДокумент в модуле формы нельзя напрямую.
Приходится это делать через ("финт ушами") "РеквизитФормыВЗначение("Объект")".
28 Pprog151713
 
21.03.24
09:01
(27) Почему финт ушами просто добавил строки эти
и строишь обычный отчет. Как на обычных формах. _ЭтотОбъект=РеквизитФормыВЗначение("Отчет");
Макет =  _ЭтотОбъект.ПолучитьМакет("Макет");
29 zelenprog
 
21.03.24
09:23
Нашел статью, которая описывает этот процесс:

https://its.1c.ru/db/pubv8devui/content/196/hdoc
30 youalex
 
21.03.24
13:40
(26) тебе же написали уже в (17)
Формируешь на сервере, возвращаешь на клиент
31 Шурик71
 
22.03.24
01:35
(27) > Ни из серверного, ни из клиентского метода в модуле формы недоступен метод "ПолучитьМакет"

Ага. А также недоступны такие методы как Показать(), Выбрать(), НайтиСтроки()... )))

А все почему? а потому, что контекст формы не имеет отношения к контексту объекта, в котором эта форма находится! И контекстом является всегда ФормаКлиентскогоПриложения. У которого нет методов отчета.

Можно, конечно, рассматривать это как минус, требующий преобразования РеквизитФормыВЗначение("Отчет").

А можно подумать о том, что в данном случае "Отчет" - это всего навсего "Основной реквизит формы. И на форме отчета могут быть еще, к примеру, несколько реквизитов "ДокументРеализацииОбъект", "СчетФактураОбъект", "НоменклатураОбъект" и т.п. И к каждому из них применимо РеквизитФормыВЗначение().

И все, что дает признак "Основного реквизита" - это дополнительные свойства/методы/события, описанные как "Расширение [Справочника/документа/отчета/..]" в документации.

Ничто не мешает сделать внешнюю обработку, сделать у нее форму, сделать реквизит к примеру "СправочникОбъект" типа "СправочникОбъект.Номенклатура", назначить этот реквизит основным и открыть эту форму через

ОткрытьФорму("ВнешняяОбработка.Форма.Форма1", Новый Структура("Ключ", МояСсылкаНаНоменклатуру));

И она будет работать как форма объекта справочника... И отредактировать и записать эту позицию можно будет. Во внешней обработке..

(Кстати, периодически использую этот подход для разработки / отладки сложных форм с большим количеством кода, чтобы не требовалось постоянно перегружать 1с.)

Так что да, ПолучитьМакет("Макет") - это метод Объектов (СправочникОбъект, ДокументОбъект, ВнешняяОбработкаОбъект...). И Объект этот надо получить; самый простой способ - как раз "РеквизитФормыВЗначение".
При этом опять никто не помешает использовать совсем другой объект, типа

макет = Документы.РеализацияТоваровУслуг.СоздатьДокумент().ПолучитьМакет("ПФ_MXL_РасходнаяНакладная");

или
макет = ВнешниеОбработки.Создать("c:\ВнешняяОбработка1.epf",Ложь).ПолучитьМакет("Макет");

И принципиально НИКАКОЙ разницы не будет.

А к вопросу в каком месте должна располагаться функция печати это точно отношения не имеет.


P.S. Сорри за "многобуковок". Но они имеют отношение к пониманию "архитектуры программы", где "что-то не продумано" ))
32 Web00001
 
22.03.24
06:34
Сначала придумают себе трудности, а потом героически их решают. Я в таких случаях использую следующий подход. Если мне не кажется правильным или оптимальным решение. Я копирую кусок кода оставляя решение как есть. Потом, глядя на другой код других людей, рано или поздно встречаешь решения задач похожих на твою и смотришь как это делали другие люди. Этого вполне достаточно, чтобы писать +- оптмиальный код. Не понятно почему ты считаешь конвертацию реквизита в объект костылем и чем по твоему мнению грозит использование этого "костыля". Есть аргументы?