Проверка заполнения полей одной строкой

Публикация № 794486

Программирование - Практика программирования

ПроверкаЗаполнения реквизиты поля проверка заполнения

7
Функция для проверки заполнения полей.

Иногда не хочется писать большой блок проверки заполнения полей типа "Если ЗначениеЗаполнено(Реквизит1) и ЗначениеЗаполнено(Реквизит2) ИЛИ ЗначениеЗаполнено(Реквизит3) И НЕ ЗначениеЗаполнено(Реквизит4) и т.д. Тогда ...". Данная портянка усложняет читаемость кода.

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

//СтрокаУсловия - строка условия, н-р: "(Контрагент + Организация) * ^Договор"

//СтрокаОшибки - если неправильно написано условие или условие не выполнилось, то здесь будет текст ошибки

// "*" - логическое "И", "+" - логическое "ИЛИ", "^" - Логическое "НЕ".
 

Функция ПроверитьЗаполнениеРеквизитов(Знач Источник, Знач СтрокаУсловия, СтрокаОшибки = "") Экспорт
    СтрокаУсловия = СтрЗаменить(СтрокаУсловия, " ", "");
    
    RegExp = Новый COMОбъект("VBScript.RegExp");// создаем объект для работы с регулярными выражениями
    RegExp.MultiLine = Истина;  // истина — текст многострочный, ложь — одна строка
    RegExp.Global = Истина;     // истина — поиск по всей строке, ложь — до первого совпадения
    RegExp.IgnoreCase = Истина; // истина — игнорировать регистр строки при поиске
    Шаблон = "[\wа-яА-ЯёЁ]+";
    RegExp.Pattern = Шаблон;
    ПроверкаСоответствияШаблону = RegExp.test(СтрокаУсловия);
    Если НЕ ПроверкаСоответствияШаблону Тогда
        СтрокаОшибки = "Некорректно задано условие проверки заполнения полей";
        Возврат Ложь;
    КонецЕсли;
    СтрокаРезультат = RegExp.Replace(СтрокаУсловия, "(ЗначениеЗаполнено(Источник.$&))"); //формируем код условия
    СтрокаРезультат = СтрЗаменить(СтрокаРезультат, "*", " И ");
    СтрокаРезультат = СтрЗаменить(СтрокаРезультат, "+", " ИЛИ ");
    СтрокаРезультат = СтрЗаменить(СтрокаРезультат, "^", " НЕ ");
    РезультатПроверки = ЛОЖЬ;
    Попытка
        Выполнить("РезультатПроверки = " + СтрокаРезультат);
    Исключение
        СтрокаОшибки = "Некорректно задано условие проверки заполнения полей";
        Возврат Ложь;
    КонецПопытки;
    Если НЕ РезультатПроверки Тогда 
        //Если условие не выполнилось
        КоллекцияНайденныхПодстрок = RegExp.Execute(СтрокаУсловия);
        СтрокаОшибки = "Нарушены условия заполнения полей:" + Символы.ПС;
        Для Счетчик = 0 По КоллекцияНайденныхПодстрок.count - 1 Цикл
            СтрокаОшибки = СтрокаОшибки + КоллекцияНайденныхПодстрок.Item(Счетчик).Value + ", ";
        КонецЦикла;
        СтрокаОшибки = Лев(СтрокаОшибки, СтрДлина(СтрокаОшибки) - 2);
    КонецЕсли;
    Возврат РезультатПроверки;
КонецФункции

Примеры использования инструмента:

1)

стр = "";
Источник = Новый Структура("аа, бб, вв", 1,,3);

Если НЕ ДополнительныеФункции.ПроверитьЗаполнениеРеквизитов(Источник, "аа*бб +  ^вв   ", стр) Тогда
   сообщить(стр);
   //Ещё кусок кода
КонецЕсли;

В результате появится сообщение:

"Нарушены условия заполнения полей:
аа, бб, вв".

2) 

стр = "";
Источник = Новый Структура("аа, бб, вв", 1,,3);
Если НЕ ДополнительныеФункции.ПроверитьЗаполнениеРеквизитов(Источник, "аа + ^бб ", стр) Тогда
   сообщить(стр);
   //Ещё кусок кода
КонецЕсли;

В результате ничего не появится, так как проверка прошла успешно.

Минусы инструмента:

1) в случае сложной какой-нибудь проверки - неполноценная формулировка по поводу заполнения полей (выводится общая фраза с перечислением всех полей)

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

7

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. ice-net 15 05.03.18 09:56 Сейчас в теме
Мне кажется не проще. Обычно сложные условия предполагают несколько ветвей кода, например:

Если перем1 и перем2 Тогда
//...общий блок1
Если перем1 тогда
//..что-то еще
КонецЕсли;
ИначеЕсли Перем1 тогда
//..еще какой-то вариант
Иначе 
//...
конецесли;
Показать

В Вашем случае предполагается только выполнение или не выполнение одного блока.

Да и вопрос еще что сложнее к пониманию, следующим программистам не надо лезть в ДополнительныеФункции и смотреть что же делает эта функция..:
Источник = Новый Структура("Перем1, Перем2, Перем3, Перем4",Истина,Неопределено,ОбщегоНазначения.ОбработатьКакуюНибудьПеременнуюИПолучитьРезультат(Переменная3), -18);
Если НЕ ДополнительныеФункции.ПроверитьЗаполнениеРеквизитов(Источник, "Перем1*Перем2+  ^Перем3 * Перем4", стр) Тогда
//...
КонецЕсли

Или..
Перем1 = ЗначениеЗаполнено(Истина);
Перем2 = ЗначениеЗаполнено(Неопределено);
Перем3 = ЗначениеЗаполнено(ОбщегоНазначения.ОбработатьКакуюНибудьПеременнуюИПолучитьРезультат(Переменная3));
Перем4 = ЗначениеЗаполнено(-18);
Если НЕ (Перем1 И Перем2            ИЛИ       НЕ Перем3  И Перем4) Тогда
//...
КонецЕсли
Показать
2. aleximus 7 05.03.18 13:56 Сейчас в теме
Закралась ошибка в начальный код:
Было
Функция ПроверитьЗаполнениеРеквизитов(Источник, Знач СтрокаУсловия, СтрокаОшибки = "") Экспорт
Изменил на:
Функция ПроверитьЗаполнениеРеквизитов(Знач Источник, Знач СтрокаУсловия, СтрокаОшибки = "") Экспорт

Функция удобна для проверки не только реквизитов структуры, но и формы (для неё и делал изначально), например:
Если НЕ ДополнительныеФункции.ПроверитьЗаполнениеРеквизитов(Объект, "Р1 * Р2 * ... * Рn, стр) Тогда
...
КонецЕсли;
Оставьте свое сообщение