В 1С 8.3 в табличной части документа есть реквизиты "Номенклатура" (типа "СправочникСсылка.Номенклатура") и "Цена". При интерактивном выборе номенклатуры автоматически подставляется цена из справочника, для чего в форме документа существует такой код:

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)
    Стр=Элементы.Товары.ТекущиеДанные;

    Стр.Цена=ПолучитьЦену(Стр.Номенклатура);

    РассчитатьСумму();
    КонецПроцедуры

    &НаСервереБезКонтекста
    Функция ПолучитьЦену(Номенклатура)
    Возврат Номенклатура.ЦенаПродажи;
    КонецФункции
```

По условию задачи у пользователя нет права на редактирование реквизита "Цена" (Если бы 1С разделяла программное и интерактивное изменение - вопроса бы не было)

Вопрос Как устанавливать цену при выборе номенклатуры в этом случае?

Есть привилегированный режим, но он работает только на сервере.

Я думал: "Сделаю как всегда - вызову вспомогательную серверную процедуру"

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)
    Стр=Элементы.Товары.ТекущиеДанные;

    УстановитьПривилегированныйРежимНаСервере(Истина);
    Стр.Цена=ПолучитьЦену(Стр.Номенклатура);
    УстановитьПривилегированныйРежимНаСервере(Ложь);

    РассчитатьСумму();
    КонецПроцедуры

    &НаСервереБезКонтекста
    Процедура УстановитьПривилегированныйРежимНаСервере(Включить)
    УстановитьПривилегированныйРежим(Включить);
    КонецПроцедуры
```

Не работает

Если передать текущую строку на сервер и менять цену уже там

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)

    Стр.Цена=ПолучитьЦену(Элементы.Товары.ТекущиеДанные);

    РассчитатьСумму();

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

    &НаСервере
    Процедура ПолучитьЦену(Стр)
    УстановитьПривилегированныйРежим(Истина);
    Стр.Цена=Стр.Номенклатура.ЦенаПродажи;
    УстановитьПривилегированныйРежим(Ложь);
    КонецПроцедуры
```

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

Думал, вынесу присвоение цены в привилегированный клиентский модуль, а они бывают только серверные.

Что делать? Включать пользователю права по условию задачи нельзя!
---
Тогда заполнение цены можно делать без привилегированного режима, а вот запись объекта с привилегированным. У вас что за конфигурация? Если типовая, то я рекомендовал бы использовать механизм внешнего заполнения объекта.

Примерно так

```1c
    ЗаполнитьДокумент(Объект.Ссылка);//Тут вы и делаете заполнение и запись в привилегированном режиме
    ОповеститьОбИзменении(Объект.Ссылка);

    ТекФорма = ПолучитьФорму("Документ.ИмяВашегоДокумента.ФормаОбъекта", Новый Структура("Ключ", Объект.Ссылка));
    ТекФорма.Прочитать();
```
---
БОЛЬШОЕ спасибо!
Ну вот, теперь благодаря ice-net всё работает. Не в обиду, маленькие уточнения:

1) ПолучитьЦену() - это вспомогательная процедура для клиента. На сервере сработает и напрямик

```1c
    Стр.Цена=Стр.Номенклатура.ЦенаПродажи;
```

2) РассчитатьСумму() - это клиентская процедура, поэтому она должна находиться в ТоварыНоменклатураПриИзменении()

И в итоге имеем:

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)

    Обработатьобъект(Элементы.Товары.ТекущиеДанные.НомерСтроки-1);
    РассчитатьСумму();

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

    &НаСервере
    Процедура Обработатьобъект(индекс)
    УстановитьПривилегированныйРежим(Истина);

    ДокОбъект = РеквизитФормыВЗначение("Объект");
    Стр = ДокОбъект.Товары[индекс];
    // Стр.Цена=ПолучитьЦену(Стр.Номенклатура);
    Стр.Цена=Стр.Номенклатура.ЦенаПродажи;
    ЗначениеВРеквизитФормы(ДокОбъект, "Объект");

    УстановитьПривилегированныйРежим(Ложь);
    КонецПроцедуры
```
---
у пользователя нет права на редактирование реквизита "Цена" - как это настроено ?
---
см. рисунок
---
перенести расчет цены в серверный модуль. Нет?
---
Уже. Ругается не на вычисление цены, а на ПРИСВАИВАНИЕ, потому что у юзера нет прав на изменение цены.
---
цена рассчитывает на основе вида цены и параметров документа.
Клиентские типы на сервер не нужно перебрасывать и все!
Посчитай цену на сервере и верни ее на клиент. А там уже меняй. Если есть права у пользователя.
Если нужно на сервере. Так редактируй объект, а не форму!!
---
Посчитай цену на сервере и верни ее на клиент.

Уже посчитал, уже вернул.

А там уже меняй. Если есть права у пользователя.

А если нет?
---
читай тогда (12) внимательно.
---
Нет, это ты читай внимательно.

Вернуть цену с сервера у меня проблем нет. Проблема записать цену в табличную часть, потому что у юзера нет прав.
---
в (19) прочитали за вас. Чукча не читатель!
---
Вы вместо строки, попробуйте отправить только номенклатуру на сервер
---
Так я и отправлял. Проблема в том, что надо прописать цену в табличную часть, а прав нет и прив. режим на клиенте не работает.
---
Тогда заполнение и запись объекта делайте на сервере, где вы и будете включать привилегированный режим.
---
Вот я и хочу это сделать, но как?

Если передать текущую строку на сервер и менять цену уже там

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)

    Стр.Цена=ПолучитьЦену(Элементы.Товары.ТекущиеДанные);

    РассчитатьСумму();

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

    &НаСервере
    Процедура ПолучитьЦену(Стр)
    УстановитьПривилегированныйРежим(Истина);
    Стр.Цена=Стр.Номенклатура.ЦенаПродажи;
    УстановитьПривилегированныйРежим(Ложь);
    КонецПроцедуры
```

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

Или тут какое-то извращение нужно сделать - передать табличную часть или форму на сервер через строку или через хранилище или что?
---
Вы где прописываете этот код? В форме самого документа?
---
Да
---
Тогда заполнение цены можно делать без привилегированного режима, а вот запись объекта с привилегированным. У вас что за конфигурация? Если типовая, то я рекомендовал бы использовать механизм внешнего заполнения объекта.

Примерно так

```1c
    ЗаполнитьДокумент(Объект.Ссылка);//Тут вы и делаете заполнение и запись в привилегированном режиме
    ОповеститьОбИзменении(Объект.Ссылка);

    ТекФорма = ПолучитьФорму("Документ.ИмяВашегоДокумента.ФормаОбъекта", Новый Структура("Ключ", Объект.Ссылка));
    ТекФорма.Прочитать();
```
---
Если типовая, то я рекомендовал бы использовать механизм внешнего заполнения объекта.
Тоже спасибо за совет. Буду знать. Кстати, об таких приёмах где-то написано? Или это тайное знание, передаваемое из уст в уста?

У вас что за конфигурация?

Тренировочная самописка. См. вложение. Требуется, чтобы Сидорчук видел цену в расходной накладной, но менять ей не мог. И чтобы при этом цена автоматически подставлялась из справочника "Номенклатура"
---
В сети много примеров внешнего заполнения объекта, легко найти.
---
сначала разберитесь с базовой логикой УФ и контекстов - очевидно, что есть пробелы.
просто нет смысла говорит о том как работать с посудомоечной машиной если человек не прочел инструкцию.

либо читаем инструкцию сами, либо пытаем "продавца"
---
"продавец" обещал разбрать на следующем занятии и "слил" вопрос. А мне нужно СРОЧНО.
---
не надо жать на все кнопки сразу
сначала закроем крышку и пустим воду

```1c
    &НаСервереБезКонтекста
    Функция ПолучитьЦену(Номенклатура)
    УстановитьПривилегированныйРежим(Истина);
    Возврат Номенклатура.ЦенаПродажи;
    КонецПроцедуры
```
---
Цену-то я получу и без прив. режима. Вопрос в том, как её прописать в табличную часть?
---
как-то так, без оптимизаций

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)

    Обработатьобъект(Элементы.Товары.ТекущиеДанные.НомерСтроки-1);

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

    &НаСервере
    Процедура Обработатьобъект(индекс)
    УстановитьПривилегированныйРежим(Истина);
    ДокОбъект = РеквизитФормыВЗначение("Объект");
    Стр = ДокОбъект.Товары[индекс];
    Стр.Цена=ПолучитьЦену(Стр .Номенклатура);
    РассчитатьСумму();
    ЗначениеВРеквизитФормы(ДокОбъект, "Объект");
    УстановитьПривилегированныйРежим(Ложь);
    КонецПроцедуры
```
---
БОЛЬШОЕ спасибо!
Ну вот, теперь благодаря ice-net всё работает. Не в обиду, маленькие уточнения:

1) ПолучитьЦену() - это вспомогательная процедура для клиента. На сервере сработает и напрямик

```1c
    Стр.Цена=Стр.Номенклатура.ЦенаПродажи;
```

2) РассчитатьСумму() - это клиентская процедура, поэтому она должна находиться в ТоварыНоменклатураПриИзменении()

И в итоге имеем:

```1c
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент)

    Обработатьобъект(Элементы.Товары.ТекущиеДанные.НомерСтроки-1);
    РассчитатьСумму();

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

    &НаСервере
    Процедура Обработатьобъект(индекс)
    УстановитьПривилегированныйРежим(Истина);

    ДокОбъект = РеквизитФормыВЗначение("Объект");
    Стр = ДокОбъект.Товары[индекс];
    // Стр.Цена=ПолучитьЦену(Стр.Номенклатура);
    Стр.Цена=Стр.Номенклатура.ЦенаПродажи;
    ЗначениеВРеквизитФормы(ДокОбъект, "Объект");

    УстановитьПривилегированныйРежим(Ложь);
    КонецПроцедуры
```
---
Какие обиды)) Просто привык все расчеты на сервере делать. Хорошего дня!) Хотя Вам подсказку еще в (12) дали
---
Элементы.Товары.ТекущиеДанные.НомерСтроки-1
Нужно было просто передавать номенклатуру. Ваш код из шапки бы итак сработал.
Ошибка была в том, что вы передавали "ДанныеФормыЭлементКоллекции".
---
> Нужно было просто передавать номенклатуру.

А можно пример кода? Мне нужно прописать цену, поэтому мне кажется, что текущая строка необходима.