Доброго времени суток, коллеги!
Подскажите, можно ли реализовать изменение списка доступных состояний инцидента в зависимости от его типа?
Например, в справочнике состояний есть состояния С1,С2,С3,С4. И типы Т1,Т2. Вот для типа Т1 должны быть доступны состояния С1, С2, С4. Для типа Т2 - С1, С3, С4.
Нравится
Здравствуйте, Андрей!
Безусловно, реализация возможна.
Подробный пример, правда, на основе других справочников, рассмотрен в статье по ссылке:
http://www.community.terrasoft.ua/blogs/6373
Андрей, спасибо. После прочтения остались подозрения, что в примере реализована связка "один к одному", т.е. определённому типу подставляется определённая категория, а не предлагается выбор перечня категорий, разрешенных для выбранного типа. Для проверки пробую реализовать, но, начиная с п.10 картинки не соответствуют тексту, и часть картинок не прогружается :-(
Здравствуйте, Андрей!
Т.к. присутствует связь многие-ко-многим, Вам потребуется создать так называемую "развязочную" таблицу "Состояние в типе", которая будет содержать колонки с идентификаторами Типа Инцидента и Состоянием инцидента.
Примеры таких таблиц уже присутствуют в конфигурации, например, tbl_UrgencyImpactInPriority (Срочность и степень воздействия в приоритете инцидента).
Но также приложу сервисы, которые я создал и использовал в рамках тестирования (во вложении).
Сервис таблицы и поля "Тип инцидента" и "Состояние инцидента":
[URL=http://fastpic.ru/][IMG]http://i68.fastpic.ru/big/2014/1202/43/35c3bb57…]
[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/ec/ed496f64…]
[URL=http://fastpic.ru/][IMG]http://i65.fastpic.ru/big/2014/1202/86/a3c69797…]
Сервисы запроса и датасета:
[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/fd/cbfdae97…]
[URL=http://fastpic.ru/][IMG]http://i67.fastpic.ru/big/2014/1202/73/45088163…]
Если Вы хотите "красиво" связывать Тип и Состояние через клиентскую часть, Вам также потребуется создать сервис окна. Для примера можете посмотреть wnd_IncidentPriorityDictionary.
Но для примера "сделал и забыл" можно просто заинзертить записи через SQL:
insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values ( (select Id from tbl_IncidentStatus where NAme = 'C1'),(select Id from tbl_IncidentType where NAme = 'T1') ) insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values ( (select Id from tbl_IncidentStatus where NAme = 'C2'),(select Id from tbl_IncidentType where NAme = 'T1') ) insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values ( (select Id from tbl_IncidentStatus where NAme = 'C4'),(select Id from tbl_IncidentType where NAme = 'T1') ) insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values ( (select Id from tbl_IncidentStatus where NAme = 'C1'),(select Id from tbl_IncidentType where NAme = 'T2') ) insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values ( (select Id from tbl_IncidentStatus where NAme = 'C3'),(select Id from tbl_IncidentType where NAme = 'T2') ) insert into tbl_StatusInType (IncidentStatusId, IncidentTypeId) values ( (select Id from tbl_IncidentStatus where NAme = 'C4'),(select Id from tbl_IncidentType where NAme = 'T2') )
В сервисе wnd_IncidentEditScript в функции DataChange(DataField) допишем код:
if (Name == 'IncidentTypeID') { // если изменяется поле "Тип", то... Dataset.Values('StatusID') = null; // очищаем значение Состояния edtStatus.UnprepareDropDownList(); //указываем полю карточки, что в следующий раз нужно зачитать список Состояний из БД, а не из кэша значений // без данной операции получить в выпадающем списке требуемый набор значений будет невозможно }
В сервисе запроса sq_IncidentStatus "заджойнить" созданную нами развязочную таблицу:
[URL=http://fastpic.ru/][IMG]http://i67.fastpic.ru/big/2014/1202/36/641fa651…]
Тут же создать параметр:
[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/34/7bedfa90…]
...и фильтр сравнения:
[URL=http://fastpic.ru/][IMG]http://i63.fastpic.ru/big/2014/1202/b6/c4ee3bca…]
В сервисе ds_Incident необходимо определить событие OnDatasetBeforeLookupDatasetOpen:
[URL=http://fastpic.ru/][IMG]http://i66.fastpic.ru/big/2014/1202/8a/347fb16f…]
... и в его обработчике написать (привожу весь листинг функции):
function ds_IncidentOnDatasetBeforeLookupDatasetOpen(Dataset, LookupDataField, LookupDataset) { var Name = LookupDataField.Name; if (Name == 'StatusID') {// если обрабатывается именно поле Состояние, то... var IncidentTypeID = Dataset.Values('IncidentTypeID'); //... считываем текущее значение Типа инцидента... ApplyDatasetFilter(LookupDataset, 'IncidentTypeID', IncidentTypeID, true); // ...и накладываем фильтр по типам инцидентов } }
В функции wnd_IncidentEditOnPrepare(Window) в самом ее конце дописать:
edtStatus.UnprepareDropDownList(); /*Это действие при каждом открытии карточки Инцидента приведет к тому, что контрол, в котором отображается список Состояний, при появлении списка будет в любом случае считывать (отфильтрованные) данные из БД, а не старый (закешированный) список значений Состояний, которых сохранился после предыдущего открытия карточки инцидента. По умолчанию LookupDataControl, который отображает данные в виде выпадающего списка, считывает из БД и запоминает перечень показанных значений, и впоследствии использует для показа этот список без обращения в базу. Это очень удобно в случае статичных списков, но в Вашем случае этот механизм приходится отключать функцией контрола UnprepareDropDownList().*/
Проверим результат:
[URL=http://fastpic.ru/][IMG]http://i65.fastpic.ru/big/2014/1202/3a/7624ee5e…]
[URL=http://fastpic.ru/][IMG]http://i63.fastpic.ru/big/2014/1202/6b/f1028c06…]
Андрей, огромное спасибо за столь подробное описание. Сам я бы до этого долго шел. Получилось именно то, что хотелось!
Пришлось вернуться к вопросу.
Пропала возможность выбирать состояние инцидента в фильтрах. Падает сообщение "Исключен DataField 'Тип' isn't enabled". Думаю, что связано с этой доработкой. Где мог косякнуть?
Здравствуйте, Андрей!
В запросе sq_* нет фильтра, на который ссылается скрипт обработчика события. Наиболее частовозникает при отсутствии фильтра по ID.
Я понял: мы в sq_IncidentStatus прицепили линковочную таблицу и создали параметр для фильтра по IncidentTypeID. На том сейчас и падаем. Видимо, в карточке инцидента придётся использовать какой-то запрос-дублёр, аналог sq_IncidentStatus с проведённой ранее доработкой, а sq_IncidentStatus вернуть в исходное. Подскажите, в каком месте и каким образом производится подмена запроса для карточки?
Андрей, не совсем так. Найдите поле "Тип" (что-то вроде IncidentTypeID или TypeID) в sq_ и проставьте галочку "всегда выбирать в запросе".
Точно! В sq_incident сия галочка помогла. Спасибо!