1с соответствие получить значение по ключу
таблица значений - почти тоже, что список, только еще с колонками.
А вот про соответствие в хелпе написано только что данный объект "Представляет доступ к соответствию".
Не собираюсь поправлять техписателей 1С - другого определения давать не буду.
С моей точки зрения, соответствие занимает промежуточное положение между структурой и массивом, с одной стороны, и списком и таблицей значений, с другой, объединяя хорошие черты этих коллекций.
Все коллекции хранят множества элементов. Структура позволяет получить нужный элемент по имени, массив - по номеру, список и таблица значений - поиском (отбором) среди других элементов. А соответствие позволяет выбрать или изменить нужный элемент по "ключу" этого элемента. При этом в качестве ключа может использоваться значение почти любого типа (например, ссылка). Возможность выбора и изменения по ключу дает возможность обрабатывать заранее неизвестное количество элементов, при этом никак их не нумеруя. Получаем практически таблицу значений, проиндексированную по колонке "ключ".
И вот тут, думаю, для многих будет сюрпризом, что доступ к элементу соответствия по ключу происходит почти со скоростью доступа к массиву или элементу структуры! - Как будто по номеру!
Будем подавать на вход обработки случайные числа в диапазоне от 1 до КоличествоРазличныхЭлементов. Обработка должна будет проверять каждое число, чтобы определить: не встречалось ли очередное число в текущей последовательности раньше. Если такого числа не было - оно добавляется в коллекцию, иначе - увеличивается число его повторений.
То есть оценивается время выполнения конструкции ". " в цикле (фиг1)
В качестве конструкции ". " используется:
Вариант 1. Массив (фиг2)
Вариант 2. Соответствие (фиг3)
Вариант 3. Индексированная ТаблицаЗначений (фиг4)
Результаты сравнения показали, что отметка в массиве занимает на тестовом компьютере 2,45 мкс, в соответствии - 7,06 мкс, в индексированной таблице значений - 15,06 мкс, причем это время не зависит от числа элементов в коллекции! Прилагаемый к статье отчет "БыстродействиеКоллекций" позволит Вам перепроверить эти результаты.
Скорость доступа к элементам соответствия и независимость скорости доступа от размера коллекции "соответствие" может удивлять, если не догадываться о ее устройстве. Можно предположить, что используется хеш-функция и хеш-таблица. Хеш-функция вычисляет номер строки хеш-таблицы, где лежит ссылка на элемент. Простая косвенная адресация! Одно лишнее (по сравнению с массивом) обращение к памяти!
При использовании для решения этой задачи списка значений, неиндексированной таблицы значений или добавления чисел в таблицу значений без контроля повторений с последующей сверткой, получаются существенно более плохие результаты. Которые, к тому же, зависят от размеров коллекций . При этом самые лучшие результаты среди аутсайдеров дает свертка.
В комментариях к статье также уже посоветовали отметить, что еще одна прелесть соответствия в том, что перед присваиванием Соответствие[Ключ] = Значение не нужна проверка на существование элемента с этим ключом, так как отсутствующий элемент в этом случае вставляется в соответствие. В приведенных примерах этому красивому приему, к сожалению, места не нашлось.
2. Пример использования соответствия в задаче подсчета повторений слов.
Приведем пример программы, подсчитывающей число повторений каждого слова в заданном тексте. Обычное решение - запоминание отдельных слов в строках таблицы значений и последующая свертка по полю "Слово". Соответствие ускоряет основную операцию в этом алгоритме минимум в два раза! При этом получается не только самый быстрый, но и выразительный код. Чтобы учесть, что слово, прочитанное в переменную "Слово" строкового типа, встретилось еще раз, используется наглядная запись: Частота[Слово] = Частота[Слово] + 1. Правда, чтобы определить, что символ является буквой, использовать соответствие будет уже неправильно: встроенная функция поиска подстроки работает быстрее!
Текст программы приведен на фиг5 и в приложенном к статье отчете "ЧастотаСлов", позволяющем проанализировать любой текстовый файл.
Прилагаемый к статье скриншот показывает результат определения частоты слов в данной статье.
3. Пример использования соответствия в задаче представления ориентированного графа.
Если стоит задача сохранить в оперативной памяти и проанализировать связи объектов информационной базы, то эффективной оказывается использование следующей структуры: Соответствие "Граф" хранит связи объекта, ссылка на который определяется ключом. Значением соответствия "Граф" является вложенное соответствие "Связи", которое для каждого связанного элемента хранит вес связи.
Например, если переменные "Элемент1" и "Элемент2" хранят ссылки на два элемента справочника "Номенклатура", причем второй входит в спецификацию первого с весом 2, то выражение
Граф[Элемент1][Элемент2] будет равно 2.
Если связи нет, то выражение Граф[Элемент1][Элемент2] будет равно "Неопределено".
Если нужно сделать вес связи равным 1, это сделает следующий код: Граф[Элемент1][Элемент2] = 1.
При этом Элемент1 и Элемент2 могут быть как ссылкой на справочник, так и ссылкой на документ и другие объекты. То есть так можно обрабатывать любые связи!
Стоит предупредить, что обращаться к элементам вложенного соответствия можно только, если во внешнем соответствии существует ключ первого элемента. Поэтому перед обращением к связям требуется проверка Граф[Элемент1] <> Неопределено.
На фиг6 приведен фрагмент кода программы, который производит чтение из базы данных в оперативную память связей номенклатуры, задаваемых в конфигурации "Бухгалтерия предприятия" в справочнике "СпецификацииНоменклатуры".
Заключительные замечания.
1. Ничего нового здесь не изобретено, просто делюсь опытом. Сам узнал о сравнительной эффективности коллекций из статьи Сергея Осипова. Спасибо ему!
2. Использование соответствия в решении задач позволяет исключить поиск при обработке заранее непронумерованных данных. Таким образом существенно ускоряется реализация многих базовых алгоритмов. Пользуйтесь соответствием в случаях, когда не нужен весь функционал таблиц значений!
3. Несмотря на ориентированность языка 1С на решение бизнес-задач, в нем есть место настоящему программированию - кодингу, в том числе и самому хитроумному. Поэтому изучайте теорию алгоритмов и программ, не мусорьте в коде и сможете сберечь нервы и время пользователей, строки кода, место на дисках, циклы процессора, электроэнергию. Делайте мир лучше!
Объект Структура создается с помощью конструктора Новый.
Структура1 = Новый Структура;
Со структурами можно работать и в серверном и клиентском контексте, причем в клиентском контексте с ними можно работать как под толстым клиентом, так и под тонким клиентом.
В значения структуры можно записать переменные любого типа, но использование типов в этом случае очень сильно зависит от контекста и от вида клиента: мы не можем в клиентском контексте задать значение, тип которого работает только в серверном контексте (например, ДокументОбъект.<>).
Как создать новую структуру, Вы знаете, теперь выясним, как создаются новые элементы данного объекта. Делается это с помощь метода Вставить.
Вот его синтаксис:
Вставить(<Ключ>,<Значение>);
Параметр Ключ имеет тип значения Строка. Он может иметь любое название, какое захочет разработчик (но помним про ограничения в названиях переменных). Параметр Значение может иметь любой тип.
Обращаю Ваше внимание, что связка «Ключ и значение» уникальна, поэтому если Вы напишете для одной структуры два метода Вставить с одинаковыми ключами и разными значениями, то все равно в структуре будет одна связка «Ключ и значение», причем значение возьмется с последнего метода.
Не всегда обязательно использовать метод Вставить, чтобы добавить пару КлючИЗначение в структуру, иногда это можно сделать в конструкторе. Тогда конструктор будет иметь следующий вид:
Структура1 = Новый Структура(Ключ, Значение);
Переделаем предыдущий пример:
В случаях выше мы не стали думать над названиями ключей, Вы же в процессе работы можете давать ключам любые названия, какие захотите. Главное, чтобы тип ключа был Строка.
В структуру можно записывать не только примитивные типы, но также любые другие объекты «1С:Предприятия», вплоть до других структур. Причем значения типов разных ключей структуры могут быть разными.
Если мы посмотрим в отладке конфигуратора на нашу структуру, то увидим, что она представляет собой некоторый список, где напротив каждого ключа есть то значение, которое мы привязали к данному ключу с помощью метода Вставить. Этот ключ является свойством структуры как объекта, и мы можем обращаться к нему.
Изменить значение ключа структуры 1С
Если нам необходимо изменить значение какого-нибудь ключа, то мы, используя метод Вставить, указываем в качестве первого параметра ключ, значение которого хотим поменять, а в качестве второго параметра новое значение для данного ключа.
Или напрямую обращаемся к ключу
Обход коллекции структуры 1С
Обход структуры осуществляется с помощью оператора цикла Для каждого…Цикл.
Обойдем уже созданную структуру.
Безошибочное получение значения элемента
Если при обращении к ключу структуры Вы укажете название несуществующего в данной структуре ключа, то программа выдаст ошибку. Но есть метод объекта Структура, с помощью которого можно обратиться к значению ключа, не боясь вызвать ошибку в случае промаха.
Этот метод – Свойство.
Данный метод является функцией и возвращает Истину, если указанный ключ есть, и Ложь, если указанного ключа нет.
Рассмотрим синтаксис метода:
Свойство(<ИмяКлюча>,<ЗаписываемоеЗначение>);
В параметр «ЗаписываемоеЗначение» будет возвращено найденное значение. В том случае, если ключа нет в структуре, то данному параметру присвоится значение Неопределено. Обращаю Ваше внимание, что параметр «ЗаписываемоеЗначение» где-то должен быть определен.
В переменную А запишется значение, которое связанно с Ключ1.
Но если мы напишем так.
То ни какой ошибки не возникнет, и в переменной А присвоится значение Неопределено.
Статьи о других универсальных коллекциях значений в 1С
Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
- Очень доступный и понятный язык изложения
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Поймете идеологию управляемого приложения 1С
- Узнаете, как разрабатывать управляемое приложение;
- Научитесь разрабатывать управляемые формы 1С;
- Сможете работать с основными и нужными элементами управляемых форм
- Программирование под управляемым приложением станет понятным
Если Вам помог этот урок решить какую-нибудь проблему, понравился или оказался полезен, то Вы можете поддержать мой проект, перечислив любую сумму:
можно оплатить вручную:
// Описание типа строки:
НовСтрока = Новый ОписаниеТипов ( "Строка" );
// Описание строки с уточнением через квалификатор: максимальная длина строки = 50 символов
КвалификаторыСтроки = Новый КвалификаторыСтроки ( 50 );
НовСтрока_50 = Новый ОписаниеТипов ( "Строка" , , КвалификаторыСтроки );
// Описание типа числа:
НовЧисло = Новый ОписаниеТипов ( "Число" );
// Описание числа с уточнением через квалификатор: общее число разрядов = 14, число дробной части = 3
КвалификаторыЧисла = Новый КвалификаторыЧисла ( 14 , 3 , ДопустимыйЗнак . Любой );
НовЧисло_14_3 = Новый ОписаниеТипов ( "Число" , КвалификаторыЧисла );
// Описание типа даты:
НовДата = Новый ОписаниеТипов ( "Дата" );
// Описание даты с уточнением через квалификатор: храниться только дата, без времени
КвалификаторыДаты = Новый КвалификаторыДаты ( ЧастиДаты . Дата );
НовДата_БезВремени = Новый ОписаниеТипов ( "Дата" , , , КвалификаторыДаты );
// Описание типа булево:
НовБулево = Новый ОписаниеТипов ( "Булево" ); // Истина, Ложь
// Описание типа справочника:
НовНоменклатура = Новый ОписаниеТипов ( "СправочникСсылка.Номенклатура" );
// Описание типа перечисление:
НовСпособОплаты = Новый ОписаниеТипов ( "ПеречислениеСсылка.СпособыОплаты" );
// Описание типа документа:
НовДоговор = Новый ОписаниеТипов ( "ДокументСсылка.Договор" );
// Описание типа структуры:
НовСтруктура = Новый ОписаниеТипов ( "Структура" );
// Описание типа соответствия:
НовСоответствие = Новый ОписаниеТипов ( "Соответствие" );
// Описание типа массива:
НовМассив = Новый ОписаниеТипов ( "Массив" );
// Описание типа хранилище значения:
НовХранилищеЗначения = Новый ОписаниеТипов ( "ХранилищеЗначения" );
// Описание типа таблица значений:
НовТаблицаЗначений = Новый ОписаниеТипов ( "ТаблицаЗначений" );
// Описание типа список значений:
НовТаблицаЗначений = Новый ОписаниеТипов ( "СписокЗначений" );
// Описание типа картинки:
НовКартинка = Новый ОписаниеТипов ( "Картинка" );
// Описание типа уникального идентификатора:
НовУникальныйИдентификатор = Новый ОписаниеТипов ( "УникальныйИдентификатор" );
// Описание типа объекта метаданых:
НовОбъектМетаданных = Новый ОписаниеТипов ( "ОбъектМетаданных, Строка" );
// Описание составного типа (Например: строка+структура+справочник):
СписокМассив = Новый Массив ;
СписокМассив . Добавить ( "Строка" );
СписокМассив . Добавить ( "Структура" );
СписокМассив . Добавить ( "СправочникСсылка.Номенклатура" );
ОписаниеСоставногоТипа = Новый ОписаниеТипов ( СписокМассив );
Формат JSON легко читается. Пример текстового файла в формате JSON:
"ОсновнойПоставщик" : "c8d578e9-9f33-11eb-80ad-364b50b7ef2d"Как правило JSON используется для обмена данными в веб-приложениях. Однако его можно применять и для обмена данными между двумя базами 1С.
JSON может включать в себя следующие элементы:
- Объект
- Строка
- Число
- Литералы: true, false, null
- Массив
Объект
Значением может быть любой тип:
- Другой JSON-объект
- Массив
- Строка
- Число
- Литералы: true, false, null
В данном примере три ключа:
- ЭтоКлюч
- ЭтоТожеКлюч
- ЭтоВложенныйОбъект
Строка и число
Литералы
В качестве литералов могут использоваться:
Массив
Значения массива могут быть любого типа: строки, числа, литералы, объекты и даже другие массивы:
ЗаписатьJSON
Чтобы записать данные в формате JSON из 1с нужно:
- Создать программный объект ЗаписьJSON
- Вызвать у него метод ОткрытьФайл, передав параметром путь к файлу, куда будут записаны данные в формате JSON
- С помощью метода глобального контекста ЗаписатьJSON выполнить сериализацию. Параметрами нужно передать созданный объект ЗаписьJSON и сами данные
- Закрыть ЗаписьJSON методом Закрыть
Соответствие между типами 1С и типами JSON:
Тип 1С | Тип JSON |
---|---|
Строка | Строка |
Число | Число |
Булево | true или false |
Дата | Строка |
Неопределено | null |
Массив | JSON-массив |
Фиксированный массив | JSON-массив |
Структура | JSON-объект |
Фиксированная структура | JSON-объект |
Соответствие | JSON-объект |
Фиксированное соответствие | JSON-объект |
Ключ соответствия и фиксированного соответствия может быть только строковым.
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON ( ПереносСтрокJSON . Авто , Символы . Таб ) ; Запись . ОткрытьФайл ( "F:\test.json" , , , ПараметрыЗаписиJSON ) ; ФиксСтруктура = Новый ФиксированнаяСтруктура ( Структура ) ; ФиксСоответствие = Новый ФиксированноеСоответствие ( Соответствие ) ;В результате файл будет содержать следующие данные:
В коде была использована строка:
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON ( ПереносСтрокJSON . Авто , Символы . Таб ) ;Здесь указывается, что при записи JSON нужно использовать перенос строк (первый параметр) и символ табуляции как отступ для каждого элемента JSON (второй параметр). Это нужно чтобы файл с JSON был более читаемым. Если указать первым параметром ПереносСтрокJSON.Нет, то JSON будет записан в одну строку.
Запись массива как JSON-объект
По умолчанию массив сериализуется в JSON-массив. Но в метод ЗаписатьJSON третьим параметром можно передать настройки сериализации JSON, где указать, что массивы нужно записывать как объекты. Ключом будет индекс элемента массива.
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON ( ПереносСтрокJSON . Авто , Символы . Таб ) ; Запись . ОткрытьФайл ( "F:\test.json" , , , ПараметрыЗаписиJSON ) ; Настройки . СериализовыватьМассивыКакОбъекты = Истина;Сериализация таблицы значений в JSON
Таблица значений является одной из часто используемых коллекций в 1С, но для нее нет автоматической сериализации в JSON. Для сериализации можно преобразовать таблицу в массив структур, а массив сериализовать в JSON:
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON ( ПереносСтрокJSON . Авто , Символы . Таб ) ; Запись . ОткрытьФайл ( "F:\test.json" , , , ПараметрыЗаписиJSON ) ;ПрочитатьJSON
Для чтения JSON файла используется программный объект ЧтениеJSON и метод ПрочитатьJSON:
- Создается программный объект ЧтениеJSON
- Методом ОткрытьФайл выполняется открытие файла с JSON
- Методом глобального контекста ПрочитатьJSON выполняется десериализация JSON
- Объект ЧтениеJSON закрывается методом Закрыть
Десериализация из JSON в типы 1С выполняется по следующим правилам:
Тип JSON | Тип 1С |
---|---|
Число | Число |
Строка | Строка |
true | Истина |
false | Ложь |
null | Неопределено |
JSON-объект | Структура или соответствие |
JSON-массив | Массив |
В результате в переменной Данные будет структура со следующим содержимым:
Чтение JSON в соответствие
Сейчас все JSON-объекты были прочитаны в структуру. Даже те, которые изначально были сериализованы из соответствия. Однако, в отличии от структуры, в ключах JSON-объектов могут быть пробелы или другие символы, которые нельзя использовать в ключах структуры. Например, если бы соответствие было записано так:
Чтобы прочитать такой JSON нужно в метод ПрочитатьJSON передать вторым параметром Истина. Тогда чтение всех JSON-объектов будет выполнено в соответствие:
В результате в переменной Данные будет соответствие со следующим содержимым:
Сериализация даты в JSON
Формат даты
При сериализации в JSON дата записывается как строка. При чтении тоже будет прочитана как строка, что не совсем удобно. Чтобы свойство с датой было прочитано как дата нужно в методе ПрочитатьJSON третьим параметром указать список имен свойств, которые должны быть прочитаны как дата. А четвертым параметром указать формат даты, в котором дата была записана в JSON. По умолчанию платформа 1С пишет дату в JSON в формате ISO.
//через запятую нужно перечислить список имен свойств, которые будут прочитаны как дата Данные = ПрочитатьJSON ( ЧтениеJSON , , ИменаСвойствСДатой , ФорматДатыJSON . ISO ) ;В результате свойство Дата будет прочитано как дата:
Платформа 1С может записывать дату в JSON в трех форматах:
Формат ISO используется по умолчанию. Для записи в формате JavaScript или Microsoft нужно явно указать это. При этом форматы JavaScript и Microsoft могут быть записаны только в варианте даты UTC (универсальная дата).
Например, запись в формате JavaScript:
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON ( ПереносСтрокJSON . Авто , Символы . Таб ) ; Запись . ОткрытьФайл ( "F:\test.json" , , , ПараметрыЗаписиJSON ) ; Данные . Вставить ( "СвойствоСДатой" , Дата ( 2021 , 6 , 3 , 15 , 0 , 0 ) ) ; //в настройках нужно указать формат даты и вариант записи даты НастройкиСериализацииJSON = Новый НастройкиСериализацииJSON ; НастройкиСериализацииJSON . ФорматСериализацииДаты = ФорматДатыJSON . JavaScript ; НастройкиСериализацииJSON . ВариантЗаписиДаты = ВариантЗаписиДатыJSON . УниверсальнаяДата ; ЗаписатьJSON ( Запись , Данные , НастройкиСериализацииJSON ) ;При чтении также нужно указать формат JavaScript:
//через запятую нужно перечислить список имен свойств, которые будут прочитаны как дата Данные = ПрочитатьJSON ( ЧтениеJSON , , ИменаСвойствСДатой , ФорматДатыJSON . JavaScript ) ;Для записи в формате Microsoft нужно указать ФорматСериализацииДаты = Microsoft:
НастройкиСериализацииJSON . ФорматСериализацииДаты = ФорматДатыJSON . Microsoft ;И то же самое при чтении JSON:
Данные = ПрочитатьJSON ( ЧтениеJSON , , ИменаСвойствСДатой , ФорматДатыJSON . Microsoft ) ;Для формата ISO дату можно записать в трех вариантах:
- Локальная дата (без часового пояса)
- Локальная дата со смещением (относительно UTC)
- UTC (универсальная дата)
Локальная дата со смещением:
НастройкиСериализацииJSON = Новый НастройкиСериализацииJSON ; НастройкиСериализацииJSON . ФорматСериализацииДаты = ФорматДатыJSON . ISO ; НастройкиСериализацииJSON . ВариантЗаписиДаты = ВариантЗаписиДатыJSON . ЛокальнаяДатаСоСмещением ; НастройкиСериализацииJSON = Новый НастройкиСериализацииJSON ; НастройкиСериализацииJSON . ФорматСериализацииДаты = ФорматДатыJSON . ISO ; НастройкиСериализацииJSON . ВариантЗаписиДаты = ВариантЗаписиДатыJSON . УниверсальнаяДата ;ПрочитатьДатуJSON
Другой способ чтения даты из JSON это использование метода ПрочитатьДатуJSON. Сначала читаем JSON методом ПрочитатьJSON, а свойства с типом дата дополнительно читаем методом ПрочитатьДатуJSON. Первым параметром передается строковое представление даты, вторым формат даты. Результатом выполнения функции будет значение с типом дата:
Дата = ПрочитатьДатуJSON ( Формат ( Данные . СвойствоСДатой , "ЧГ=0" ) , ФорматДатыJSON . ISO ) ;Функции преобразования и восстановления
Функция преобразования
Для возможности выгрузки данных прикладных типов 1С можно использовать функцию преобразования. Данная функция указывается в методе ЗаписатьJSON четвертым параметром. Она должна быть экспортной. Пятым параметром указывается где находится данная функция (если в этом же модуле, то нужно указать ЭтотОбъект). Шестым параметром можно указать произвольные дополнительные данные, которые будут переданы в функцию преобразования. Данная функция будет вызвана для тех типов, которые по умолчанию не сериализуются в JSON. Функция вызывается для всех свойств, включая вложенные свойства, а также для элементов массива.
Например, выгрузим контрагента, у которого в реквизите ДатаРегистрации содержится дата, в реквизите ОсновнойДоговор ссылка на справочник Договоры, а в табличной части список контактных лиц. Причем одно контактное лицо указано строкой, а второе ссылкой на справочник Контактные лица:
Читайте также: