Как передать Таблицу Значений в Динамический Список?

17.10.22

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

До версии 8.3.9 ответ однозначен - никак. Потом были добавлены временные таблицы для динамических списков, но официальный ответ остался неизменным - никак. Ну а если очень надо?

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

Наименование Файл Версия Размер
Тестовая база с демонстрацией концепции
.dt 78,41Kb
11
.dt 78,41Kb 11 Скачать

Зачем?

Динамический Список - это очень мощный и удобный инструмент пользователя для работы с данными базы. Но у него есть ограничение - работа только с данными базы. Хотя иногда хочется их дополнительно "обогатить".

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

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

Мой опыт и анализ форумов по ключевым словам показывают, что есть две основные альтернативы для решения данного класса задач:

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

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

 

Почему нет?

Обычно в запросах для передачи Таблицы Значений для заполнения Временной Таблицы мы используем установку этой таблицы в качестве параметра, а далее используем этот параметр в секции ИЗ нашей Временной Таблицы. Если мы попробуем сделать такое с Динамическим Списком, то получим ошибку еще при попытке внести данные в конструкторе этого реквизита формы:

Проблема заключена в типе ТаблицаЗначений ('{http://v8.1c.ru/8.1/data/core}ValueTable'), который необъяснимо невзлюбили и запретили перемещать между клиентом и сервером (состояние на версию 8.3.22).

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

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


 

Что нам доступно?

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

Так же, несмотря на то, что Динамический Список использует технологию СКД, но он использует её ограниченно - в качестве источника данных можно передавать исключительно текст запроса. Никаких Таблиц Значений, Табличных Частей, Выборок из Результатов Запроса и тому подобного!

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

В принципе этого достаточно для решения нашей задачи. Напомню, что в описании запроса обязательной секцией является только ВЫБРАТЬ, но вовсе не ИЗ. Так же напомню, что ТаблицаЗначений - это всего лишь двухмерный массив, где на пересечении строк и колонок хранятся значения, которым разрешено быть параметрами Динамического Списка.

 

Описание концепции

Если нельзя напрямую использовать Таблицу Значений, то будем ее эмулировать с помощью программной верстки текста Временной Таблицы, где для каждой строки будет подзапрос, в котором в секции ВЫБРАТЬ будут перечислены параметры запроса с псевдонимами соответствующих колонок. В результате выполнения такого запроса мы получим требуемую Временную Таблицу, которой "обогатим" данные основного запроса.

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

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

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

 

Реализация

Для демонстрации выберем задачу "видеть актуальные складские остатки во время заполнения документа". В качестве данных нам потребуется справочник "Товары" и два документа - "Приход товаров" и "Расход товаров". Складские остатки будем фиксировать в регистре накопления "Наличие товаров" (оба документа будут регистраторами).

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

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

 

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

 

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

 

 

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

 

ТаблицаЗначений ДинамическийСписок УправляемаяФорма

См. также

Печать любых непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать любые печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

3480 руб.

22.08.2023    805    1    0    

1

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

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

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

27.03.2023    5465    SeiOkami    10    

129

Версионирование объектов VS История данных

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

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    10147    dsdred    48    

144

Практическая шпаргалка по новым возможностям языка запросов 1С

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

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

21.11.2022    19484    quazare    34    

120

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    13231    102    sapervodichka    106    

118

Шпаргалка по функциям АСИНХ

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

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

29.07.2022    25546    zeltyr    19    

173

Динамическое обновление - это зло?

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

Копнем глубже в тему "Что же такое динамическое обновление" и почему оно может привести к проблемам. И может ли?

09.05.2022    21383    Infostart    82    

232

Модули общего назначения - готовые полезные функции и процедуры конфигураций на БСП

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

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

25.04.2022    12171    quazare    11    

136
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. SlavaKron 17.10.22 10:57 Сейчас в теме
В функции ПолучитьВременнуюТаблицуИзТаблицыЗначений зачем формировать временную таблицу из вложенного запроса? Можно же сразу строки помещать во временную таблицу:
ВЫБРАТЬ
	&ЗначениеТЗ_1 КАК Поле1, &ЗначениеТЗ_2 КАК Поле2, &ЗначениеТЗ_3 КАК Поле3
ПОМЕСТИТЬ ВТ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	&ЗначениеТЗ_4, &ЗначениеТЗ_5, &ЗначениеТЗ_6

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	&ЗначениеТЗ_7, &ЗначениеТЗ_8, &ЗначениеТЗ_9

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	&ЗначениеТЗ_10, &ЗначениеТЗ_11, &ЗначениеТЗ_12
Показать


В целом, способ, наверно, имеет право на существование, если количество строк ТЗ не больше 2-3 десятков.
2. Dementor 956 17.10.22 11:02 Сейчас в теме
(1) это был мой первый дизайн ))
Но если закинуть во внутреннюю таблицу, то облегчается программная верстка - первая строка, где помещаем во временную таблицу, и последующие становятся идентичны и не требуют флагов.
6. Serg2000mr 163 26.10.22 14:21 Сейчас в теме
(1) Вот мой вариант реализации такого алгоритма:

https://infostart.ru/public/1748114/

Проверено на 2000 строк - скорость неплохая
Прикрепленные файлы:
Mizhgan42; Dementor; +2 Ответить
3. user1209971 72 18.10.22 22:10 Сейчас в теме
Для этих целей лучше использовать обработчик Динамического списка ПриПолученииДанныхНаСервере
https://xn----1-bedvffifm4g.xn--p1ai/news/2017-12-26-many-values-in-one-cell/
sulfur17; +1 Ответить
4. Dementor 956 19.10.22 10:00 Сейчас в теме
(3) обычно я именно так и делал, но!

У меня была реальная задача с фильтрацией строк, по которым был остаток в регистре накопления, и при таком подходе я не мог дополнительно скрыть строки - только выводить их с нулями. Или может быть обратная задача при складских перемещениях или взаимозачетах - нужно вернуть на динамический список строки, которые ранее отфильтровались в секции ГДЕ запроса - с методом ПриПолученииДанныхНаСервере такие задачи не имеют решения.
5. PersianovMS 23.10.22 13:02 Сейчас в теме
Коллеги, здравствуйте.
Недавно занимался как раз таким же вопросом - и пришёл к такому же решению, только приходилось делать ДС из чисто таблицы значений, не похожей ни на один объект конфигурации. Поэтому, чтобы сохранить возможность отборов, пришлось типизировать колонки по колонкам таблицы значений, а не объекта. Получилась такая функция.
Минус - в ДС не работает отбор по "Подобно".
На паре тысяч строк тормозит, но работает.

&НаСервере
// Преобразует таблицу значений в динамический список. ВНИМАНИЕ! Колонки ДС не обновляются, их надо обновлять функцией СоэдатьКолонкиТаблицы.
// Параметры:
// ДинСписок - Динамический список - Реквизит формы, приёмник
// ТабИсточник - Таблица значений - Источник данных. Не проверялось для больших таблиц.
// ТипизироватьКолонки - Строка - Список через запятую имён колонок или "ВСЕ". Если пустая строка (по умолчанию) - ни одна колонка не типизируется.
// Типизация влияет на применение, например, вида сравнения "в иерархии".
// ИмяПоляКлюча - Строка - Имя специального поля поле с уникальным номером строки. По умолчанию "КлючСтроки". Если пустое - поле ключа не создаётся
Процедура ДинамическийСписокИзТаблицыЗначений(ДинСписок, ТабИсточник, ТипизироватьКолонки = "", ИмяПоляКлюча = "КлючСтроки") Экспорт
ПерваяСтрока = Истина;
#Область ТИПИЗАЦИЯ
Если ТипизироватьКолонки <> "" Тогда
#Область ТАБЛИЦА_ПРИМЕРНЫХ_ЗНАЧЕНИЙ
ОбозначениеПараметра = Новый Цвет;
ТабЗнТипы = ТабИсточник.СкопироватьКолонки();
ТабЗнТипы = Новый ТаблицаЗначений;
Для каждого Колонка Из ТабИсточник.Колонки Цикл
ТабЗнТипы.Колонки.Добавить(Колонка.Имя);
КонецЦикла;
ТабЗнТипы.Добавить();
СтруктураТипизируемыхКолонок = Новый Структура(ТипизироватьКолонки);
Для каждого Колонка Из ТабИсточник.Колонки Цикл
ИмяКолонки = Колонка.Имя;
ТекТипы = Колонка.ТипЗначения.Типы();
Если ТекТипы.Количество() И ?(ТипизироватьКолонки = "ВСЕ", Истина, СтруктураТипизируемыхКолонок.Свойство(ИмяКолонки)) Тогда
ЁХ = 0;
Для каждого Тек_Тип Из ТекТипы Цикл
Если ЁХ = ТабЗнТипы.Количество() Тогда
ТабЗнТипы.Добавить();
КонецЕсли;
ТабЗнТипы[ЁХ][ИмяКолонки] = ПримерноеЗначение(
Тек_Тип,
Колонка.ТипЗначения.КвалификаторыЧисла,
Колонка.ТипЗначения.КвалификаторыСтроки,
Колонка.ТипЗначения.КвалификаторыДаты);
ЁХ = ЁХ + 1;
КонецЦикла;
Иначе
ТабЗнТипы[0][ИмяКолонки] = ОбозначениеПараметра;
КонецЕсли;
КонецЦикла;
#КонецОбласти
#Область ТЕКСТ_ТИПИЗАЦИИ
ТекстТипизации = "";
Для каждого Строчка Из ТабЗнТипы Цикл
ТекстПоСтроке = "";
Для каждого Колонка Из ТабЗнТипы.Колонки Цикл
ТекЗнч = Строчка[Колонка.Имя];
ТекстПоСтроке = ТекстПоСтроке + "," + Символы.ПС
+ ?(ЗначениеЗаполнено(ТекЗнч) И ТекЗнч <> ОбозначениеПараметра, ТекЗнч, "&ПараметрПусто")
+ ?(ПерваяСтрока, " КАК " + Колонка.Имя, "");
КонецЦикла;
Если ЗначениеЗаполнено(ИмяПоляКлюча) Тогда
ТекстПоСтроке = ТекстПоСтроке + "," + Символы.ПС + "0"
+ ?(ПерваяСтрока, " КАК " + ИмяПоляКлюча, "");
КонецЕсли;
ПерваяСтрока = Ложь;
ТекстТипизации = ТекстТипизации + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС + "ВЫБРАТЬ" + Сред(ТекстПоСтроке, 2) + Символы.ПС + "ГДЕ ЛОЖЬ" + Символы.ПС;
КонецЦикла;
#КонецОбласти
КонецЕсли;
#КонецОбласти
#Область ФОРМИРОВАНИЕ_ТЕКСТА_И_ПАРАМЕТРОВ_ЗАПРОСА
#Область ТЕКСТ_ПАРАМЕТРОВ_И_ПАРАМЕТРЫ
ЁХ = 0;
ТекстЗапроса = ТекстТипизации;
НовыеПараметры = Новый Структура;
Для каждого Строчка Из ТабИсточник Цикл
ТекстПоСтроке = "";
Для каждого Колонка Из ТабЗнТипы.Колонки Цикл
ИмяКолонки = Колонка.Имя;
ИмяПараметра = "Строчка" + ?(ЁХ = 0, "0", Формат(ЁХ, "ЧГ=0")) + ИмяКолонки;
ТекЗнч = Строчка[Колонка.Имя];
НовыеПараметры.Вставить(ИмяПараметра, ТекЗнч);
ТекстПоСтроке = ТекстПоСтроке + "," + Символы.ПС + "&" + ИмяПараметра
+ ?(ПерваяСтрока, " КАК " + Колонка.Имя, "");
КонецЦикла;
Если ЗначениеЗаполнено(ИмяПоляКлюча) Тогда
ТекстПоСтроке = ТекстПоСтроке + "," + Символы.ПС + ?(ЁХ = 0, "0", Формат(ЁХ, "ЧГ=0"))
+ ?(ПерваяСтрока, " КАК " + ИмяПоляКлюча, "");
КонецЕсли;
ПерваяСтрока = Ложь;
ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС + "ВЫБРАТЬ" + Сред(ТекстПоСтроке, 2) + Символы.ПС;
ЁХ = ЁХ + 1;
КонецЦикла;
#КонецОбласти
#Область БАЗОВЫЙ_И_ФИНАЛЬНЫЙ_ТЕКСТ
ДинСписок.ТекстЗапроса = Сред(ТекстЗапроса, 16);
Если Найти(ДинСписок.ТекстЗапроса, "&ПараметрПусто") > 0 Тогда
ДинСписок.Параметры.УстановитьЗначениеПараметра("ПараметрПусто", Неопределено);
КонецЕсли;
Для каждого КиЗ Из НовыеПараметры Цикл
ДинСписок.Параметры.УстановитьЗначениеПараметра(КиЗ.Ключ, КиЗ.Значение);
КонецЦикла;
#КонецОбласти
#КонецОбласти
КонецПроцедуры // ДинамическийСписокИзТаблицыЗначений

&НаСервере
// Возвращает примерное значение указанного типа. Для строки, даты и числа это будет значение указанной квалификации, состоящее из единиц,
// для ссылки - пустая ссылка, для остальных = приведение единицы к описанию типа.
// Параметры:
// Источник - Тип - Значение которого надо получить
// КвалификаторЧисла - КвалификаторыЧисла - Квалификатор типа
// КвалификаторСтроки - КвалификаторыСтроки - Квалификатор типа
// КвалификаторДаты - КвалификаторыДаты - Квалификатор типа
// Строкой - Булево - Представить значение в виде строки для текста запроса
// Возвращаемое значение:
// Произвольный - Примерное значение указанного типа
Функция ПримерноеЗначение(Источник, КвалификаторЧисла = "", КвалификаторСтроки = "", КвалификаторДаты = "", Строкой = Истина) Экспорт
Результат = Новый Соответствие;
Если Источник = Тип("Число") Тогда
Если КвалификаторЧисла = "" ИЛИ КвалификаторЧисла.Разрядность = 0 Тогда
Результат = 1;
Иначе
Результат = 0;
Исходная = 1;
Для ЁХ = 1 По КвалификаторЧисла.РазрядностьДробнойЧасти Цикл
Исходная = Исходная / 10;
Результат = Результат + Исходная;
КонецЦикла;
Исходная = 1;
Для ЁХ = 1 По КвалификаторЧисла.Разрядность - КвалификаторЧисла.РазрядностьДробнойЧасти Цикл
Результат = Результат + Исходная;
Исходная = Исходная * 10;
КонецЦикла;
Если КвалификаторЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Любой Тогда
Результат = - Результат;
КонецЕсли;
КонецЕсли;
Если Строкой Тогда
Результат = СтрЗаменить(ФОРМАТ(Результат, "ЧГ=0"), ",", ".");
КонецЕсли;
ИначеЕсли Источник = Тип("Булево") Тогда
Если Строкой Тогда
Результат = "ИСТИНА";
Иначе
Результат = Истина;
КонецЕсли;
ИначеЕсли Источник = Тип("Строка") Тогда
Результат = "";
Если КвалификаторСтроки <> "" Тогда
Для ЁХ = 1 По КвалификаторСтроки.Длина Цикл
Результат = Результат + "1";
КонецЦикла;
КонецЕсли;
Если Строкой Тогда
Результат = """" + Результат + """";
КонецЕсли;
ИначеЕсли Источник = Тип("Дата") ИЛИ Источник = Тип("СтандартнаяДатаНачала") ИЛИ Источник = Тип("СтандартныйПериод") Тогда
Результат = '11111111111111';
мТипов = Новый Массив;
мТипов.Добавить(Тип("Дата"));
ТекОТ = ?(КвалификаторДаты = "", Новый ОписаниеТипов(мТипов), Новый ОписаниеТипов(мТипов,,, КвалификаторДаты));
ИсхДата = ТекОТ.ПривестиЗначение(Результат);
Если Источник = Тип("СтандартнаяДатаНачала") Тогда
Результат = Новый СтандартнаяДатаНачала;
Результат.Дата = ИсхДата;
Если Строкой Тогда
Результат = Неопределено;
КонецЕсли;
ИначеЕсли Источник = Тип("СтандартныйПериод") Тогда
Результат = Новый СтандартныйПериод;
Результат.ДатаНачала = ИсхДата;
Результат.ДатаОкончания = ИсхДата;
Если Строкой Тогда
Результат = Неопределено;
КонецЕсли;
Иначе
Результат = ИсхДата;
Если Строкой Тогда
ТекГод = Год(Результат);
ТекМес = Месяц(Результат);
ТекДень = День(Результат);
ТекЧас = Час(Результат);
ТекМин = Минута(Результат);
ТекСек = Секунда(Результат);
Результат = "ДАТАВРЕМЯ("
+ ?(ТекГод = 0, 1, Формат(ТекГод, "ЧГ=0")) + "," +
+ ?(ТекМес = 0, 1, ТекМес) + "," +
+ ?(ТекДень = 0, 1, ТекДень) + "," +
+ ?(ТекЧас = 0, 1, ТекЧас) + "," +
+ ?(ТекМин = 0, 1, ТекМин) + "," +
+ ?(ТекСек = 0, 1, ТекСек) + ")";
КонецЕсли;
КонецЕсли;
Иначе
Если Строкой Тогда
Результат = ИмяТаблицыОбъектаПоТипу(Источник);
Если Результат = Неопределено Тогда
Результат = "НЕОПРЕДЕЛЕНО";
Иначе
Результат = "ЗНАЧЕНИЕ(" + Результат + ".ПустаяСсылка)"
КонецЕсли;
Иначе
мТипов = Новый Массив;
мТипов.Добавить(Источник);
ТекОТ = Новый ОписаниеТипов(мТипов);
Результат = ТекОТ.ПривестиЗначение(1);
КонецЕсли;
КонецЕсли;
Возврат Результат
КонецФункции // ПримерноеЗначение

Функция ИмяТаблицыОбъектаПоТипу(Тип_, Полностью = Ложь) Экспорт
МетаХ = Метаданные.НайтиПоТипу(Тип_);
Если МетаХ = Неопределено Тогда
Результат = Неопределено
ИначеЕсли Полностью = "Метаданные" Тогда
Результат = МетаХ;
Иначе
ТекИмя = МетаХ.Имя;
Полная = Новый Структура;
НуженМенеджер = (Найти("," + Полностью + ",", ",Менеджер,") > 0) ИЛИ (Полностью = Истина);
Если Метаданные.Документы.Содержит(МетаХ) Тогда
СтрокаТипа = "Документ";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", Документы[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.Справочники.Содержит(МетаХ) Тогда
СтрокаТипа = "Справочник";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", Справочники[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.Перечисления.Содержит(МетаХ) Тогда
СтрокаТипа = "Перечисление";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", Перечисления[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.ПланыВидовХарактеристик.Содержит(МетаХ) Тогда
СтрокаТипа = "ПланВидовХарактеристик";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", ПланыВидовХарактеристик[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.ПланыСчетов.Содержит(МетаХ) Тогда
СтрокаТипа = "ПланСчетов";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", ПланыСчетов[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.ПланыВидовРасчета.Содержит(МетаХ) Тогда
СтрокаТипа = "ПланВидовРасчета";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", ПланыВидовРасчета[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.БизнесПроцессы.Содержит(МетаХ) Тогда
СтрокаТипа = "БизнесПроцесс";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", БизнесПроцессы[ТекИмя]);
КонецЕсли;
ИначеЕсли Метаданные.Задачи.Содержит(МетаХ) Тогда
СтрокаТипа = "Задача";
Если НуженМенеджер Тогда
Полная.Вставить("Менеджер", Задачи[ТекИмя]);
КонецЕсли;
Иначе
Результат = "";
КонецЕсли;
Если ?(Полностью = Истина, Истина, ?(Полностью = Ложь, Истина, Найти("," + Полностью + ",", ",ИмяТаблицы,") > 0)) Тогда
Полная.Вставить("ИмяТаблицы", СтрокаТипа + "." + ТекИмя);
КонецЕсли;
Если ?(Полностью = Истина, Истина, Найти("," + Полностью + ",", ",Текст,") > 0) Тогда
Полная.Вставить("Текст", СтрокаТипа + ТекИмя);
КонецЕсли;
Если ?(Полностью = Истина, Истина, Найти("," + Полностью + ",", ",Метаданные,") > 0) Тогда
Полная.Вставить("Метаданные", МетаХ);
КонецЕсли;
Результат = Полная;
Если Результат.Количество() = 1 Тогда
Для каждого КиЗ Из Полная Цикл
Результат = КиЗ.Значение;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Результат
КонецФункции // ИмяТаблицыОбъектаПоТипу()
7. lexushka 05.11.22 19:23 Сейчас в теме
Как сказал наш коллега на Мисте, я как все 1с-ники ленив
Поэтому мой код для ВЫРАЗИТЬ несколько короче


Функция ПолучитьВременнуюТаблицуИзТаблицыЗначений(Таблица, НазваниеВременнойТаблицы, ТекстПустойТаблицы) Экспорт

	Результат = Новый Структура("Текст, Параметры", ТекстПустойТаблицы, Новый Структура);
	Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") ИЛИ Таблица.Количество() = 0 Тогда
		Возврат Результат;
	КонецЕсли;

	ВыбранныеПоля = Новый Массив;
	Для каждого Колонка Из Таблица.Колонки Цикл
		ВыбранныеПоля.Добавить(Колонка.Имя);
	КонецЦикла;
	
	НомерПараметра = 1;
	СтрокиВложенногоЗапроса = Новый Массив;
	Для каждого СтрокаТаблицы Из Таблица Цикл
		КолонкиВложенногоЗапроса = Новый Массив;
		Для каждого ВыбранноеПоле Из ВыбранныеПоля Цикл
			ИмяПеременной = "ЗначениеТЗ_" + Формат(НомерПараметра, "ЧН=; ЧГ=");
			Результат.Параметры.Вставить(ИмяПеременной, СтрокаТаблицы[ВыбранноеПоле]);
			
			//Добавление ВЫРАЗИТЬ КАК
			Если ЗначениеЗаполнено(СтрокаТаблицы[ВыбранноеПоле]) Тогда
				Если Метаданные.НайтиПоТипу(ТипЗнч(СтрокаТаблицы[ВыбранноеПоле])) = Неопределено
					Тогда 
					СтрокаКАК = Строка(ТипЗнч(СтрокаТаблицы[ВыбранноеПоле]));
				Иначе          
					СтрокаКАК = Метаданные.НайтиПоТипу(ТипЗнч(СтрокаТаблицы[ВыбранноеПоле])).ПолноеИмя();
				КонецЕсли;
				ТекстПараметра = "ВЫРАЗИТЬ(&" + ИмяПеременной + " КАК " + СтрокаКАК + ")";
				
			Иначе
				ТекстПараметра = "&" + ИмяПеременной;
			КонецЕсли;
			КолонкиВложенногоЗапроса.Добавить(ТекстПараметра + " КАК " + ВыбранноеПоле);
			//
			
			//КолонкиВложенногоЗапроса.Добавить("&" + ИмяПеременной + " КАК " + ВыбранноеПоле);
			НомерПараметра = НомерПараметра + 1;
		КонецЦикла;
		СтрокиВложенногоЗапроса.Добавить(
		"ВЫБРАТЬ
		|	" + СтрСоединить(КолонкиВложенногоЗапроса, ",
		|	"));
	КонецЦикла;
	
	Результат.Текст = 
		"ВЫБРАТЬ
	|	" + СтрСоединить(ВыбранныеПоля, ", ") + "
	|ПОМЕСТИТЬ " + НазваниеВременнойТаблицы + "
	|ИЗ
	|(" + 
    СтрСоединить(СтрокиВложенногоЗапроса, "
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|") + ") КАК " + НазваниеВременнойТаблицы;
	
	Возврат Результат;
Показать


КонецФункции // ПолучитьВременнуюТаблицуИзТаблицыЗначений()


Вроде как работает
Dementor; +1 Ответить
8. Dementor 956 06.11.22 15:11 Сейчас в теме
(7) хороший вариант.
9. perepetulichka 867 11.01.23 15:29 Сейчас в теме
Получилось, отлично, спасибо ❤️
Dementor; +1 Ответить
Оставьте свое сообщение