Изменения от 12.06.2012:
Изменено именование классов со "Справочник.ХХХ.А" / "Справочник.ХХХ.Б" на: "Справочник.ХХХ",
поэтому теперь при подключении классов нет необходимости переименовывать все справочники в конфигурации.
Немалая часть вылетов 1С 7.7 на SQL базах связано с записью в справочники. Иногда 1с про ошибки говорит и вылетает. Это desdlock-и и "недопустимые состояния курсора". А иногда уходит по английски, ничего не сказав. Я думаю это связано с очень поверхностной обработкой ошибок которые 1С получает от SQL.
Что "Справочник плюс" дает.
1. Запись выполняется без монопольных блокировок таблиц.
2. Можно управлять блокировками используя "почти штатные" методы.
3. Скорость записи немного выше.
4. Открытая форма элемента не блокирует запись.
5. Пишется только то, что изменил пользователь. Например пользователь мог открыть форму элемента, поменять там один реквизит, пойти покурить. Пока форма открыта, программно было записано 2 реквизита. Когда пользователь нажмет ОК. Запишется только один, изменненый им, реквизит.
6. Следствие пункта 5: Легко отслеживать и, при необходимости, фиксировать, что менял пользователь.
7. Нет нужды в перехвате событий справочника как объекта. Все события у вас уже под руками.
8. Со временем хочу заменить все штатные (курсорные) выборки на запросы. И скорость выше и нагрузка не систему ниже и встреч с "недопустимыми состояниями курсора" не будет.
Как это работает:
Как подключаются компоненты и классы можно посмотреть в тестовой конфигурации и, если чего не понятно, почитать на www.1cpp.ru/
Я укажу только суть:
1. В глобальнике:
Еще до загрузки 1CPP.dll проверяется и при необходимости пересоздается файл определения классов с полным перечнем справочников.
Далее при загрузке 1CPP.dll создаются классы вида "Справочник.ХХХ", которые являются наследниками от "Reference.ХХХ" и "ТаблицаЗначений".
2. В формах:
События формы перехватываются Классом ПерехватчикГК (Это класс выполняющий роль фабрики событий группового контекста) и направляются в класс ПерехватчикГК.Справочник - класс обслуживающий прямую запись во всех формах справочников (и в формах списков и элементов и групп). В классе можно указать "Неперехватываемые" справочники.
При выполнении события ПриЗаписи() устанавливается СтатусВозврата(0) 1с-у говорим, что записывать не будем, создаем объект "Справочник.Вид.Б" и при специальным методом "ЗаписатьИзФормы" пишем самостоятельно.
Минусы при записи из формы:
1. После записи нового элемента форма не знает, что элемент записан, поэтому Выбран() = 0 а ТекущийЭлемент() = пустое значение. Для обхода этой проблемы к контексту формы добавляется свойство: ТекущийЭлементПрямойЗаписи. А для получения текущего элемента формы лучше использовать глобальную функцию: глТекущийЭлементФормы(Контекст).
ТРЕБОВАНИЯ и ОГРАНИЧЕНИЯ:
1. FormEx.dll, 1CPP.dll (вложены)
2. УРБД не поддержано. Если разработка заинтересовала готов поддержать.
3. В ПриЗаписи() нельзя использовать метод формы Записать() - происходит выход 1с-а в астрал.
4. Если используется событие ФормаПослеЗаписи() в начале Метода НЕОБХОДИМО вставить: СтатусВозврата(1); это связано с особенностью реализации этого метода: при СтатусеВозврата() = 0 в ПриЗаписи() этот метод уже на входе имеет СтатусВозврата() = 0
5. ТекущийЭлемент() в форме необходимо получать через глобальную функцию
глТекущийЭлементФормы(Контекст)
6. Если запись выполняется без закрытия формы, то После записи форма закрывается, а затем открывается. Так проще.
7. Наверно нужно причислить к недостаткам: Фабрика событий не стандартный класс фабрики событий 1Cpp. Ну не нравится мне передача параметров через список. Сначала укладываем, потом разукладываем это ведь время.
Состав архива:
Каталог тестовой базы со всем необходимым внутри + Выгрузка этой же базы.
Пример использования:
Как генерить гарантированно уникальные записи в справочиках.
Измененный метод НайтиПоРеквизиту() имеет два дополнительных параметра. Синтаксис:
НайтиПоРеквизиту(ИмяРеквизита,Значение,ФлагГлобальногоПоиска=1,Хинт=0,ТолькоСсылку=0)
Хинт - способ чтения. Можно указать строкой, можно числом. Строка - все, что съест ms SQL; Число: наиболее полезные подсказки: 0 - nolock, 1 - readcommitted, 2 - serializable, 3 - updlock
ТолькоСсылку значения: 0 - прочитать все реквизиты (по умолчанию); 1 - только найти ссылку (ТекущийЭлемент())
спр = СоздатьОбъект("Справочник.УникальныйПоРеквизиту");
// Ищем ссылку с хинтом 2 (serializable) (гарантированно записанные и никем не изменяемые в момент чтения данные)
Если спр.НайтиПоРеквизиту("УникальныйРеквизит",125,1,2,1) = 0 Тогда
// Если Не нашли: открываем транзакцию и читаем с хинтом 3 (updlock) - чтение, дающее гарантию, что до завершения
// транзакции никто другой не сможет записать анналогичные данные. (Данные соответсвующие нашим условиям).
НачатьТранзакцию();
Если спр.НайтиПоРеквизиту("УникальныйРеквизит",125,1,3,1) = 0 Тогда
// Если не нашли со спокойной совестью пишем гарантия уникальности = 100%
спр.Новый();
спр.УникальныйРеквизит= 125;
спр.Записать();
КонецЕсли;
ЗафиксироватьТранзакцию();
КонецЕсли;