Секрета нет в том, что большие ERP системы работают на оракле, ms sql-е... . под каким нибуть самописным софтом на дельфях, си или еще чем нибуть, как правило это голая управленка (первичка), без намека на бух. отчетность и соответственно весь бух.учет в 1С .Эта статья позволяет с минимальными правками изменить регламентированный отчет Декларация по НДС за 2015 год и в то же время получить объедененную книгу покупок и продаж с возможностью выгрузки в формате XML.Все модификации на Бухгалтерия предприятия КОРП, редакция 2.0 (2.0.64.18/ 2.0.64.19).
Методика стара как мир, в нужный момент 1С подкинуть наши данные, а дальше он их схавает и сформирует кп и кп , потом штатно выгрузить xml.Загрузкой книг занимается общий модуль УчетНДС, ниже приведены куски кода из него и места вставок с моим комментарием см.
Есть одна засада связанная с кодом вида операции счет фактур, которую я обходил тупо заменой в XML файле. Код вида операции "26" это проверка счет фактуры в базе 1С на наличие и заполнености определенных полей (судя по запросу, может я не правильно понял) (а в 1С у нас ее нет, мы же куклы используем, она у нас в управленке). Попробуйте сами решить это, мне не влом XML поправить было.
//Точечная вставка в модуль УчетНДС
//Процедура ПреобразоватьЗаписиКнигиПокупок(СтруктураПараметров, НаборЗаписей, ТабличныйДокумент = Неопределено,
// СписокСчетовФактур, ИтогПоОрганизации = 0, ПараметрыСтроки = Неопределено,
// ТаблицаДокумента = Неопределено, СтруктураСекций = Неопределено) Экспорт
//
// ДеревоЗаписей = НаборЗаписей.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
// РДВ_КП.КнигаПокупокДополнитьДаннымиАСУ(ДеревоЗаписей,СтруктураПараметров); //Петров 2015
//в процедуре 2 строки на попытку
//Процедура ЗаполнитьСтрокуКнигиПокупок(
// Попытка СоставСтроки.СчетФактура = ЗаписьКниги.СчетФактураДокументРасшифровка; Исключение КонецПопытки; //Петров 2015
// Попытка СоставСтроки.СчетФактура = СтрокаЗаписи.СчетФактураДокументРасшифровка; Исключение КонецПопытки; //Петров 2015
// Попытка СоставСтроки.Вставить("ДокументРасшифровки", СоставСтроки.СчетФактура); Исключение КонецПопытки; // Петров 2015
//И
//Процедура ПреобразоватьЗаписиКнигиПродаж(
// СтруктураПараметров, НаборЗаписей, ТабличныйДокумент = Неопределено,
// СписокСчетовФактур, ИтогПоОрганизации = 0, ПараметрыСтроки = Неопределено,
// ТаблицаДокумента = Неопределено, СтруктураСекций = Неопределено) Экспорт
//
// ЕстьЗаписиПоКолонке20 = Ложь;
//
// Если НЕ СтруктураПараметров.Свойство("ЗаполнениеДекларации") Тогда
// СтруктураПараметров.Вставить("ЗаполнениеДекларации", Ложь);
// ИначеЕсли СтруктураПараметров.ЗаполнениеДекларации И СтруктураПараметров.КонецПериода < '20150101' Тогда
// СтруктураПараметров.ЗаполнениеДекларации = Ложь;
// КонецЕсли;
//
// ДеревоЗаписей = НаборЗаписей.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
// РДВ_КП.КнигаПродажДополнитьДаннымиАСУ(ДеревоЗаписей,СтруктураПараметров); //Петров 2015
Для того что бы все это начало работать в общих модулях создадим модуль РДВ_КП (или на ваше усмотрение только верхний код поправьте) модуль создаем как на картинке
И его код , далее с комментариями по коду
-----------------Начало
//процедура входа
Процедура КнигаПокупокДополнитьДаннымиАСУ(ДеревоЗаписей,СтруктураПараметров) Экспорт
Тб=ТаблицуИзАСУ("КПокупок",СтруктураПараметров);
ПоОрг=ДеревоЗаписей.Строки[0].Строки.Добавить();
НДС=ДеревоЗаписей.Строки[0].НДС;
Для Каждого Стр Из Тб Цикл
//это попытка сэмулировать группировки , является подводным камнем , так как от релиза к релизу 1С может изменить количество группировок
ПоДок = ПоОрг.Строки.Добавить();
ЗаполнитьСтрокуКПокупокДерева(Стр,ПоДок);
ПоКор = ПоДок.Строки.Добавить();
ЗаполнитьСтрокуКПокупокДерева(Стр,ПоКор);
ЗаписьКП = ПоКор.Строки.Добавить();
НДС=НДС+ЗаполнитьСтрокуКПокупокДерева(Стр,ЗаписьКП);
КонецЦикла;
//тут обновим Итоги
ДеревоЗаписей.Строки[0].НДС=НДС;
КонецПроцедуры
Функция ПреобразоватьДату(СтрДата,Направление="")
Если ПустаяСтрока(Направление) Тогда
День=Лев(СтрДата,2);
Месяц=Сред(СтрДата,4,2);
Год=Прав(СтрДата,4);
Иначе
День=Прав(СтрДата,2);
Месяц=Сред(СтрДата,5,2);
Год=Лев(СтрДата,4);
КонецЕсли;
Возврат Дата(Число(Год),Число(Месяц),Число(День));
КонецФункции
//Левая часть из отладчика, правую оставил как есть для наглядности
Функция ЗаполнитьСтрокуКПокупокДерева(Стр,СтрД)
СтрД.Валюта = Null;
СтрД.ВалютаКод = Null;
СтрД.ВсегоПокупок = Число(Стр.FULLPRICE);
СтрД.ДатаДокументаОплаты = 1 ; //01.01.0001 0:00:00 Дата
СтрД.ДатаИсправления = Null;
СтрД.ДатаИсправленияКорректировки = Null;
СтрД.ДатаКорректировки = Null;
СтрД.ДатаОплаты = ПреобразоватьДату(Лев(Стр.PAY_DATE,10));
СтрД.ДатаОприходования = ПреобразоватьДату(Стр.SF_DATE);
СтрД.ДатаПринятияНаУчет = ПреобразоватьДату(Стр.SF_DATE);
СтрД.ДатаСобытия = Null;
СтрД.ДатаСчетаФактуры = ПреобразоватьДату(Стр.SF_DATE);
СтрД.ДоговорАванса = Null;
СтрД.ДокументОснованиеСчетаФактуры = Null;
СтрД.Исправление = Null;
СтрД.ИсправленныйСчетФактура = Null;
СтрД.КодВидаОперации = "01";
Если ПустаяСтрока(Стр.object_string_1c) Тогда
Контрагент=Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",Стр.INN).Ссылка;
Иначе
Контрагент=ЗначениеИзСтрокиВнутр(Стр.object_string_1c).Ссылка;
КонецЕсли;
СтрД.Контрагент = Контрагент;
СтрД.НДС0 = 0;
СтрД.НДС10 = Число(Стр.VAT_10);
СтрД.НДС18 = Число(Стр.VAT_18);
СтрД.НДС20 = Число(Стр.VAT_20);
СтрД.НДС = СтрД.НДС0+СтрД.НДС10+СтрД.НДС18+СтрД.НДС20;
СтрД.НаАванс = Ложь;
СтрД.НалоговыйПериод = Null;
СтрД.НомерДокументаОплаты = "";
СтрД.НомерИсправления = Null;
СтрД.НомерИсправленияКорректировки = Null;
СтрД.НомерКорректировки = Null;
СтрД.НомерСчетаФактуры = Формат(Число(Стр.SF_NUM),"ЧГ=0");
СтрД.ОбрабатыватьНомерДокумента = Ложь; // обратите внимание на это если ложь то дальше в коде не обрабатывается объект документ
СтрД.Организация = Null;
СтрД.Посредник = Null;
СтрД.ПосредникИНН = Null;
СтрД.ПосредникКПП = Null;
СтрД.Продавец = Стр.CLIENT;
СтрД.ПродавецИНН = Стр.INN;
СтрД.ПродавецКПП = Стр.KPP;
СтрД.СводныйКорректировочный = Ложь;
СтрД.СтавкаНДС_Аванс = Null;
СтрД.СуммаБезНДС10 = Число(Стр.WITHOUT_10);
СтрД.СуммаБезНДС18 = Число(Стр.WITHOUT_18);
СтрД.СуммаБезНДС20 = Число(Стр.WITHOUT_20);
СтрД.СуммаСовсемБезНДС = Число(Стр.WITHOUT_0);
//тут наши куклы
СтрД.СчетФактура = Документы.СчетФактураПолученный.НайтиПоНомеру("00000002",Дата(2002,01,01)).Ссылка;
СтрД.СчетФактураДата = ПреобразоватьДату(Стр.SF_DATE);
СтрД.СчетФактураДокумент = Стр.SF_SALER;
//тут наши куклы
СтрД.СчетФактураДокументРасшифровка = Документы.СчетФактураПолученный.НайтиПоНомеру("00000002",Дата(2002,01,01)).Ссылка;
Возврат СтрД.НДС;
КонецФункции
Функция ЗаполнитьСтрокуКПродажДерева(Стр,СтрД)
СтрД.Валюта = Null;
СтрД.ВалютаКод = Null;
СтрД.ВсегоПродаж = Число(Стр.TOTAL);
СтрД.ВсегоПродажВВалюте = Null;
СтрД.ДатаДокументаОплаты = Стр.PAYMENTDATE;
СтрД.ДатаИсправления = Null;
СтрД.ДатаИсправленияКорректировки = Null;
СтрД.ДатаКорректировки = Null;
СтрД.ДатаОплаты = Стр.PAYMENTDATE;
СтрД.ДатаСобытия = Null;
СтрД.ДатаСчетаФактуры = Стр.INVOICEDATE;
СтрД.ДатаСчетаФактурыСортировка = Стр.INVOICEDATE;
СтрД.ДоговорАванса = Null;
СтрД.ДокументОплаты = Null;
СтрД.Исправление = Null;
СтрД.ИсправленныйСчетФактура = Null;
СтрД.КодВидаОперации = Стр.OPTYPE;
Если ПустаяСтрока(Стр.object_string_1c) Тогда
Контрагент=Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",Стр.INN).Ссылка;
Иначе
Контрагент=ЗначениеИзСтрокиВнутр(Стр.object_string_1c).Ссылка; //это связка оракла и 1С у вас может быть другая
КонецЕсли;
Если ПустаяСтрока(Стр.INN) Тогда
ИНН=Контрагент.ИНН;
КПП=Контрагент.КПП;
Иначе
ИНН=Стр.INN;
КПП=Стр.KPP;
КонецЕсли;
СтрД.Контрагент = Контрагент;
СтрД.НДС0 = Число(Стр.NDS9_09);
СтрД.НДС10 = Число(Стр.NDS10);
СтрД.НДС18 = Число(Стр.NDS18);
СтрД.НДС20 = Число(Стр.NDS20);
СтрД.НаАванс = Null;
СтрД.НаСуммовуюРазницу = Null;
СтрД.НалоговыйПериод = Null;
СтрД.НомерДокументаОплаты = Стр.PAYMENTDOCNUM;
СтрД.НомерИсправления = Null;
СтрД.НомерИсправленияКорректировки = Null;
СтрД.НомерКорректировки = Null;
СтрД.НомерСчетаФактуры = Стр.INVOICENUMBER;
СтрД.НомерСчетаФактурыСортировка = Стр.INVOICENUMBER;
СтрД.ОбрабатыватьНомерДокумента = Ложь; // обратите внимание на это если ложь то дальше в коде не обрабатывается объект документ
СтрД.Организация = Null;
СтрД.Покупатель = Стр.CLIENTNAME;
СтрД.ПокупательИНН = ИНН;
СтрД.ПокупательКПП = КПП;
СтрД.Посредник = Null;
СтрД.ПосредникИНН = Null;
СтрД.ПосредникКПП = Null;
СтрД.СводныйКомиссионный = Ложь;
СтрД.СводныйКорректировочный = Ложь;
СтрД.Событие = Null;
СтрД.СтавкаНДС_Аванс = Null;
СтрД.СуммаБезНДС10 = Число(Стр.SUM10);
СтрД.СуммаБезНДС18 = Число(Стр.SUM18);
СтрД.СуммаБезНДС20 = Число(Стр.SUM20);
СтрД.СуммаСовсемБезНДС = Число(Стр.SUM9_09);
СтрД.СчетФактура = Документы.СчетФактураВыданный.НайтиПоНомеру(00000002",Дата(2002,01,01)).Ссылка;
СтрД.СчетФактураДата = Стр.INVOICEDATE;
СтрД.СчетФактураДокумент = Документы.СчетФактураВыданный.НайтиПоНомеру(00000002",Дата(2002,01,01)).Ссылка;
СтруктураНДС=Новый Структура("НДС0,НДС10,НДС18,НДС20,СуммаБезНДС10,СуммаБезНДС18,СуммаБезНДС20,СуммаСовсемБезНДС",СтрД.НДС0
,СтрД.НДС10,СтрД.НДС18,СтрД.НДС20,СтрД.СуммаБезНДС10,СтрД.СуммаБезНДС18,СтрД.СуммаБезНДС20,СтрД.СуммаСовсемБезНДС);
Возврат СтруктураНДС;
КонецФункции
Процедура КнигаПродажДополнитьДаннымиАСУ(ДеревоЗаписей,СтруктураПараметров) Экспорт
Тб=ТаблицуИзАСУ("КПродаж",СтруктураПараметров);
ПоОрг=ДеревоЗаписей.Строки[0].Строки.Добавить();
НДС0 =ДеревоЗаписей.Строки[0].НДС0;
НДС10 =ДеревоЗаписей.Строки[0].НДС10;
НДС18 =ДеревоЗаписей.Строки[0].НДС18;
НДС20 =ДеревоЗаписей.Строки[0].НДС20;
СуммаБезНДС10 =ДеревоЗаписей.Строки[0].СуммаБезНДС10;
СуммаБезНДС18 =ДеревоЗаписей.Строки[0].СуммаБезНДС18;
СуммаБезНДС20 =ДеревоЗаписей.Строки[0].СуммаБезНДС20;
СуммаСовсемБезНДС =ДеревоЗаписей.Строки[0].СуммаСовсемБезНДС;
Для Каждого Стр Из Тб Цикл
ПоНП = ПоОрг.Строки.Добавить();
ЗаполнитьСтрокуКПродажДерева(Стр,ПоНП);
ПоПО = ПоНП.Строки.Добавить();
ЗаполнитьСтрокуКПродажДерева(Стр,ПоПО);
ПоПД = ПоПО.Строки.Добавить();
ЗаполнитьСтрокуКПродажДерева(Стр,ПоПД);
ЗаписьКниги = ПоПД.Строки.Добавить();
СтруктураНДС=ЗаполнитьСтрокуКПродажДерева(Стр,ЗаписьКниги);
НДС0 =НДС0 +СтруктураНДС.НДС0;
НДС10 =НДС10 +СтруктураНДС.НДС10;
НДС18 =НДС18 +СтруктураНДС.НДС18;
НДС20 =НДС20 +СтруктураНДС.НДС20;
СуммаБезНДС10 =СуммаБезНДС10 +СтруктураНДС.СуммаБезНДС10;
СуммаБезНДС18 =СуммаБезНДС18 +СтруктураНДС.СуммаБезНДС18;
СуммаБезНДС20 =СуммаБезНДС20 +СтруктураНДС.СуммаБезНДС20;
СуммаСовсемБезНДС =СуммаСовсемБезНДС +СтруктураНДС.СуммаСовсемБезНДС;
КонецЦикла;
ДеревоЗаписей.Строки[0].НДС0 =НДС0;
ДеревоЗаписей.Строки[0].НДС10 =НДС10;
ДеревоЗаписей.Строки[0].НДС18 =НДС18;
ДеревоЗаписей.Строки[0].НДС20 =НДС20;
ДеревоЗаписей.Строки[0].СуммаБезНДС10 =СуммаБезНДС10;
ДеревоЗаписей.Строки[0].СуммаБезНДС18 =СуммаБезНДС18;
ДеревоЗаписей.Строки[0].СуммаБезНДС20 =СуммаБезНДС20;
ДеревоЗаписей.Строки[0].СуммаСовсемБезНДС =СуммаСовсемБезНДС;
КонецПроцедуры
Функция СформироватьСтрокуПодключенияOracle()
Сервер = Константы.РДВ_ИмяСервера.Получить();
Возврат("Provider=OraOLEDB.Oracle;Data Source="+Сервер+";Password=ххх;User ID=ххх;PLSQLRSet=1");
КонецФункции
//функция по рекордсету возвращает таблицу значений колонки строятся по именам полей запроса (хорошая функция для конструктора)
Функция ВыполнитьЗапрос(Соединение,Запрос="",СписПарам="",ТипЗапроса="") Экспорт
ТЗ = Новый ТаблицаЗначений;
Если ПустаяСтрока(Запрос)=1 Тогда
Сообщить("Запрос пуст!");
Возврат ТЗ;
КонецЕсли;
СоздЗапрос = Новый COMObject("ADODB.Command");
СоздЗапрос.ActiveConnection = Соединение;
Если ЗначениеЗаполнено(ТипЗапроса) Тогда
СоздЗапрос.CommandType = Число(ТипЗапроса);
КонецЕсли;
СоздЗапрос.CommandText = Запрос;
РезЗапроса = Новый COMObject("ADODB.RecordSet");
РезЗапроса.CursorType=0;
РезЗапроса.CursorLocation = 2;
Если ЗначениеЗаполнено(СписПарам) Тогда
Если СписПарам.Количество()<>0 Тогда
Для й=0 по СписПарам.Количество()-1 Цикл
Зн = СписПарам.Получить(й).Значение;
Стр= СписПарам.Получить(й).Представление;
СоздЗапрос.Parameters.Append(СоздЗапрос.CreateParameter(Стр, 200, 1, СтрДлина(Зн), Зн));
КонецЦикла;
КонецЕсли;
КонецЕсли;
Попытка
РезЗапроса = СоздЗапрос.Execute();
Исключение
Сообщить(Запрос);
КонецПопытки;
Если РезЗапроса.Fields.Count>0 Тогда
Если РезЗапроса.BOF()=0 Тогда
Для й=0 По РезЗапроса.Fields.Count-1 Цикл
Колонка = РезЗапроса.Fields.Item(й);
ТЗ.Колонки.Добавить(Колонка.Name);
КонецЦикла;
РезЗапроса.MoveFirst();
Пока РезЗапроса.EOF()=0 Цикл
СтрТб=ТЗ.Добавить();
Для й=0 По РезЗапроса.Fields.Count-1 Цикл
СтрТб[й]=Строка(РезЗапроса.Fields(РезЗапроса.Fields.Item(й).Name).Value);
КонецЦикла;
РезЗапроса.MoveNext();
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат ТЗ;
КонецФункции
Функция ТаблицуИзАСУ(ВидКниги,СтруктураПараметров)
Home_org=0;
Попытка
НастрПодкл = Справочники.РДВ_НастройкиПодключенияАСУ.НайтиПоКоду("000000001");
Home_org=НастрПодкл.home_org_id;
Исключение
Сообщить("----");
Возврат Неопределено;
КонецПопытки;
Если НЕ ЗначениеЗаполнено(Home_org) Тогда
Возврат Неопределено;
КонецЕсли;
//это куклы документов для подстановки данных я их создаю в начале времен и они у меня не проведенные
СчПол=Документы.СчетФактураПолученный.НайтиПоНомеру("00000002",Дата(2002,01,01)).Ссылка;
СчВыд=Документы.СчетФактураВыданный.НайтиПоНомеру("00000002",Дата(2002,01,01)).Ссылка;
Если СчПол=Документы.СчетФактураПолученный.ПустаяСсылка() Тогда
СчПол=Документы.СчетФактураПолученный.СоздатьДокумент();
СчПол.Дата=Дата(2002,01,01);
СчПол.Номер="00000002";
СчПол.ПометкаУдаления=Истина;
СчПол.Записать();
Сообщить("Создана пустая сч/ф "+СчПол.Ссылка);
КонецЕсли;
Если СчВыд=Документы.СчетФактураВыданный.ПустаяСсылка() Тогда
СчВыд=Документы.СчетФактураВыданный.СоздатьДокумент();
СчВыд.Дата=Дата(2002,01,01);
СчВыд.Номер="00000002";
СчВыд.ПометкаУдаления=Истина;
СчВыд.Записать();
Сообщить("Создана пустая сч/ф "+СчВыд.Ссылка);
КонецЕсли;
Подключение = Новый COMObject("ADODB.Connection");
Подключение.ConnectionTimeOut=100;
СтрокаПодключения = СформироватьСтрокуПодключенияOracle();
Подключение.Open(СтрокаПодключения);
ТексЗапроса=ПолучитьЗапрос(СтруктураПараметров.НачалоПериода,СтруктураПараметров.КонецПериода,Home_org,ВидКниги);
Тб=ВыполнитьЗапрос(Подключение,ТексЗапроса);
Подключение=Неопределено;
Возврат Тб;
КонецФункции
Функция ПолучитьЗапрос(ДатаНач,ДатаКон,КодHom_org,ВидКниги) Экспорт
ТексЗапроса="";
Если ВидКниги="КПокупок" Тогда
ТексЗапроса="Select тут запрос к ораклу с таблицей книги продаж";
КонецЕсли;
Если ВидКниги="КПродаж" Тогда
ТексЗапроса="SELECT тут запрос к ораклу с таблицей книги продаж ";
КонецЕсли;
Возврат ТексЗапроса;
КонецФункции
------------------Конец
Вот это все, если все правильно сделали должно работать.