v8: Программно генерируемый запрос для отчета по оборотам между заданными счетами Ключевые слова: запрос,бухгалтерия,генерация
Даже не знаю, как правильно назвать статью, придумаете - переименуйте.
Очень часто в бухгалтерии встречаются запросы, где нужны обороты (дебетовые или кредитовые) между конкретными счетами и аналитика по ним, например:
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 Обнаружена ошибка в этой функции! Вместо ОБЪЕДИНИТЬ нужно использовать ОБЪЕДИНИТЬ ВСЕ !!! Текст функции поправил!
|