![]() |
|
Массив структур: обращение к элементу при переборе takefive, Ногаминебить, dchumak, RomanYS, Мультук, Табуретко, АгентБезопаснойНацио, Sanchez_22, X Leshiy, formista2000, Eiffil123, ЕRPe, nick86, privetik, Terrixus, crotnn, maxab72, Гипервизор, RVN, aka MIK, PLUT, Amfiaray, Mankubus, Vasvas, alexela, Климов Сергей, U4Me2, paramedic, Telcher, Fedor-1971, lubitelxml, Kongo2019, Howaitokira, Prog_man, Галахад, ndrv, Волшебник, boozin, tir654, yurikmellon2, Chai Nic, zenik, Fish, Ненавижу 1С, pasha_d, ptiz, Дмитрий, d4rkmesa, CepeLLlka, spiller26, Chameleon1980, lexushka, Кир Пластелинин, backfire, Timon1405, DemonShinji2, Anton1307, vyaz, okmail, LLeonidov, Zombi, 2S, DiMel_77, Kigo_Kigo, Михаил Козлов, DeeK, Bad_Aleks, maxar, программистище, rozer76, Crusher, Hawk_1c, Gucci76, Вадим33, Builder, Чужой, obs191, dmrjan, rbcvg, Caesar, DrLekter
| ☑ | ||
---|---|---|---|---|
0
formista2000
13.10.25
✎
10:03
|
Привет!
Есть сабж. Работает по-разному. Почему? Задача - модифицировать структуру, которая передаётся в качестве параметра. С таким перебором не работает: Для Каждого ЭлементМассива Из МойМассив Цикл ОбработатьСтруктуру(ЭлементМассива); КонецЦикла; А с таким перебором работает: Для Индекс = 0 По МойМассив.Количество()-1 Цикл ОбработатьСтруктуру(МойМассив[Индекс]); КонецЦикла; Почему так? ЗЫ: Массив на клиенте, процедура обработки на сервере. |
|||
1
Ненавижу 1С
гуру
13.10.25
✎
10:19
|
Покажите, что вы там меняете в ОбработатьСтруктуру - код с заголовком нужен
По-хорошему надо один раз передать массив на сервер и там все обработать, потом вернуть на клиент |
|||
2
Eiffil123
13.10.25
✎
10:19
|
а процедура ОбработатьСтруктуру(ххх)
она точно меняет структуру, а не создает в ней новую? подозрение на второе |
|||
3
paramedic
13.10.25
✎
10:25
|
(0) Это смотря что вы делаете в ОбработатьСтруктуру.
|
|||
4
formista2000
13.10.25
✎
10:28
|
(1) &НаСервереБезКонтекста
Функция ОбработатьСтруктуру(Структ) Если Структ.Свойство("МоеСвойство") Тогда ...что-то делаем со структурой... Результат = 1; Иначе Структ.Вставить("МоеСвойство", МоеЗначение); Результат = 0 КонецЕсли; Возврат Результат; КонецФункции Массив передать и обработать полностью сразу не получится, так как при обработке в некоторых случаях надо запрашивать действие пользователя. Функция вызывается как процедура, так что на Результат не обращайте внимания. (2) Точно. |
|||
5
formista2000
13.10.25
✎
10:29
|
(3) Дополняю своими свойствами структуру.
|
|||
6
LLeonidov
13.10.25
✎
10:35
|
(0) Да ты прав, воспроизводится.
Отдельно хочу заметить что (1) прав. Вызовы сервера должны быть минимальны. Но, если ты с клиента вызываешь с клиента обработку каких то партий в каждой структуре, по 300 или по 3000штук то это конечно же норм. Это кст не бага, а фича. &НаКлиенте Процедура Структура(Команда) МассивСтруктур = Новый Массив; Для Ном = 0 По 10 Цикл Структура = Новый Структура("Ном, Число", Ном, 0); МассивСтруктур.Добавить(Структура); КонецЦикла; Сообщить(СтрШаблон("%1: %2", "Базовое", ЗаписьВСтрокуJSON(МассивСтруктур))); Для Каждого текЭлемент Из МассивСтруктур Цикл Добавить1(текЭлемент); КонецЦикла; Сообщить(СтрШаблон("%1: %2", "Перебор ""Для Каждого""", ЗаписьВСтрокуJSON(МассивСтруктур))); Для Ном = 0 По МассивСтруктур.Количество() - 1 Цикл Добавить1(МассивСтруктур[Ном], 10); КонецЦикла; Сообщить(СтрШаблон("%1: %2", "Перебор ""По индексу""", ЗаписьВСтрокуJSON(МассивСтруктур))); КонецПроцедуры &НаСервере Процедура Добавить1(Элемент, Число = 1) Элемент.Число = Элемент.Число + Число; КонецПроцедуры &НаКлиенте Функция ЗаписьВСтрокуJSON(Значение, Знач СтруктураОбмена = Неопределено) Экспорт ЗаписьJSON = Новый ЗаписьJSON; ЗаписьJSON.УстановитьСтроку(); ЗаписатьJSON(ЗаписьJSON, Значение); СериализованноеЗначение = ЗаписьJSON.Закрыть(); Возврат СериализованноеЗначение; КонецФункции |
|||
7
maxab72
13.10.25
✎
10:40
|
а почему ОбработатьСтруктуру функция, а вызывается как процедура?
P.S. на обычных формах не воспроизводится. |
|||
8
formista2000
13.10.25
✎
10:38
|
(7) это долгая история ))
|
|||
9
Eiffil123
13.10.25
✎
10:43
|
(0) похоже на баг платформы. было бы в заголовке Знач, тогда поведение было бы ожидаемое.
похожий случай видел, когда массив структур был реквизитом формы, и при изменении структур этот массив не возвращался на клиент если не поправить любой другой реквизит (текст например в другом реквизите). Но тут то точно должно работать. регистрируйте в поддержке |
|||
10
formista2000
13.10.25
✎
10:43
|
(9) Реквизит формы типа массив?! Да ладно!!11 О.о
|
|||
11
Мультук
гуру
13.10.25
✎
10:45
|
(0)
0) Я думаю, это просто фича 1) й = 0; Для каждого строка из мас Цикл //Вот тут строка это всё еще один и тот же указатель с элементом мас. //Т.е Строка=мас[й] это ИСТИНА ОбработатьМас(строка); //Вот тут строка вернулась из обработки, она хорошая и красивая, но увы //она уже сама по себе и //Строка=мас[й] это ЛОЖЬ й = й +1; КонецЦикла; P.S. А будет ли работать вот такой код ? В применении к массив структур Имена итераторов то повторяются. Ужас-Ужас Для каждого строка из мас Цикл Для каждого строка из строка Цикл Сообщить(Строка.Ключ + ":" + Строка.Значение); КонецЦикла; КонецЦикла; |
|||
12
Chai Nic
13.10.25
✎
10:54
|
(9) "похоже на баг платформы. было бы в заголовке Знач, тогда поведение было бы ожидаемое."
Модификатор Знач влияет только на невозможность изменения передаваемого значения. А структура - это же по сути ссылка, а не само значение. То есть, Знач не должен запрещать изменение значений по ссылке, а только изменение самой ссылки внутри процедуры. Но здесь клиент-серверный обмен, там при передаче всё сериализуется, так что по идее не должно меняться в обоих случаях, если не происходит обратная сериализация. Или же должно опять таки в обоих случаях. Ведь и в том и в другом случае передается элемент массива с типом Структура. И неважно, как мы его получили, по идее. Через итератор или через индекс. |
|||
13
Eiffil123
13.10.25
✎
10:56
|
(10) ну да, тип "Произвольный", достаточно часто встречается.
|
|||
14
formista2000
13.10.25
✎
10:57
|
(13) А, ну да ))
|
|||
15
Eiffil123
13.10.25
✎
10:59
|
(12) в случае, если Знач у серверной процедуры, а она вызывается с клиента, тогда переданное значение не будет возвращаться, даже если менялось на сервере.
Такие необычные спецэффекты, но надо учитывать. https://infostart.ru/1c/articles/388527/?ysclid=mgotrlnkp94368307 |
|||
16
formista2000
13.10.25
✎
11:06
|
(15) Всё правильно. Никаких "Знач" у меня нет.
|
|||
17
Ненавижу 1С
гуру
13.10.25
✎
11:18
|
При передаче с сервера возвращаются другие объекты (по другим адресам в памяти клиента). Соответственно
Для Каждого ЭлементМассива Из МойМассив Цикл ОбработатьСтруктуру(ЭлементМассива); КонецЦикла; замещается переменная ЭлементМассива, но она уже отвязана от массива и в массив изменения не попадут Для Каждого ЭлементМассива Из МойМассив Цикл ПромежуточныйЭлемент = ЭлементМассива; ОбработатьСтруктуру(ПромежуточныйЭлемент); //по окончании это разные структуры ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ЭлементМассива, ПромежуточныйЭлемент, Истина); КонецЦикла; |
|||
18
RomanYS
13.10.25
✎
11:19
|
(6) Почему не баг? Никакого разумного объяснения не видно. В какой-то момент на сервере возникает копия структуры и она передается на клиент.
|
|||
19
Chai Nic
13.10.25
✎
11:23
|
Вообще конечно надо было четко и недвусмысленно заявить, что передача параметров клиент-сервер всегда однонаправленная. А если надо вернуть обратно - пусть возвращают через возвращаемые значения.
|
|||
20
Ненавижу 1С
гуру
13.10.25
✎
11:24
|
(18) это такой криворукий дизайн языка. Передача параметров зависит от контекста (есть передача между клиентом и сервером или нет)
|
|||
21
maxab72
13.10.25
✎
11:43
|
(0) Вроде нашел в чем отличие. Действительно, это не баг а фича.
В первом случае ты передаешь на сервер ссылку на структуру с клиента, и получаешь в ответ новую ссылку, во втором случае, при передаче по индексу, ты неявно передаешь весь массив. Если изменить код на: Для Индекс = 0 По МойМассив.Количество()-1 Цикл текЭлемент = МойМассив[Индекс]; ОбработатьСтруктуру(текЭлемент); КонецЦикла; То опять ничего в массиве не поменяется. |
|||
22
RomanYS
13.10.25
✎
11:51
|
(21) Блин, почему не баг то? В документации это где-то описано?
Или есть какие-то другие критерии отличия багов от фич? Из общей логики не вижу как можно придти к тому, что это не баг. (20)👍 |
|||
23
maxab72
13.10.25
✎
11:58
|
(22) фича в синтаксисе. Смотри, когда ты пишешь: ОбработатьСтруктуру(МойМассив[Индекс]);, ты фактически на сервер, где живет процедура ОбработатьСтруктуру передаешь два параметра: массив целиком и индекс. И все изменения происходят в самом массиве.
А если пишешь текЭлемент = МойМассив[Индекс]; ОбработатьСтруктуру(текЭлемент); то передаешь на сервер один параметр - ссылку на структуру, без привязки к массиву, и получаешь в ответ ссылку на структуру уже на сервере, а ссылка на структуру на клиенте остается как была неизменной. и массив не меняется. |
|||
24
RomanYS
13.10.25
✎
12:16
|
(23) Спасибо. Логику понял. Но принять такое не готов (хотя и выбора вроде нет))
|
|||
25
Eiffil123
13.10.25
✎
13:03
|
(23) скорее всего не массив катается на сервер, а после десериализации значение структуры помещается в переменную МойМассив[Индекс], поэтому и значение внутри массива меняется.
|
|||
26
maxab72
13.10.25
✎
13:30
|
(25) вот нашел в справке: "При передаче управления с клиента на сервер (и обратно) всегда передаются копии параметров. При вызове серверной процедуры или функции с клиента происходит создание копии фактического параметра и передача этой копии на сторону сервера. При возврате управления с сервера на клиента, также происходит создание копии формального параметра (с которым происходила работы в вызванной процедуре или функции) для передачи обратно на клиента." То есть в первом случае: ОбработатьСтруктуру(текЭлемент), возвращается новая ссылка текЭлемент, которая подменяет старую, и массив не меняется, а во втором случае ОбработатьСтруктуру(МойМассив[Индекс]) возвращается новая ссылка на сам массив, и массив изменяется. То есть похоже что гоняется туда-сюда весь массив. Хотя интерпретировать справку можно по разному.
|
|||
27
Eiffil123
13.10.25
✎
13:41
|
(26) нет, не правильно интерпретируете прочитанное. Массив не передается на сервер. С сервера возвращается новая копия структуры, которая помещается в ту же переменную, которая была до передачи управления на сервер, т.е. в МойМассив[Индекс].
Сам массив на сервер не путешествует, для этого нет оснований |
|||
28
RomanYS
13.10.25
✎
13:55
|
(27) Выглядит логичным, но не объясняет бага.
Почему в одном случае переданная ссылка заместилась пришедшей с сервера, а в другом случае зажила своей жизнью. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |