Дано: есть внешний отчёт. Он должен работать как под обычным толстым клиентом, так и под тонким, и под толстым управляемым..
Насколько я понял, это реализовать можно только создав две формы в отчёте: основную и дополнительную. Понятно, что функционал будет реализовываться немного по-разному, но большая часть процедур и функций будет одинаковой. Хочется, чтобы всё, что одинаково, существовало в одном экземпляре. Казалось бы - перекинуть всё одинаковое в модуль внешнего отчёта, обозвать экспортным (для обычной формы) и наладить "правильный" вызов из управляемой формы процедур модуля отчёта, и все довольны.... НО...!!!
Такое легко проходит с процедурами и функциями, исполняемыми на сервере, а вот как быть с исполняемыми на клиенте? У меня в обоих формах на клиенте формируется на основе word-шаблона документ... Код 1 в 1. Никакой разницы. Хочется и его иметь в единственном экземпляре, но как? Общий модуль не предлагать. Отчёт внешний!
Есть ли возможность во внешнем отчёте иметь общую для обоих форм процедуру, выполняемую на клиенте?
---
Есть ли возможность во внешнем отчёте иметь общую для обоих форм процедуру, выполняемую на клиенте?

Нет, к сожалению, и это печально так как потребность в оформлении общих клиентских процедур имеется. Может быть когда-то появится некий "клиентский модуль" для внешних отчетов и обработок, да и не для внешних не помешало бы.
---
Есть ли возможность во внешнем отчёте иметь общую для обоих форм процедуру, выполняемую на клиенте?

Нет, к сожалению, и это печально так как потребность в оформлении общих клиентских процедур имеется. Может быть когда-то появится некий "клиентский модуль" для внешних отчетов и обработок, да и не для внешних не помешало бы.
---
если толстый клиент управляемого приложения, то будет 1 в 1. А если ОФ, то там логика другая!
---
Если нужен один отчет для управляемого интерфейса, то для тонкого и толстого клиента достаточно одной формы,
написанной для исполнения в тонком клиенте.
---
внешние отчеты о обработки не будут работать в управляемом режиме толстого клиента - только в составе конфигурации
---
что за бред
---
не верьте на слово, проверьте)
---
Возможно вы имели ввиду, что если в обработке есть только управляемая форма, то ее не открыть в "толстый клиент (обычное приложение)"? потому, что просто "толстый клиент" (управляемое приложение) всё прекрасно открывается без включения в конфигурацию.
---
ну да может не совсем ясно выразился, речь конечно про УФ в толстом клиенте
---
Для начала, в свойствах конфигурации должна стоять галка "Использовать управляемые формы в толстом клиенте в обычном режиме". Далее процитирую KonstB: Внешние отчеты/обработки на УФ не открыть в обычном приложении. Их необходимо предварительно встроить в конфигурацию.
---
...
---
Отчет на СКД можно и без форм.

Если надо 2 формы - обычная и управляемая, то научитесь вызывать на клиенте УФ грамотно вызывать процедуры и функции из модуля объекта (на сервере). И передавать непередаваемое через ПоместитьВоВременноеХранилище ну и получить из него же.
---
Если надо 2 формы - обычная и управляемая, то научитесь вызывать на клиенте УФ грамотно вызывать процедуры и функции из модуля объекта (на сервере)С вызовом серверной части проблем нет, я уже об этом написал. Вопрос с вызовами на клиенте. СКД отпадает. Специфика. Заказчик сказал "Word", значит "рулим" COM-объектами.

(4) в свойствах конфигурации должна стоять галка "Использовать управляемые формы в толстом клиенте в обычном режиме"
Что-то я не нашёл такой "галки". Поподробнее можно?
---
Что-то я не нашёл такой "галки". Поподробнее можно?
---
Нуу-у. Эта "галка" стоит... И не помогает :(...
Внутриконфигурации всё работает. А вот при вызове внешней обработки/отчёта чётко работает "правило": под "толстым обычным" - только обычные формы, под "толстым упр." и "тонким" - только УФ.
Если что, платформа 8.3.16
---
Скорее всего, если стоит эта галка, тогда обычную форму из обработки нужно убрать совсем. и встраивать обработку в конфигурацию, как говорили ранее. Тогда управляемая форма должна открыться и в обычном приложении и в управляемом. Могу ошибаться, но я так понял эту ветку ответов.
Если же нужен запуск именно как внешней обработки (без встраивания), то только 2 формы и наличие этой галки роли не играет
---
Если надо 2 формы - обычная и управляемая Мне оно не надо. Другое дело, что по-другому не получается... Под толстым клиентом внешняя обработка с УФ просто не работает. Обратная ситуация точно такая же. Под тонким клиентом обычные формы не открываются... Вызываешь обработку... и всё... тишина....
---
а чем конкретно смущают клиентские процедуры в модуле обработки?
---
Наверное тем, что в модуле объекта нельзя создать клиентскую процедуру/функцию
---
Код, помещённый в модуль объекта, выполняется на сервере.
(16) Именно...
---
вообще да... вызов между разнотипными формами тоже не пройдет... остается только дублировать
---
совсем извращенный вариант, не факт, что сработает, как нужно:
Весь одинаковый код пишем в модуле, но в виде строкового значения, которое возвращается на клиент.
на клиенте этот код используем в методе Выполнить().
---
"Мсье знает толк в извращениях..." (с) анекдот
Сработает, скорее всего, но отладку такого кода не пожелаю и врагу. Пробовал на другом примере...
---
Ради эксперимента реализовал данную идею. Пришлось "потанцевать с бубном" , но таки всё заработало. Появилась даже мысль нацарапать обработку-преобразователь текстов процедур в "исполняемый текст".
---
что подразумевается под "потанцевать с бубном"? просто интересно, с какими проблемами столкнулись. вдруг когда-то придется так же извращаться)
---
Сначала просто сделал многострочный текст, добавляя в начало каждой строки "|" и обрамил текст процедуры в кавычки. Затем удвоил все кавычки внутри.
Затем требуется анализ самого текста, поскольку использования "Возврат <>" запрещено. Мне, в данном случае, пришлось ввести флаг Отказ и модифицировать код процедуры так, чтобы всё работало как надо. В данном случае, вставил два "Если".
Было:
```1c
    Процедура СформироватьКопию()
    wdStory=6;
    wdMove=0;
    wdPageBreak=7;

    Состояние("Создание документа...");
    Попытка
    MSWord = Новый COMОбъект("Word.Application");
    Исключение
    Сообщить("Ошибка при попытке создать объект "MS Word"!" + Символы.ПС +
    "Возможно приложение "MS Word" не установлено или установлено неправильно.", СтатусСообщения.Внимание);
    Возврат;
    КонецПопытки;

    //Открываем шаблон
    Попытка
    MSWord.Documents.Add();
    Исключение
    Сообщить("Ошибка при попытке открыть новый файл", СтатусСообщения.Внимание);
    Возврат;
    КонецПопытки;
    // здесь добавление шапки

    Состояние("Добавление страниц...");
    Для х=0 По СписокФайлов.Количество()-1 Цикл
    Элем=СписокФайлов[х];
    Если Элем.НомерПП<0 Тогда
    Продолжить;
    КонецЕсли;
    MSWord.ActiveDocument.InlineShapes.AddPicture(Элем.МестоХранения,Ложь,Истина);
    MSWord.Selection.EndOf(wdStory,wdMove);
    Если х<>СписокФайлов.Количество()-1 Тогда
    MSWord.Selection.InsertBreak(wdPageBreak);
    КонецЕсли;
    Состояние("Добавление страниц..."+Элем.НомерПП);
    КонецЦикла;
    MSWord.Visible=Истина;
    MSWord.Activate();
    Состояние("Формирование закончено");
    КонецПроцедуры
```

Стало:
```1c
    // это в модуле обработки
    Функция ПолучитьТекстПроцедуры() Экспорт
    Возврат "
    |Отказ=Ложь;
    |wdStory=6;
    |wdMove=0;
    |wdPageBreak=7;

    |Состояние("Создание документа...");
    |Попытка
    | MSWord = Новый COMОбъект("Word.Application");
    |Исключение
    | Сообщить("Ошибка при попытке создать объект ""MS Word""!" + Символы.ПС +
    | "Возможно приложение ""MS Word"" не установлено или установлено неправильно.", СтатусСообщения.Внимание);
    | Отказ=Истина;
    |КонецПопытки;
    |
    |Если Не Отказ Тогда
    | Попытка
    | MSWord.Documents.Add();
    | Исключение
    | Сообщить("Ошибка при попытке открыть новый файл", СтатусСообщения.Внимание);
    | Отказ=Истина;
    | КонецПопытки;
    |
    |Если Не Отказ Тогда
    |Состояние("Добавление страниц...");
    |Для х=0 По СписокФайлов.Количество()-1 Цикл
    | Элем=СписокФайлов[х];
    | Если Элем.НомерПП<0 Тогда
    | Продолжить;
    | КонецЕсли;
    | MSWord.ActiveDocument.InlineShapes.AddPicture(Элем.МестоХранения,Ложь,Истина);
    | MSWord.Selection.EndOf(wdStory,wdMove);
    | Если х<>СписокФайлов.Количество()-1 Тогда
    | MSWord.Selection.InsertBreak(wdPageBreak);
    | КонецЕсли;
    | Состояние("Добавление страниц..."+Элем.НомерПП);
    |КонецЦикла;
    |MSWord.Visible=Истина;
    |MSWord.Activate();
    |Состояние("Формирование закончено");
    |КонецЕсли;
    |КонецЕсли;
    |";
    КонецФункции
```

Использование.
в толстом клиенте:
```1c
    Процедура СформироватьКопию()
    Текст=ПолучитьТекстПроцедуры();
    Выполнить(Текст);
    КонецПроцедуры
```

в тонком:
```1c
    &НаСервере
    Функция ПолучитьТекстПроцедуры()
    Модуль=РеквизитФормыВЗначение("Отчет");
    Возврат Модуль.ПолучитьТекстПроцедуры()
    КонецФункции

    &НаКлиенте
    Процедура СформироватьКопию()
    Текст=ПолучитьТекстПроцедуры();
    Выполнить(Текст);
    КонецПроцедуры
```
---
Понятно. Спасибо за разъяснение.