1С-ная магия

06.10.23

Разработка - Механизмы платформы 1С

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

Меня зовут Виталий Черненко, я – ведущий разработчик компании Магнит и лидер 1С:Сообщества Магнита. Это комьюнити внутри Магнита, в котором 1С-ники обмениваются опытом, проводят внутренние митапы, пилят свои инструменты – даже реализовали свою библиотеку стандартных подсистем Магнита.

Еще я автор телеграм-канала Желтый чайник 1С, люблю испытывать платформу на прочность и делиться результатами на своем канале. Также практикую C# и Unity.

 

 

Для начала дисклеймер:

Все, что я буду говорить, похоже на накидывание лепех на вентилятор. Честно говоря, так оно и есть. Но вы можете просто расслабиться, посмотреть на все эти интересности внутри платформы, и, возможно, прийти к тому же выводу, что и я.

 

 

…Что все это – просто такая «1С-ная магия»…

 

Кто такие маги 1С? Это специалисты – каждый в своей отрасли. Кто-то из них – эксперт по платформе, кто-то – по архитектуре, кто-то – по девопсу, кто-то – по консультированию...

 

У них есть множество сертификатов, которые подтверждают, что они – маги 1С. Например, есть люди, на которых держится 7.7, кто-то любит SonarQube, кто-то – всякие новомодные фреймворки и так далее.

 

 

Но есть еще один маг 1С, про которого мало кто знает, но при этом все с ним сталкиваются. Этот маг 1С достаточно специфичный и обожает всякого рода нюансы платформы, которые могут создать проблемы у разработчиков.

Также он очень любит недокументированные возможности и старается везде впихнуть любую недокументированную возможность, про которую знает.

Зачем он это делает? Об этом поговорим чуть позже.

 

Простые примеры магии. Приведение типов

 

Начнем с приведения типов. Все знают мем о том, что в JavaScript очень непонятное приведение строк и чисел – объединение строк и чисел приводит к иногда неожиданным результатам для тех, кто только начинает работать.

Оказывается, 1С в этом тоже недалеко ушла и даже в некотором роде превзошла JavaScript.

 

Например, на слайде показано, как приводятся к числам различные варианты строк.

  • Первый вариант – «4E1». Здесь можно догадаться, что это 40 + 2 = 42.

  • Второй вариант – «12E3». Понятно, что это такая запись чисел, где после E указано количество нулей, которые мы добавляем – т.е. это 12000. Оказывается, такие строки тоже приводятся к числам.

  • Но следующие строки – вообще очень странные. Для обычного разработчика выглядят как кракозябры. Например, эти два символа в третьем примере означают 69. А предпоследний и последний примеры показывают совмещение экспонентной записи и этих странных чисел.

Оказывается, если на вход приведения к числу попадет такая строка, 1С не выдаст ошибку – она приведет ее к числу так, как считает нужным.

 

Я провел небольшое исследование и сформировал простой отчет, который показывает, какие символы 1С считает цифрами. В этом отчете каждый символ — это отдельная цифра.

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

И 1С все это поймет. А JavaScript, кстати, нет.

 

ВЫБРАТЬ ПЕРВЫЕ

 

Давайте посмотрим на практический пример, в котором наш злой и вредный маг 1С подставляет разработчиков.

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

Но что здесь не так? Возможно, вы уже догадались, потому что эта проблема в 1С встречается часто, и наверняка многие с ней уже сталкивались.

 

Дело в том, что, когда мы приводим число к строке, у нас добавляются пробелы в качестве разделителей групп. Например, 1000 будет уже выглядеть как «1 000». И такой кусочек запроса не выполнится – он просто упадет в ошибку.

Казалось бы, все очевидно и логично, но не для начинающего разработчика, который с этим еще не столкнулся. Ему кажется, что он написал правильный метод, но на самом деле его код упадет. Хотя упадет не всегда, а только тогда, когда начнут выбирать больше 999.

 

Естественно, это можно поправить обычной функцией Формат(). Тогда мы решим эту проблему, и наш вредина-маг 1С будет не очень доволен.

Но такие простые, тривиальные проблемы возникают довольно часто, и дело не только в постановке запроса. Поэтому реальный маг 1С, который считает себя специалистом, отличается от начинающего junior-разработчика тем, что у него сразу в голове в процессе написания кода буквально желтой рамочкой подсвечиваются возможные ошибки. Или, когда он читает чужой код, ему мозг подсказывает, что сюда подставится пробел, и это может вызвать какие-то проблемы.

Такие подсказки мозг делает часто. И делает он их на основании того, что разработчик уже сталкивался с такой ситуацией или откуда-то об этом слышал.

 

Переопределение (ТЧ, реквизит)

 

 

Перейдем к следующему примеру. Что здесь у нас не так?

Это просто обработка, которая так и называется – ПростоОбработка. Она имеет табличную часть Документы и реквизиты – Организации и Пользователи. Вроде ничего страшного.

Здесь проблема в табличной части, которая называется Документы. Дело в том, что это – зарезервированное имя внутри платформы, менеджер документов.

И если мы попытаемся обратиться к модулю объекта какого-либо документа через этот менеджер, мы это сделать уже не сможем. Потому что мы его перекрыли табличной частью.

Проблема достаточно тривиальная, простая. И решается вроде бы логично – достаточно просто не называть табличную часть словом «Документы». Но это приходит в голову разработчику только после того, как он с этим уже столкнулся.

Ведь в принципе-то название «Документы» логичное – у нас есть коллекция, в которой будут храниться документы. Вроде всё правильно.

Возможно, эта обработка уже содержит огромное количество строк кода, завязанное на логику, что у нас в «Документах» лежат документы. Но как только нам понадобится обратиться к какому-то реальному документу системы, появятся проблемы. В таких случаях правильнее всего переделать эту обработку. Или использовать для исправления какие-то костыльные методы, о которых я расскажу позже.

 

Такая же проблема – с реквизитом «Пользователи», потому что такое же имя имеет стандартный общий модуль БСП, который содержит функциональность работы с пользователями.

У него не очень хорошее название, потому что в результате мы нигде не можем использовать реквизит или переменную, которая называется «Пользователи». Если же мы все-таки заведем такую переменную или реквизит, мы не сможем обратиться к текущему пользователю. При попытке его вызвать платформа будет обращаться к реквизиту «Пользователи», в котором лежит какое-то значение – в данном случае, список.

 

Помимо проблем с именами реквизитов у нас есть еще и предопределенные свойства формы. С ними все намного сложнее, потому что это огромное количество свойств, которые тоже нельзя переопределять. Если попробовать туда поместить какое-то значение, ты либо сломаешь какую-то логику, либо просто получишь исключение – 1С не даст это сделать.

Например, свойство формы ТекущийЭлемент. Часто можно видеть код, когда изначально разработчик пытается создать:

Для Каждого ТекущийЭлемент Из Коллекция….

Естественно, это не сработает. Или сработает не так, как разработчик этого ожидал.

Помимо свойств, форма может иметь еще огромное количество реквизитов. Разработчики часто любят накидывать в форму реквизиты, которые даже не имеет смысла добавлять – они не вводятся на форму, их можно было бы просто сгруппировать – сделать какой-нибудь реквизит вида «Структура» с названием «ДополнительныеСвойства» или «СгруппироватьПоСмыслу» и помещать туда любые данные, не засоряя тем самым контекст.

Например, на скрине выше показана типовая обработка, у которой созданы такие реквизиты формы, как «ПолноеИмя», «Причина», «КодАлгоритма», «Алгоритм» и так далее. Это достаточно общие названия, которые можно было бы использовать в качестве переменной. И какой-нибудь разработчик, когда начнет добавлять сюда свою кнопочку, может поначалу просто не понять, что переопределяет существующий реквизит формы, на который завязана, возможно, какая-то логика.

 

Покажу еще два прикольных момента, которые может использовать наш волшебный маг, любящий всякие костыли:

  • Самый интересный вариант – это захватить имя переменной, сделать так, чтобы в контексте этого метода (процедуры или функции) эта переменная не была привязана к форме. Например, у формы есть свойство Заголовок. Если его менять, изменится заголовок у формы. Но, если мы его сделаем, например, параметром метода, это будет независимая переменная – после этого обратиться к заголовку формы мы не сможем. Естественно, сломать его тоже.

  • Или, например, мы можем добавить в модуль Перем – он вообще замечательный, может переопределить все подряд. Например, если вы в начале процедуры напишете Перем, и объявите переменные Метаданные, ЭтотОбъект, Документы, Справочники и так далее, то тем самым “захватите” эти ключевые слова. И можете поприсваивать туда вообще другие контексты. Очень интересные поведения потом можно наблюдать.

 

Директивы

 

А еще эту проблему можно решать изолированными методами – такими, которые создаются с помощью директив компиляции НаСервереБезКонтекста, НаКлиентеБезКонтекста, НаКлиентеНаСервереБезКонтекста.

Наверное, вы уже догадались, что здесь есть подвох – не бывает у нас НаКлиентеБезКонтекста. Или бывает?

На самом деле наш маг-волшебник 1С знает, что такое бывает. Правда, это недокументированная возможность, и для этого нужно использовать директиву компиляции &Клиент, которая очень похожа на инструкции препроцессора:

#Если Клиент Тогда

…

#КонецЕсли

В случае, если код обернут в такую конструкцию, он компилируется только на клиенте.

Директива компиляции &Клиент работает на клиенте без контекста. Можно было бы сделать и нормальную &НаКлиентеБезКонтекста, но наш волшебный маг любит сложности и любит ставить в тупик всех тех, кто будет потом читать этот код.

 

Оказывается, директивы компиляции взаимозаменяемы с инструкциями препроцессора. Можно писать и так, как слева, и так, как справа.

Можете попробовать провести эксперименты, посмотреть, что будет – это очень интересно, иногда даже можно вставлять несколько директив компиляции на один метод, можете попробовать.

 

РеквизитФормыВЗначение

 

 

Следующий интересный пример я захотел показать, потому что он меня прямо иногда подбешивает.

У нас есть метод РеквизитФормыВЗначение – он создаёт из текущей формы объект, к которому эта форма подвязана, и помещает в этот изолированный объект все реквизиты из формы.

И потом этот изолированный объект можно как-то менять и вызывать его методы. При этом никакие реквизиты этого объекта не перенесутся на форму, пока мы не используем там другой парный метод. Получается, что этот изолированный объект мы можем менять, как хотим, и потом его просто закрыть.

На слайде – пример с табличной частью: мы добавляем в новый изолированный объект строчку, и она не появляется на форме.

 

Но, когда дело касается именно списка значений, поведение другое – мы создаём изолированный объект, добавляем в список значений строчку, и эта строчка появляется и на форме. Даже если мы не переносим данные из объекта обратно в форму.

 

Таким образом мы, например, можем создать два изолированных объекта, каждый поменять, а потом сравнить все списки в первом объекте, во втором объекте и на форме.

Они окажутся одинаковыми – это один и тот же список. И это логично, потому что 1С при создании объекта переносит значение списка значений по ссылке – у нас на форме ссылка на один список, и эта же ссылка перенеслась в новый изолированный объект. Об этом можно догадаться. Но до тех пор, пока ты с этим не столкнешься, ты, скорее всего, об этом не подумаешь.

И если тебе важно где-то менять список в изолированном объекте, не меняя его на форме, ты можешь столкнуться с таким нюансом и удивиться.

 

Максимальное значение в массиве

 

Следующие примеры – про то, как ведут себя конструкторы или методы платформы, когда ожидают увидеть какие-то параметры, но мы им передаем на вход не совсем то, которые они ожидали или не совсем того диапазона. В таких случаях тоже можно получить очень странный результат.

Например, у нас есть конструктор Новый Массив, в который можно передать количество элементов создаваемого массива.

Сделаем обработку, которая выводит:

  • размер создаваемого массива – то количество параметров, которое мы передали в конструктор;

  • и размер созданного массива – то, что у нас в результате получится.

Проведем эксперименты, на что вообще готов Новый Массив.

 

Сначала кинем в массив 2 миллиарда записей – на форме мы видим, что размер созданного массива 2 миллиарда, все правильно.

Но если кинем 3 миллиарда, то получим ошибку – исключение «Недопустимое значение параметра». Видимо, мы нащупали какое-то ограничение по количеству элементов в массиве.

Но, допустим, передадим туда 5 миллиардов. И получаем 705 миллионов. С копейками.

Почему так? Не совсем понятно. Вроде мы хотели 5 миллиардов, а получили 705 – не совпадает.

 

На самом деле, методом тыка можно проверить и увидеть, что, оказывается, есть ограничение – 2 147 483 647. Это число напоминает некий тип данных в C++.

Видимо, когда мы превышаем границы этого числа, конструктор массива перестает работать. Или перестает работать корректно.

Например, если мы увеличим это число в 2 раза, накинем еще несколько цифр, размер массива пойдет снова с 0 – мы передаем 4 миллиарда, а получаем единичку. Передаем 5 миллиардов, а получаем миллиард.

Таких странностей в платформе 1С много. Но в массиве мы просто превысили какое-то слишком большое число, такой массив в принципе создавать не имеет смысла.

 

Генератор случайных чисел

 

А вот, например, генератор случайных чисел: у него есть классная особенность, которая дает еще и новую функциональность.

Обратите внимание, при вызове его метода СлучайноеЧисло() нужно передать два параметра – нижнюю и верхнюю границы. Согласно справке, оба параметра у нас целые – чтобы получить число, нужно передать целый параметр.

Но мы все-таки можем передать дробные. Кто нам мешает? Давайте попробуем.

В принципе, туда действительно попасть могут дробные числа, если они содержатся, например, в каких-то переменных, а мы их туда уже дальше передаем. Ну, алгоритм посчитал и случайно насчитал дробное число.

Оказывается, что если передать дробное число, то мы таким образом регулируем частоту выпадания целых чисел на границах этого числа. Например, если мы передадим в качестве нижней и верхней границы 0 и 0.1, мы регулируем частоту выпадания 0 и 1.

Чем меньше у нас дробное число, тем меньше шансов, что генератор случайных чисел выдаст 1. Это наглядно показано на скриншотах.

 

Дата()

 

Еще один пример – метод, который возвращает дату. Мы в него можем передать строку со значениями, соответствующими дню, месяцу, году и так далее – они должны быть указаны в строгом порядке.

Но что, если мы будем туда передавать какие-то вообще необычные числа, не подходящие для даты?

Оказывается, метод сработает и даст вполне рабочие даты, просто неожиданные для нас. Например, дату, где все нули, превратит в 30 ноября 2-го года.

Хотя примеры на слайде изначально странные и непонятные, они рабочие – если на вход методу «Дата» попадет такая строка, метод сработает, исключения не будет. Поэтому прежде чем в этот метод передавать какое-то строковое значение, стоит подумать – действительно ли вам нужно получать такие даты?

Обратите внимание на четвертый, предпоследний, пример – если мы передадим 1 марта 2022 года с минус 1 секундой, мы получим конец последнего дня февраля. Это интуитивно понятно, и мы можем примерно догадаться, что 1С сначала создает 1 марта 00:00, а потом вычитает из этой даты 1 секунду, и мы получаем 28 февраля 23:59. Таким образом мы можем узнать последний день февраля в этом году – естественно, с учетом високосных месяцев.

Еще мне нравится последний пример – 256 января. Что это за дата? 1С знает, что в 2022 году 13 сентября был днем программиста. Естественно, мы опять можем догадаться, как это работает: до тех пор, пока числа попадают в месяц, все хорошо. А если у нас там уже 32 января, это будет 1 февраля, и 1С будет продолжать прибавлять все эти дни.

Таким образом можно и вычитать – и дни, и года, и месяцы, и секунды – и прибавлять, и так далее. И все это 1С с удовольствием нам конвертнёт в дату.

 

 

Дату еще можно задать константой с одинарными кавычками. Но иногда прям подбешивает, что сходу не вспомнить – какой вообще порядок этих чисел? Года, месяца, дня и так далее?

Оказывается, если помнить этот порядок, в одинарные кавычки можно запихнуть любой текст – главное, чтобы он содержал даты в нужном порядке. Тогда эта строчка корректно преобразуется в дату.

 

Кстати, на этом слайде показана еще одна особенность, которая вроде и документирована, но о ней мало кто помнит.

Потому что последняя дата в 1С не 3999, а 9999. Просто 3999 – максимальная, которая запишется в базу данных, но в коде мы можем оперировать и такими датами.

И еще в справке указано, что дата хранится с дробными значениями – например, если к дате прибавить 0.1, визуально она для будет такая же, но по значению уже не будет равна предыдущей, будет содержать дополнительные миллисекунды.

 

ОписаниеТипов как «костыль» для создания типов

 

Мы подошли к самому интересному пункту. Оказывается, описание типов – это классный и универсальный инструмент для создания новых объектов.

Например, у нас здесь есть функция НовыйОбъект, которая просто использует ОписаниеТипов и метод ПривестиЗначение().

 

И дальше мы попытаемся использовать эту функцию для создания структуры, массива, таблицы и дерева значений. Причем не только. И все это – при помощи описания типов.

Например, мы можем создать ДанныеФормыКоллекция, которую так просто нельзя создать – для этого нужно иметь форму, получить ее реквизит и так далее. Здесь мы можем это делать вне формы.

Таким же образом мы можем создать ДинамическийСписок, ГруппуФормы, HTTPОтвет, HTTPСервисЗапрос, РезультатЗапроса, который тоже нельзя просто так создать.

С этим всем можно поиграться, посмотреть, как платформа будет себя вести. Скажу сразу – странно. В некоторых моментах она будет просто падать, завершая сеанс с очень странным описанием ошибок.

Но это можно взять на вооружение в качестве эксперимента и вынести из этого какую-то пользу.

На слайде показаны полезности, как это можно использовать на практике.

  • Во-первых, можно создать независимую табличную часть, которая будет вообще вне объекта, при этом объект создаваться не будет.

  • Можно сделать какую-то обработку, накидать шаблоны табличных частей, а потом на их основании быстро создавать таблицы значений нужной структуры (вторая строчка).

  • Мы можем создать менеджер документов – помните, у нас была проблема, когда мы переопределили документы табличной частью? Мы можем создать свой менеджер, и он будет абсолютно такой же, как и стандартный. Это, скорее всего, синглтон-объект.

  • Также мы можем создать менеджер конкретного объекта.

  • И можем получать значения по умолчанию, потому что они у разных системных перечислений разные – где-то «Авто», где-то «Равно», где-то «Пустая», где-то «Используется» и так далее.

