Описание формата внутреннего представления данных 1С в контексте обмена данными

Публикация № 1116103

Разработка - Практика программирования

интеграция обмен формат ЗначениеВСтрокуВнутр ЗначениеИзСтрокиВнутр

Фирма 1С не рекомендует использовать внутреннее представление данных для любых целей, которые отличны от обмена с 1С:Предприятием 7.7. Но сама возможность заглянуть на "внутреннюю кухню" платформы с помощью функций ЗначениеВСтрокуВнутр(), ЗначениеВФайл(), ЗначениеИзСтрокиВнутр() и ЗначениеИзФайла(), дала возможность сообществу программистов 1С разработать новые приемы разработки и анализа. Так, именно на использовании внутреннего представления был построен алгоритм "быстрого массива", который позволяет практически мгновенно создать массив в памяти на основании строки с разделителями. С помощью разбора внутреннего представления можно "на лету" программным кодом выполнить анализ обычной формы и даже сделать редактор графической схемы. Во внутреннем формате сохраняют свои данные между сеансами различные популярные внешние обработки. А еще это возможность сделать быстрый обмен с внешними системами.
Содержание.

 

Зачем нужна эта статья? 

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

В первых релизах я пробовал обмен сначала с помощью XML, а потом и на JSON. Но слишком много времени уходило на конвертацию. Попробовал вместо типовых функций написать собственный "велосипед" с потоковым парсингом, но и тут получил лишь незначительный выигрыш.

Тогда я вспомнил про внутреннее представление. По моему ТЗ наш сишник сделал задачу парсинга "формата 1С" на расчетном сервере и в результате у нас получилось практически мгновенное превращение расчетного задания в текст для сервера, а затем не менее быстрое превращение результатов расчета в объект, готовый для демонстрации логисту на карте.

К сожаления, я тогда не сохранил свои наработки, так как посчитал, что у нас весьма экзотический случай и ценность для других данной темы не высока. И был крайне удивлен, когда на днях на Toster.ru (сайт вопросов-ответов) один php-программист попросил помощи с парсингом формата 1С. Внезапно оказалось, что:

  1. До сих пор появляются задачи обмена именно в "формате 1С",
  2. До сих пор отсутствует документация, которая может помочь специалистам, не знающим внутреннюю кухню платформы 1С.

 

Общие правила и Рекомендации.

Строка внутреннего представления данных, получаемая с помощью ЗначениеВСтрокуВнутр() или ЗначениеВФайл() - это текст, обычно в формате UTF-8. Отличительная особенность от других текстовых форматов - синтаксис фигурных кавычек. Описание данных, которые представлены внутренним форматом 1С, начинается с открывающейся фигурной скобки "{" и заканчивается закрывающейся фигурной скобкой "}". Содержимое между фигурными скобками - это инструкции парсеру данных (далее - параметры). Если параметров больше одного, то они разделяются символом запятой. Первый параметр - это всегда один символ признака типа в двойных кавычках. Остальные параметры - это или уточнение типа, или указание на количество элементов, или указание на конкретные элементы из множества, или описание значения свойств, или другие инструкции парсеру по сборке.

По моему опыту, для полноценного обмена вполне достаточно описать такие типы как Число, Строка, Дата, Булево, Массив, Соответствие и Неопределено. Эти простые типы, которые интуитивно понятны современным системным и веб-программистам, в которых те увидят аналогии с базовыми типами в своих языках. Тип Структура - это частный случай Соответствия и с точки зрения внутренней структуры они полностью идентичны, а потому я его не рекомендую. СписокЗначений, ТаблицыЗначений и особенно ДереваЗначений - будут мало интересны из-за своей направленности на интерактивную работу с пользователем, а потому имеющие сложную внутреннюю структуру, которую запросто можно повторить многомерным Массивом или Массивом Соответствий. Ссылочные типы я бы тоже не рекомендовал использовать из-за избыточности представляемой информации - те же код/номер или УИД из ссылки будут намного компактнее.

Важные замечание из моего опыта парсинга:

  1. Регистр символов для обозначения типов (первый параметр) имеет важное значение!
  2. Игнорируются все пробельные символы (пробелы, табуляции, переносы строк) в произвольных местах между фигурными скобками и параметрами - т.е. руки развязаны и для эстетов, и для любителей покомпактнее.
  3. Выражения в неправильном формате, но с правильной структурой (ошибочный тип или идентификатор) распознаются как Неопределено!
  4. Нарушение структуры или неправильные типы параметров на предопределенных позициях приводят к выводу ошибки: "Ошибка преобразования: Ошибка формата потока"
  5. Лишние параметры игнорируются и не считаются нарушением структуры. Для примера {"N", 5, "S", "Test"} - это все равно будет число 5.

 

Примитивные типы.

Тип Шаблон Описание типа и формат значения Примеры
Null {"L"} Без значения. Символизирует пустые значения, полученные из запроса как результат соединения или обращения к вложенным полям пустых ссылок через точку. {"L"}
Неопределено {"U"} Без значения. Символизирует неинициализированные переменную или свойство объекта составного типа. {"U"}
Число {"N",<?>} Тип для описания вещественных чисел. Во второй позиции представления находится число в десятеричной системе счисления. При наличии дробной части разделителем выступает символ точки. {"N", 3.14}
{"N", 777}
Строка {"S","<?>"} Строковое значение заключается в двойные кавычки. Символы экранирования не используются за исключением двойного вывода самой двойной кавычки, если она должна быть в строке. {"S", "тест"} = тест
{"S", " ""} "} = "}
Булево {"B",<?>} Для False/Ложь значение равно 0, а для True/Истина будет равно 1 {"B", 0}
{"B", 1}
Дата {"D",<?>} Значение даты указывается с точностью до секунды в формате YYYYMMDDhhmmss. В 1С пустая дата - это 1 января 1 года н.е. {"D",00010101000000}  = пустая дата
{"D",20190830203450}  = 20:34:50 30 августа 2019 года

 

Примечание 1. Еще раз обращаю внимание на замечания из предыдущего пункта. Так при парсинге из выражения {"N" , 7     } - мы получаем цифру 7, но если напишем {"n",7} - то в результате будет значение Неопределено!

Примечание 2. С точки зрения логики внутреннего формата к примитивным типам так же относятся Типы (идентификаторы классов данных). Описание Типа состоит из двух параметров - "T" и внутреннего идентификатора. Примеры: тип Строка = {"T",9b6abf8b-0173-48e5-b0a0-83b21fcf63c5}, тип Число = {"T",b0be78f2-0ee6-4d31-a3bb-77dd32ba5bec}, тип Массив = {"T",51e7a0d2-530b-11d4-b98a-008048da3034}.

 

Коллекции.

Чтобы описать коллекцию значений, необходимо в качестве первого параметра указать символ типа "#", а вторым параметром записать идентификатор типа. Для коллекций (также как и для Ссылок, Объектов, Списков, Выборок и так далее), в качестве идентификатора используется 32-разрядное 16-ричное число. Регистр для символов A-F (цифры с 10 по 15) не имеет значение - хоть большие и маленькие вперемешку. Но важно наличие разделение дефисами на 5 групп символов по правилу 8-4-4-4-12 и отсутствие пробельных символов внутри идентификатора - нарушение этих правил приводит к ошибке потока.

Для коллекций значений предопределены (со времен 7.7, а может даже раньше) следующие идентификаторы:

