Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как программно разрешить или запретить сохранение реквизита...
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 7.7
Victor Skif
Добрый вечер.
1С 7.70.027.
Формекс.

Наведите на мысль, плз.

Имеем форму списка справочника. Пользователь редактирует реквизит. Когда он нажимает Энтер - необходимо программно проверять введенное значение (частный случай - проверить уникальность), и в зависимости от результатов проверки, разрешить или запретить сохранение. Как это по-нормальному сделать? Что-то у меня не придумывается. Отследить нажатие энтера, и устроить проверку - можно в назначенной реквизиту процедуре. Но как в ней сказать, что это значение не годится, и запретить его сохранять?
Gazulo
Victor Skif @ Вчера, 23:08 необходимо зарегистрироваться для просмотра ссылки ,
Примерно так
Сообщить("Ваше сообщение");
ВашРеквизит = "";
Victor Skif
Gazulo @ Сегодня, 18:52 необходимо зарегистрироваться для просмотра ссылки ,

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

Можно, конечно, его ре-активизировать программно (прямо нельзя, через ложное закрытие можно), и подставить заранее сохраненное старое значение... Но это некрасиво ) Похоже, нет менее геморройного способа?
Bernet
Victor Skif @ Вчера, 19:51 необходимо зарегистрироваться для просмотра ссылки ,
Проверку делайте в модуле объекта в процедуре "Перед записью" - выполняете свою проверку, если проверку не прошло пишите Отказ = Истина и ниже сообщение что пользователь ввел херню. Тогда выдаст сообщение и не даст сохранить изменения

P.S. провтыкал что это должно быть на 7-ку, на 7-ке не знаю, я с ней стараюсь не стыкаться
Стрелок
В ПриЗаписи делаете следующее
1. создаете объект типа текущего справочника
2. находите текущий элемент
3. сравниваете текущее значение реквизита (оно доступно в контексте формы) со значением из найденной ссылки или с допустимым значением (то что "не херня"). Не прошла проверка - СтатусВозврата(0) и Возврат. И Вы остаетесь в режиме редактирования. а по esc вернете старое значение.

у меня по такому принципу работает моя расширенная система логирования изменений в документах. Система фиксирует старое значение реквизита, новое значение реквизита и позволяет "откатить" назад все изменения внесенные в документ
Flexy
Зачем так сложно?
В свойствах поля ввода на закладке "Дополнительно" в поле "Формула" пишите имя Вашей процедуры, в которой будут происходить проверка введенного значения. Напр. ПроверитьЗначение().
В модуле формы:
Процедура ПроверитьЗначение()
Если МойРеквизит <> НужноеЗначение Тогда
        Возврат;
КонецЕсли;
КонецПроцедуры
Стрелок
Flexy @ Сегодня, 17:47 необходимо зарегистрироваться для просмотра ссылки ,

не сработает.
volodya1122
Цитата(Стрелок @ 26.12.17, 18:07) необходимо зарегистрироваться для просмотра ссылки
Flexy @ Сегодня, 17:47 * ,

не сработает.


Повністю робочий варіант. В мене таким методом контролюється введення години в текстовий реквізит. І якщо формат години не відповідає 24:60 то по "ентеру" вийти з редагування цього реквізиту неможливо.
Стрелок
volodya1122 @ Сегодня, 10:03 необходимо зарегистрироваться для просмотра ссылки ,

серьезно? а можно код посмотреть этого чуда smile.gif
прям глаза открыли мне smile.gif
или вы тоже путаете предопределенные процедуры (например ПриЗаписи) в которых срабатывает СтатусВозврата(0) и Возврат() и процедуры срабатывающие при ЗАВЕРШЕНИИ редактирования реквизита?
просто "возврат" означает выход из процедуры но никак не возврат в режим редактирования

и как интересно происходит запуск процедуры проверки корректности формата если процедура прописанная в свойствах реквизита формы стартует именно при нажатии ENTER (или потери фокуса реквизита формы - переход например по Tab или мышкой)
volodya1122
Стрелок @ Вчера, 14:20 необходимо зарегистрироваться для просмотра ссылки ,
Все елементарно, Ватсон.
На реквізиті (на формі) вішаємо процедуру (вводГодини()) і прописуємо маску 99:99 - Все в розділі Дополнительно.
Сама процедура
Процедура вводГодини()  
//ГодОпл    
//Если СтрДлина(СокрЛП(ГодОпл))=3 тогда
// ГодОпл="0"+СокрЛП(ГодОпл);    
Если СтрДлина(СокрЛП(ГодОпл))=4 тогда
    Симв2=Сред(СокрЛП(ГодОпл),2,1);
    Если (Симв2="1") или (Симв2="2") или (Симв2="3") или (Симв2="4") или (Симв2="5") или (Симв2="6") или (Симв2="7") или (Симв2="8") или (Симв2="9") или (Симв2="0") тогда
    иначе
    ГодОпл="0"+СокрЛП(ГодОпл);
//    Возврат;
    КонецЕсли;
Иначеесли СтрДлина(СокрЛП(ГодОпл))<4 тогда
Предупреждение("Ще не заповнена година розпломбування",0);
Возврат;
КонецЕсли;      

год=Лев(СокрЛП(ГодОпл),2);
хв=Прав(СокрЛП(ГодОпл),2);  
хв2=Лев(хв,1);
хв1=Прав(хв,1);
Если (хв1="1") или (хв1="2") или (хв1="3") или (хв1="4") или (хв1="5") или (хв1="6") или (хв1="7") или (хв1="8") или (хв1="9") или (хв1="0") тогда
иначе
Предупреждение("Невірно задано хвилини");
Возврат;
КонецЕсли;     
Если (хв2="1") или (хв2="2") или (хв2="3") или (хв2="4") или (хв2="5") или (хв2="0") тогда
иначе
Предупреждение("Невірно задано хвилини");
Возврат;
КонецЕсли;  
год1=Прав(год,1);
год2=Лев(год,1);
Если (год1="1") или (год1="2") или (год1="3") или (год1="4") или (год1="5") или (год1="6") или (год1="7") или (год1="8") или (год1="9") или (год1="0") тогда
иначе
Предупреждение("Невірно задано годину");
Возврат;
КонецЕсли;
Если (год2="1") или (год2="2") или (год2="0") тогда
иначе
Предупреждение("Невірно задано годину");
Возврат;
КонецЕсли;


если Число(год)>23 тогда
Предупреждение("Невірно задано годину");
Возврат;
КонецЕсли;

если Число(хв)>59 тогда
Предупреждение("Невірно задано хвилини");
Возврат;
КонецЕсли;

ГодОпл=год+":"+хв;
ВирахЧасРемонту()

КонецПроцедуры


Хоча код зовсім не ідеальний (писав давно, а переписувати не хочеться).
Як все відбувається. Користувач набирає на формі годину (наприклад 12:75) нажимає "ентер" А йому на екран повідомлення"про невірні хвилини. і знову повертається до того самого реквізиту для виправлення години. Тобто при неправильній годині по "єнтер" користувач не зможе перейти до редагування слідуючого реквізиту.
Стрелок
volodya1122 @ Вчера, 9:38 необходимо зарегистрироваться для просмотра ссылки ,

1. вводим "00:88"
2. тыкаем энтер
3. получаем предупреждение
4. тыкаем мышкой на другой реквизит или Табом и вуаля- попадаем на следующий реквизит без всяких проверок

понятна логика? процедура в "дополнительно" срабатывает ТОЛЬКО если значение реквизита изменено и ТОЛЬКО один раз. Для нового срабатывания нужно чтобы реквизит опять изменился.
вот поэтому и "не сработает". Конечно можно в вашей процедуре Холмс поставить ГодОпл="00:00" (эта комбинация не проверяется в коде никак). Но даже если поставить ошибочное значение реквизита
то мышкой или табулятором проверка спокойно игнорируется... так что.....

ЗЫ
и код не "не идеальный". он ужасный. я бы руки отрывал за такое
Flexy
Цитата(Стрелок @ 29.12.17, 12:31) необходимо зарегистрироваться для просмотра ссылки
2. тыкаем энтер

Дык автор писал, что юзер тыкает энтер.
Цитата(Стрелок @ 29.12.17, 12:31) необходимо зарегистрироваться для просмотра ссылки
процедура в "дополнительно" срабатывает ТОЛЬКО если значение реквизита изменено и ТОЛЬКО один раз. Для нового срабатывания нужно чтобы реквизит опять изменился.

У меня постоянно срабатывает smile.gif Видимо, какая-то другая 7.7 у меня smile.gif

Да и кстати:
Форма.МойРеквизит.ВыполнятьФормулуТолькоПриИзменении(0);

Ни кто не отменял.
Стрелок
Flexy @ Сегодня, 12:45 необходимо зарегистрироваться для просмотра ссылки ,
Цитата(Flexy @ 29.12.17, 12:45) необходимо зарегистрироваться для просмотра ссылки
Да и кстати:

Форма.МойРеквизит.ВыполнятьФормулуТолькоПриИзменении(0);

Ни кто не отменял.


верно, никто. но по умолчанию (без этой инструкции в коде модуля формы) срабатывает только при изменении. так что "не сработает" smile.gif
Victor Skif
Стрелок @ 29.12.17, 21:56 необходимо зарегистрироваться для просмотра ссылки ,
Спасибо за обсуждение!

Я решил вопрос в итоге следующим способом: проверку реквизита Артикул вешаю на процедуру этого реквизита ИзмАртикул(); перед этим сохраняю старое значение в переменную; если значение плохое - то возвращаю в реквизит сохраненное старое значение, и активизирую. Активизирую ректально - через ложное закрытие, других путей нет. Минус решения - плохое значение в этот момент уже записано. Если пользователь выйдет по эскейпу - оно останется. Это не критично, в целом результат удовлетворительный.

Вот код:

Перем флЛожноеЗакрытие;

// =========================
Процедура ПриЗакрытии()
    Если флЛожноеЗакрытие = 1 Тогда
        флЛожноеЗакрытие = 0;
        Активизировать("Артикул");
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
КонецПроцедуры


// =========================
Процедура АктивистАртикул()             // вот через такую жопу можно активировать отсюда объект
    флЛожноеЗакрытие = 1;
    Форма.Закрыть(0);
КонецПроцедуры


// =========================
Процедура ИзмАртикул()
    Арт = Стро(Артикул);  
    Если Арт = "" Тогда
        Возврат;
    КонецЕсли;
    СтарыйАрт = Стро(ТекущийЭлемент().Артикул);  // берем старое значение из записанного реквизита!
    Если СтарыйАрт = Арт Тогда
        Возврат; // не менялось ничего
    КонецЕсли;
    Если УникальностьАртикула(Арт) = 0 Тогда
        Предупреждение("Артикул " + Арт + " не уникален!");
        // СтатусВозврата(0);  // - не работает!
        // сохраняем старое значение
        // а теперь обратно активизируем
        Артикул = СтарыйАрт;
        АктивистАртикул();
    КонецЕсли;
КонецПроцедуры
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.