// Проверка наличия реквизитов, табличных частей их полей для объекта метаданных
// ПроверяемыеРеквизиты - структура. Ключи - названия реквизитов.
// ПроверяемыеТабличныеЧастиПоля - структура структур. Ключи структуры верхнего уровня - имена ТЧ, Ключи структур нижнего уровня, имена полей.
// Возвращает Тип Булево.
// Пример,
// РеквизитыДляКонтроля = Новый Структура("ДатаСоздания,Автор,ДоговорКонтрагента,Продукт");
// ТаблицыПоляДляКонтроля = Новый Структура;
// ТаблицыПоляДляКонтроля.Вставить("Услуги", Новый Структура("НовоеПоле,СтароеПоле"));
// ТаблицыПоляДляКонтроля.Вставить("Затраты");
// Валидация = ЕстьРеквизитыТабличныеЧастиПоля(ОбъектСсылка, ПроверяемыеРеквизиты, ПроверяемыеТабличныеЧастиПоля);
// Проверит наличие
// реквизитов: ДатаСоздания, Автор, ДоговорКонтрагента, Продукт
// табличный частей: Услуги, Затраты
// для ТЧ Услули полей: НовоеПоле, СтароеПоле
Функция ЕстьРеквизитыТабличныеЧастиПоля(Знач ОбъектСсылка, ПроверяемыеРеквизиты = Неопределено, ПроверяемыеТабличныеЧастиИПоля = Неопределено) Экспорт
УстановитьНаличиеРеквизитовТабличныхЧастейПолей(ОбъектСсылка, ПроверяемыеРеквизиты, ПроверяемыеТабличныеЧастиИПоля);
ЕстьПроверяемые = Истина;
Для Каждого Реквизит Из ПроверяемыеРеквизиты Цикл
// учитываем наличие реквизитов
ЕстьПроверяемые = Реквизит.Значение;
Если НЕ ЕстьПроверяемые Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого СтруктураКонтрольнойТаблицы Из ПроверяемыеТабличныеЧастиИПоля Цикл
Если НЕ ЕстьПроверяемые Тогда
Прервать;
КонецЕсли;
Если ТипЗнч(СтруктураКонтрольнойТаблицы.Значение) <> Тип("Структура") Тогда
// учитываем наличие таблицы, без контроля полей
ЕстьПроверяемые = СтруктураКонтрольнойТаблицы.Значение;
Иначе
// учитываем поля текущей проверяемой таблицы
ПоляТаблицы = СтруктураКонтрольнойТаблицы.Значение;
Для Каждого Поле Из ПоляТаблицы Цикл
ЕстьПроверяемые = Поле.Значение;
Если НЕ ЕстьПроверяемые Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Возврат ЕстьПроверяемые;
КонецФункции
// Возвращает текстовое описание по результату проверки наличия в объекте метаданный реквизитов, таблиц, полей таблиц
// Параметры см. функция ЕстьРеквизитыТабличныеЧастиПоля
// Пример возвращаемого описания:
// Отсутствуют реквизиты: Наименоввание, Масса.
// Отсутствуют таблицы: Издержки.
// В таблице <Обслуживание> отсутствуют поля: ШиринаУлыбки.
// В таблице <УсловияХранения> отсутствуют поля: НеРазмораживать, НеОбливатьЖидкимОзотом.
Функция ОписаниеСтрокойОтсутствуютРеквизитыТабличныеЧастиПоля(Знач ОбъектСсылка, ПроверяемыеРеквизиты = Неопределено, ПроверяемыеТабличныеЧастиИПоля = Неопределено) Экспорт
УстановитьНаличиеРеквизитовТабличныхЧастейПолей(ОбъектСсылка, ПроверяемыеРеквизиты, ПроверяемыеТабличныеЧастиИПоля);
ОтсутствующиеРеквизиты = Новый Массив;
Для Каждого Реквизит Из ПроверяемыеРеквизиты Цикл
// учитываем наличие реквизитов
ЕстьПроверяемые = Реквизит.Значение;
Если НЕ ЕстьПроверяемые Тогда
ОтсутствующиеРеквизиты.Добавить(Реквизит.Ключ);
КонецЕсли;
КонецЦикла;
ОтсутствующиеТаблицы = Новый Массив;
ОтсутствующиеПоляТаблиц = Новый Структура; // Структура массивов, в массивы поместим имена отсутствующих полей
Для Каждого СтруктураКонтрольнойТаблицы Из ПроверяемыеТабличныеЧастиИПоля Цикл
Если ТипЗнч(СтруктураКонтрольнойТаблицы.Значение) <> Тип("Структура") Тогда
// учитываем наличие таблицы, без контроля полей
ЕстьПроверяемые = СтруктураКонтрольнойТаблицы.Значение;
Если НЕ ЕстьПроверяемые Тогда
ОтсутствующиеТаблицы.Добавить(СтруктураКонтрольнойТаблицы.Ключ);
КонецЕсли;
Иначе
// учитываем поля текущей проверяемой таблицы
ПоляТаблицы = СтруктураКонтрольнойТаблицы.Значение;
Для Каждого Поле Из ПоляТаблицы Цикл
ЕстьПроверяемые = Поле.Значение;
Если НЕ ЕстьПроверяемые Тогда
ИмяТаблицы = СтруктураКонтрольнойТаблицы.Ключ;
ОбходилиТаблицу = ОтсутствующиеПоляТаблиц.Свойство(ИмяТаблицы);
Если НЕ ОбходилиТаблицу Тогда
// массив для пустых полей новой проверяемой таблицы
ОтсутствующиеПоляТаблиц.Вставить(ИмяТаблицы, Новый Массив);
КонецЕсли;
ОтсутствующиеПоляТаблиц[ИмяТаблицы].Добавить(Поле.Ключ);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Возврат ПолучитьТекстовоеОписаниеРезультатаПроверки(ОтсутствующиеРеквизиты, ОтсутствующиеТаблицы, ОтсутствующиеПоляТаблиц);
КонецФункции
Функция ПолучитьТекстовоеОписаниеРезультатаПроверки(ОтсутствующиеРеквизиты, ОтсутствующиеТаблицы, ОтсутствующиеПоляТаблиц)
ТекстСообщения = "";
Если ОтсутствующиеРеквизиты.Количество() > 0 Тогда
ТекстСообщения = СтрШаблон("%1 Отсутствуют реквизиты: %2.%3",
ТекстСообщения, СтрСоединить(ОтсутствующиеРеквизиты, ", "), Символы.ПС);
КонецЕсли;
Если ОтсутствующиеТаблицы.Количество() > 0 Тогда
ТекстСообщения = СтрШаблон("%1 Отсутствуют таблицы: %2.%3",
ТекстСообщения, СтрСоединить(ОтсутствующиеТаблицы, ", "), Символы.ПС);
КонецЕсли;
Если ОтсутствующиеПоляТаблиц.Количество() > 0 Тогда
Для Каждого Таблица Из ОтсутствующиеПоляТаблиц Цикл
ИменаНезаполненныхПолей = Таблица.Значение;
Если ИменаНезаполненныхПолей.Количество() > 0 Тогда
ТекстСообщения = СтрШаблон("%1 В таблице <%2> отсутствуют поля: %3.%4",
ТекстСообщения, Таблица.Ключ, СтрСоединить(ИменаНезаполненныхПолей, ", "), Символы.ПС);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ТекстСообщения;
КонецФункции
Процедура УстановитьНаличиеРеквизитовТабличныхЧастейПолей(Знач ОбъектСсылка, ИскомыеРеквизиты = Неопределено, ИскомыеТабличныеЧастиИПоля = Неопределено) Экспорт
ЕслиНеСтруктураСделатьПустойСтруктурой(ИскомыеРеквизиты);
ЕслиНеСтруктураСделатьПустойСтруктурой(ИскомыеТабличныеЧастиИПоля);
МетаданныеОбъекта = ОбъектСсылка.Метаданные();
Реквизиты = МетаданныеОбъекта.Реквизиты;
ТабличныеЧасти = МетаданныеОбъекта.Табличныечасти;
Для Каждого ИскомыйРеквизит Из ИскомыеРеквизиты Цикл
Имя = ИскомыйРеквизит.Ключ;
ЕстьРеквизит = Реквизиты.Найти(Имя) <> Неопределено;
ИскомыеРеквизиты.Вставить(Имя, ЕстьРеквизит);
КонецЦикла;
Для Каждого ИскомаяТЧ Из ИскомыеТабличныеЧастиИПоля Цикл
ИмяТЧ = ИскомаяТЧ.Ключ;
ЕстьТабличнаяЧасть = ТабличныеЧасти.Найти(ИмяТЧ) <> Неопределено;
Если ЕстьТабличнаяЧасть Тогда
НужноПроверитьПоляТЧ = (ТипЗнч(ИскомаяТЧ.Значение) = Тип("Структура"));
Если НужноПроверитьПоляТЧ Тогда
ИскомыеПоля = ИскомаяТЧ.Значение;
ЕслиНеСтруктураСделатьПустойСтруктурой(ИскомыеПоля);
Для Каждого Поле Из ИскомыеПоля Цикл
ИмяПоля = Поле.Ключ;
ИскомыеПоля.Вставить(ИмяПоля, Реквизиты.Найти(ИмяПоля) <> Неопределено);
КонецЦикла;
Иначе
ИскомыеТабличныеЧастиИПоля.Вставить(ИмяТЧ, Истина);
КонецЕсли;
Иначе
ИскомыеТабличныеЧастиИПоля.Вставить(ИмяТЧ, Ложь);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ЕслиНеСтруктураСделатьПустойСтруктурой(Структура)
Если ТипЗнч(Структура) <> Тип("Структура") Тогда
Структура = Новый Структура;
КонецЕсли;
КонецПроцедуры