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

17.10.22

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Тестовая база с демонстрацией концепции
.dt 78,41Kb
24
24 Скачать (1 SM) Купить за 1 850 руб.

Зачем?

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

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

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

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

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

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

 

Почему нет?

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

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

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

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


 

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

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

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

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

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

 

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

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

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

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

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

 

Реализация

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

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

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

 

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

 

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

 

 

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

 

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

См. также

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

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

23.06.2024    7425    bayselonarrend    20    

154

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

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

21.05.2024    20113    dimanich70    81    

144

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

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11216    dsdred    44    

130

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

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

06.10.2023    23753    SeiOkami    48    

135

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

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

28.08.2023    14728    YA_418728146    7    

166

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

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

2 стартмани

22.08.2023    3578    56    progmaster    8    

4

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

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    25519    SeiOkami    31    

113
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
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 1035 17.10.22 11:02 Сейчас в теме
(1) это был мой первый дизайн ))
Но если закинуть во внутреннюю таблицу, то облегчается программная верстка - первая строка, где помещаем во временную таблицу, и последующие становятся идентичны и не требуют флагов.
6. Serg2000mr 670 26.10.22 14:21 Сейчас в теме
(1) Вот мой вариант реализации такого алгоритма:

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

Проверено на 2000 строк - скорость неплохая
Прикрепленные файлы:
Mizhgan42; Dementor; +2 Ответить
3. user1209971 74 18.10.22 22:10 Сейчас в теме
Для этих целей лучше использовать обработчик Динамического списка ПриПолученииДанныхНаСервере
https://xn----1-bedvffifm4g.xn--p1ai/news/2017-12-26-many-values-in-one-cell/
sulfur17; +1 Ответить
4. Dementor 1035 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;
		КонецЦикла;
		СтрокиВложенногоЗапроса.Добавить(
		"ВЫБРАТЬ
		|	" + СтрСоединить(КолонкиВложенногоЗапроса, ",
		|	"));
	КонецЦикла;
	
	Результат.Текст = 
		"ВЫБРАТЬ
	|	" + СтрСоединить(ВыбранныеПоля, ", ") + "
	|ПОМЕСТИТЬ " + НазваниеВременнойТаблицы + "
	|ИЗ
	|(" + 
    СтрСоединить(СтрокиВложенногоЗапроса, "
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|") + ") КАК " + НазваниеВременнойТаблицы;
	
	Возврат Результат;
Показать


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


Вроде как работает
wokituk; annetto; Dementor; +3 Ответить
8. Dementor 1035 06.11.22 15:11 Сейчас в теме
11. wokituk 17 12.08.24 18:30 Сейчас в теме
(7)
Гениально!!!!

Корректировка от Меня:
Я в этом коде заменил
//Если ЗначениеЗаполнено(СтрокаТаблицы[ВыбранноеПоле]) Тогда
Если СтрокаТаблицы[ВыбранноеПоле])<>Null И СтрокаТаблицы[ВыбранноеПоле])<>Неопределено Тогда

т.к. бывает в первой строке пустые значения: 0, ПустаяДата, пустые значения справочников и т.п. (и тогда если не делать такую замену в исходном коде, то не будет типизации)
Dementor; +1 Ответить
9. perepetulichka 909 11.01.23 15:29 Сейчас в теме
Получилось, отлично, спасибо ❤️
Dementor; +1 Ответить
10. Dalglish 26 20.10.23 11:37 Сейчас в теме
Спасибо, очень помог метод!
Dementor; +1 Ответить
Оставьте свое сообщение