Т.е. если нам нужно срочно получить какое-то значение по умолчанию для нужного типа, мы можем использовать функцию НовыйОбъект, которая просто использует ОписаниеТипов.

 

Таблица значений и дерево значений на клиенте

 

 

Ну и последняя фишечка – таблица и дерево значений на клиенте.

Оказывается, таблица значений в тонком клиенте существует и полноценно работает – можно добавлять колонки, индексы, сортировать и т.д.

 

Даже можно поместить ее в переменную – естественно, клиентскую. И в коде, на протяжении всего сеанса работы к ней обращаться – по кнопочкам добавлять значения, где-то там что-то искать, хранить некий кэш, например.

Точно так же можно работать и с деревом значений.

 

И все-таки это лучше не использовать

 

Но почему это нельзя использовать, как бы вам этого ни хотелось?

Напомню вам, у нас есть прекрасный пример – оператор «вопросительный знак», который очень быстро забанили, когда статья про него набрала популярность.

Он давал нам много возможностей, но его забанили, и обратно этих возможностей нам, естественно, не дали, поэтому код не перепишешь.

Но, слава Богу, «вопросительный знак» никто и не использовал, потому что это слишком уж эзотерическое программирование.

Но предыдущие примеры наверняка кто-то использует. И, если вы это делаете, подумайте хорошенько – может быть, вам сразу заранее переписать код и не слушать того вредного мага-программиста?

Кстати, давайте все-таки вернёмся к нему.

 

Выводы

 

Всё это – маги 1С. Они специалисты и профессионалы в своём деле.

 

 

Но как они стали такими? Чтобы узнать все то, о чем они рассказывают на конференциях и в своих статьях на Инфостарте, им пришлось столкнуться с магом, который постоянно вставлял им палки в колеса и подставлял.

Именно этот маг – руками других программистов, ведь мы же не совершаем ошибок – и помогал нашим магам 1С расти профессионально и быстрее выявлять ошибки. Возможно потому, что он уже сталкивался с теми или иными нюансами, которые я показал, или с какими-то другими.

Благодаря нему они становились сильнее как специалисты.

 

 

Так что мы можем сказать этому магу даже спасибо. Ведь он на самом деле очень добрый, он помогает нам расти и становиться лучше.

Ну или ему просто нравится всё разрушать. Его же не спросишь)

 

*************

Статья написана по итогам доклада (видео), прочитанного на конференции Infostart Event.

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7982    bayselonarrend    20    

156

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    6252    dsdred    18    

80

Инструментарий разработчика Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Расскажу про разработку расширения-фреймворка на 1С на примере проекта "Расширенный глобальный поиск", про нюансы, с которыми столкнулся, и способы их обхода.

20.02.2024    5523    SeiOkami    5    

59

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    18914    YA_418728146    26    

72

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    15131    YA_418728146    7    

169
Отзывы
10. SeiOkami 3521 06.10.23 15:02 Сейчас в теме
Больше всякой магии можно увидеть в телеграм канале: https://t.me/JuniorOneS
Остальные комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. maksa2005 551 06.10.23 10:54 Сейчас в теме
Оказывается, если помнить этот порядок, в одинарные кавычки можно запихнуть любой текст – главное, чтобы он содержал даты в нужном порядке. Тогда эта строчка корректно преобразуется в дату.

Забавно)
2. maksa2005 551 06.10.23 10:56 Сейчас в теме
Картману снится, что он маг в 1с:
— Да, я программист! программист!
Просыпается:
— А чёрт, я никто!
g_b; Yakuskenergo; DrAku1a; +3 Ответить
3. Bit_Man 06.10.23 11:55 Сейчас в теме
"Таблица значений и дерево значений на клиенте" вот это крутяк.
Было бы не плохо, если бы фичу "легализовали" ))
mrChOP93; TerveRus; Дмитрий74Чел; PowerBoy; +4 Ответить
6. PowerBoy 3418 06.10.23 12:44 Сейчас в теме
(3) Все эти годы она была там, а от нас ее просто прятали :)
DrAku1a; mrChOP93; TerveRus; +3 Ответить
23. tindir 06.10.23 16:07 Сейчас в теме
(3)
"легализовали"

Ну их нафик! Дай адынэс-слесралю гонять таблицу значений между сервером и клиентом, он ведь вообще перестанет думать и будет результат запроса на 6кк-100ккк строк отдавть в клиента или складывать на сервер. "И пусть весь мир падажжжжёт".
24. SeiOkami 3521 06.10.23 16:15 Сейчас в теме
(23) справедливости ради, 1Сник и так это делает. Гоняет ДанныеФормыКоллекция. Или делает бессмысленные превращения таблицы в массив структур (для чего БСП услужлево предоставляет удобный метод)
DrAku1a; zqzq; PowerBoy; +3 Ответить
25. tindir 06.10.23 16:27 Сейчас в теме
(24)
(24)
БСП услужлево предоставляет удобный метод


