gifts2017

Усовершенствованная проверка заполнения реквизитов

Опубликовал Ярослав Волохов (YVolohov) в раздел Программирование - Универсальные функции

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

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

Основные преимущества по сравнению со стандартными процедурами:

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

-================-

// Функция проверяет заполнение шапки или табличной части справочника, документа или плана, бизнес-процесса, задачи
// Параметры:
// пИмяТаблицы (строка) - имя табличной части объекта, если не указано то будет проверятся шапка объекта
// пИменаПолей (массив строк) - имена проверяемых реквизитов объекта
// пВыводитьСообщения - если это свойство установлено в "Истина" то будут выводится сообщения в табло о
//     незаполненных реквизитах таблицы, если не установлено - то не будут
// пСсылка (ссылка) - ссылка на элемент справочника или плана, документ, по которому будет произведена проверка
// Возвращаемое значение:
// Истина - если все реквизиты найдены и заполнены
// Ложь - если хоть один реквизит не заполнен, табличная часть не найдена
// или хоть один реквизит не найден

Функция ПроверитьЗаполнениеТаблицыОбъекта(пИмяТаблицы = Неопределено,
   
пИменаПолей, пВыводитьСообщения = Истина, пСсылка) Экспорт

   
МассивСообщений   = Новый Массив;
   
ЗначениеВозврата  = Истина;
   
МетаданныеОбъекта = пСсылка.Метаданные();

    Если НЕ(
пИмяТаблицы = Неопределено) Тогда
       
МетаданныеТаблицы = МетаданныеОбъекта.ТабличныеЧасти.Найти(пИмяТаблицы);
    Иначе
       
МетаданныеТаблицы = МетаданныеОбъекта;
    КонецЕсли;

   
// Проверка существования табличной части
   
Если НЕ(МетаданныеТаблицы = Неопределено) Тогда

       
МассивМетаданныхРеквизитов  = Новый Массив;
       
МетаданныеРеквизитов        = МетаданныеТаблицы.Реквизиты;

       
// Проверка существования полей
       
Для Каждого ИмяПоля Из пИменаПолей Цикл

           
МетаданныеРеквизита = МетаданныеРеквизитов.Найти(ИмяПоля);

            Если НЕ(
МетаданныеРеквизита = Неопределено) Тогда
               
МассивМетаданныхРеквизитов.Добавить(МетаданныеРеквизита);
            Иначе

                Если
пИмяТаблицы = Неопределено Тогда
                   
МассивСообщений.Добавить("Реквизит шапки с именем '" + ИмяПоля + "' не найден !!!");
                Иначе
                   
МассивСообщений.Добавить("Реквизит табличной части '" + пИмяТаблицы + "' с именем '" +
                   
ИмяПоля + "' не найден !!!");
                КонецЕсли;

               
ЗначениеВозврата = Ложь;
            КонецЕсли;

        КонецЦикла;

       
// Проверка заполнения полей
       
КоличествоСтрокТаблицы = ?(НЕ(пИмяТаблицы = Неопределено), пСсылка[пИмяТаблицы].Количество(), 1);
       
КоличествоСтрокТаблицы = ?(МассивМетаданныхРеквизитов.Количество() > 0, КоличествоСтрокТаблицы, 0);

       
// Обход строк таблицы
       
Для НомерСтрокиТаблицы = 1 По КоличествоСтрокТаблицы Цикл

           
СтрокаТаблицы = ?(НЕ(пИмяТаблицы = Неопределено),
           
пСсылка[пИмяТаблицы].Получить(НомерСтрокиТаблицы - 1), пСсылка);

           
// Обход списка проверяемых реквизитов
           
Для Каждого ЭлементМетаданныхРеквизитов Из МассивМетаданныхРеквизитов Цикл

               
// Получение значения ячейки и проверка ее заполнения
               
ЗначениеЯчейкиТЧ = СтрокаТаблицы[ЭлементМетаданныхРеквизитов.Имя];
               
ЯчейкаПустая     = НЕ(ЗначениеЗаполнено(ЗначениеЯчейкиТЧ));

               
// Если значение пустое, добавляем сообщение в массив сообщений
               
Если ЯчейкаПустая Тогда

                    Если
пИмяТаблицы = Неопределено Тогда
                       
МассивСообщений.Добавить("Реквизит шапки с именем '" + ЭлементМетаданныхРеквизитов.Имя + "' не заполнен !!!");
                    Иначе
                       
МассивСообщений.Добавить("В строке № " + НомерСтрокиТаблицы + " табличной части '" +
                       
пИмяТаблицы + "' не заполнен реквизит с именем '" + ЭлементМетаданныхРеквизитов.Имя + "' !!!");
                    КонецЕсли;

                   
ЗначениеВозврата = Ложь;

                КонецЕсли;

            КонецЦикла;

        КонецЦикла;

    Иначе
       
МассивСообщений.Добавить("Табличная часть с именем '" + пИмяТаблицы + "' не найдена !!!");
       
ЗначениеВозврата = Ложь;
    КонецЕсли;

   
// Здесь выводим все сообщения
   
Если пВыводитьСообщения Тогда

        Для Каждого
ТекстСообщения Из МассивСообщений Цикл
           
Сообщить(ТекстСообщения, СтатусСообщения.Важное);
        КонецЦикла;

    КонецЕсли;

    Возврат
ЗначениеВозврата;

КонецФункции

См. также

Подписаться Добавить вознаграждение

Комментарии

2. Ярослав Волохов (YVolohov) 14.03.11 17:03
(1) Не видел. Но это разные вещи. В одном случае единичная функция, в другом целая подсистема с возможностью тонкой настройки и кучей фич. Думаю и тот и другой продукт может быть полезен.
3. Игорь Исхаков (Ish_2) 17.03.11 17:54
Если (ТипЗначенияЯчейкиТЧ = Тип("Число")) и (ЗначениеЯчейкиТЧ = 0) Тогда
ЯчейкаПустая = Истина;
ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип("Строка")) и (ПустаяСтрока(ЗначениеЯчейкиТЧ)) Тогда
ЯчейкаПустая = Истина;
ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип("Дата")) и (ЗначениеЯчейкиТЧ = '00010101000000') Тогда
ЯчейкаПустая = Истина;
ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип("Булево")) Тогда
ЯчейкаПустая = Ложь;
ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип("Неопределено")) Тогда
ЯчейкаПустая = Истина;


Не понял. Для чего тогда встроенная функция "ЗначениеЗаполнено(ЗначениеЯчейкиТЧ)" ?
Для "хранилища",наверное, проверку можно оставить.
И почему
ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип("Булево")) Тогда
ЯчейкаПустая = Ложь;

Логичнее результат функции "ЗначениеЗаполнено()" для булевого параметра : если параметр = "ложь" ,то ячейка считается незаполненной .

Через "Попытку" определять заполненность ссылочного значения - это совсем плохо.
4. Ярослав Волохов (YVolohov) 18.03.11 10:08
(3) Не знал про эту функцию. Спасибо за подсказку. В ближайшее время допилю.

А вот булевское значение я тоже думал сначала проверять на "параметр = ложь". Но потом решил этого не делать. Если некий реквизит должен постоянно иметь значение "Истина", то он просто не имеет смысла.
5. Игорь Исхаков (Ish_2) 18.03.11 10:11
(4) Функция ЗначениеЗаполнено() может вызывать ошибку для каких-то типов данных. Сейчас не вспомню.
6. Ярослав Волохов (YVolohov) 18.03.11 10:19
(5) Попробую погуглить. А хранилище значения наверное лучше вообще не проверять. Думаю это может повлиять на производительность (если программа извлекает значение из хранилища, чтобы проверить его заполненность).
7. Иван (Spartan) 18.03.11 10:23
(5),(6) Для мутабельных...
YVolohov; Ish_2; +2 Ответить
8. Ярослав Волохов (YVolohov) 18.03.11 10:57
Значения примитивных типов и ссылки все не мутабельны. В теории функция должна работать даже с хранилищем значения.
9. Ярослав Волохов (YVolohov) 21.03.11 19:34
Обновил публикацию. Теперь для проверки заполнения значения использую встроенную функцию ЗначениеЗаполнено(). Тестирование показало, что эта функция игнорирует значения с типами "Булево" и "ХранилищеЗначения" всегда возвращая в результате их проверки "Истина", что в общем достаточно логично.
10. Сергей Ожерельев (Поручик) 21.03.11 19:56
>>> Тестирование показало
Поржало. А в СП заглянуть: Для значений типа Булево всегда возвращается Истина.
11. Ярослав Волохов (YVolohov) 21.03.11 20:07
(10) Это в моем характере, не особо вникать в документацию и изобретать велосипеды. Иногда вредно а иногда здорово помагает :D
12. Игорь Исхаков (Ish_2) 22.03.11 08:14
(9) Ага,в (3) ошибка. В функции "ЗначениеЗаполнено()" для параметра булевого типа выдается только "Истина".
13. Ярослав Волохов (YVolohov) 22.03.11 13:18
(12) Нет, ошибки там не будет. Переменная "ЯчейкаПустая" будет всегда принимать значение "Ложь", т.е. всегда будет считаться не пустой, независимо от значения. Сейчас (после обновления) я ипользовал для этого оператор НЕ:

ЯчейкаПустая = НЕ(ЗначениеЗаполнено(ЗначениеЯчейкиТЧ));
14. Igor E (igea) 14.08.12 15:12
пСсылка (ссылка) - ссылка на элемент справочника или плана, документ.
Этот параметр лучше передавать не ссылкой, а через ЭтотОбъект, т.к. при передаче ссылкой, если документ уже был заведен -заполненный зрительно реквизит будет передаваться пустым из процедуры ПередЗаписью. У меня была такая проблема. А так автору респект и большой ПЛЮС.
shoy; YVolohov; +2 Ответить
15. shoy Андрей ais (shoy) 22.08.14 12:06
(1) Публикация не найдена!

В целом неплохой код и можно использовать. Можно через подписку на события проверять доки, например.
Конечно, код чуть править придётся.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа