Книга знаний

1С:Предприятие / v8 / Объекты конфигурации / Бухгалтерский учет

v8: Программно генерируемый запрос для отчета по оборотам между заданными счетами

Один из вариантов генерации отчета для конкретного сложного запроса.Автор статьи: Гений 1С | Редакторы:
Последняя редакция №4 от 20.10.06 | История
URL: http://kb.mista.ru/article.php?id=376

Ключевые слова: запрос,бухгалтерия,генерация


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

90 - 20 Подразделение, Договор - Дебетовый оборот
90 - 41 Подразделение, Товар - Кредитовый оборот




Вручную написать такой запрос достаточно трудоемко, поэтому проще всего его генерировать автоматически.

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

Времени объяснять подробно нету, смотрите по коду примера.

Схему запроса можно заполнить программно:

    ТЗ=Новый ТаблицаЗначений();
    ТЗ.Колонки.Добавить("Субконто_Подразделение");
    //ТЗ.Колонки.Добавить("Субконто_Договор");
    ТЗ.Колонки.Добавить("Субконто_ВидТовара");
    ТЗ.Колонки.Добавить("Субконто_Сдельный");
    ТЗ.Колонки.Добавить("Субконто_СтатьяЗатрат");
    ТЗ.Колонки.Добавить("Функция_ВаловыйДоход");
    ТЗ.Колонки.Добавить("Функция_ВаловаяПрибыль");
    ТЗ.Колонки.Добавить("Функция_Себестоимость");
    ТЗ.Колонки.Добавить("Функция_ПрямыеРасходы");
    ТЗ.Колонки.Добавить("Функция_Зарплата");
    ТЗ.Колонки.Добавить("УсловиеСчет");
    ТЗ.Колонки.Добавить("УсловиеКорСчет");
    ТЗ.Колонки.Добавить("УсловиеЗапроса");
    
    УсловиеПоПодразделению="(Субконто_Подразделение В ИЕРАРХИИ (&Подразделение))";
    
    ЗаполнитьЗначенияСвойств(ТЗ.Добавить(),
        Новый Структура("Функция_ПрямыеРасходы, Функция_ВаловаяПрибыль, УсловиеСчет, УсловиеКорСчет,Субконто_Подразделение, Субконто_ВидТовара, Субконто_СтатьяЗатрат ",  
            "СуммаОборотДт", "-СуммаОборотДт", "Счет=&ПланыСчетов_Основной_ХХ_1", "КорСчет=&ПланыСчетов_Основной_ХХ_1", "КорСубконто1", "Субконто2", "КорСубконто3"));
    ЗаполнитьЗначенияСвойств(ТЗ.Добавить(),
        Новый Структура("Функция_ВаловыйДоход, Функция_ВаловаяПрибыль, УсловиеСчет, УсловиеКорСчет,Субконто_Подразделение,Субконто_ВидТовара",  
            "СуммаОборотДт", "СуммаОборотДт", "Счет=&ПланыСчетов_Основной_ХХ_1", "КорСчет=&ПланыСчетов_Основной_ХХ_1", "КорСубконто1", "КорСубконто2"));
    ЗаполнитьЗначенияСвойств(ТЗ.Добавить(),
        Новый Структура("Функция_Себестоимость, Функция_ВаловаяПрибыль, УсловиеСчет, УсловиеКорСчет,Субконто_Подразделение,Субконто_ВидТовара",  
            "СуммаОборотДт","-СуммаОборотДт",  "Счет=&ПланыСчетов_Основной_ХХ_4", "КорСчет=&ПланыСчетов_Основной_41_3", "Субконто1", "Субконто2"));
    ЗаполнитьЗначенияСвойств(ТЗ.Добавить(),
        Новый Структура("Функция_ВаловыйДоход, Функция_ВаловаяПрибыль, УсловиеСчет, УсловиеКорСчет,Субконто_Подразделение,Субконто_ВидТовара",  
            "СуммаОборотДт", "СуммаОборотДт", "Счет=&ПланыСчетов_Основной_ХХ_3", "КорСчет=&ПланыСчетов_Основной_ХХ_4", "КорСубконто1", "КорСубконто2"));
    //Запрлата        
    ЗаполнитьЗначенияСвойств(ТЗ.Добавить(),
        Новый Структура("Функция_Зарплата, Функция_ВаловаяПрибыль, УсловиеСчет, УсловиеКорСчет,Субконто_Подразделение, Субконто_ВидТовара,  Субконто_Сдельный",  
            "СуммаОборотДт", "0", "Счет=&ПланыСчетов_Основной_ХХ_1", "КорСчет=&ПланыСчетов_Основной_ХХ_2", "Субконто1", "Субконто2", "КорСубконто2"));
    ЗаполнитьЗначенияСвойств(ТЗ.Добавить(),
        Новый Структура("Функция_Зарплата, Функция_ВаловаяПрибыль, УсловиеСчет, УсловиеКорСчет,Субконто_Подразделение,Субконто_ВидТовара",  
            "СуммаОборотДт", "0","Счет=&ПланыСчетов_Основной_ХХ_4", "КорСчет=&ПланыСчетов_Основной_44", "Субконто1", "Субконто2",  "КорСубконто2", "КорСубконто2.ВидТовара"));



Или же загрузить из макета (что проще и нагляднее):

СЮДА ТОВАРИЩ ВОЛШЕБНИК ВСТАВИТ КАРТИНКУ!!!


    ТЗ.ЗаполнитьЗначения(УсловиеПоПодразделению, "УсловиеЗапроса");
    //ТЗ.Колонки.Удалить(ТЗ.Колонки.Субконто_Договор); //Договор нам не нужен
            
    
    // Вставить содержимое обработчика.
    БазовыйТекстЗапроса="ВЫБРАТЬ Счет,КорСчет, 
                        |    &Функция,
                        |    &Субконто 
                        |ИЗ
                        |    РегистрБухгалтерии.Основной.Обороты(&Дата1, &Дата2, , &УсловиеСчет, , &УсловиеЗапроса, &УсловиеКорСчет, ) КАК ОсновнойОбороты";
                       
    //БазовыйТекстЗапроса=БазовыйТекстЗапроса+"";                       
    Запрос=Новый Запрос();
    
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_1",ПланыСчетов.Основной.НайтиПоКоду("ХХ.1"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_2",ПланыСчетов.Основной.НайтиПоКоду("ХХ.2"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_3",ПланыСчетов.Основной.НайтиПоКоду("ХХ.3"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_4",ПланыСчетов.Основной.НайтиПоКоду("ХХ.4"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_5",ПланыСчетов.Основной.НайтиПоКоду("ХХ.5"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_1",ПланыСчетов.Основной.НайтиПоКоду("ХХ.1"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_1",ПланыСчетов.Основной.НайтиПоКоду("ХХ.1"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_2",ПланыСчетов.Основной.НайтиПоКоду("ХХ.2"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_4",ПланыСчетов.Основной.НайтиПоКоду("ХХ.4"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ",ПланыСчетов.Основной.НайтиПоКоду("44"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_3",ПланыСчетов.Основной.НайтиПоКоду("ХХ.3"));                        
    Запрос.УстановитьПараметр("ПланыСчетов_Основной_ХХ_3",ПланыСчетов.Основной.НайтиПоКоду("ХХ.3"));                        
    Запрос.УстановитьПараметр("Подразделение", ВыбПодразделение);                        
    
    Запрос.УстановитьПараметр("Дата1",НачалоДня(Дата1));                        
    Запрос.УстановитьПараметр("Дата2",КонецДня(Дата2));    
    
    
    Запрос.Текст=обЗапросКБухгалтерииПоПараметрам(Запрос, БазовыйТекстЗапроса, ТЗ);
    
    РезультатОтчета=Запрос.Выполнить().Выгрузить();




Функция обЗапросКБухгалтерииПоПараметрам(Запрос, БазовыйТекстЗапроса, ТЗ) Экспорт
    РезТекст="";
    Для Каждого Стр из ТЗ Цикл
        Текст=БазовыйТекстЗапроса;
        Если Стр.УсловиеСчет=Неопределено Тогда
            УсловиеСчет="ИСТИНА";
        Иначе
            УсловиеСчет=Стр.УсловиеСчет;
        КонецЕсли;
        Текст=СтрЗаменить(Текст, "&УсловиеСчет", УсловиеСчет);
        
        Если Стр.УсловиеКорСчет=Неопределено Тогда
            УсловиеКорСчет="ИСТИНА";
        Иначе
            УсловиеКорСчет=Стр.УсловиеКорСчет;
        КонецЕсли;
        Текст=СтрЗаменить(Текст, "&УсловиеКорСчет", УсловиеКорСчет);
        
        Если Стр.УсловиеЗапроса=Неопределено Тогда
            УсловиеЗапроса="ИСТИНА";
        Иначе
            УсловиеЗапроса=Стр.УсловиеЗапроса;
        КонецЕсли;
        
        ТекстФункций="";
        Для Каждого Колонка из ТЗ.Колонки Цикл
            ИмяКолонки=Колонка.Имя;
            Если Найти(ИмяКолонки, "Функция_")=1 Тогда
                ИмяФункции=Сред(ИмяКолонки, 9);
                Если Стр[ИмяКолонки]=Неопределено Тогда
                    ЗначФункции="0";
                Иначе
                    ЗначФункции=Стр[ИмяКолонки];
                КонецЕсли;
                ТекстФункции="("+ЗначФункции+") КАК "+ИмяФункции;
                ТекстФункций=ТекстФункций+?(ТекстФункций="", "", ",")+ ТекстФункции;                       
            КонецЕсли;
        КонецЦикла;
        Если ТекстФункций="" Тогда ТекстФункций="НЕОПРЕДЕЛЕНО" КонецЕсли;
        Текст=СтрЗаменить(Текст, "&Функция", ТекстФункций);
    
        ТекстСубконтов="";
        Для Каждого Колонка из ТЗ.Колонки Цикл
            ИмяКолонки=Колонка.Имя;
            Если Найти(ИмяКолонки, "Субконто_")=1 Тогда
                ИмяСубконто=Сред(ИмяКолонки, 10);
                Если Стр[ИмяКолонки]=Неопределено Тогда
                    ЗначСубконто="Неопределено";
                Иначе
                    ЗначСубконто=Стр[ИмяКолонки];
                КонецЕсли;
                ТекстСубконто="("+ЗначСубконто+") КАК "+ИмяСубконто;
                ТекстСубконтов=ТекстСубконтов+?(ТекстСубконтов="", "", ",")+ ТекстСубконто;                       
                
                //Смотрим, встречается ли субконто в условии 
                УсловиеЗапроса=СтрЗаменить(УсловиеЗапроса, ИмяКолонки, ЗначСубконто);
                
                
            КонецЕсли;
        КонецЦикла;
        Если ТекстСубконтов="" Тогда ТекстСубконтов="НЕОПРЕДЕЛЕНО" КонецЕсли;
        Текст=СтрЗаменить(Текст, "&Субконто", ТекстСубконтов);
        
        //Меняем условие запроса с учетом субконтов
        Текст=СтрЗаменить(Текст, "&УсловиеЗапроса", УсловиеЗапроса);

        
        РезТекст=РезТекст+?(РезТекст="", "", " ОБЪЕДИНИТЬ ВСЕ ")+ Текст;                       
    КонецЦикла;
    Возврат РезТекст;
КонецФункции




Можно также не устанавливать все счета в запрос, а распознать используемые в запросе счета с помощью:

Приятно также, что в условии по субконто можно писать например так Субконто_Подразделение.Код="11", вместо Субконто_Подразделение автоматически подставится код для получения нужного субконто, например Субконто1.

Внимание!!! Субконто и функции нельзя называть так, чтобы название одного субконто входило в название другого, например Подраздлеление и ПодразделениеКонтроля, лучше назвать так Подразделение и КонтрольноеПодразделение, иначе будет ошибка!

20061020 Обнаружена ошибка в этой функции! Вместо ОБЪЕДИНИТЬ нужно использовать ОБЪЕДИНИТЬ ВСЕ !!! Текст функции поправил!

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика