новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

1С 7.7 Множественный фильтр в полном журнале или пример работы компоненты vk_hook1C.dll

  • Добавить свою публикацию
  • для этого требуется регистрация

Думаю, что каждому программисту, который пишет или писал на "семерке", хотя бы раз заказчик задавал вопрос "А можно ли настроить отбор по нескольким полям в общем журнале?".

Дело в том, что стандартными средствами реализовать такое нельзя, отбор можно делать только по одному из реквизитов - "вид документа", "контрагент", "автор" и т.д. Можно написать обработку, которая внешним видом будет напоминать обычный журнал, но при этом пользователь будет иметь возможность указывать несколько фильтров для отбора документов. Однако в этом случае мы очень сильно будем терять в производительности работы такого "псевдо-журнала". Любая подобная обработка будет работать на порядок медленнее обычного журнала.

Остается смотреть в сторону нестандартных подходов в решении проблемы. Один из таких подходов и будет описан в данной статье, его суть заключается в применении внешней библиотеки vk_hook1C.dll.

 

Сразу стоит отметить, что данный метод подходит только для 1С SQL-версии. Т.к. основная задача библиотеки в том, чтобы перехватывать запросы, посылаемые 1С в базу SQL Server и подставлять в них требуемые значения.

 

Итак, исходные данные:

- SQL Server 2005 (2000 тоже подойдет, насчет версий старше 2005 ничего не могу сказать)

- 1С, сопряженная с SQL Server

- компонента vk_hook1C.dll

- описание структуры таблиц 1С в SQL (подходит и для DBF-версии)

 

Копируем содержимое архива в каталог БД. Подключаем компоненту при запуске 1С

 

    Если ЗагрузитьВнешнююКомпоненту("vk_Hook1C.dll") = 1 Тогда
        ЗагрузитьВнешнююКомпоненту(КаталогИБ()+"vk_Hook1C.dll"); 
        vk_hook=СоздатьОбъект("Addin.vk_Hook1C");
        vk_hook.ПерехватSQLPrepare();
        
        Если Вопрос("Отображать запросы SQL?","Да+Нет")="Да" Тогда
            vk_hook.ПоказыватьSQL=1;
        КонецЕсли;
    Иначе
        Сообщить("Не удалось загрузить компоненту vk_Hook1C.dll. Некоторые функции могут быть недоступны.");
    КонецЕсли;    
 

 

Далее создаем "Обычный журнал", устанавливаем в нем несколько видов отбора. В моем случае это: "Вид документа", "Автор", "Флаг Проведенные/Непроведенные", "Флаг Помеченные на удаление/Не помеченные на удаление".

 

Изображение

 

Для отбора можно устанавливать любые "общие реквизиты" документов и некоторые стандартные поля для таблицы журнала (вроде "флага проведения").

Список полей, которые можно использовать в качестве фильтра можно посмотреть либо в таблице "_1SJOURN" в базе SQL, либо в файле 1cv7.dds, который хранит в себе полное описание всех структур таблиц базы SQL.

 

Пишем код, который отключает стандартный отбор журнала и включает наш "расширенный" отбор.

(т.к. вставка фрагмента кода подглючивает (уж простите, администрация) - напишу обычным текстом)

 

//*******************************************
Процедура ф_Отбор()
    
    //Устанавливаем произвольный отбор, чтобы сбросить настройку отбора журнала
    УстановитьОтбор("ПКО");
    
    ////Генерим событие (оно будет изловлено в ОбработкаВнешнегоСобытия)
    vk_hook.ВызватьСобытие("vk_hook","Отбор","Журнал");

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

 

//*******************************************
//Преобразует объект в идентификатор, который понимает SQL
Функция ПолучитьИД(прм_Объект)
    стр=СокрЛП(ЗначениеВСтрокуВнутр(прм_Объект));
    стр=Сред(стр,2,СтрДлина(стр)-2); //Убираем {}
    сз=СоздатьОбъект("СписокЗначений");
    сз.ИзСтрокиСРазделителями(стр);
    стр=сз.ПолучитьЗначение(7);
    иб=Прав(стр,3);
    стр=Лев(стр, СтрДлина(стр)-3); //Убираем последние 3 символа
    стр=_IdToStr(стр);
    стр=стр+иб;

    Пока СтрДлина(стр)        стр=" "+стр;
    КонецЦикла;

    Возврат стр;
КонецФункции    // ПолучитьИД

//*******************************************
Процедура ОбработкаВнешнегоСобытия(прм_Источник,прм_Событие,прм_Данные)
    Сообщить(прм_Источник+"  "+прм_Событие+" "+прм_Данные);
    Если (прм_Источник="vk_hook") и (прм_Событие="Отбор") и (прм_Данные="Журнал") Тогда
        стр="";
        Если ПустоеЗначение(ВыбАвтор)=0 Тогда         
            стр=стр+"SP74='"+ПолучитьИД(ВыбАвтор)+"' and ";
        КонецЕсли;
        Если СписокДокументов.ТекущаяСтрока()>1 Тогда
            стр=стр+"IDDOCDEF="+СписокДокументов.ПолучитьЗначение(СписокДокументов.ТекущаяСтрока())+" and ";
        КонецЕсли;
        Если Проведенные=1 Тогда
            стр=стр+"CLOSED='1' and ";
        КонецЕсли;    
        Если НеПомеченныеНаУдаление=1 Тогда
            стр=стр+"ISMARK='0' and ";
        КонецЕсли;    
        
        vk_hook.ТекстSQL="Select * from _1SJOURN(NOLOCK INDEX=JOURNAL) where IDJOURNAL=? and DATE_TIME_IDDOC>=? and DATE_TIME_IDDOC        vk_hook.НовыйSQL="Select * from _1SJOURN(NOLOCK INDEX=JOURNAL) where "+стр+" IDJOURNAL=? and DATE_TIME_IDDOC>=? and DATE_TIME_IDDOC        vk_hook.УстановитьЗаменуSQL();
        
        vk_hook.ТекстSQL="Select COUNT(*) from _1SJOURN(NOLOCK) where IDJOURNAL=? and DATE_TIME_IDDOC>=? and DATE_TIME_IDDOC        vk_hook.НовыйSQL="Select COUNT(*) from _1SJOURN(NOLOCK) where "+стр+" IDJOURNAL=? and DATE_TIME_IDDOC>=? and DATE_TIME_IDDOC        vk_hook.УстановитьЗаменуSQL();
        УстановитьОтбор("");

    КонецЕсли;    
КонецПроцедуры

СписокДокументов.ДобавитьЗначение("все");
СписокДокументов.ДобавитьЗначение(2457,"заявка покупателя");
СписокДокументов.ДобавитьЗначение(1611,"реализация");
СписокДокументов.ДобавитьЗначение(1656,"возврат от покупателя");
СписокДокументов.ДобавитьЗначение(2742,"заказ поставщику");
СписокДокументов.ДобавитьЗначение(1582,"поступление ТМЦ");
СписокДокументов.ДобавитьЗначение(1684,"возврат поставщику");
СписокДокументов.ДобавитьЗначение(2196,"ПКО");
СписокДокументов.ДобавитьЗначение(2225,"РКО");
СписокДокументов.ДобавитьЗначение(8980,"транзит денежных средств");
СписокДокументов.ТекущаяСтрока(1);

 

 

Пояснение по коду:

1. Процедура ф_Отбор() устанавливается на все элементы, изменение которых должно автоматически фильтровать журнал документов.

2. При помощи функции ПолучитьИД(прм_Объект) мы можем получить идентификатор объекта 1С, чтобы строить по нему фильтр в запросе.

3. В список значений уже добавлены типы документов с их идентификаторами (их можно найти в файле 1cv7.dds). К примеру, на рисунке показан идентификатор к документу "ЗаявкаПокупателя".

 

Изображение

 

SQL-запрос мы "склеиваем" как обычную строку.

В коде встречаются 4 идентификатора полей таблицы SQL в которые мы передаем наши значения фильтров:

SP74 - это поле, в котором хранится "автор документа"

IDDOCDEF - в этом поле хранится идентификатор вида документа

CLOSED - флаг проведения

ISMARK - флаг пометки удаления

 

Как уже было сказано ранее, принцип работы компоненты в подмене SQL-запросов, поступающих из 1С в базу данных SQL.

Изначально запрос выглядит вот так:

vk_hook.ТекстSQL="Select * from _1SJOURN(NOLOCK INDEX=JOURNAL) where IDJOURNAL=? and DATE_TIME_IDDOC>=? and DATE_TIME_IDDOC

Пусть вас не пугают вопросительные знаки в запросе, вместо них подставляются стандартные значения, передаваемые 1С для журнала - в данном случае это идентификатор самого журнала и интервал его открытия.

Мы же заменяем его на:

vk_hook.НовыйSQL="Select * from _1SJOURN(NOLOCK INDEX=JOURNAL) where "+стр+" IDJOURNAL=? and DATE_TIME_IDDOC>=? and DATE_TIME_IDDOC

Практически ничего не изменилось, за исключением добавления условия "where".

Команда vk_hook.УстановитьЗаменуSQL(), собственно и активизирует эту подмену.

 

На практике это выглядит примерно так:

1. Журнал без отборов

Изображение

   2. Журнал с отбором по типу документа

 Изображение

 3. Журнал с отбором по типу документа и автору

 Изображение

 4. Журнал с отбором только проведенных документов по типу документа и автору

 Изображение

 

Теперь время пришло сказать о недостатках описанного варианта организации множественного отбора, а точнее возможных его глюках. Дело в том, что данный метод отказывался корректно работать со сложным запросом (вложенной командой SELECT или множественным фильтром по одному из параметров, допустим выборе в качестве фильтра сразу 2-х типов документов). Фильтр вроде бы отрабатывал корректно, но при перемещении курсора внутри журнала, сам журнал вдруг "вешался" и все документы выборки пропадали. По всей видимости, это недоработки именно в самой компоненте. Не хотелось бы, чтобы для Вас это стало неприятной неожиданностью, в случае, если решите использовать этот способ на практике.

 

В заключении, хотелось бы сказать, что данный вариант решения задачи "множественного отбора в журнале документов" не единственный. В качестве альтернативы можно использовать библиотеки 1СРР.dll и Formex.dll, которые в связке дают схожий результат. Но этот путь для программиста будет более долгим и "тернистым", особенно если у Вас не было ранее опыта работы с этими библиотеками.

 

На этом все. Разрешите откланяться. И да пребудет с вами Сила)

 

P.S. Отдельное спасибо romix - автору компоненте vk_hook1C.dll.

 
0
Читайте также
Перенос документов из ТИС в Бух 7.7
Решение проблем, возникающих при переносе из ТИС в Бух7.7?
1С помощь и настройка 1с 7.7
Настройка 1С 7.7 может быть осуществлена самим пользователем
(V 7.7) Справка по работе с метаданными (с примерами)
Получение метаданных в программе 1С 7.7 происходит через объект "Метаданные"
Разработки
Групповое обновление конфигураций
Групповое обновление конфигураций 1С7.7
Отчет по продажам(выручке).Отчет по рентабельности. для бухгалтерии 8.2.
Отчет по продажам товаров - выводит продажи по ставкам НДС
Еще от автора
≡ к списку статей