Имя: Пароль:
1C
1С v8
Вызов серверной функции из клиентской процедуры
, ,
0 Exilles
 
15.02.18
21:45
Здравствуйте, новичек в 1С, пытаюсь реализовать автоматическое заполнение поля "Цена" в документе при выборе "Услуга" с помощью регистра сведений "Расценка".
Есть следующий код:
&НаКлиенте
Процедура ДоговорУслугаПриИзменении(Элемент)
    СтрокаТабличнойЧасти = Элементы.Договор.ТекущиеДанные;
    СтрокаТабличнойЧасти.Цена = ДоговорУслугаПриИзмененииНаСервере(Объект.Дата, СтрокаТабличнойЧасти);
    РаботаСДокументами.РассчитатьВыполненныйОбъем(СтрокаТабличнойЧасти);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ДоговорУслугаПриИзмененииНаСервере(АктуальнаяДата, СтрокаТабличнойЧасти)
    Отбор = Новый Структура("Услуга", СтрокаТабличнойЧасти.Услуга);
    ЗначенияРесурсов = РегистрыСведений.Расценка.ПолучитьПоследнее(АктуальнаяДата, Отбор);
    Возврат ЗначенияРесурсов.Цена;
КонецФункции

В синтаксисе всё норм при проверке, а когда начинаю заполнять документ, при выборе какой-либо "Услуга", то выходит ошибка:
Ошибка отображения типов:
Отсутствует отображение для типа 'ДанныеФормыЭлементЭлементКоллекции'
1 Мимохожий Однако
 
15.02.18
21:58
Встань отладчиком на строку с ошибкой. Что-то не договариваешь...
2 jsmith82
 
15.02.18
22:05
И что ты хотел?
3 4St
 
15.02.18
22:06
Передавай в серверную  функцию не всю строку таб. части, а только то, что тебе надо. Т.е. Услуга. И лучше передавай по значению, чуток на трафике сэкономишь .
4 jsmith82
 
15.02.18
22:06
Раз ты пишешь процедуру без контекста, передавай не данные формы элемент коллекции, а номенклатуру (СтрокаТабличнойЧасти.Номенклатура)
5 Fram
 
15.02.18
22:10
(3) что значит "передавай по значению" ?
6 vv2304
 
15.02.18
22:28
"Раз ты пишешь процедуру без контекста, передавай не данные формы элемент коллекции, а номенклатуру (СтрокаТабличнойЧасти.Номенклатура)"
Ну или убери &НаСервереБезКонтекста
7 Cyberhawk
 
15.02.18
22:29
(5) Параметр метода Знач
8 Exilles
 
15.02.18
22:49
(1) Ошибка в конфигурации появляется
(3) и (4) стал передавать только Услугу и вышла новая ошибка вместо предыдущей:
Поле объекта не обнаружено (Расценка)

"Расценка" - это регистр сведений, где у меня цена за услуги заполняется с помощью другого документа.

Теперь код выглядит так:
&НаКлиенте
Процедура ДоговорУслугаПриИзменении(Элемент)
    СтрокаТабличнойЧасти = Элементы.Договор.ТекущиеДанные;
    СтрокаТабличнойЧасти.Цена = ДоговорУслугаПриИзмененииНаСервере(Объект.Дата, СтрокаТабличнойЧасти.Услуга);
    РаботаСДокументами.РассчитатьВыполненныйОбъем(СтрокаТабличнойЧасти);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ДоговорУслугаПриИзмененииНаСервере(АктуальнаяДата, Услуга)
    Отбор = Новый Структура("Услуга", Услуга);
    ЗначенияРесурсов = РегистрыСведений.Расценка.ПолучитьПоследнее(АктуальнаяДата, Отбор);
    Возврат ЗначенияРесурсов.Цена;
КонецФункции
9 Exilles
 
15.02.18
22:51
Ошибка, потому что называется не "Расценка", а "Расценки" и теперь всё работает.
Всем огромное спасибо!
Очень долго с этим мучился, потом решился написать сюда и не ошибся, ура, товарищи!
10 Fram
 
15.02.18
22:53
(7) это экономит трафик?
11 jsmith82
 
15.02.18
23:07
Я не понял, как можно ссылку на справочник передать по значению?
12 Cyberhawk
 
15.02.18
23:18
(10) Конечно
13 jsmith82
 
15.02.18
23:28
(12) (11)
14 Cyberhawk
 
15.02.18
23:39
(13) Ну (7) же
15 ВРедная
 
15.02.18
23:50
(11) Ссылку же, не объект.
16 jsmith82
 
15.02.18
23:51
(14) Я не про это. Я про то, что по значению передаются копии объектов (таблица значений, например)
Что будет передано при передаче ссылке по значению? Ссылка же не хранит адрес в оперативной памяти какого-нибудь объекта
Во-вторых, при передаче по значению стек, наоборот, увеличивается
17 jsmith82
 
15.02.18
23:51
*ссылка 1с
18 Cyberhawk
 
15.02.18
23:55
(16) "по значению передаются копии объектов (таблица значений, например)" // Если смены контекста не происходит, то копия не передается, однако.
"Что будет передано при передаче ссылке по значению?" // Ну, объект встроенного языка с типом "СправочникСсылка.такой-то" или "ДокументСсылка.такой-то" и т.д.
19 jsmith82
 
15.02.18
23:59
Если речь идёт о клиент-серверном взаимодействии, то:

При передаче объекта на сервер происходит сериализация, т.е. выполняется "глубокая" копия объекта. А при наличии слова Знач объект не поедет с сервера обратно на клиента.
http://catalog.mista.ru/public/388527/

Т.е. если не использовать Знач, значит СправочникСсылка будет ездить в сериализованном виде?
20 Cyberhawk
 
15.02.18
23:59
(19) Будет ездить, ага
21 jsmith82
 
15.02.18
23:59
Почему все примеры на сайте 1с и на ИС для объектов типа таблица значений, список значений, массив и проч.?
Почему не говорят про ссылки?
22 Cyberhawk
 
16.02.18
00:01
(21) Наверное, потому что примеры с агрегатными объектами лучше отражают особенности поведения, чем ссылки
23 Cyberhawk
 
16.02.18
00:01
Чего про ссылки-то говорить? Я так и не понял, почему ты решил докопаться до них )
24 jsmith82
 
16.02.18
00:03
(23) Пополняю багаж знаний. Не подумал бы, что ссылки надо по значению передавать между клиентом и сервером.
25 Cyberhawk
 
16.02.18
00:04
(24) Между клиентом и сервером рекомендуется передавать по значению вообще все параметры, которые не являются выходными
26 jsmith82
 
16.02.18
00:06
Обычно под передачей по значению имеют в виду как раз передачу копии объекта (при этом затрачивается время на "сериализацию", растёт размер стека)
А тут получается (в случае К-С) создание сериализованной копии происходит, наоборот, при (формальной) передаче не по значению.
Поэтому у меня когнитивный диссонанс вышел.
27 Cyberhawk
 
16.02.18
00:13
(26) Нет, в К-С копия создается _всегда_, независимо от того, по значению параметр передается или не по значению
28 Cyberhawk
 
16.02.18
00:15
И наоборот: копия объекта-параметра без К-С (без смены контекста) не создается _никогда_, независимо от того, по значению он или не по значению передается :)
29 Fram
 
16.02.18
00:25
(27) тогда почему (12)?
30 Fram
 
16.02.18
00:28
(29) пардон.. тут речь про объект. это понятно.
так почему при передаче "по значению" трафик меньше. по идее копия параметра же создается
31 Cyberhawk
 
16.02.18
00:31
(30) Экономия только в К-С, т.к. обратно копия не сериализуется, не возвращается, не десериализуется
32 Fram
 
16.02.18
00:34
(31) ясно.. экономия на ответном трафике
33 Fram
 
16.02.18
00:39
а это только в теории? анализатором трафика проверял кто-нить чего там кодеры платформы наделали?
34 H A D G E H O G s
 
16.02.18
01:14
Как это печально.

http://v8.1c.ru/o7/201312opt/index.htm

В-четвёртых, использование ключевого слова Знач при объявлении параметров процедур и функций. Дело в том, что при клиент-серверном взаимодействии это ключевое слово значит совсем не то, что при работе внутри одного компьютера, клиентского или серверного. Когда мы используем Знач при объявлении параметра серверной процедуры и вызываем её с клиента, это означает, что значение этого параметра обратно на клиент не приедет. Если же мы не устанавливаем Знач, а стандартно так и есть, то происходит следующее. Допустим, мы вызываем серверную процедуру и передаём в неё массив. Предположим, что на клиенте мы даже не собираемся потом этим массивом пользоваться. Он просто был параметром и на самом деле нам не нужен больше. Но когда серверный вызов закончится, массив будет упакован в XML или JSON (на веб-клиенте), и уедет обратно на клиент. Понятно, что это совсем неэффективно. Поэтому если вам не нужно возвращаемое значение, переданное через параметр, пишите ключевое слово Знач у таких параметров. Конечно, если параметр Булево, Знач можно сэкономить и не писать. Но по сути это нехорошо.
35 Cyberhawk
 
16.02.18
10:48
(34) Так уже обсосали все это. Чо сказать хотел, не знал что ли?
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший