RLS в v77 возможен? Для SQL-поставки - легко!

26.08.10

Разработка - Разработка внешних компонент

MS SQL Server позволяет автоматизировать многие задачи учета, но все задумки упираются в ограничения v77-платформы. Попробуем эти ограничения обойти и вот простой и наглядный пример этого...

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Внешняя компонента
.rar 89,49Kb
54
54 Скачать (1 SM) Купить за 1 850 руб.
Пример запуска компоненты
.rar 7,69Kb
21
21 Скачать (1 SM) Купить за 1 850 руб.

Если имеется крайняя необходимость, например, скрыть от определенной группы пользователей некоторые документов (по виду, дате, набору реквизитов и пр.), то одни реализуют алтернативные журналы документов (на основе ТЗ, ТП или даже в виде отчетов), другие задаются философским китайским вопрос (и отказываются от этой затеи), а мы пойдем "прямым" путем...

Начальные условия:

0. Имеется в распоряжении  MS SQL Server 2k/2k5 - обязательная часть;

1. Имеется желание - необязательная часть;

2. Имеются sql-знания - крайне желательная часть, но может и без них проканать;

Суть идеи:

Необходимо вмешаться в процесс передачи запроса от v77-клиента на sql-сервер и внести изменения в текст запроса так, чтобы он возвращал все документы, кроме Банковских выписок. Начнем с конца...

V77-клиент для журнала документов формирует запрос к таблице [_1SJOURN].

Для типовой 1С:Бухгалтерии v5.x структура таблицы [_1SJOURN] следующая (смотрим сами так: EXEC sp_help '_1SJOURN'):

  • ROW_ID - первичный ключ;
  • IDJOURNAL - идентификатор журнала;
  • IDDOC - идентификатор документа;
  • IDDOCDEF - идентификатор вида документа;
  • APPCODE - битовая маска, определяющая  какие компоненты использует док-т;
  • DATE_TIME_IDDOC - композитное поле из даты, времени и идентификатора документа;
  • DNPREFIX - префикс номера документа;
  • DOCNO - номер документа;
  • CLOSED - битовая маска состояния документа;
  • ISMARK - пометка удаления документа;
  • ACTCNT - счетчик движений документа;
  • VERSTAMP - счетчик изменений документа;

 

И запрос формируемый v77-клиентом, при открытии журнала документов (в общем случае):

Select * from _1SJOURN(NOLOCK) (1)

Чтобы отсеить Банковские выписки, нужно наложить условие на вид документа (IDDOCDEF). Для Банковской выписки идентификатор вида документа = 238. Что в общем виде должно быть так:

Select * from _1SJOURN(NOLOCK) WHERE IDDOCDEF != 238 (2)

Некоторые могут спросить, а почему "не равно 238", но мы ведь хотим видеть все документы, кроме документов вида Банковская выписка.

От общего вида переходим к конкретным деталям - на самом деле v77-клиент формирует запросы сложнее, чем указано выше, а реализовывать свой sql-парсер, который универсально сможет подменить оригинальный текст запроса на модифицированный - дело не совсем тривиальное. Значит упростим себе задачу, и воспользуемся возможностями sql-сервера - VIEW (представление) нам поможет. Обернем запрос (2) в представление с названием [vw_oops_1SJOURN] и, забегая вперед, подменим оригинальные запросы к таблице [_1SJOURN] на запросы к представлению [vw_oops_1SJOURN], и будем наслаждаться. Но, некоторые могут усомниться, что не взлетит запись (с чтением проблем не будет же), а некоторые не будут в этом сомневаться, но будут уверены, что в конкурентном окружении будут проблемы.

Скрипт на создание представления:

CREATE VIEW [dbo].[vw_oops_1SJOURN]
AS
    SELECT

        NULLIF(ROW_ID, NULL) as ROW_ID,
        IDJOURNAL,
        IDDOC,
        IDDOCDEF,
        APPCODE,
        DATE_TIME_IDDOC,
        DNPREFIX,
        DOCNO,  
        CLOSED,
        ISMARK,
        ACTCNT,
        VERSTAMP
    FROM [dbo].[_1SJOURN]
    WHERE IDDOCDEF != 238

Давайте разбираться...

С чтением (SELECT) проблем быть не должно, хинты типа NOLOCK, вставляемые v77-клиентом в запросах, по прежнему будут, т.е. на сервер будут уходить запросы типа: Select * from vw_oops_1SJOURN(NOLOCK).

Запись (INSERT/UPDATE) тоже будет работать, так как представление vw_oops_1SJOURN является обновляемым: используется одна базовая таблица, нет вычисляемых полей, IDENTITY-поле ROW_ID обернуто в NULLIF.

Остается вопрос с хранимыми процедурами, сгенерированными v77-клиентом, и эскалациями блокировок, но для нашего примера это не актуально (было бы актуально, если бы мы переопределили таблицу [_1SJOURN] на какую-либо свою и/или на представление, основанное на другой базовой таблице). Однако, хранимую процедуру [_1sp__1SJOURN_ByIDDOC] переопределить желательно (хоть и не обязательно, на тот случай, если нужно закрутить гайки по-максимуму) на [vw_oops_1sp__1SJOURN_ByIDDOC]:

CREATE PROCEDURE [dbo].[vw_oops_1sp__1SJOURN_ByIDDOC](@id CHAR(9))
AS
      SELECT *
      FROM vw_oops_1sjourn(NOLOCK)
      WHERE IDDOC=@id
GO
 

C sql-частью определились, теперь возвращаемся к v77-клиенту. Штатно переопределить источник данных нельзя, значит нужно использовать нештатные методы для этого. Не останавливаясь на деталях проектирования и реализации внешней компоненты, продоставляющей функционал подмены запросов, переходим к финальной части - описанию ее программного интерфейса.

Для нашей задачи необходимо создать экземпляр класса:

oQueryAct = СоздатьОбъект("QueryAct");

Пока объект "жив" (находится в области видимости), функционал манипулирования с запросами будет работать, как только объект разрушен - начинается штатная жизнь. Отсюда первое правило: если функционал нужен в течение всего сеанса работы пользователя - создавай глобальную экспортную переменную.

Дальше необходимо заполнить коллекцию базовых объектов, над которыми будут выполняться манипуляции:

Манипуляторы = oQueryAct.Манипуляторы; // коллекция, которую будем заполнять

Заполнение коллекции (переопределение таблицы [_1SJOURN]):

Манипулятор = Манипуляторы.Добавить("_1sjourn");
Манипулятор.Поведение  = 2; // поведение манипулятора
Манипулятор.Суррогат = "vw_oops_1sjourn";
// суррогатный объект, которым будет подменен оригинальный объект, в данном случае _1sjourn
 

Заполнение коллекции (переопределениехранимой процедуры [_1sp__1SJOURN_ByIDDOC]):

Манипулятор = Манипуляторы.Добавить("_1sp__1SJOURN_ByIDDOC");
Манипулятор.Поведение = 2;
Манипулятор.Суррогат = "vw_oops_1sp__1SJOURN_ByIDDOC";
 

И финишный аккорд (активация манипуляторов):

oQueryAct.Применить(); 

И пока объект oQueryAct будет "жив", будет выполняться подмена объектов на суррогаты.


Программный интерфейс класса "QueryAct": 

Методы:

   - Применить / Employ - задействовать новые правила, описанные в коллекции Манипуляторы;

Свойства:

   - Манипуляторы / Handlers - коллекция правил, описывающая новое поведение обращения к источникам данных;

Элемент коллекции:

Свойства:

   - Поведение / Behaviour (Число) - поведение манипулятора. Возможные значения: 1 - вырезать INDEX-хинты, 2 - заменить имя источника данных на суррогат;

   -  Суррогат / Substitute (Строка) - имя суррогатного объекта. Имеет смысл указывать при выбранном Поведении = 2;

Работа с коллекцией:

   - Добавить / Add - добавить элемент в коллекцию;

   - Удалить / Remove (Число/Строка) - удалить элемент из коллекции;

   - Очистить / Clear - очистить коллекцию;

   - Количество / Count - получить количество элементов в коллекции;

   - Получить / Get (Число/Строка) - получить элемент коллекции;


 Disclaimer:

Возможно, некоторым нужно будет установить VC runtime library, которую компания Microsoft любезно выложила у себя и совершенно бесплатно предлагает к скачиванию и распространению...

 

Продолжение следует: а в следующей серии мы поговорим о секционировании! 

См. также

Разработка внешних компонент WEB-интеграция Программист Платформа 1С v7.7 1C77 Платные (руб)

Компонента HttpSrv7 позволяет создавать веб-сервисы в среде 1С 7.7 и даже, используя файлы HTML, несложные веб-сайты. С помощью нее можно обеспечить доступ к данным 1С 7.7 из браузера. Дополнительно используя компоненту HTTP_Async или синхронный клиент HTTP для 1С 7.7 (публикация № 1152364) можно наладить обмен данными между удаленными информационными базами. С помощью компоненты HTTP_Async можно сначала послать несколько запросов к сайтам, веб-сервисам (в т.ч. к HttpSrv7), а затем обрабатывать данные по мере их поступления. Компонента GISMT в дополнение к HTTP_Async имеет функцию цифровой подписи и, таким образом, имеет все возможности для работы с API ГИС МТ "Честный знак" непосредственно из среды 1С 7.7.

2000 руб.

27.05.2022    9427    24    17    

35

Разработка внешних компонент Программист Платформа 1С v7.7 1C77 Абонемент ($m)

Компонента позволяет в среде 1С 7.7 генерировать двухмерный QR код из любого текста длиною до 1800 символов и сохранять его в файле BMP формата. Из файла он может быть загружен в объект 1С "Картинка".

1 стартмани

29.01.2025    529    3    mdbruyfn    4    

5

Разработка внешних компонент Системный администратор Программист Платформа 1С v7.7 Платформа 1С v8.3 Платформа 1C v8.2 Платформа 1С v8.1 Россия Платные (руб)

Аддон "Структура Обмена" (ExchangeStruc) - это компонента, которая обеспечивает доступ к разделяемым процессом структурам, аналогичным структурам 1С. Обеспечивает прозрачную передачу данных примитивных типов, в том числе Двоичных данных, в режиме Реального времени между разными контекстами (формами) или потоками одного процесса. В перспективе функционал будет расширен для обмена между процессами, даже разных версий платформ. Совместим с версиями Windows рабочих станций и серверов, с платформами 1С разных версий и релизов в режиме Native начиная с 8.2, и в режиме COM начиная с версий 7.7. По скорости чтения и записи лишь немногим уступает стандартной структуре 1С. НОВОЕ: Добавлен функционал регистрации компоненты COM в качестве OLE Auto (COMОбъект) для поддержки её работы в серверах старых версий 1С: 8.0 и 8.1, где работа с компонентами исключена. Теперь можно коммуникацию с Фоновыми заданиями на этих версиях проводить.

7200 руб.

19.04.2023    5441    1    0    

3

Разработка внешних компонент Программист Платформа 1С v7.7 Платные (руб)

Компонента для выбора значения из больших списков значений.

1200 руб.

02.12.2021    6425    2    19    

4

Разработка внешних компонент Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v7.7 1C77 Абонемент ($m)

Эта внешняя компонента Base64.dll предназначена для платформы 1С версии 7.7. Используется для преобразования файлов из/в кодировку Base64 из встроенного языка 1С Предприятие. Компонента тестировалась на базе конфигурации Бухгалтерский учет для Казахстана, редакции 7.70.257.

10 стартмани

06.04.2021    10431    14    softmaker    13    

5

Разработка внешних компонент Защита ПО и шифрование Программист Платформа 1С v7.7 Абонемент ($m)

Цифровые подписи, шифрование, просмотр сертификатов ключей ЭЦП, работа с различными криптопровайдерами (в т.ч. КриптоПРО ГОСТ 2012) в 1С 7.7.

1 стартмани

08.06.2020    9663    28    mdbruyfn    10    

9

Разработка внешних компонент Программист Платформа 1С v7.7 Абонемент ($m)

Обмен сообщениями и небольшими файлами по протоколу UDP с 1С и внешними приложениями в локальной сети или сети VPN.

1 стартмани

23.05.2020    7796    8    mdbruyfn    0    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. CheBurator 3139 26.08.10 22:03 Сейчас в теме
QueryAct - откуда берется, из "VC runtime library" - ???
2. hogik 444 26.08.10 22:35 Сейчас в теме
(1)
Сергей.
Так, для общей информации (теории). ;-)
В разработке: http://infostart.ru/public/15211/
Это делается одной строчкой: Ext._(60,"1SJOURN","Val(IDDOCDEF)<> 238")
3. CheBurator 3139 26.08.10 22:44 Сейчас в теме
(2) за ценное замечание - спсб, но тянуть клиент/сервер Advantage 8.1/9.1 ради такой одной строчки - я не рискну... $-) а так, конечно - спсб за ценный комментарий - закросспощу его в мисту... http://www.forum.mista.ru/topic.php?id=501406
4. hogik 444 26.08.10 23:09 Сейчас в теме
(3)
Так лучше: Ext._(60,"1SJOURN","IDDOCDEF<>""238 """)
nvhelsing; mike581; +2 Ответить
5. spock 601 27.08.10 04:38 Сейчас в теме
(1)ну, если глубоко копать, то оттуда, да :)
6. ev-kov 5 10.03.11 19:18 Сейчас в теме
Интересно, а с подменой таблиц движений и остатков регистра, проблем не возникнет при проведении документов по этому регистру ?
7. poyson 22.02.13 14:29 Сейчас в теме
Отличная вещь. спасибо!
8. kos 46 27.11.14 13:07 Сейчас в теме
1. автору: хотелось бы услышать ответ на вопрос от ev-kov (про регистры)
2. всем : "QueryAct vs vk_hook1C" : кто-нибудь сравнивал быстродействие и безглючность этой компоненты и hook (http://infostart.ru/public/83504) ?
9. kos 46 02.12.14 13:57 Сейчас в теме
1) пытаюсь выполнить метод "Insert(а,б)/Вставить(а,б)"
Манипулятор2 = Манипуляторы.Вставить(1,"_1sp__1SJOURN_ByIDDOC_2");
Манипулятор2 = Манипуляторы.Вставить("_1sp__1SJOURN_ByIDDOC_2",1);
Манипулятор2 = Манипуляторы.Вставить(Манипулятор1,"_1sp__1SJOURN_ByIDDOC_2");
Манипулятор2 = Манипуляторы.Вставить(Манипулятор1,1);

выдает ошибку:
{С:\....\МАНИПУЛЯТОРЫ.ERT(69)}: Недопустимый тип первого параметра!


Какие параметры у метода "функция Insert(а,б)/Вставить(а,б)"
и что она возвращает (догадываюсь что элемент коллекции)

2) Кроме того есть метод "процедура Move(а,б)/Сдвинуть(а,б)"
Аналогично: какие у него параметры ?

3) с остальными методами разобрался:

'чКолво' функция Count() Количество()
получить количество элементов в коллекции

'оМанипуляторы' функция Get(чИндекс[,сИмяМанипулятора]) Получить(чИндекс[,сИмяМанипулятора])
получить элемент коллекции (Индекс=0...Колво-1)

'оМанипуляторы' функция Get(сИмяМанипулятора[,чИндекс]) Получить(сИмяМанипулятора[,чИндекс])
получить элемент коллекции (Индекс=0...Колво-1)

'чИндекс' функция IndexOf(оМанипуляторы) Индекс(оМанипуляторы)
получить индекс элемента коллекции (Индекс=0...Колво-1)

'оМанипуляторы' функция Add(сИмяМанипулятора) Добавить(сИмяМанипулятора)
добавить элемент в коллекцию

void процедура Remove(чИндекс|сИмяМанипулятора) Удалить(чИндекс|сИмяМанипулятора)
удалить элемент из коллекции (Индекс=0...Колво-1).
Индексация сдвигается на '-1'

void процедура Clear() Очистить()
очистить коллекцию
10. kos 46 06.12.14 16:47 Сейчас в теме
вот и нарвался на первый случай "проблемы конкурентного окружения"

1) подменил запросы "sel ect ... fr om _1SJOURN ...."
на множественный фильтр по графе отбора

sel ect ...
FR OM _1SJOURN AS TabJ
INNER JOIN _1SCRDOC AS TabGraf with (NOLOCK,INDEX(CHILD))
ON (TabGraf.CHILDID = TabJ.IDDOC)
AND (TabGraf.MDID = "+чИдГрафы+")
AND (TabGraf.PARENTVAL "+СтрУсловияОтбора+")

2) получил "какашку": при создании нового документа на сервер уходит запрос
(поймал профилером)

set rowcount 1;
sel ect DOCNO fr om vw_oops__1SJOURN_XXXЮзер
WITH (NOLOCK)
wh ere DNPREFIX=' 11972014 '
order by DNPREFIX DESC, DOCNO DESC;
set rowcount 0

что приводит к выдаче не "вообще" максимально номера документа в таблице
а к "отфильтрованному" максимальному номеру 8((( для пользователя "XXXЮзер")

В результате имеем задвоение нумерации :
если разные конкурирующие пользователи
используют разные фильтры - по СВОИМ значениям отборов

При этом : пользователь без фильтров
видит два документа с одинаковым номером
введенные этими двумя разными "отфильтрованными" пользователями

Чтобы адекватно пользоваться данной ВК,
в ней нужна доработка ( читаем "запрос на фичи к этой ВК" ):

1) иметь режим "QueryAct.Отладка(0/1)"
чтобы видеть что реально уходит на сервер

2) иметь возможность условной замены "суррогатов"(имен),
для чего добавить 2 свойства
* Манипулятор.ПриУсловииДа=ХХХ
* Манипулятор.ПриУсловииНе=УУУ
тогда суррогат будет срабатывать (выполнять замену запроса)
только при условии что в тексте запроса
* есть подстрока вида "ХХХ"
* нет подстроки вида "УУУ"
Если параметр пустой - безусловная замена.
В моем случае эти параметры будут такими:
* Манипулятор.ПриУсловииДа=""
* Манипулятор.ПриУсловииНе="sel ect DOCNO fr om "

Можно ожидать такие доработки?
Иначе в продакшене использовать эту ВК не имеет смысла.

P.S> ну или выложить здесь исходники,
дабы (кто хочет) сам доработал под свои нужды то, что хочет....
11. dicwork 01.04.15 12:16 Сейчас в теме
Так доработали эту компоненту? Или уже никто не хочет заниматься семеркой?
12. spock 601 01.04.15 16:27 Сейчас в теме
(11) dicwork, кому-то это еще интересно?
Оставьте свое сообщение