Как известно, реквизиты бывают двух типов - сохраняемые и вычисляемые. Вычисляемые реквизиты обычно либо агрегируют некую информацию, связанную с записью, либо просто переносят справочные данные из другой записи. Примером могут служить реквизиты РКК, отображающие информацию о связанных задачах, плановых и фактических датах.
Для того, чтобы добавить вычисляемый реквизит в главный набор данных (т.е. в карточку) надо воспользоваться функцией СпрИзмНабДан(), позволяющей модифицировать SQL-запрос получения набора данных с сервера и добавить в него свои реквизиты. Хороший пример - как это делается можно, опять же, посмотреть в РКК в событии "Набор данных / Открытие".
С реквизитами карточки в целом все просто. Сложности могут возникнуть только с формированием дополнений к SQL-запросу, но, вооружившись знанием T-SQL и Profiler с ними можно справиться. С реквизитами детальных наборов данных (т.е. табличными реквизитами) все несколько хитрее.
Дело в том, что при открытии набора данных подгружается не весь справочник, а только те данные, которые отображаются в форме-списке (плюс несколько системных вроде ИД). Табличные реквизиты туда вытащить нельзя, поэтому и загружать их сразу для всех записей в этом событии не имеет смысла. Все реквизиты записи загружаются только при открытии карточки, т.е. в событии "Карточка / Открытие".
Соответственно, если у нас есть вычисляемые табличные реквизиты, то вычислить их мы можем в событии открытия карточки. Итак, мы имеем данные, которые хотим добавить в реквизит. Записываем их туда кодом на ISBL. Получаем искомый результат - данные в карточке есть. Но мы изменили карточку, поэтому набор данных перешел в состояние "Изменение". И при открытии записи пользователь всегда видит активную кнопку "Сохранить", а при закрытии его предупреждают, что запись надо сохранить. Хотя он никаких изменений не делал.
Мне известно 2 способа борьбы с этим "злом". Первый - сохранять карточку при ее открытии. Но этот способ нехорош тем, что затормозит открытие карточки, а так же при каждом открытии будет добавлять запись в истории об изменении карточки. Кроме того, пользователь может и не иметь прав на сохранение этой записи, тогда этот способ вообще не будет работать.
Второй способ - воспользоваться недокументированными функциями IS-Builder - DisableModified(IDataSet) и EnableModified(IDataSet). Конечно, недокументированные функции это плохо, риск что она перестанет работать есть при каждом обновлении, но если нужны вычисляемые табличные реквизиты, то недокументированная функция - меньшее из зол. Буду рад, кстати, если кто-нибудь подскажет более правильный способ для решения этой задачи.
Итак, недокументированные функции. DisableModified(IDataSet) устанавливает запрет на проверку Modified набора данных, то есть набор данных не будет считаться изменившимся, даже если в нем что-то изменилось. Функция EnableModified(IDataSet) возвращает проверку. Вычисляемый реквизит табличной части я заполняю так:
// отключить проверку, если запись не вновь созданная
if not Object.Inserted
DisableModified(Object.DataSet)
endif
// заполнить реквизит ISBGroupThresholdKind тестовыми значениями
DS = Object.DetailDataSet(1)
while DS.RecordCount > 0
DS.Delete
endwhile
i = 1
while i < 10
DS.Insert
DS.ISBGroupThresholdKind = 'Строка ' & i
i = i + 1
endwhile
// включить проверку обратно
if not Object.Inserted
EnableModified(Object.DataSet)
endif
Важные примечания:
Опять недокументированные функции
Сколько же их там еще осталось таких, о которых мы до сих пор не знаем?!
Огласите весь список пожалуйста!!!
Оглашаю по мере появления ситуаций, не решаемых обычными путями. Тогда приходится пытать разработчиков платформы на предмет чего-нибудь экзотического, что мне бы подошло.
как-то пытался использовать эти скрытые возможности при разработке. На тот момент не знал, что они применимы только для детальных разделов. Я применял для главных и наблюдал следующие грабли:во первых применять эти функции нужно было в обратном порядке; во вторых иногда случалось, что последующие изменения карточки не приводили к "активации" кнопки сохранить.
А можно подробнее про то как использовать СпрИзмНабДан() для аналогичных целей.
Допустим, есть в главном разделе вычисляемый реквизит. Чтобы IS-Builder смог отобразить его значение, поле, соответствующее этому реквизиту, должно присутствовать в SQL-запросе, который посылается на сервер при открытии справочника как в режиме списка, так и при открытии карточки отдельной записи справочника. Просто так этот запрос состоит только из тех реквизитов, значения которых хранятся на сервере (т.е. не вычисляемых). Соответственно, для наших целей надо этот запрос модифицировать, добавить к нему поле, соответствующее вычисляемому реквизиту (в AddSelect) и вычисление его (в AddFrom и AddWhere). Наглядный пример есть в РКК.
Всем привет!
Проверили на IS-Builder 7.8 - не работает :(
Проверил на 7.8.3.1046 и 7.9.2.2305 - работает.
Может кто подтвердить, что в 5.0 работает? А то у меня что- то не получается с детальным разделом.
Что-то не работает: состояние отображается Просмотр, но при этом кнопки Сохранить активны и при закрытии предлагает сохранить запись.
При этом в историю такие "псевдосохранения" не попадают.
Спасибо, Марина.
Мне даже такого поведения не удалось добиться... Может, конечно, эксперимент не чистый... DisableModified(Object.DataSet) "работает" (ваше поведение), только если реквизиты в Показ/Открытие заполнять? Я хотел в действии его использовать, которое добавит строку.
Столкнулась с такой задачей на практике и сама себя поправлю: работает без проблем на событии Запись.Открытие. Кривовато работало на Форме.Показ. Версия 5.0.0.12, IS 7.11.0.2506
Добрый день! Я попробовал 2-ой способ, но что-то сомневаюсь. А как можно сохранить карточку при открытии справочника? Через набор данных?
Может кому-то пригодится еще один способ:
Можно воспользоваться методами IDataSet.AddSelect и IRequisiteFactory.CreateRequisite, в справке они описаны. Воспользоваться ими можно в событии Открытие набора данных. Методы вызывать у объекта, Object.DetailDataSet(i).
При этом есть нюансы:
Если нужно не просто считать значения в реквизитах, а показывать полностью "виртуальные" строки детального раздела, то этого можно достичь с помощью AddJoin/AddWhere, но тогда обязательно нужно запрещать добавлять/удалять строки, и не отображать в таблице хранимых реквизитов. Если кому-нибудь будет интересно, могу отдельно написать.
Авторизуйтесь, чтобы написать комментарий