Тип Идентификатор
Массив 51e7a0d2-530b-11d4-b98a-008048da3034
Структура 4238019d-7e49-4fc9-91db-b6b951d5cf8e
Соответствие 3d48feae-a9c6-4c5a-a099-9eb6477630c6
СписокЗначений 4772b3b4-f4a3-49c0-a1a5-8cb5961511a3
ТаблицаЗначений acf6192e-81ca-46ef-93a6-5a6968b78663
ДеревоЗначений e603c0f2-92fb-4d47-8f38-a44a381cf235
ФиксированныйМассив 4500381b-db30-4a10-9db4-990038032acf
ФиксированнаяСтруктура 3ee983d7-ace7-40f9-bb7e-2e916fcddd56
ФиксированноеСоответствие 220455ea-6c85-4513-996f-bbe79ed07774

 

Примечание. Если заменить символ "#" на "T", то получим вместо объекта значения объект его типа.

 
 Если использовать параметр "T" и идентификатор, то получим значение типа Тип:

 

Массив.

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

Структурно внутреннее описание массива состоит из 3 параметров - "#", 51e7a0d2-530b-11d4-b98a-008048da3034 и содержимого массива в фигурных скобках. Содержимое в свою очередь состоит из количества элементов массива, а потом перечисления этих элементов через запятую, в формате, который соответствует их типу. 

Для пустого массива содержимое будет {0}. Если в массиве только одно число 12, то его содержимое равно {1,{"N",12}}. Эти же примеры полностью: 

  • {"#",51e7a0d2-530b-11d4-b98a-008048da3034,{0}}
  • {"#",51e7a0d2-530b-11d4-b98a-008048da3034,{1,{"N",12}}}

Примечание. Практика показала, что точное указание количества на платформах 8.х не важно. Главное написать в первой позиции описания какое-то целое число равное или больше нулю, а далее платформа будет создавать Массив по фактически перечисленным элементам; и при вызов у нового объекта метода Количество() вернет верное фактическое значение. Указание в позиции количества любого значения кроме положительного целочисленного значения или нуля будет приводить к ошибке чтения потока, а если указать отрицательное число - даже к краху платформы с записью дампа.

 
 Создание Массива (с игнорированием указанного количества)

 

Структура и Соответствие

Структура и Соответствие - это типы, которые позволяют получать некие значения по указанным ключам. Особенностью этих коллекций является то, что это фактически множество пар Ключа и Значения, которые можно обойти с помощью итератора в цикле. Внутреннее представление отражает эту особенность - описание состоит из троих параметров - "#", идентификатора (4238019d-7e49-4fc9-91db-b6b951d5cf8e или 3d48feae-a9c6-4c5a-a099-9eb6477630c6) и содержимого в фигурных скобках. Содержимое в свою очередь состоит из количества пар Ключ-Значение, а потом перечисления этих пар через запятую. Описывается пара Ключ-Значение с помощью фигурных скобок, где указаны через запятую значение Ключа и значение Значения. Пример описания пары Ключ-Значение вида ID=12 имеет вид: {{"S","ID"},{"N","12"}}

Примеры. Пустое соответствие: {"#",3d48feae-a9c6-4c5a-a099-9eb6477630c6,{0}}. Структура с двумя ключами: {"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,{2,{{"S","id_local"},{"N",10}},{{"S","id_global"},{"N",215}}}}

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

 
 Пример создания Соответствия с игнорированием ошибок

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

 

Фиксированные массив, структура и соответствие

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

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

Примечание 1. Все мои замечания относительно количества элементов остаются в силе. Все идентично вплоть до того, что отрицательное количество нормально принимается фиксированными структурой и соответствием, а попытка использовать его для создания фиксированного массива вызывает крах платформы.

Примечание 2. Кстати, на будущее получаем лайфхак. Средствами платформы можно преобразовывать только пары Структура с Фиксированной Структурой и Соответствие с Фиксированным Соответствием. Для остальных комбинаций нужно делать циклы и перекидывать пары Ключей-Значений в новый объект. С помощью внутреннего представления и замены идентификатора можно преобразовать намного быстрее, да еще и вернуть результат в ту же переменную :)

 
 Валидное описание Структуры с легкостью превращаем в описание Фиксированного Соответствия

 

Список значений

Это особый вид коллекции значений, который предназначен для формирования вариантов выбора для элементов форм или может самостоятельно выводится на форму или даже в отдельное окно. Интересно, что один заранее сформированный список значений может использоваться для формирования доступных значений в другом списке значений, который интерактивно редактирует пользователь. Так же с помощью специального объекта ОписаниеТипов можно ограничить диапазон допустимых значений (только справочник Склады, или только справочники Покупатели и Физлица, или только строки и числа с точностью до 2 знака). Еще значения иногда могут иметь вид непонятный для пользователей (к примеру, вложенные массивы или коды операций), то в списке поддерживается отдельное хранение понятного строкового представления. Так же для каждого значения можно назначить вывод пиктограммы (из библиотеки предопределенных или из конфигурации). Для необходимости отметить в списке некоторые из значений предусмотрено дополнительное поле, которое при показе связывается с флажком. Все вышеперечисленные возможности ожидаемо отразились на структуре хранимого значения.

Как и другие коллекции, данная состоит из троих параметров - "#", идентификатора (4772b3b4-f4a3-49c0-a1a5-8cb5961511a3) и содержимого в фигурных скобках. Содержимое списка значений состоит из таких элементов: число 6 (или другое целое число большего значения), идентификатор 1e512aab-1b41-4ef6-9375-f0137be9dd91 (можно любой другой), число 0 (или 1), число 0 (или любое другое целое число), описание перечня элементов списка в фигурных кавычках (см. ниже), описание доступных типов  или можно так {""}, признак наличия ограничивающего списка - 0 если нет и 1 если да. Если есть ограничивающий значения список, то добавляется еще один параметр - описание вложенного списка (то описание, которое начинается с 6).

Описание перечня элементов списка состоит из количества этих элементов (на самом деле подходит любое целое число) и через запятую описание строк списка в фигурных скобках. Строка списка состоит из двух параметров: идентификатор 1e512aab-1b41-4ef6-9375-f0137be9dd91 (если указать другой, то при парсинге этот элемент будет проигнорирован; при этом тот идентификатор, который был ранее после числа 6, может отличаться) и описание элемента списка в фигурных скобках.

Элемент списка состоит из таких параметров: текстовое описание элемента, отметка выбора (0 - нет, 1 - да), полное описание значения (если там был список, то описание начинается с "#"), описание пиктограммы (для пустого значения:  {4,0,{0},"",-1,-1,0,0,""} ). Далее еще могут быть параметры, но их отсутствие ни на что не влияет.

Пример. Если нужно сделать список значений из пары элементов 100 и 200, один из которых с пометкой, то в результате получаем такое описание:

{"#",4772b3b4-f4a3-49c0-a1a5-8cb5961511a3,
    {6,1e512aab-1b41-4ef6-9375-f0137be9dd91,0,0,

    {2,
        {
            1e512aab-1b41-4ef6-9375-f0137be9dd91,
            {"Сотня", 0,  {"N",100},  {4,0,{0},"",-1,-1,0,0,""} }
        },

        {
            1e512aab-1b41-4ef6-9375-f0137be9dd91,
            {"Двести", 1,  {"N",200},  {4,0,{0},"",-1,-1,0,0,""} }
        }
    },

    {""},0}
}
 
 Парсинг примера Списка Значений

 

Примечание. Может показаться, что 1e512aab-1b41-4ef6-9375-f0137be9dd91 из описания строки - это идентификатор строки списка, но на самом деле идентификатором строки является c27d99e0-2f53-11d5-a3be-0050bae0a776. Что же означает первый идентификатор (который после числа 6), я так и не смог выяснить.

 
 Тип строки списка значений

 

Таблица значений

Особенность этого вида коллекций заключается в наличии колонок. По-умолчанию, в колонку можно писать значения любого типа, но при необходимости можно ограничить допустимые типы. Еще каждой колонке можно назначить заголовок и ширину для красивого вывода на форму или для открытия в отдельном окне. В каждой строке таблицы можно заполнять ячейки соответствующих колонок, а явно неинициализированные ячейки примут значения по-умолчанию для типов своих колонок (если типы не заданы, то будет Неопределено). А еще таблицам значений можно создавать произвольные индексы по колонкам для дальнейшего быстрого поиска/сортировки. Эти особенности отразились на структуре хранимого значения.

Как и другие коллекции, данная состоит из троих параметров - "#", идентификатора (acf6192e-81ca-46ef-93a6-5a6968b78663) и содержимого в фигурных скобках. В содержимом таблицы первым параметром должно быть целое число 9 (на самом деле от 7 и выше), на втором месте блок с описанием колонок, на третьем месте блок с описанием строк, на четвертом месте блок с описание индексов.

В блоке описания колонок первым параметром идет количество колонок (тут важно, чтобы было реальное количество колонок!), а далее через запятую блоки описания конкретных колонок. В блоке описания конкретной колонки пять параметров - порядковый индекс (отсчет от нуля; порядок не обязательно прямой, но далее в описании строк нужно не ошибиться с позицией для размещения значения), внутренний идентификатор колонки по правилу наименования переменных (для обращения из программного кода), описание типа колонки (можно просто {""}), строка с заголовком для вывода на формы, ширина колонки для вывода на формы.

В блоке описания строк сначала идет магическое целое число, которое при значениях меньше 2 не создает строки у результирующего объекта ТаблицаЗначений (а при значениях выше не заметил никаких различий в поведении). Далее вторым параметром идет указание сколько колонок из описанных в блоке колонок требуется взять для создания результирующего объекта (т.е. можно описать больше, но взять не все - и они не будут доступны через свойство-коллекцию Колонки у результирующего объекта); после чего указываются через запятую парами индекс колонки для описания позиции значения из расположенного ниже описания строки и соответствующий ей индекс колонки из описания колонок. Таким образом для одной колонки получим {2,1,0,0,  ; для двух колонок {2,2,0,0,1,1 ; для троих можно так: {2,3,2,2,0,0,1,1 

Примечание. Если напутать порядок индексов для колонок и позиций в данных, то результат будет не совсем ожидаемый (я смог добиться результата, когда у таблицы из троих колонок в коллекции колонок было три идентичных описания, по которым получали одно и тоже значение, но если обратится через индексы, то можем прочитать "скрытые" колонки). Возможно эту фичу можно использовать для быстрого создания таблиц, где разным колонкам нужно дать одинаковое значение, но такую таблицу лучше не редактировать так как тут есть опасность в том, что, изменив значение в одной из колонок, получим изменение в других (разные колонки будут ссылаться на одну и туже ячейку в памяти).

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

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

Третий блок описания таблицы значений - это блок индексов. По моему мнению, тут не нужно заморачиваться. Программист 1С сам должен решать, что делать с полученной из внешнего источника таблицей значений - если там понадобятся индексы, то пусть он их сам создаст. Если же веб-программисту для загрузки на сайт отдали описание с блоком индексов - при написании своего парсинга проигнорируйте тот блок. Блок без индексов выглядит так - {0,0}.

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

{"#",acf6192e-81ca-46ef-93a6-5a6968b78663,
{9,
    {2,
        {0,"Артикул",{""},"",0},
        {1,"Цена",{""},"",0}
    },

    {2,2,0,0,1,1,
        {1,3,
            {2,0,2, {"S","Часы"}, {"N",750.99}, 0},
            {2,1,2, {"S","Кеды"}, {"N",150.99}, 0},
            {2,2,2, {"S","Шапка"}, {"N",200}, 0}
        },
    1,2},

    {0,0}
}}
 
 Парсинг примера Таблицы Значений

 

Дерево значений

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

Как и другие коллекции, данная состоит из троих параметров - "#", идентификатора (e603c0f2-92fb-4d47-8f38-a44a381cf235) и содержимого в фигурных скобках. В содержимом первым параметром должно быть целое число 1 (на самом деле любое, даже отрицательное), на втором месте блок с описанием колонок, на третьем месте блок с описанием строк.

В блоке описания колонок первым параметром идет количество колонок (тут важно, чтобы было реальное количество колонок!), а далее через запятую блоки описания конкретных колонок. В блоке описания конкретной колонки пять параметров - порядковый индекс (отсчет от нуля; порядок не обязательно прямой, но далее в описании строк нужно не ошибиться с позицией для размещения значения), внутренний идентификатор колонки по правилу наименования переменных (для обращения из программного кода), описание типа колонки (можно просто {""}), строка с заголовком для вывода на формы, ширина колонки для вывода на формы.

В блоке описания строк сначала идет магическое целое число, которое при значениях меньше 2 не создает строки у результирующего объекта ДеревоЗначений (тут все как у ТаблицыЗначений). Далее вторым параметром идет указание сколько колонок из описанных в блоке колонок требуется взять для создания результирующего объекта, после чего указываются через запятую парами индекс колонки для описания позиции значения из расположенного ниже описания строки и соответствующий ей индекс колонки из описания колонок (снова все идентично ТаблицеЗначений - подробности смотрите ранее в соответствующем разделе).

После перечисления всех нужных нам колонок открывается новый блок - с содержимым строк. В этом блоке первым параметром снова идет магическое целое число, значение которого ни на что не влияет и может быть даже отрицательным (обычно 1). Вторым параметром блока содержимого строк идет число количества строк - важно указать правильное количество, так как при указании меньшего значения, вы столько и получите, потеряв остальные, а при указании большего числа получите только ошибку формата потока на попытке парсинга такого описания. После числа количества строк через запятую идут блоки самих строк, после которых указываются еще два числа - максимальный индекс использованной колонки и максимальный индекс строки (индексы начинаются с нуля и потому будут меньше количества на единицу) - хотя практика показала, что для корректного парсинга важно просто поставить там хоть какие-то два числа, хоть нули (снова все идентично ТаблицеЗначений).

Блок строки таблицы снова открывает какое-то целое число (значение не важно, как и в ТаблицеЗначений - обычно 2). Вторым параметром указывается индекс строки (практика показала, что этот параметр при загрузке игнорируется - можно хоть одинаковый указать во всех строках). Третьим параметром указывается количество описываемых значений в данной строке - важно, так как количество значений в строке может быть меньше или больше чем колонок (если далее указать не то количество значений как мы тут объявили, то получим ошибку парсинга). После указания количества значений строки идет перечисление этих значений через запятую. Потом идет признак наличия подстрок: 0 - нет подстрок и на том описание блока строки закрывается, 1 - подстроки есть и далее следует еще один параметр с блоком описания этих подстрок.

Пример. На практике все довольно просто. Пусть мы хотим описать состав склада по категориям: у нас есть какие-то запчасти в количестве 1000 штук и бытовая техника из 100 изделий, где 10 видов утюгов, 20 стиральных машин, 30 холодильников и 50 смартфонов, из которых 10 моделей айфонов и 40 - андроидов. Описание дерева значений получается таким:

{"#",e603c0f2-92fb-4d47-8f38-a44a381cf235,
{1,
    {2,
        {0,"Категория",{""},"",0},
        {1,"Количество",{""},"",0}
    },
    {2,2,0,0,1,1,
        {1,2,
            {2,0,2, {"S","Запчасти"}, {"N",1000}, 0 },
            {2,1,2, {"S","Бытовая техника"}, {"N",100}, 1,
                {1,4, 
                    {2,2,2, {"S","Утюги"}, {"N",10}, 0},
                    {2,3,2, {"S","Стиральные машины"}, {"N",20}, 0},
                    {2,4,2, {"S","Холодильники"}, {"N",30}, 0},
                    {2,5,2, {"S","Смартфоны"}, {"N",50}, 1,
                        {1,2,
                            {2,6,2, {"S","iPhone"}, {"N",10}, 0},
                            {2,7,2, {"S","Android"}, {"N",40}, 0}
                        }
                    }
                }
            }
        },1,7
    }
}
}
 
 Парсинг примера Дерева Значений

 

Ссылочные типы.

Если в выгрузке "формата 1С" вам попадается сущность вида: {"#", <идентификатор_1>, <число>: <идентификатор_2>}, то знайте - вам передали значение ссылочного вида, назначение которого ссылаться на конкретное значение в базе данных. Если вы запрашиваете данные по задолженностям, то вам запросто могут выдать таблицу, где вместо кодов клиентов и номеров документов будут именно такие значения.

В представлении ссылочного типа первым идентификатором указывается идентификатор вида данных, который хранится в конфигурации 1С, а второй идентификатор - то указатель внутри таблицы данных, которая связана с указанным видом данных. Еще в представлении есть число - это суффикс физической таблицы, которая создается в СУБД для хранения содержимого данного вида данных.

Сформировать подобное значение можно и без функции ЗначениеВСтрокуВнутр(). Для того нужно выгрузить конфигурацию и выбрать для интересующего вида данных идентификатор для ссылочного типа (там могут быть и другие идентификаторы - объектов, менеджеров, выборок и т.д.). Далее с помощью ПолучитьСтруктуруХраненияБазыДанных() узнаем суффикс. А последний идентификатор получаем из ссылки с помощью метода УникальныйИдентификатор() с последующим преобразование в перевернуты формат (тут подробно про форматы идентификаторов в 1С).

Давайте попробуем получить ссылочное представление для Доллара из справочника Валюты. Начнем с выгрузки конфигурации (стандартная выгрузка в файлы или с помощью v8unpack.exe) и получения идентификатора ссылочного типа справочника Валюты - это 3a87ef2a-9de1-4d34-9e5f-3c8cdf53b3ab

 
 скриншот файла описания справочника Валюты

Далее узнаем, что в СУБД суффикс справочника валют будет 53

 
 скриншот получения суффикса

И узнаем идентификатор из ссылки: 68c80f28-24ce-11e6-8f41-e91b9a8c6dd6 -> 8f41e91b9a8c6dd611e624ce68c80f28

 
 скриншот получения идентификатора из ссылки

В результате получаем конструкцию вида: {"#", 3a87ef2a-9de1-4d34-9e5f-3c8cdf53b3ab,  53: 8f41e91b9a8c6dd611e624ce68c80f28}, верность которой проверяем с помощью ЗначениеИзСтрокиВнутр()

 
 скриншот проверки описания ссылочного типа

 

Заключение.

Я описал далеко не все, что можно представить во внутреннем формате. За рамками статьи остались Запросы, Выборки, Списки, Формы, Графические Схемы, Схемы Компоновки, Элементы Отборов и многое другое. Но я надеюсь, что смог именно для целей обмена дать все необходимые базовые знания по внутреннему формату 1С.

Чтобы любой мог попробовать повторить примеры из статьи, самостоятельно поэкспериментировать (особенно в плане создания таблиц с невидимыми колонками) или проверить валидность результатов выгрузки из внешней системы, я добавляю свою обработку, с которой делал скриншоты для этой статьи. Обработка поддерживает работу в обычном и управляемом интерфейсе. Для демонстрации там уже есть вставка всех популярных типов значений. Результаты парсинга показываются в понятном виде. А если хочется программно создать какой-то произвольный объект и увидеть его представление, то в обработке есть вкладка "Исполняемый код", где нужно установить требуемое значение переменной Значение.

Обработка была проверена в режимах управляемого и обычного интерфейсов на платформе 8.3.15.1565. Но должна работать и на прочих 8.3.* 

 
 Пример проверки данных, которые озадачили PHP-программиста на Toster.ru

Скачать файлы

Наименование Файл Версия Размер
Обработка для изучения формата внутреннего представления данных

.epf 14,23Kb
06.09.19
15
.epf 1.0 14,23Kb 15 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Evil Beaver 6852 07.09.19 09:22 Сейчас в теме
Кто-то наконец уже должен был это задокументировать!
Несмотря на общеизвестность формата и его простоту, до сих пор не было твердой копии описания. Спасибо.

Однако
задачи обмена именно в "формате 1С"
- это как? Почти 2020 год на дворе, Скайнет давно победил людишек, а у нас на полном серьезе требуют обмен в формате сериализации 1С? Поделитесь, зачем? Кому это нужно?
3. Perfolenta 189 07.09.19 12:08 Сейчас в теме
(1) бывает удобно иногда... например, мне однажды понадобилось загрузить для анализа данные из 7.7 в 8, а в 7.7 уже был отчет, внутри которого формировалась ТЗ как раз с нужными данными...
Еще из Native ВК передавать данные в 1с тоже было бы удобно в некоторых случаях...
Если были бы полноценные чтение/запись такого формата во внешнем мире, то пригодились бы при случае...
28. Darklight 24 03.03.20 14:53 Сейчас в теме
(3)Лучше без нужды внутренний формат 1С не трогать. Для взаимодействий между 1С8 и внешними системами (включая ВК) - лучше всё-таки использовать универсальную XML/JSON сериализацию! Это не сложнее, чем во внутренний формат.
4. Dementor 726 07.09.19 15:15 Сейчас в теме
(1)

у нас на полном серьезе требуют обмен в формате сериализации 1С? Поделитесь, зачем? Кому это нужно?

Может так же как в моем случае просто обмен во внутреннем формате быстрее? Или может там такой объем данных, что при записи в JSON/XML оперативки не хватает и сильно свопит? ХЗ, просто есть факт потребности. А если есть потребность, то пусть будет статья.
Fox-trot; +1 Ответить
11. Evil Beaver 6852 09.09.19 11:46 Сейчас в теме
(4) сильно сомневаюсь что формат "скобок" обгоняет по требованиям к памяти, например CSV. Да и Json радикально не сильно тяжелее будет
8. Yashazz 3473 09.09.19 11:03 Сейчас в теме
(1) Знаете, я это в 2008-м задокументировал, и меня забанили на одном замечательном интернет-ресурсе, посвящённом 1С. Да ещё злобно наезжали, что мол, не рекомендует 1С это делать, вот и нехрен делать.
Так что, есть такая документация. У меня на старом харде. 11 лет уже, как есть, и полагаю, мало что с той поры изменилось. А вот желающие прыгать на грабли и огребать за нарушение рекомендаций, смотрю, всё не переводятся) То к скулю напрямую обращаются, то во внутренний формат лезут...
Serj1C; Evil Beaver; +2 Ответить
15. Dementor 726 09.09.19 15:18 Сейчас в теме
(8) спасибо за мнение. Но есть такое понятие как "целевая аудитория", к которой вы просто не относитесь. Лично для меня было интересно пройтись по недокументированному "минному полю" - узнал некоторые интересные вещи о платформе.

P.S. О том, что 1С не рекомендует использовать данный механизм я сам написал в статье и тем самым предупредил читателей.
P.S.S. Тут не "замечательный интернет-ресурс", так как моя статья успешно прошла премодерацию. Можно выдыхать :)
WellMaster; +1 Ответить
2. for_sale 815 07.09.19 10:10 Сейчас в теме
Не совсем понял посыл статьи, кроме общего описания формата. Но, вдохновлённый фразой "быстрый массив", решил проверить на одном месте в моём коде, где несколько десятков тысяч строк сохраняются в джейсон, а потом - в файл, и, соответственно, обратно извлекаются по надобности.

В общем, извлечение джейсона (стандартными средствами платформы) такого объёма заняло 5 секунд, ЗначениеИзСтрокиВнутр - 12 секунд.
Drivingblind; AllexSoft; fomix; +3 Ответить
21. fomix 26 11.09.19 11:30 Сейчас в теме
(2) Что JSON, что XML (он же внутр.формат) - суть не важно, все равно и то и другое избыточно по составу. Другое дело скорость выгрузки из 1С всего этого бреда! А тут еще попутно надо #С-нику или PHP-шнику объяснять что и как в 1С устроено.
6. SeiOkami 1668 08.09.19 08:34 Сейчас в теме
(0), очень интересный материал, спасибо за публикацию!
TreeDogNight; +1 Ответить
7. VIA_1C 64 09.09.19 08:48 Сейчас в теме
(0) Автору спасибо за наглядное и очень понятное изложение материала. Так и хочется сказать: аффтар пиши есчо! ))
TreeDogNight; altu71; Dementor; +3 1 Ответить
9. Yashazz 3473 09.09.19 11:04 Сейчас в теме
(7) Автор, не пиши такого. Есть инструментарий, вот им и следует пользоваться. А не лазить, куда не рекомендовано.
10. VIA_1C 64 09.09.19 11:08 Сейчас в теме
(9) если Вы не умеете это "готовить", то это сугубо Ваши личные проблемы
TreeDogNight; +1 Ответить
12. Evil Beaver 6852 09.09.19 11:48 Сейчас в теме
(10) О, а вы разве умеете? Или вы просто не очень осознаете риски написания в продакшене парсера под недокументированный формат, являющийся, как говорят, "subject-to-change"?
13. VIA_1C 64 09.09.19 12:09 Сейчас в теме
(12) я возможности этого недокументированного формата еще в 7.7 использовал, при необходимости... А вообще каждый сам для себя решает нужно оно ему или нет. Мне - иногда нужно и не надо меня убеждать в том, что мне это не нужно. ))
TreeDogNight; Dementor; +2 Ответить
17. Yashazz 3473 09.09.19 22:35 Сейчас в теме
(13) Ну многие использовали, но флагом махать зачем? Я тоже много интересного могу рассказать про разницу между ЗначениеВСтроку и ЗначениеВСтрокуВнутр, особенно в плане производительности, и?
16. Yashazz 3473 09.09.19 22:34 Сейчас в теме
(10) Я-то дофига всего умею. Но если предлагают готовить крысятину, то да, я скажу, "не надо" и меня поддержат, несмотря на отличное изложение книги "101 рецепт из крысиного мяса".
14. vadim1011985 82 09.09.19 13:01 Сейчас в теме
Этот формат очень похож (или даже скорее всего это он и есть) на формат описания самой конфигурации 1с (легко можно убедиться через Tools 1CD посмотрев таблицу CONFIG поле BINARYDATA)
portwein; Dementor; +2 Ответить
19. DrZombi 173 10.09.19 11:04 Сейчас в теме
(0) Бред, форменный... поставил бы минус, но вам повезло :)
20. Dementor 726 10.09.19 14:08 Сейчас в теме
(19) Борис Георгиевич, перелогиньтесь :))
22. Alex17 12.09.19 16:16 Сейчас в теме
Еще бы автор выложил функцию, которой бы заменой значений можно было исправить типы, ссылочных данных, при перегрузках на разных конфигурациях 1С, цены бы не было. За статью спасибо.
23. Dementor 726 13.09.19 10:27 Сейчас в теме
(22) написать можно, но как вы видите такую замену? Идентификаторы объектов метаданных - разные, уникальные идентификаторы ссылок - тоже разные. Когда мы значение ссылки открываем в чужой базе, мы не только не сможем определить, что это был за справочник, но даже не сможем понять, что это вообще Справочник, а не Документ или характеристика.

Можно выгружать метаданные из первой конфигурации, с помощью дополнительной обработки делать сопоставление объектов во второй (как минимум по наименованию и типу), а далее эту настройку использовать при загрузке. Но что, если нужных уидов не будет? В загруженных документах будет "объект не найден".
24. Alex17 13.09.19 10:56 Сейчас в теме
У меня задача проще. Был перенос данных из УПП в БУХ 3.0. в основном все справочники перенесли по UID. Сейчас идет выверка данных и постобработка документов ввода остатков. Очень удобно сохранить в исходнике во внешний файл срез регистра в ТЗ и потом читать в приемнике. Напр:
UID источника d4ba178b-3934-11e1-a59a-18a905e37a56
ЗначениеВСтрокуВнутр {"#",a86305d7-b8a1-4312-901f-2ade3efdb351,164:a59a18a905e37a5611e13934d4ba178b}

UID приемника d4ba178b-3934-11e1-a59a-18a905e37a56
ЗначениеВСтрокуВнутр {"#",c92a1124-c41e-42a4-bda7-3bbac9c6039e,188:a59a18a905e37a5611e13934d4ba178b}

Имея данную информацию можно ли сделать подмену
25. Alex17 13.09.19 11:19 Сейчас в теме
Правильно ли я понимаю что достаточно во всех местах заменить {"#",a86305d7-b8a1-4312-901f-2ade3efdb351,164: на {"#",c92a1124-c41e-42a4-bda7-3bbac9c6039e,188: и ссылка будет работоспособной, у меня не прокатило.
26. Alex17 13.09.19 11:35 Сейчас в теме
Вопрос снят, еще раз спасибо, помогло разобраться.
27. Alex17 13.09.19 18:28 Сейчас в теме
Вот собственно функции, может кому понадобятся

Процедура КоманднаяПанельРезультатСохратьТаблицуВФайлУниверсальная(Кнопка)
	
	ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
	ДиалогВыбораФайла.Фильтр = "Файл данных (*.txt)|*.txt";
	ДиалогВыбораФайла.Расширение = "txt";
	ДиалогВыбораФайла.ПредварительныйПросмотр = Ложь;
	ДиалогВыбораФайла.ИндексФильтра = 0;
	
	Если ДиалогВыбораФайла.Выбрать() Тогда
		
		СоответствиеЗамены = ПолучитьСоответствиеЗамены();
		Т = ЗначениеВСтрокуВнутр(РезультатТаблица);
		Для каждого стр Из СоответствиеЗамены Цикл
			Т = СтрЗаменить(Т,стр.Значение,стр.Имя);
			Т = СтрЗаменить(Т,Лев(стр.Значение,36),"_" + стр.Имя);    
		КонецЦикла; 
		
		 ТекстовыйФайл = Новый ТекстовыйДокумент;
		 ТекстовыйФайл.УстановитьТекст(Т);
		 ТекстовыйФайл.Записать(ДиалогВыбораФайла.ПолноеИмяФайла);
		 
	КонецЕсли;
КонецПроцедуры

Процедура КоманднаяПанельРезультатЗагрузитьТаблицуИЗФайлаУниверсальная­(Кнопка)
	
	ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	ДиалогВыбораФайла.Фильтр = "Файл данных (*.txt)|*.txt";
	ДиалогВыбораФайла.Расширение = "txt";
	ДиалогВыбораФайла.ПредварительныйПросмотр = Ложь;
	ДиалогВыбораФайла.ИндексФильтра = 0;
	
	Если ДиалогВыбораФайла.Выбрать() Тогда
		ТекстовыйФайл = Новый ТекстовыйДокумент;
		ТекстовыйФайл.Прочитать(ДиалогВыбораФайла.ПолноеИмяФайла);
		Т = ТекстовыйФайл.ПолучитьТекст();
		СоответствиеЗамены = ПолучитьСоответствиеЗамены();
		Для каждого стр Из СоответствиеЗамены Цикл
			Т = СтрЗаменить(Т,"_" + стр.Имя,Лев(стр.Значение,36));
			Т = СтрЗаменить(Т,стр.Имя,стр.Значение);
		КонецЦикла;
		
		РезультатТаблица = ЗначениеИзСтрокиВнутр(Т);
		
		ЭлементыФормы.ТаблицаРезультата.СоздатьКолонки();
		ЭлементыФормы.КоманднаяПанельРезультат.Кнопки.ВыполнитьАлгоритм.Доступность = Истина;
	КонецЕсли;  
	ЭлементыФормы.НадписьКолСтрокРезультата.Заголовок = СокрЛП(РезультатТаблица.Количество()) + " строк";

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

Функция ПолучитьСоответствиеЗамены()
	
	СоответствиеТипов = Новый ТаблицаЗначений;
	СоответствиеТипов.Колонки.Добавить("Имя");
	СоответствиеТипов.Колонки.Добавить("Значение");
	
	ЗапросТекстИтог = "";
	
	Для каждого стр Из Метаданные.Справочники Цикл
		ЗапросТекст = 
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	Ссылка,
		|	""<Имя>"" КАК Имя
		|ИЗ
		|	<Имя>
		|ОБЪЕДИНИТЬ ВСЕ
		|/////////////////////////////
		|";
		ЗапросТекст = СтрЗаменить(ЗапросТекст, "<Имя>", "Справочник." + стр.Имя);
		
		ЗапросТекстИтог = ЗапросТекстИтог + ЗапросТекст;
		
	КонецЦикла;
	
	//Для каждого стр Из Метаданные.Документы Цикл
	//	ЗапросТекст = 
	//	"ВЫБРАТЬ ПЕРВЫЕ 1
	//	|	Ссылка,
	//	|	""<Имя>"" КАК Имя
	//	|ИЗ
	//	|	<Имя>
	//	|ОБЪЕДИНИТЬ ВСЕ
	//	|/////////////////////////////
	//	|";
	//	ЗапросТекст = СтрЗаменить(ЗапросТекст, "<Имя>", "Документ." + стр.Имя);
	//	
	//	ЗапросТекстИтог = ЗапросТекстИтог + ЗапросТекст;
	//	
	//КонецЦикла;
	
	ЗапросТекстИтог = Лев(ЗапросТекстИтог,СтрДлина(ЗапросТекстИтог) - 45);
	
	Запрос = Новый Запрос;
	Запрос.Текст = ЗапросТекстИтог;
	ТЗ = Запрос.Выполнить().Выгрузить();   
	
	Для каждого стр Из ТЗ Цикл
		//"{"#",0b5f521e-459d-4962-86a6-f3a45fe61010,34:810100155d08eb1f11e7e01fe335f24f}"
		Значение = ЗначениеВСтрокуВнутр(стр.Ссылка);
		раз = Найти(Значение,":");
		НоваяСтрока = СоответствиеТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока,стр);
		НоваяСтрока.Значение = Сред(Значение,6,раз - 6);
	КонецЦикла; 
	
	Возврат СоответствиеТипов;
	
КонецФункции
Показать
29. zhichkin 749 05.03.20 12:30 Сейчас в теме
Статья - супер! Спасибо автору! Пишите ещё чего знаете про платформу =)
Самое главное: никого не слушайте - всё, что Вы сделали, это правильно и полезно.
Нужно знать свой инструмент, чем глубже, тем лучше.
Dementor; +1 Ответить
30. МихаилМ 09.06.20 12:16 Сейчас в теме
в 16 релизе 1с что поменяло в структуре строки внутренней в тз и дз.
что именно - пока не разбирался. у них там была ошибка (до 16 точно )- при удалении строк из тз счетчик строк в строке внутренней не менялся.
Dementor; +1 Ответить
Оставьте свое сообщение

См. также

Безопасная работа с транзакциями во встроенном языке Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Разбираемся с опасностями использования транзакций во встроенном языке 1С. Познаем ошибку "В данной транзакции уже происходили ошибки". Учимся защищаться от них.

1 стартмани

25.03.2019    35168    tormozit    54    

Cбор и анализ ошибок при помощи Sentry, или как упростить жизнь себе и пользователям

Практика программирования Интеграция v8 Абонемент ($m)

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

1 стартмани

09.10.2020    2254    hexhoc    12    

Программная корректировка при выводе отчета СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

08.10.2020    2509    dabu-dabu    8    

Загрузка, скачивание, удаление файлов с помощью НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера()

Практика программирования v8 1cv8.cf Абонемент ($m)

В платформе 8.3.15 появились новые методы НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера(). В данной статье рассмотрено готовое решение проверенное и прекрасно работающее на тонком и веб-клиенте.

1 стартмани

25.07.2020    3108    Flashill    10    

Как выполнить отчет на СКД через COM и получить данные отчета? Промо

Практика программирования v8 УПП1 Россия Абонемент ($m)

Для чего это нужно. Например, нужно в одной базе получить какой-либо показатель из другой базы. Этот показатель вычисляется в каком-либо сложном отчете, который написан на СКД. Можно, конечно, "скопипастить" текст запроса из другой базы, немного подправить его и выполнять в том же COM подключении. Но с этим теряется гибкость: если отчет изменился, то нужно помнить о том, что где-то есть его "немного модифицированная" копия. В статье будет рассмотрен пример получения данных из базы ЗУП.

2 стартмани

08.05.2018    27094    wowik    3    

Параллельные вычисления расчета факториала числа N

Практика программирования v8 1cv8.cf Абонемент ($m)

Распараллеливание алгоритма с помощью фоновых заданий (асинхронные вычисления)

1 стартмани

29.06.2020    2618    Rustig    17    

Запуск фонового задания во внешней обработке без регистрации в справочнике "Дополнительные отчеты и обработки"

Практика программирования v8::УФ ЗУП3.x Россия Абонемент ($m)

Описал, как показать прогресс выполнения длительной операции во внешней обработке, и при этом не регистрировать обработку в справочнике "ДополнительныеОтчетыИОбработки". Проверял на БСП версии "3.1.2.264".

1 стартмани

09.03.2020    4027    VinnieThePOOH    5    

Методика обновления формы объекта данных при изменении объекта

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

В формах объектов данных часто встречаются элементы, косвенно связанные с объектом. Логику обновления этих элементов при изменении объекта обычно вызывают из обработчиков ПриСозданнииНаСервере и ПриОткрытии, забывая про наличие других способов изменения объекта. В статье предложена методика для обычных и управляемых форм, учитывающая все способы.

1 стартмани

09.03.2020    8172    tormozit    13    

Программное создание динамического списка на управляемой форме. (Динамическое создание динамического списка). Готовая процедура + обработка - демонстрационный пример Промо

Практика программирования Универсальные функции v8::УФ 1cv8.cf Абонемент ($m)

Если у вас возникает необходимость на форму влиять динамически и создавать элементы управляемой формы программно, а особенно хотите вывести программно (динамически) динамический список, вам будет интересна эта процедура. Процедура включает также возможность формирования своей командной панели (а-ля снятие галочки "Автозаполнение" у стандартной командной панели списка).

1 стартмани

19.01.2018    58077    rpgshnik    29    

Отправка уведомлений с помощью командной строки, Оповещения с сервера на клиент с помощью командной строки

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Отправка уведомлений с помощью команды командной строки msg. Оповестить пользователей из серверного модуля или регламентного задания, с помощью командной строки msg.

1 стартмани

05.03.2020    5729    user5300    3    

Вывод сообщений в HTML поле средствами 1С

Практика программирования v8 v8::УФ Абонемент ($m)

Пример использования вывода большого количества сообщений в поле HTML. С возможностью открывать ссылочные объекты и создавать новые объекты передавая параметры прямо из HTML поля. Протестировано на релизах 8.3.12 и 8.3.15+

2 стартмани

31.01.2020    5839    burni4    16    

Как в 1С создать паутинку "как на Инфостарте"

Практика программирования v8::УФ 1cv8.cf Россия Абонемент ($m)

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

1 стартмани

15.01.2020    9080    user660153_aleks.pisanets    17    

Как нарисовать граф на 1С Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

09.08.2013    70505    ildarovich    117    

Краткое руководство по внесению изменений в конфигурацию

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

13.01.2020    17198    sapervodichka    41    

Универсальные функции: разложение произвольной строки адреса в структуру

Практика программирования Универсальные функции v8 1cv8.cf Абонемент ($m)

Процедуры и функции раскладывают произвольную строку адрес в структуру по ключевым словам.

1 стартмани

30.12.2019    3739    vik070777    10    

"Живые" картинки со Snap.SVG

Практика программирования WEB Работа с интерфейсом v8 Абонемент ($m)

В статье рассмотрен пример использования http-сервисов для визуализации данных

1 стартмани

24.10.2019    13544    blackhole321    7    

Простой способ индексирования интервалов Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

28.09.2016    39502    ildarovich    22    

RLS - дубли условий в запросах к СУБД

Практика программирования Роли и права v8 v8::Права 1cv8.cf Абонемент ($m)

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

1 стартмани

07.10.2019    8456    geron4    4    

Полезные процедуры и функции для программиста

Практика программирования Универсальные функции v8 1cv8.cf Россия Абонемент ($m)

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

07.10.2019    30209    HostHost    40    

Вебхук. Путь Телеграма

Внешние источники данных Интеграция v8 Абонемент ($m)

Долгое (на самом деле нет) и нелегкое путешествие телеграма к неведомым (из за РКН) конфигурациям 1С. Памятка себе.

1 стартмани

03.10.2019    17607    platonov.e    26    

Бесплатная проверка контрагентов в ФНС (общий модуль с алгоритмом). На примере выводим статус в список справочника контрагентов Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Если вам интересно проверить контрагенте в ФНС, вам поможет данная публикация. Весь алгоритм работы строится на основе данных, полученных с сервиса http://npchk.nalog.ru совершенно бесплатно.

1 стартмани

01.02.2018    35098    rpgshnik    49    

Полное копирование одной формы в другую

Практика программирования Универсальные обработки Работа с интерфейсом v8 1cv8.cf Абонемент ($m)

Однажды я столкнулся с необходимостью открыть форму ЛЮБОГО документа с определенными изменениями, не зависящими от структуры объекта (например, заблокировать все кнопки). В интернете решения я не нашел. Обычно на форумах на запросы подобного рода отвечают чем-то вроде "покажи первоначальную задачу, а не спрашивай как реализовать то, что ты придумал". Тем не менее, мне стало интересно, как это можно сделать.

1 стартмани

03.10.2019    5092    nekit_rdx    23    

Многопоточная обработка данных на примере перепроведения документов

Обработка документов Практика программирования v8 ERP2 УТ11 КА2 Абонемент ($m)

Дальнейшее развитие темы фоновой обработки данных - проведение документов в потоках. Настройка параметров и запуск основного процесса (менеджера потоков). Разбивка документов для проведения на не связанные друг с другом наборы и запуск дополнительных фоновых заданий для отдельных потоков. Отслеживание выполнения каждого потока в родительском сеансе.

1 стартмани

17.09.2019    9222    ids79    46    

Отображение истории выполнения по всем задачам комплексного процесса в документообороте

Документооборот и делопроизводство Практика программирования v8 ДО Абонемент ($m)

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

1 стартмани

15.09.2019    6837    pavelpribytkin96    8    

БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному Промо

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Абонемент ($m)

Очень много попадается странных решений, которые можно решить через БСП:Дополнительные отчеты и обработки. Я бы вообще БСП из-за этой подсистемы переименовал в «Большое Спасибо Программистам». Поработаем с подсистемой в части написания регламентных заданий.

1 стартмани

10.05.2018    44891    dsdred    36    

Удобный просмотр результата запроса с большим количеством временных таблиц

Практика программирования v8 Абонемент ($m)

Если Вам часто приходится просматривать в отладчике сложные пакетные запросы с большим количеством временных таблиц, то эта статья для Вас.

1 стартмани

27.08.2019    10874    ids79    21    

Обмен большими данными между клиентом и сервером

Внешние источники данных v8 Абонемент ($m)

В статье рассматривается вопрос передачи больших объемов данных, превышающих теоретический лимит сеансовых данных (4Гб за вызов) (они же временное хранилище) как с клиента на сервер, так и в обратном направлении.

1 стартмани

27.08.2019    13528    logos    24    

Запуск фонового задания во внешней обработке. Отключение предупреждений защиты от опасных действий в фоновом задании

Практика программирования v8 1cv8.cf Абонемент ($m)

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

2 стартмани

24.08.2019    10846    BenGunn    22    

Некоторая работа с данными через COM Промо

Практика программирования v8 Абонемент ($m)

В статье приведены примеры работы с Платформой 8.X через COM (точнее, через объект COMConnector). Примеры кода были использованы при реализации прикладных задач в процессе трудовой деятельности.

2 стартмани

05.12.2012    57541    wowik    32    

Изменяющееся контекстное меню в 1С 8.3

Практика программирования Работа с интерфейсом Разработка v8 v8::УФ Абонемент ($m)

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

1 стартмани

06.08.2019    15805    signum2009    16    

Процедура ПриКомпоновкеРезультата

Практика программирования v8 1cv8.cf Абонемент ($m)

Коллекция кода

1 стартмани

26.07.2019    38730    vasilev2015    64    

10 способов получить модуль числа (а может, и больше)

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

1 стартмани

11.07.2019    8348    sam441    29    

Работа со схемой запроса Промо

Инструментарий разработчика Практика программирования v8 v8::Запросы Абонемент ($m)

Стандартом взаимодействия с реляционной базой данных стал язык SQL. Приемником SQL в 1С является язык запросов. Язык запросов, также как и SQL, является структурированным. Составляющие структуры запроса отвечают на разные вопросы о том, какие данные требуется получить и какие манипуляции с множествами данных необходимо произвести при получении. В простых случаях текст запроса можно написать вручную, однако в сложных случаях, а также при программном формировании, - лучше воспользоваться объектной моделью запроса и использовать объект "Схема запроса". В статье дается описание объектной модели и особенностей работы с ней, а также приводится решение, упрощающее взаимодействие с объектом "Схема запроса".

1 стартмани

24.04.2018    44156    kalyaka    35    

Ловец дедлоков СУБД

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Россия Абонемент ($m)

Анализ простейшего дедлока СУБД в рабочей базе с использованием ЦУП (центра управления производительностью) и profiler MS SQL (Microsoft SQL Server). Эта статья будет полезна людям, изучающим вопросы оптимизации работы 1С, или тем, у кого возникают дедлоки в рабочей базе. UPD 09.07.2019 добавлено воспроизведение блокировки в случае установки управляемой блокировки перед чтением набора записей регистра сведений. UPD 10.07.2019 добавлена тестовая база с примером.

1 стартмани

08.07.2019    11120    azazana    79    

Мониторинг производительности и искусственный интеллект

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Абонемент ($m)

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

1 стартмани

01.07.2019    9267    ivanov660    28    

Интеграция 1С с Битрикс CRM через REST API

Внешние источники данных v8 1cv8.cf Абонемент ($m)

На фоне неутихающего обострения «бизнеса» по внедрению СРМ-систем остро встают вопросы обмена данными с уже существующими системами. В статье рассматривается выгрузка контактов, товаров и сделок из 1С в Битрикс CRM через REST API, приложена обработка для тестирования.

1 стартмани

28.06.2019    22143    muzipov    9    

Многопоточность. Универсальный «Менеджер потоков» (фреймворк) с отслеживанием зависимости объектов Промо

Практика программирования Математика и алгоритмы Универсальные функции Производительность и оптимизация (HighLoad) v8 1cv8.cf Россия Абонемент ($m)

Восстановление партий, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

26.05.2017    49104    DarkAn    86    

"Убер на складе": динамический расчет маршрутов с учетом реальных расстояний

Учет ТМЦ Практика программирования Учет ТМЦ v8 УУ Абонемент ($m)

Представляю методику и инструмент для динамического расчета маршрутов отбора на высоконагруженных складах для максимального повышения эффективности склада, ускорения проходимости и, как следствие, экономии денег. Это методика и обработка для интеграции в WMS решения. Тестировалось на 1С 8.3.14.1565.

3 стартмани

24.06.2019    15747    informa1555    17    

1С:Ассемблер. Немного летнего веселья!

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

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

1 стартмани

21.06.2019    29156    Evil Beaver    127    

Простые примеры сложных отчетов на СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Подписи в отчете. Особенности соединения наборов: как соединить несоединяемое. Остатки на дату и обороты по месяцам в одном отчете. Курс валюты на каждую дату без группировок и соединений в запросе. Отчет с произвольными колонками и с произвольной последовательностью. "Неадекватный отчет".

1 стартмани

12.06.2019    29872    Hatson    31    

Новый запрос и новая таблица значений как функции Промо

Практика программирования v8 Абонемент ($m)

Предлагается две простые функции, использование которых уменьшает объем кода в конфигурациях на платформе «1С:Предприятие 8». Эти функции можно добавлять к своему общему модулю, что сделает процесс программирования более эффективным.

1 стартмани

27.11.2012    45267    ildarovich    46    

Картинки во внешней печатной форме (Шапка и табличная часть)

Печатные формы документов Практика программирования Разработка v8::ОУ v8::УФ УТ11 Россия Абонемент ($m)

Способы вывести на печать картинку в шапке и в табличной части внешней печатной формы. Управление торговлей, редакция 11 (11.4.7.150).

1 стартмани

27.05.2019    10973    Povinger    2    

Создание внешней печатной формы в формате документа Word

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В статье написано, как создать внешнюю печатную форму (для конфигураций с БСП) в формате Word.

1 стартмани

17.05.2019    13692    ВикторП    21    

Табличная часть из дополнительных реквизитов с обработкой событий в расширении

Практика программирования Работа с интерфейсом Разработка v8::УФ 1cv8.cf Абонемент ($m)

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

1 стартмани

13.05.2019    10314    mvxyz    17    

Уровни, глубина, прародители, циклы и аналоги запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

В продолжение публикации «Транзитивное замыкание запросом» [http://infostart.ru/public/158512/] добавлены другие варианты использования того же приема. Приведены запросы для быстрого определения уровней всех элементов справочника, максимальной глубины справочника, прародителей произвольных элементов справочника, запрос для быстрого определения циклов (на примере справочника спецификаций «1С:Управление производственным предприятием») и определения множеств аналогов номенклатуры (также на примере конфигурации «1С:Управление производственным предприятием»).

1 стартмани

13.11.2012    112030    ildarovich    98    

Пример настройки шаблонов и реализации печати отчетов в документ MS Word используя функциональную часть "Библиотеки Стандартных Подсистем 1С" (БСП)

Практика программирования Разработка v8 Россия Абонемент ($m)

В конфигурации выбраны и использованы только необходимые объекты библиотеки стандартных подсистем для реализации вывода отчёта, с табличными частями, в документ MS Word. Показан пример создания необходимых областей в шаблоне для вывода параметров в отчёт.

1 стартмани

23.04.2019    6267    olegpkc    11    

Ops средствами 1С:Предприятие

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В статье описан программный пакет "Автоматизация ИТ-процессов" (АИТП), позволяющий автоматизировать задачи по администрированию, управлению и обслуживанию ИТ-инфраструктуры.

1 стартмани

23.04.2019    17401    blackhole321    28    

1C + Python + Django Rest Framework + Vue.js. Опыт несложной full-stack разработки

Практика программирования Внешние источники данных Обмен через XML WEB Разработка v8 1cv8.cf Абонемент ($m)

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

1 стартмани

22.04.2019    33183    riposte    65    

Неоплаченные долги при распределении оплаты по правилу ФИФО одним запросом и намного быстрее, чем Вы думали Промо

Практика программирования Дебиторская и кредиторская задолженность Дебиторская и кредиторская задолженность v8 v8::СКД КА1 УТ10 УПП1 УУ Абонемент ($m)

Предлагается метод для быстрого нахождения неоплаченных долгов при распределении оплаты по правилу ФИФО, основанный на дихотомии. Описывается реализация метода в виде достаточно простого запроса, решающего за линейное время указанную задачу, считавшуюся ранее существенно более трудоемкой. Приводятся примеры использования запроса в отчетах на СКД для конфигураций УТ, КА, УПП.

1 стартмани

28.02.2014    68314    ildarovich    125    

Вывод вариантов СКД в таблицы на управляемой форме

Практика программирования Работа с интерфейсом v8 v8::УФ v8::СКД 1cv8.cf Абонемент ($m)

Задача стояла такая: есть 2 различных запроса, результаты которых выгружаются на форму обработки в таблицы значений (далее ТЗ) и программно "соприкасаются" между собой определенным образом (как именно- в рамках данной статьи неважно). Нюанс в том, что запросы должны иметь свой компоновщик настроек и могут интерактивно на форме изменяться пользователем. На оригинальность публикации не претендую - изначально в рамках поставленной задачи пытался найти что-то подобное (уже готовый шаблон) на инфостарте, возможно "плохо искал" ;)

05.04.2019    11219    artkor    1    

Аутентификация на внешних сервисах посредством OAuth

Информационная безопасность Внешние источники данных v8 v8::УФ 1cv8.cf Абонемент ($m)

Пример подключения к сервисам Google из 1С с помощью протокола OAuth и получения данных с внешнего сервиса.

1 стартмани

03.04.2019    20225    binx    126    

[EnterpriseData] Антисвертка характеристик номенклатуры при выгрузке в Бухгалтерию

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 v8::ПВХ КД УНФ БП3.0 Россия БУ Абонемент ($m)

Рассмотрена выгрузка каждой пары значений Номенклатура - Характерстика из УНФ 1.6 в отдельную номенклатуру в Бухгалтерию 3.0 путём доработки правил обмена в формате EnterpriseData.

1 стартмани

27.03.2019    4637    nforce    6