Ага. Знаю эту штуку. Но если человек не 1слесраль, то он обратит внимание, что этот метод определен с "Служебном" модуле для рег.отчетности и наверное он "подумает", а нужно ли мне использовать этот метод в ПриОткрытии_наКлиенте() модуля формы (и это не моя выдумка, у меня в базе "коллега" в этом методе в форму документа "загружает" весь "взаиморосчет" в три дерева). За ДФК не скажу, свечку не держал. Есть мысль что оно там аккуратно ползает.
26. SeiOkami 3521 06.10.23 16:35 Сейчас в теме
(25) может в служебном тоже есть, но и в ОбщегоНазначения в области ПрограммныйИнтерфейс )
Прикрепленные файлы:
VyacheslavShilov; +1 Ответить
27. tindir 06.10.23 16:52 Сейчас в теме
(26)
"ооооохххббб....." - это фсе что могу сказать по этому поводу =)

Ну, не мне "зауралчорту" судить логику в ЕРП, но это сложно понимаемо. Может вы с высоты опыта можете подкинуть мысль зачем?

По собственным ощущениям "прекрасного", когда руки "пихают невпихуемое" - пришло время сходить покурить и переосмыслить "ошибки молодости". И обычно этот ритуал помогает сделать лучше, быстрее и частенько удобнее для пользователя.
41. SeiOkami 3521 09.10.23 17:09 Сейчас в теме
42. tindir 10.10.23 04:31 Сейчас в теме
(41)
"ооооооххххбббб" - это все что я могу добавить =)
На работе ютуп забанен, ознакомлюсь позже. Но очень расчитываю. что вы обратили внимание в ролике на то что гонять гигатаблицы харам.
43. SeiOkami 3521 10.10.23 06:25 Сейчас в теме
4. johnnyshut23 75 06.10.23 12:36 Сейчас в теме
Детский сад какой то... ИМХО
kuzyara; aka Любитель XML; svmix; +3 Ответить
5. ZOMI 141 06.10.23 12:42 Сейчас в теме
7. Vasvas05 27 06.10.23 14:19 Сейчас в теме
8. PavelGlazachev 06.10.23 14:51 Сейчас в теме
Вот эта магия у меня убила кучу часов, в сложном парсере эту ошибку обнаружить было - АД
Что вернет код в каждом из вариантов?

// Вариант 1
Позиция = СтрНайти("Привет", "П");
Сообщить(Позиция );

// Вариант 2
Результат = СтрНайти("Позиция ", Неопределено);
Сообщить(Позиция );

// Вариант 3
Результат = СтрНайти("Позиция ", "");
Сообщить(Позиция );
Показать
SeiOkami; +1 Ответить
9. SeiOkami 3521 06.10.23 14:57 Сейчас в теме
(8) Да, смешное поведение) В эту коллекцию можно ещё добавить Null
Правда тут перепутаны Результат и Позиция
12. PavelGlazachev 06.10.23 15:17 Сейчас в теме
Да, спасибо, чуть торопился и что-то не так нарефакторил, вот так должно быть:

// Вариант 1
Позиция = СтрНайти("Привет", "П");
Сообщить(Позиция);

// Вариант 2
Позиция = СтрНайти("Привет", Неопределено);
Сообщить(Позиция);

// Вариант 3
Позиция = СтрНайти("Привет", "");
Сообщить(Позиция);
Показать
10. SeiOkami 3521 06.10.23 15:02 Сейчас в теме
Больше всякой магии можно увидеть в телеграм канале: https://t.me/JuniorOneS
11. naf2000 06.10.23 15:04 Сейчас в теме
в копилку, поведение понятное, но надо знать:
&НаКлиенте
Процедура Команда1(Команда) 
	Массив1 = Новый Массив;
	ИзменимМассивНаКлиенте(Массив1);
	Сообщить(Массив1.Количество());		// 1
	Массив2 = Новый Массив;
	ИзменимМассивНаСервере(Массив2);	// 0
	Сообщить(Массив2.Количество());
КонецПроцедуры

&НаКлиенте
Процедура ИзменимМассивНаКлиенте(Знач Массив)
	Массив.Добавить();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ИзменимМассивНаСервере(Знач Массив)
	Массив.Добавить();
КонецПроцедуры
Показать
13. PavelGlazachev 06.10.23 15:19 Сейчас в теме
(11) Не верю 😂 Сейчас проверю
14. PavelGlazachev 06.10.23 15:24 Сейчас в теме
(11) И правда, это значит знач на клиенте для коллекций некорректно отрабатывает? Со структурой таже тема

&НаКлиенте
Процедура Команда1(Команда) 
    Структура = Новый Структура;
    ИзменимМассивНаКлиенте(Структура);
    Сообщить(Структура.Количество()); // 1        
    Структура2 = Новый Структура;
    ИзменимМассивНаСервере(Структура2);    
    Сообщить(Структура2.Количество()); // 0         
КонецПроцедуры

&НаКлиенте
Процедура ИзменимМассивНаКлиенте(Знач Структура)
    Структура.Вставить("Привет", "Омлет");
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ИзменимМассивНаСервере(Знач Структура)
    Структура.Вставить("Привет", "Омлет");
КонецПроцедуры
Показать
16. SeiOkami 3521 06.10.23 15:41 Сейчас в теме
(14)
Про эту тему есть ещё такая викторина)
https://t.me/JuniorOneS/569
Прикрепленные файлы:
TerveRus; +1 Ответить
15. PavelGlazachev 06.10.23 15:28 Сейчас в теме
Со строкой всё ок:

&НаКлиенте
Процедура Команда1(Команда) 
    Строка = "Привет";
	ИзменимМассивНаКлиенте(Строка);
    Сообщить(Строка); // Привет        
    Строка2 = "Привет2";
    ИзменимМассивНаСервере(Строка2);    
    Сообщить(Строка2); // Привет2         
КонецПроцедуры

&НаКлиенте
Процедура ИзменимМассивНаКлиенте(Знач Строка)
    Строка = Строка + " омлет";
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ИзменимМассивНаСервере(Знач Строка)
    Строка = Строка + " омлет";
КонецПроцедуры
Показать
18. naf2000 06.10.23 15:47 Сейчас в теме
(15) со строкой, числами и вообще атомарными не ссылочными данными не пройдёт. Про стройку можно конечно пофилософствовать
17. naf2000 06.10.23 15:44 Сейчас в теме
(14) это значит что на клиенте передается ссылка, назад не возвращается. Но объекта и не надо. Он будет изменён.
А при передаче на сервер передаётся копия массива и назад не возвращается. Поэтому все что сделано на сервере - останется на сервере.
19. PavelGlazachev 06.10.23 15:47 Сейчас в теме
(17) Ну это же явно ошибка? Если я использую "Знач" значит я намеренно хочу работать с копией данных, и не важно строка это или коллекция
20. naf2000 06.10.23 15:49 Сейчас в теме
(19) нет. Почитайте про ссылочные данные.
PavelGlazachev; +1 Ответить
21. PavelGlazachev 06.10.23 16:02 Сейчас в теме
(20) Спс, прочитал на ИТС https://its.1c.ru/db/metod8dev/content/2606/hdoc , я был не прав, соз знач, действительно тоже просто передается копия ссылки, копия данных в памяти не создается. Буду знать
22. SeiOkami 3521 06.10.23 16:05 Сейчас в теме
(19) "знач" не создаёт копию данных) Это популярное заблуждение, которое появилось из-за размытости справки

Знач говорит, что 1С создаст новую (независимую от вызывающего кода) переменную и поместит в неё значение из твоей переменной. А в твоей переменной лежит ссылка на структуру в памяти.

Т.е. платформа берёт твою переменную. Там лежит ссылка ( путь как url ). Создает новую переменную. И помещает в неё тот же url на структуру


Процедура Процедура1()
  
  //У нас есть структура, ссылка на которую лежит в нашей личной переменной
    Структура = Новый Структура("А");
  
  //Мы передаем ССЫЛКУ на нашу структуру в метод
  Процедура2(Структура);
                                       
  Сообщить(Структура.Количество()); //2

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

Процедура Процедура2(Знач Структура)
  
  //Знач создало новую переменную 
  //и поместила в неё ссылку на ТУ ЖЕ структуру
  
  //Здесь меняется свойство общей структуры
    Структура.А = 1; 
  
  //Здесь в общую структуру добавляется свойство
    Структура.Вставить("Б");
  
  //А здесь мы ТЕКУЩУЮ ПЕРЕМЕННУЮ перезатираем новой структурой
  //Входящая структура при этом не обнуляется
  //Потому что наш параметр ЗНАЧ, 
  //  а значит это наша личная ПЕРЕМЕНАЯ, в которой мы можем хранить что угодно
    Структура = Новый Структура;

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

Показать
28. naf2000 06.10.23 17:07 Сейчас в теме
(22) да, но нет)) смотрите разное поведение в (11)
29. SeiOkami 3521 06.10.23 17:12 Сейчас в теме
(28) а здесь всё логично)
Между сервером и клиентом не бывает общих ссылок. Платформа вынуждена сделать копию и передать. Но она делает копию даже без Знач. В любом случае платформа копирует объект для передачи на сервер. А вот вернёт уже его обратно зависит от Знач


Попробуйте решить (16) и прочитайте там пояснение - очень интересное поведение. И там рядом в канале как раз викторины про это
30. naf2000 06.10.23 19:13 Сейчас в теме
(29) (16) согласен, по круче будет
Но что-то осталось чувство неудовлетворённости.
1. Где это описано в стандарте?
2. Зачем такая реализация языка?
31. Alxby 1116 06.10.23 19:56 Сейчас в теме
Таблица значений на клиенте:
Прикрепленные файлы:
SeiOkami; +1 Ответить
32. naf2000 06.10.23 20:53 Сейчас в теме
&НаКлиенте
Процедура Команда1(Команда) 	 
	А = Новый Структура("Х");
	А.Х = А; 
	Тест(А);
КонецПроцедуры

&НаСервере
Процедура Тест(Структура)
КонецПроцедуры
Показать

Этот простой код валит 1С. Оно и понятно, оно на сервере пытается воссоздать копии данных, но уже без цикличности. Бесконечная рекурсия...
user611208_ilnur.shay; +1 Ответить
33. Alxby 1116 06.10.23 21:10 Сейчас в теме
(32)Указанная в (31) функция как раз и позволяет найти такие проблемы
34. sandr13 35 07.10.23 09:27 Сейчас в теме
Весьма занимательно. Спасибо за статью. Плюсую.
35. ixijixi 1923 07.10.23 12:47 Сейчас в теме
Виталий опять раскопал какую-то одинэсовскую хтонь)) За что ему лучи респекта!
36. SlavaKron 07.10.23 15:24 Сейчас в теме
Вашу функцию НовыйОбъект, использующую ОписаниеТипов, можно заменить на ключевое слово "Новый", а в качестве параметра указать имя типа:
Менеджер = Новый ("РегистрСведенийМенеджер.МойРегистрСведений");
ДокументОбъект = Новый("ДокументОбъект.МойДокумент");
ОбъектВнешнейОбработки =Новый("ВнешняяОбработкаОбъект.ВнешняяОбработка1");

Кстати, последний вариант позволяет получить объект внешней обработки в модуле формы при безконтекстном вызове.
37. SeiOkami 3521 07.10.23 16:39 Сейчас в теме
(36) если я правильно помню, то Новый() не все типы позволяет создавать. Например, таблицу значений на клиенте
38. SlavaKron 09.10.23 09:43 Сейчас в теме
(37) Так на клиенте таблица значений и не живёт. На сервере создаётся. Поведение ровно такое же как у метода ПривестиЗначение.
Естественно, это можно поправить обычной функцией Формат()
Лучше XMLСтрока.
39. SeiOkami 3521 09.10.23 09:44 Сейчас в теме
(38)
Поведение ровно такое же как у метода ПривестиЗначение

ПривестиЗначение создает ТЗ на клиенте, а Новый - нет
40. SlavaKron 09.10.23 10:03 Сейчас в теме
(39)
ТЗ на клиенте
И правда, удивительно.
44. SeiOkami 3521 10.10.23 21:51 Сейчас в теме
(40) ещё при помощи описания типов можно даже Обещание создать... Которое никогда не дождёшься, но всё же)
45. user1950534 11.10.23 16:41 Сейчас в теме
огонь статья, про даты в миллисекундах откровенно порадовало, не знал, спасибо!
46. dsdred 3640 25.10.23 08:16 Сейчас в теме
Меня лично удивляет тот факт, что 1с дает в GET методы вложить тело запроса, Хотя в других языках это приводит к ошибке, так как GET не должно содержать тело запроса.
Как то на проекте отчитывал франчей за то, что они в GET помещали json со словами: -Работает же.
Да, работает, а когда этот баг\фичу вылечат тогда что?
Все переделывать на POST в судорогах.
47. user1826876 14.11.24 07:22 Сейчас в теме
Странно, за 23 года в 1С ни разу такие траблы не встречались, наверное потому что я делаю все правильно и в голову не приходит извращаться, а может мозг просто на корню обходит эти места. А вот из за невнимательности при копировании частей кода бывает, но это уже другая тема.
48. Serg2000mr 691 17.11.24 23:18 Сейчас в теме
Добавлю в раздел 1С-ной магии строку из функции БСП ОбщегоНазначения.ВерсияРежимаСовместимости()

// РежимСовместимости = "Версия8_3_24"

ВерсияРежимаСовместимости = СтрСоединить(СтрРазделить(РежимСовместимости, 
			СтрСоединить(СтрРазделить(РежимСовместимости, "1234567890", Ложь), ""), Ложь), ".");


Шутка конечно, но все же... ))
Оставьте свое сообщение