Содержание:
1. Когда возникает необходимость проверить наличие реквизита 1С?
2. Как можно получить метаданные объекта 1С?
1. Когда возникает необходимость проверить наличие реквизита 1С
Потребность проверки наличия реквизита обычно возникает при написании общих, универсальных процедур или функций, к примеру, когда необходимо выполнить ряд однообразных действий, проверить заполнение перед проведением, при этом реквизитный состав обрабатываемых объектов метаданных отличается незначительно (например, в документе, отражающем продажу товара, есть реквизит Склад, а в документе, отражающем перемещение товара – реквизиты Склад-отправитель и Склад-получатель).
В ряде типовых конфигураций 1С предлагается стандартная функция проверки наличия реквизита в объекте (расположена в модуле “ОбщегоНазначения”)
Функция ЕстьРеквизитОбъекта(ИмяРеквизита, МетаданныеОбъекта) Экспорт
Возврат НЕ (МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита) = Неопределено);
КонецФункции
2. Как можно получить метаданные объекта 1С
Однако написать свою функцию также не представляет труда. В первую очередь необходимо получить метаданные объекта 1С одним из способов:
через функцию Метаданные() объекта
пример синтаксиса: СправочникСсылка.Метаданные()
ДокументСсылка.Метаданные()
через свойство глобального контекста Метаданные
пример синтаксиса: Метаданные.Справочники.[ИмяСправочника]
Метаданные.Документы.[ИмяДокумента]
Далее через свойство “Реквизиты” использовать функцию Найти(). В случае, если реквизит не найден, возвращается значение Неопределено.
Пример 1
Метаданные = Контрагент.Метаданные();
Если Метаданные.Реквизиты.Найти(«Ответственный») = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
Пример 2
Функция ПолучитьОрганизацию(Контрагент, Пользователь)
Если Метаданные.Справочники.Контрагенты.Реквизиты.Найти(«Организация») <> Неопределено Тогда
Возврат Контрагент.Организация;
Иначе
Возврат Пользователь.Организация;
КонецЕсли;
КонецФункции
Описанный алгоритм подходит для случаев проверки наличия реквизита шапки. Но что делать, когда возникает необходимость определить, существует ли реквизит в табличной части 1С (справочника или документа)? Для этого используется следующая конструкция:
Метаданные.Справочники.<ИмяСправочника>.ТабличныеЧасти.Реквизиты.Найти(<ИмяОбъектаПоиска>).
При обработке таблиц значений также возможно выполнить проверку существования колонки – в этом случае применяется метод Свойство(), с помощью которого, помимо основной функции – получения значения элемента по указанному имени, можно проверить, имеется ли указанного свойство.
Пример синтаксиса:
Если НЕ ТекущаяСтрока.Свойство(«Исключить») ИЛИ НЕ ТекущаяСтрока.Исключить Тогда
ЗаполнитьЗначенияСвойств(ТаблицаЗагрузки.Добавить(); ТекущаяСтрока);
КонецЕсли;
Специалист компании ООО «Кодерлайн»
Кондренко Анна Сергеевна
Определить наличие реквизита в строке ТЧ |
Я |
07.06.13 — 08:28
Доброго всем.
Есть процедура в которую передается строка ТЧ. Эта входящая строка может быть либо от ТЧ1, либо от ТЧ2. Разница алгоритма процедуры заключается в использовании 1 реквизита ТЧ. В одном случае (у ТЧ1) реквизит есть, а в другом (у ТЧ2) реквизита нет.
Как можно проверить наличие реквизита в строке ТЧ (естественно не имею доступа к самой ТЧ)?
1 — 07.06.13 — 08:29
по второму параметру процедуры?
2 — 07.06.13 — 08:30
(1) это понятно ,что можно еще уточняющий параметр передать. А вот без него можно?
Т.е. имеем только строку ТЧ. Можно определить наличие или отсутствие определенного реквизита в ней или нет?!
3 — 07.06.13 — 08:30
Попытка или второй параметр процедуры
4 — 07.06.13 — 08:31
(2) или как вариант через строку ТЧ выйти на саму ТЧ, а уже в ней проверить?!
5 — 07.06.13 — 08:31
у метаданных спросить можно
6 — 07.06.13 — 08:31
Одна процедура — одно действие. Флаги в параметрах, определяющие ход процедуры, или хуже того, разбор типа параметра — это всё копание в г*код.
7 — 07.06.13 — 08:31
(5) а как ты через метаданные хочешь это сделать?!
8 — 07.06.13 — 08:32
(6) это лишь твое мнение. А я не сторонник пложить километры строк одного и того же кода лишь из-за одного параметра!
9 — 07.06.13 — 08:33
например найти колонку
10 — 07.06.13 — 08:34
(4) РеквизитЕсть = Истина;
Попытка
кк = СтрокаТЧ.РекизитЭтот
Исключение
РеквизитЕсть = Ложь;
КонецПопытки;
Если реквизит есть тогда бла-бла-бла
11 — 07.06.13 — 08:35
(10) А вообще, лучше конечно или второй параметр или другая процедура
12 — 07.06.13 — 08:36
(6) ага. и в случае чего переписать код в трёх местах
13 — 07.06.13 — 08:36
(0) «естественно не имею доступа к самой ТЧ» — ты, естественно, не имеешь. А кто читал СП — тот имеет.
(8) А так же, смотрю, не сторонник давать реквизитам нормальные имена
14 — 07.06.13 — 08:37
(10) это я уже рассматривал. Использовать «попытку» не хотелось.
15 — 07.06.13 — 08:37
(9) ты как всегда гениален, а твои советы как всегда прозаичны.
Найти колонку в чем?
16 — 07.06.13 — 08:38
УИ = Новый УникальныйИдентификатор();
СтруктураПроверки = Новый Структура(«ИмяПроверяемогоПоля», УИ);
ЗаполнитьЗначенияСвойств(СтруктураПроверки,СтрокаТЧ);
Если Структура.ИмяПроверяемогоПоля = УИ Тогда
Сообщить(«Нет такого поля»);
Иначе
Сообщить(«Есть такое поле»);
Конец
17 — 07.06.13 — 08:39
(8) Хорошего кода не бывает километры в одной процедуре.
(12) Кто сказал что нужно дублировать код?
Наоборот, когда у него изменится одна из двух ТЧ, он опять будет г*кодить в этой процедуре.
18 — 07.06.13 — 08:39
(13)
«ты, естественно, не имеешь. А кто читал СП — тот имеет.» — ткни в СП.
«А так же, смотрю, не сторонник давать реквизитам нормальные имена» — это тут причем?!
19 — 07.06.13 — 08:39
(15) А у тебя избыток вариантов?
20 — 07.06.13 — 08:40
(17) ты сказал: «Одна процедура — одно действие». А у меня два действия, которые сходытся в одну процедуру.
21 — 07.06.13 — 08:41
(19) тебе сегодня жена не дала или просто хреновое настроение в связи с погодой?! Хочешь что-то сказать по существу — говори. В противном случае чего пишешь? Толку с таких сообщений 0.
22 — 07.06.13 — 08:43
(18) Если у тебя процедура делает одно и то же с разными реквизитами, то есть неплохие шансы, что эти реквизиты означают одно и то же в разных ТЧ. Но называются, ЧСХ, по-разному.
23 — 07.06.13 — 08:43
(20) Общие для табличных частей поля, обрабатывай одной (считай как базовый класс) процедурой. Особенности каждой ТЧ в своей. Я понимаю 1С отнекивается от ООП, но надо хотя бы понимать принципы…
24 — 07.06.13 — 08:44
(21) Тебя забыл спросить, где мне писать,а где нет
25 — 07.06.13 — 08:44
(21) не тупи
Defender aka LINN ответил по делу, как и всегда
26 — 07.06.13 — 08:45
(22) хреново быть плохим экстасенсом. Ты сделал абсолютно неверные выводы (причем из-за того, что плохо прочел (0))!!! Давай ты не будешь угадывать, а просто ответишь на поставленный вопрос в (0).
27 — 07.06.13 — 08:46
(25) не вижу тут никакого дела.
28 — 07.06.13 — 08:48
(26) В (0) спрашивается, как сделать самопридуманый костыль. Хочешь помощи — потрудись описать ЗАДАЧУ, а не изобретенный твоей левой пяткой метод ее решения.
29 — 07.06.13 — 08:51
(28) Остальные отписавшиеся меня вполне поняли. Если ты подтупливаешь, то это уже твои проблемы. Что-то тут объяснять, расписывать и учить тебя никто не просил.
30 — 07.06.13 — 08:52
«» + строкатч
31 — 07.06.13 — 08:53
(29) То-то я эту тему создал…
32 — 07.06.13 — 08:55
Вообще, ответ тебе в (5) еще дали. Хренли ты тут до сих пор делаешь — мне непонятно. Наверное, нравится, когда тебя пинают.
33 — 07.06.13 — 08:57
(32) прочти (24)
34 — 07.06.13 — 08:59
мне, лично, (16) нравится.
35 — 07.06.13 — 08:59
(32) Просто меня бесят упыри, подобные тебе, которые считают себя пупами земли, считая, что они знают все лучше всех.
Можешь помочь советом — помоги, а расплескивать сопли по поводу «Я такой крутой» нафиг не надо!
36 — 07.06.13 — 08:59
(34) Да, красиво!
нужно будет запомнить.
37 — 07.06.13 — 09:02
Пятница? Самый простой вариант — Попытка Исключение КонецПопытки, без обращения к метаданным и т.д.
38 — 07.06.13 — 09:04
(37) Честно говоря с метаданными не могу догнать.
Как имея одну строку ТЧ через метаданные определить наличие определенного реквизита в ней?!
Ну так ,чисто ради любопытства вопрос.
39 — 07.06.13 — 09:11
(38) Имя строки табличной части формируется следующим образом:
<Префикс полного имени объекта>ТабличнаяЧастьСтрока.<Имя прикладного объекта>.<Имя табличной части>.
Например: СправочникТабличнаяЧастьСтрока.Номенклатура.Состав, где «Номенклатура» — имя справочника, как оно задано в конфигураторе, «Состав» — имя табличной части справочника «Номенклатура».
Смотришь в метаданных реквизиты соответствующей табличной части объекта …
40 — 07.06.13 — 09:15
(34) Жесть какая
41 — 07.06.13 — 09:16
(39) Тип можно получить в разы проще
(33) Даже ответ не можешь сам придумать
42 — 07.06.13 — 09:19
(41) я просто ответил тебе твоими же словами!
А ты давай, продолжай считать себя вершиной эволюции 1С-ка.
43 — 07.06.13 — 09:26
(40) и что тут жестяного? Очень удобный способ проверить наличие чего-то, что другими способами проверить проблематично… Например, наличие реквизита обычной формы…
44 — 07.06.13 — 09:27
Г*код победил. Ничего, рано или поздно силы бобра доберутся до него и (0) его перепишет.
45 — 07.06.13 — 09:27
(43) Для строки ТЧ есть (5).
(42) Приступ попаболи?
46 — 07.06.13 — 09:28
(45) ну боится человек этого слова…
47 — 07.06.13 — 09:35
Метаданные.НайтиПоТипу(ТипЗнч(СтрокаТЧ)).Реквизиты
mzelensky
48 — 07.06.13 — 09:40
(47) Спасибо.
искать метаданные по типу значения не догадался.
0
Как определить какие реквизиты имеются в табличной части документа
ПоступлениеТовара = Метаданные.Документы.ПоступлениеТовара;
Реквизиты = ПоступлениеТовара.ТабличныеЧасти.Товары.Реквизиты;
Для каждого наим из Реквизиты Цикл
Сообщить("Имя реквизита " + наим.Имя +
"; тип реквизита " + наим.Тип);
КонецЦикла;
// Результат:
// Имя реквизита Наименование; тип реквизита Справочник ссылка: Номенклатура
// Имя реквизита Количество; тип реквизита Число
// Имя реквизита Цена; тип реквизита Число
// Имя реквизита Сумма; тип реквизита Число
ПоступлениеТовара = Метаданные.Документы.ПоступлениеТовара;
Реквизиты = ПоступлениеТовара.ТабличныеЧасти.Товары.Реквизиты;
Для каждого наим из Реквизиты Цикл
Сообщить("Имя реквизита " + наим.Имя +
"; тип реквизита " + наим.Тип);
КонецЦикла;
// Результат:
// Имя реквизита Наименование; тип реквизита Справочник ссылка: Номенклатура
// Имя реквизита Количество; тип реквизита Число
// Имя реквизита Цена; тип реквизита Число
// Имя реквизита Сумма; тип реквизита Число
Информация взята с сайта http://helpf.pro
Хотите узнать больше по этому вопросу?
Подпишитесь на нашу рассылку новостей
Подписаться
Чтобы задать вопрос или предложить тему статьи, нажмите на кнопку ниже:
Предложить статью
// Функция «ЕстьРеквизитТабЧастиДокумента»
// Позволяет определить есть ли среди реквизитов табличной части документа
// реквизит с переданным именем.
//
// Параметры:
// ИмяРеквизита — строковое имя искомого реквизита,
// МетаданныеДокумента — объект описания метаданных документа, среди реквизитов которого производится поиск.
// ИмяТабЧасти — строковое имя табличной части документа, среди реквизитов которого производится поиск
//
// Возвращаемое значение:
// Истина — нашли реквизит с таким именем, Ложь — не нашли.
//
Функция ЕстьРеквизитТабЧастиДокумента(ИмяРеквизита, МетаданныеДокумента, ИмяТабЧасти) Экспорт
ТабЧасть = МетаданныеДокумента.ТабличныеЧасти.Найти(ИмяТабЧасти);
Если ТабЧасть = Неопределено Тогда // Нет такой таб. части в документе
Возврат Ложь;
Иначе
Возврат НЕ (ТабЧасть.Реквизиты.Найти(ИмяРеквизита) = Неопределено);
КонецЕсли;
КонецФункции // ЕстьРеквизитТабЧастиДокумента()
Перейти в раздел примеры кода 1С 8.3:
При наличии в конфигурации БСП, желательно использовать метод ЕстьРеквизитИлиСвойствоОбъекта (ссылка выше). Но что делать если конфигурация нетиповая? Вариантов (в зависимости от поставленной задачи) несколько: скопировать метод из БСП, проверить на свойство объекта, проверить через поиск, использовать попытку (не рекомендуется, только как временная заплатка).
Проверка реквизита через свойство объекта в 1С 8.3:
Функция ПроверкаНаСвойствоОбъекта(Объект, ИмяСвойстваОбъекта) Экспорт
ЕстьСвойство = Ложь;
СтруктураОбъекта = Новый Структура(ИмяСвойстваОбъекта, Неопределено);
ЗаполнитьЗначенияСвойств(СтруктураОбъекта, Объект);
Если СтруктураОбъекта[ИмяСвойстваОбъекта] = Неопределено Тогда
СтруктураОбъекта[ИмяСвойстваОбъекта] = Ложь;
ЗаполнитьЗначенияСвойств(СтруктураОбъекта, Объект);
Если СтруктураОбъекта[ИмяСвойстваОбъекта] <> Ложь Тогда
ЕстьСвойство = Истина;
КонецЕсли;
Иначе
ЕстьСвойство = Истина;
КонецЕсли;
Возврат ЕстьСвойство;// Булево
КонецФункции
Проверка реквизита через Найти в 1С 8.3:
Функция ПроверитьНаРеквизит(ИмяРеквизита, МетаданныеДок) // универсальная функция
// Например ИмяРеквизита=»ДрагМеталлы»;
Если МетаданныеДок.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Функция НайтиДрагМеталлы(Номенклатура, Материал, ОсновноеСредство) // пример использования в универсальной обработке
// если реквизит шапки
ИмяРеквизита=«ДрагМеталлы»;
Если Метаданные.Справочники.Товары.Реквизиты.Найти(ИмяРеквизита) <> Неопределено Тогда
Возврат Номенклатура.ДрагМеталлы;
ИначеЕсли Метаданные.Справочники.Материалы.Реквизиты.Найти(ИмяРеквизита) <> Неопределено Тогда
Возврат Материал.ДрагМеталлы;
ИначеЕсли Метаданные.Справочники.ОсновныеСредства.Реквизиты.Найти(ИмяРеквизита) <> Неопределено Тогда
Возврат ОсновноеСредство.ДрагМеталлы;
Иначе
Возврат Ложь;
КонецЕсли;
// если реквизит таб.части
//Если НЕ ТекущаяСтрока.Свойство(ИмяРеквизита) ИЛИ НЕ ТекущаяСтрока.ДрагМеталлы Тогда
// ЗаполнитьЗначенияСвойств(ТаблицаДок.Добавить(), ТекущаяСтрока); // приёмник, источник
//КонецЕсли;
КонецФункции
Проверка реквизита через Попытка (&НаКлиенте) в 1С 8.3:
&НаКлиенте
Функция ПроверитьНаНаличиеРеквизитаЧерезПопытку(ИмяРеквизита)
Попытка
РеквизитФормыПоИмени = ЭтаФорма[ИмяРеквизита];
ЕстьРеквизитНаФорме = Истина;
Исключение
ЕстьРеквизитНаФорме = Ложь;
КонецПопытки;
Возврат ЕстьРеквизитНаФорме;
КонецФункции
В определенных задачах можно использовать метод в 1С 8.3:
ПолучитьРеквизиты(GetAttributes)
Синтаксис:
ПолучитьРеквизиты(<Путь>)
Параметры:
<Путь> (необязательный)
Тип: Строка.
Указывает путь к родительскому реквизиту. Если параметр опущен или указана пустая строка, возвращаются реквизиты верхнего уровня.
Возвращаемое значение:
Тип: Массив.
Массив объектов РеквизитФормы.
Описание:
Получает описание реквизитов формы.
Copyright©, «Программист 1С в г.Минске», 06.11.2021
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник
Вопрос Как определить программно, существует ли у документа требуемый реквизит
С давних времен в типовых конфигурациях для этого существовала специальная функция.
В конфигурациях последних редакций эта функция стала более универсальной и кроме того стала неожиданно оригинальной, даже эстетически восхитительной.
Так, на сегодня, в 2019 г., эта функция называется ЕстьРеквизитИлиСвойствоОбъекта и располагается в общем модуле ОбщегоНазначенияКлиентСервер. Обращение к функции:
ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Форма, "ПериодРегистрацииИсправленногоДокумента")
Сама функция проверки выглядит сейчас (2019 год) так:
// Проверяет наличие реквизита или свойства у произвольного объекта без обращения к метаданным. // // Параметры: // Объект - Произвольный - объект, у которого нужно проверить наличие реквизита или свойства; // ИмяРеквизита - Строка - имя реквизита или свойства. // // Возвращаемое значение: // Булево - Истина, если есть. // Функция ЕстьРеквизитИлиСвойствоОбъекта(Объект, ИмяРеквизита) Экспорт КлючУникальности = Новый УникальныйИдентификатор; СтруктураРеквизита = Новый Структура(ИмяРеквизита, КлючУникальности); ЗаполнитьЗначенияСвойств(СтруктураРеквизита, Объект); Возврат СтруктураРеквизита[ИмяРеквизита] <> КлючУникальности; КонецФункции
В типовых конфигурациях 1С по состоянию на 2010 г. для этой цели использовалась функция, например, «ЕстьРеквизитДокумента» общего модуля «ОбщегоНазначения» и была построена на получении метаданных. Обращение к функции:
Если ОбщегоНазначения.ЕстьРеквизитДокумента("БанковскийСчет", МетаданныеДокумента) Тогда ...
где «БанковскийСчет» — пример наименования искомого реквизита,
«МетаданныеДокумента«:
МетаданныеДокумента = ДокументОбъект.Метаданные();
Сама функция проверки (расположенная в общем модуле «ОбщегоНазначения«):
// Позволяет определить есть ли среди реквизитов шапки документа // реквизит с переданным именем. // // Параметры: // ИмяРеквизита - строковое имя искомого реквизита, // МетаданныеДокумента - объект описания метаданных документа, среди реквизитов которого производится поиск. // // Возвращаемое значение: // Истина - нашли реквизит с таким именем, Ложь - не нашли. // Функция ЕстьРеквизитДокумента(ИмяРеквизита, МетаданныеДокумента) Экспорт Если МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда Возврат Ложь; Иначе Возврат Истина; КонецЕсли; КонецФункции // ЕстьРеквизитДокумента()
Next Post
-
v8
-
Программисту 1C
Ср Ноя 10 , 2010
Примеры работы с регистами сведений см. также в Шпаргалке по программированию для системы 1С:Предприятие 8.2 Оглавление 1. Как из регистра сведений «РасчетчикиЗарплатыОрганизации» получить в виде массива всех расчетчиков зарплаты определенного подразделения организации 2. Как добавить запись в непериодический независимый регистр сведений 3. Как считать содержимое непериодического независимого регистра сведений «СобственныеКонтрагенты» […]