Имя: Пароль:
1C
1С v8
Прошу объяснить причину (изменение строки в тч)
0 vrTiess
 
16.05.19
16:42
Добрый день. Есть некий код:

&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    Если НЕ ЗначениеЗаполнено(Объект.Основание) Тогда
        Предупреждение("Сначала заполните Основание");
        Возврат;
    КонецЕсли;
    Тек = Элементы.Товары.ТекущиеДанные;
    ТоварыНоменклатураПриИзмененииНаСервере(Тек.Номенклатура, Элементы.Товары.ТекущаяСтрока, Тек.Количество);
КонецПроцедуры

&НаСервере
Процедура ТоварыНоменклатураПриИзмененииНаСервере(Номен, ТекСтрока, Количество)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ПоступлениеТоваровУслугТовары.Номенклатура,
    |    СУММА(ПоступлениеТоваровУслугТовары.Количество) КАК Количество
    |ИЗ
    |    Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
    |ГДЕ
    |    ПоступлениеТоваровУслугТовары.Номенклатура = &Номенклатура
    |    И ПоступлениеТоваровУслугТовары.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |    ПоступлениеТоваровУслугТовары.Номенклатура";
    Запрос.УстановитьПараметр("Ссылка", Объект.Основание);
    Запрос.УстановитьПараметр("Номенклатура", Номен);
    Результат = Запрос.Выполнить().Выгрузить();
    Если Результат.Количество() = 0 Тогда
        Сообщить("Номенклатуры " + Номен + " нет в документе, указанном в Основании.");
        Объект.Товары.Удалить(ТекСтрока);
        Возврат;
    ИначеЕсли Количество <> 0 И Результат[0].Количество < Количество Тогда
        Сообщить("Вы пытаетесь списать больше, чем есть. Не хватает " + (Количество - Результат[0].Количество) + " шт.");
        Объект.Товары[ТекСтрока].Количество = Результат[0].Количество;
    КонецЕсли;
КонецПроцедуры

Когда смотрю по отладке в этой строке
Объект.Товары[ТекСтрока].Количество = Результат[0].Количество;
количество изменяется. Вроде все нормально, но как только возвращаемся с сервера на клиент, все сбрасывается до того, как было до изменения.
Но. Если мы в объявлении процедуры вместо этого
Процедура ТоварыНоменклатураПриИзмененииНаСервере(Номен, ТекСтрока, Количество)
пишем это
Процедура ТоварыНоменклатураПриИзмененииНаСервере(знач Номен, знач ТекСтрока, знач Количество)
то все ок.
Я погуглила, но ничего не нашла по этой теме. Может мне кто-нибудь это объяснить?
1 Garykom
 
гуру
16.05.19
16:46
2 fisher
 
16.05.19
17:04
Странно. На первый взгляд никаких сайд-эффектов не нахожу.
Да и количество/текстрока - это числа, они и так передаются по значению.
3 fisher
 
16.05.19
17:07
Тьфу, опять забыл что в 1С все по ссылке передается.
4 Garykom
 
гуру
16.05.19
17:13
(3) В Go все по умолчание по значению, сначала было непривычно целых два часа себя одергивал постоянно, потом привык.
5 fisher
 
16.05.19
17:14
Не знаю, почему поведение отличается, но вот эта строка неправильная:
Объект.Товары[ТекСтрока].Количество = Результат[0].Количество;
Правильная:
Объект.Товары.НайтиПоИдентификатору(ТекСтрока).Количество = Результат[0].Количество;
6 sqr4
 
16.05.19
17:14
(5) а в Текстрока не идентификато будет
7 sqr4
 
16.05.19
17:15
(6) хотя я могу врать
8 fisher
 
16.05.19
17:17
(7) Ага :)
9 hhhh
 
16.05.19
17:20
(8) да, ТекСтрока - это другое. Это идентификатор.
10 hhhh
 
16.05.19
17:22
(8) Это важно, если вы удаляете в процессе строчки. Или меняете местами. Тогда идентификатор сбивается и уже не равен номеру строки.
11 sqr4
 
16.05.19
17:22
(9) я мало того что болтун, так еще и жадный до букв
12 fisher
 
16.05.19
17:22
Думаю, просто совпало когда при одном тесте идентификатор совпал с индексом и получилось что ожидалось, а в другом тесте они отличались и количество поменялось в другой строке. И удаление строки там тоже неправильное.
13 fisher
 
16.05.19
17:23
А не, вру. Удаление как раз правильное.
14 fisher
 
16.05.19
17:24
Тьфу, да что ж такое :) Таки неправильное. Удаление либо по индексу, либо по элементу строки работает.
15 dezss
 
16.05.19
17:24
Во-первых, чета фотки нет))
Во-вторых, а как проверялось, что "количество изменяется. Вроде все нормально, но как только возвращаемся с сервера на клиент, все сбрасывается до того, как было до изменения."
Ну в-третьих, имхо, дело вот в чем
Процедура ТоварыНоменклатураПриИзмененииНаСервере(Номен, ТекСтрока, ЗНАЧ Количество)
После возврата с сервера, устанавливается старое количество.
Соответственно, если без ЗНАЧ писать не
        Объект.Товары[ТекСтрока].Количество = Результат[0].Количество;
а просто
Количество = Результат[0].Количество
То все будет гут)
16 fisher
 
16.05.19
17:26
(15) > После возврата с сервера, устанавливается старое количество.
Это что еще за новости?
17 dezss
 
16.05.19
17:27
(16) Ну я просто предположил. Потому и во-вторых еще было)
Оно ж не по значению передавалось, на сервере элемент не менялся, вот и осталось в нем старое значение. Сам не проверял, просто предположил.
18 dezss
 
16.05.19
17:28
И было бы еще интересно посмотреть на ТЧ при повторном заходе на сервер до изменений.
19 Сияющий в темноте
 
16.05.19
19:05
все очень просто,значения если не написано знач должны передаваться по ссылке,но 1с не может передать ссылку с клиента на сервер,она передает туда значение,а при выходе из процедуры передает обратно
20 dezss
 
17.05.19
09:54
(19) О как...значит, я оказался прав, ошибившись только в нюансах.
21 dezss
 
17.05.19
09:55
(20) ошибившись -> ошибся
22 dezss
 
17.05.19
10:07
Проверил на обычном реквизите. Передал в серверную процедуру элемента формы "ТекстРедактирования" (тестНаСервере(Элементы.Мойрек.ТекстРедактирования);). Если не указать "Знач", то при возврате из серверной процедуры:
Поле объекта недоступно для записи (ТекстРедактирования)
    тестНаСервере(Элементы.Мойрек.ТекстРедактирования);
23 RomaH
 
naïve
17.05.19
10:35
(0) кстати - хорошая задачка на тестирование
24 RomaH
 
naïve
17.05.19
10:37
+(19) поэтому просто не думая - надо выработать привычку везде, где не нужно изменение значения параметра функции - писать Знач
25 fisher
 
17.05.19
15:24
(19) Вот блин. Таки да. Жесть жестяная.