Доброго времени суток! Данная статья является шаблоном для разработки обработки - загрузки данных из программного продукта Algoritm-S, она призвана облегчить труды и сэкономить время, данный код можно использовать, как законченный продукт, а можно дорабатывать по своим требованиям и желаниям. Пример будет рассмотрен на конфигурации "Бухгалтерия предприятия 3.0 (3.0.79.21), возможно подойдет и для других с идентичными метаданными.
Что имеем:
-файлы выгрузки из Algoritm-S в формате *.dbf;
-PROD.DBF - файл выгрузки номенклатуры;
-KONTR.DBF - файл выгрузки контрагентов;
-INC.DBF - файл выгрузки документов поступлений;
-ROUT.DBF - файл выгрузки документов продажи;
Создадим внешнюю обработку, разработаем самую простую форму с минимальными набором реквизитов:
Добавим команду загрузить и привяжем ее к процедуре загрузить()
Для элемента формы ДиалогВыбораФайла назначим обработчик для события НачалоВыбора
В модуле формы должна располагаться следующая процедура:
&НаКлиенте
Процедура ДиалогВыбораФайлаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
Диалог.Заголовок = "Выберите каталог";
Диалог.МножественныйВыбор = Ложь;
Если Диалог.Выбрать() Тогда
ПутьКФайлу = Диалог.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
Логика данного шаблона, в следующем, пользователь выбирает каталог, ищем в каталоге файлы с названиями выгрузок, обрабатываем загрузку.
По команде загрузить будем перебирать файлы в каталоге и искать необходимые:
&НаКлиенте
Процедура Загрузить(Команда)
ЗагрузитьНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьНаСервере()
МассивНайденныхФайлов = НайтиФайлы(ПутьКФайлу, "*.dbf", Ложь);
ФайлНоменклатуры = Неопределено;
ФайлКонтрагентов = Неопределено;
ФайлПриходов = Неопределено;
ФайлПродаж = Неопределено;
Для Каждого Файл Из МассивНайденныхФайлов Цикл
Если СтрНайти(Файл.ПолноеИмя, "PROD.DBF") Тогда
ФайлНоменклатуры = Файл.ПолноеИмя;
КонецЕсли;
Если СтрНайти(Файл.ПолноеИмя, "KONTR.DBF") Тогда
ФайлКонтрагентов = Файл.ПолноеИмя;
КонецЕсли;
Если СтрНайти(Файл.ПолноеИмя, "INC.DBF") Тогда
ФайлПриходов = Файл.ПолноеИмя;
КонецЕсли;
Если СтрНайти(Файл.ПолноеИмя, "ROUT.DBF") Тогда
ФайлПродаж = Файл.ПолноеИмя;
КонецЕсли;
КонецЦикла;
Если ФайлНоменклатуры <> Неопределено Тогда
Попытка
ЗагрузитьНоменклатуру(ФайлНоменклатуры);
Сообщить("Номенклатура успешно загружена");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Если ФайлКонтрагентов <> Неопределено Тогда
Попытка
ЗагрузитьКонтрагентов(ФайлКонтрагентов);
Сообщить("Контрагенты успешно загружены");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Если ФайлПриходов <> Неопределено Тогда
Попытка
ЗагрузитьПоступления(ФайлПриходов);
Сообщить("Поступления успешно загружены");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Если ФайлПродаж <> Неопределено Тогда
Попытка
ЗагрузитьПродажи(ФайлПродаж);
Сообщить("Продажи успешно загружены");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Сама функция по загрузке DBF-файла так же взята из шаблона (Публикация № 103060, спасибо автору) и немного доработана под нужды:
&НаСервере
Функция ЗаполнитьТЗизDBF(ИмяФайла, Кодировка, СписокКолонок)
ФайлДанных = Новый XBase();
ФайлДанных.ОткрытьФайл(ИмяФайла,,Истина);
ФайлДанных.Кодировка = Кодировка;
Если Не ФайлДанных.Открыта() Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Произошла ошибка при открытии файла " + ИмяФайла;
Сообщение.Сообщить();
Возврат Неопределено;
КонецЕсли;
ОписаниеБулево = Новый ОписаниеТипов("Булево");
ОписаниеДаты = Новый ОписаниеТипов("Дата",,, Новый КвалификаторыДаты(ЧастиДаты.Дата));
ТабЗнач = Новый ТаблицаЗначений;
Для Каждого Поле из ФайлДанных.Поля Цикл
Колонка = СписокКолонок.НайтиПоЗначению(Поле.Имя);
Если Колонка <> Неопределено Тогда
Если Поле.Тип = "L" Тогда
Тип = ОписаниеБулево;
ИначеЕсли Поле.Тип = "D" Тогда
Тип = ОписаниеДаты;
ИначеЕсли (Поле.Тип = "N") ИЛИ (Поле.Тип = "F") ИЛИ (Поле.Тип = "S") Тогда
Тип = Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(Поле.Длина));
Иначе
Тип = Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(Поле.Длина));
КонецЕсли;
Если СтрНайти(Колонка.Представление,"Цена") > 0 ИЛИ СтрНайти(Колонка.Представление,"Сумма") > 0 ИЛИ СтрНайти(Колонка.Представление,"Количество") > 0 Тогда
ТабЗнач.Колонки.Добавить(Колонка.Представление, Новый ОписаниеТипов("Число"));
Иначе
ТабЗнач.Колонки.Добавить(Колонка.Представление, Тип);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если (ТабЗнач.Колонки.Количество() <> 0) И (ФайлДанных.Первая()) Тогда
Пока Истина Цикл
СтрокаТаб = ТабЗнач.Добавить();
Для Каждого Поле из ФайлДанных.Поля Цикл
Колонка = СписокКолонок.НайтиПоЗначению(Поле.Имя);
Если (Колонка <> Неопределено) И Колонка.Пометка Тогда
СтрокаТаб[Колонка.Представление] = ФайлДанных[Поле.Имя];
КонецЕсли;
КонецЦикла;
Если Не ФайлДанных.Следующая() Тогда Прервать; КонецЕсли;
КонецЦикла;
КонецЕсли;
ФайлДанных.ЗакрытьФайл();
Возврат ТабЗнач;
КонецФункции
Далее идут процедуры загрузки, а загружаются:
-справочник номенклатура;
-справочник контрагенты;
-документ поступление товар и услуг;
-документ отчет о розничных продажах;
В процедурах в списке колонок определяем структуру нашего DBF-файла выгрузки, остальное думаю понятно
Процедура ЗагрузитьПродажи(ФайлПродаж)
Кодировка = КодировкаXBase.OEM ;
СписокКолонок = Новый СписокЗначений;
СписокКолонок.Добавить("PROD_ID", "КодТовара", Истина);
СписокКолонок.Добавить("OUT_H_ID", "КодДокумента", Истина);
СписокКолонок.Добавить("DATE_SALE", "ДатаПродажи", Истина);
СписокКолонок.Добавить("OPER_ID", "ИДОперации", Истина);
СписокКолонок.Добавить("OUT_CNT", "Количество", Истина);
СписокКолонок.Добавить("NDS_SIZE", "СтавкаНДС", Истина);
СписокКолонок.Добавить("INC_NDS", "СуммаНДС", Истина);
СписокКолонок.Добавить("INC_W", "Цена", Истина);
СписокКолонок.Добавить("SUM_NO_SK", "Сумма", Истина);
ТЗ = ЗаполнитьТЗизDBF(ФайлПродаж, Кодировка, СписокКолонок);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.КодТовара КАК КодТовара,
| ТЗ.КодДокумента КАК КодДокумента,
| ТЗ.ДатаПродажи КАК ДатаПродажи,
| ТЗ.ИДОперации КАК ИДОперации,
| ТЗ.Количество КАК Количество,
| ТЗ.СтавкаНДС КАК СтавкаНДС,
| ТЗ.СуммаНДС КАК СуммаНДС,
| ТЗ.Цена КАК Цена,
| ТЗ.Сумма КАК Сумма
|ПОМЕСТИТЬ ВТ
|ИЗ
| &ТЗ КАК ТЗ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ.КодТовара КАК КодТовара,
| ВТ.КодДокумента КАК КодДокумента,
| ВТ.ДатаПродажи КАК ДатаПродажи,
| ВТ.ИДОперации КАК ИДОперации,
| СУММА(ВТ.Количество) КАК Количество,
| ВТ.СтавкаНДС КАК СтавкаНДС,
| СУММА(ВТ.СуммаНДС) КАК СуммаНДС,
| СРЕДНЕЕ(ВТ.Цена) КАК Цена,
| СУММА(ВТ.Сумма) КАК Сумма
|ИЗ
| ВТ КАК ВТ
|
|СГРУППИРОВАТЬ ПО
| ВТ.КодТовара,
| ВТ.КодДокумента,
| ВТ.ДатаПродажи,
| ВТ.ИДОперации,
| ВТ.СтавкаНДС
|ИТОГИ ПО
| ДатаПродажи";
Запрос.УстановитьПараметр("ТЗ", ТЗ);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаКодДокумента = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
ДатаНакладной = "20001010";
Пока ВыборкаКодДокумента.Следующий() Цикл
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ОтчетОРозничныхПродажах.Ссылка КАК Ссылка
|ИЗ
| Документ.ОтчетОРозничныхПродажах КАК ОтчетОРозничныхПродажах
|ГДЕ
| ОтчетОРозничныхПродажах.Дата = &Дата";
Запрос.УстановитьПараметр("Дата", ВыборкаКодДокумента.ДатаПродажи);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
Документ = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
Иначе
Документ = Документы.ОтчетОРозничныхПродажах.СоздатьДокумент();
КонецЕсли;
Документ.ВидОперации = Перечисления.ВидыОперацийОтчетОРозничныхПродажах.ОтчетККМОПродажах;
Документ.ВалютаДокумента = Справочники.Валюты.НайтиПоНаименованию("руб");
Документ.Организация = Объект.Организация;
Документ.Склад = Объект.Склад;
Документ.СчетКасса = ПланыСчетов.Хозрасчетный.Касса;
Документ.ДокументБезНДС = Ложь;
Документ.СуммаВключаетНДС = Истина;
ВыборкаДетальныеЗаписи = ВыборкаКодДокумента.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Документ.Дата = ВыборкаДетальныеЗаписи.ДатаПродажи;
СтрТЧ = Документ.Товары.Добавить();
СтрТЧ.Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Лев(ВыборкаДетальныеЗаписи.КодТовара,11));
СтрТЧ.Количество = ВыборкаДетальныеЗаписи.Количество;
СтрТЧ.Цена = ВыборкаДетальныеЗаписи.Цена;
СтрТЧ.Сумма = ВыборкаДетальныеЗаписи.Сумма + ВыборкаДетальныеЗаписи.СуммаНДС;
СтрТЧ.СуммаНДС = ВыборкаДетальныеЗаписи.СуммаНДС;
Если ВыборкаДетальныеЗаписи.СтавкаНДС = "10" Тогда
СтавкаНДС = Перечисления.СтавкиНДС.НДС10;
ИначеЕсли ВыборкаДетальныеЗаписи.СтавкаНДС = "20" Тогда
СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
Иначе СтавкаНДС = Перечисления.СтавкиНДС.БезНДС;
КонецЕсли;
СтрТЧ.СтавкаНДС = СтавкаНДС;
ДатаНакладной = ВыборкаКодДокумента.ДатаПродажи;
Если ВыборкаДетальныеЗаписи.ИДОперации = "545" Тогда
СтрОплаты = Документ.Оплата.Добавить();
СтрОплаты.ВидОплаты = Справочники.ВидыОплатОрганизаций.НайтиПоНаименованию("Эквайринг");
СтрОплаты.СуммаОплаты = ВыборкаДетальныеЗаписи.Сумма + ВыборкаДетальныеЗаписи.СуммаНДС;
КонецЕсли;
КонецЦикла;
СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаРасчетов(Документ);
СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаВТабличнойЧасти(Документ, "Товары");
Попытка
Документ.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Документ.Записать(РежимЗаписиДокумента.Запись);
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьНоменклатуру(ФайлНоменклатуры)
Кодировка = КодировкаXBase.OEM ;
СписокКолонок = Новый СписокЗначений;
СписокКолонок.Добавить("PR_ID", "Код", Истина);
СписокКолонок.Добавить("PROD_N", "Наименование", Истина);
СписокКолонок.Добавить("MEAS_N", "ЕдиницаИзмерения", Истина);
ТЗ = ЗаполнитьТЗизDBF(ФайлНоменклатуры, Кодировка, СписокКолонок);
Для Каждого Стр из ТЗ Цикл
Об = Справочники.Номенклатура.СоздатьЭлемент();
Об.Код = Лев(Стр.Код,11);
Об.ВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Товар");
Об.Наименование = СокрЛП(Стр.Наименование);
Об.ЕдиницаИзмерения = Справочники.КлассификаторЕдиницИзмерения.НайтиПоНаименованию("Шт");
Об.ОбменДанными.Загрузка = Истина;
Если Справочники.Номенклатура.НайтиПоКоду(Лев(Стр.Код,11)) = Справочники.Номенклатура.ПустаяСсылка() Тогда
Об.Записать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьКонтрагентов(ФайлКонтрагентов)
Кодировка = КодировкаXBase.OEM ;
СписокКолонок = Новый СписокЗначений;
СписокКолонок.Добавить("INN", "ИНН", Истина);
СписокКолонок.Добавить("PART_N", "Наименование", Истина);
СписокКолонок.Добавить("PART_ID", "Код", Истина);
ТЗ = ЗаполнитьТЗизDBF(ФайлКонтрагентов, Кодировка, СписокКолонок);
Для Каждого Стр из ТЗ Цикл
Об = Справочники.Контрагенты.СоздатьЭлемент();
Об.Код = Лев(Стр.Код,9);
Об.ЮридическоеФизическоеЛицо = Перечисления.ЮридическоеФизическоеЛицо.ЮридическоеЛицо;
Об.СтранаРегистрации = Справочники.СтраныМира.Россия;
Об.Наименование = СокрЛП(Стр.Наименование);
Об.ИНН = СокрЛП(Стр.ИНН);
Об.ОбменДанными.Загрузка = Истина;
Если Справочники.Контрагенты.НайтиПоКоду(Лев(Стр.Код,9)) = Справочники.Контрагенты.ПустаяСсылка() Тогда
Об.Записать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьПоступления(ФайлПриходов)
Кодировка = КодировкаXBase.OEM ;
СписокКолонок = Новый СписокЗначений;
СписокКолонок.Добавить("PART_ID", "КодКонтрагента", Истина);
СписокКолонок.Добавить("H_NUM", "КодДокумента", Истина);
СписокКолонок.Добавить("PROD_ID", "КодТовара", Истина);
СписокКолонок.Добавить("H_DATE", "ДатаДокумента", Истина);
СписокКолонок.Добавить("INC_CNT", "Количество", Истина);
СписокКолонок.Добавить("NDS_SIZE", "СтавкаНДС", Истина);
СписокКолонок.Добавить("INC_NO", "ЦенаСНДС", Истина);
СписокКолонок.Добавить("INC_NDS", "СуммаНДС", Истина);
СписокКолонок.Добавить("INC_SUM_W", "СуммаСНДС", Истина);
ТЗ = ЗаполнитьТЗизDBF(ФайлПриходов, Кодировка, СписокКолонок);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ.КодКонтрагента КАК КодКонтрагента,
| ТЗ.КодДокумента КАК КодДокумента,
| ТЗ.ДатаДокумента КАК ДатаДокумента,
| ТЗ.Количество КАК Количество,
| ТЗ.СтавкаНДС КАК СтавкаНДС,
| ТЗ.СуммаНДС КАК СуммаНДС,
| ТЗ.ЦенаСНДС КАК ЦенаСНДС,
| ТЗ.СуммаСНДС КАК СуммаСНДС,
| ТЗ.КодТовара КАК КодТовара
|ПОМЕСТИТЬ ВТ
|ИЗ
| &ТЗ КАК ТЗ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ.КодКонтрагента КАК КодКонтрагента,
| ВТ.КодДокумента КАК КодДокумента,
| ВТ.ДатаДокумента КАК ДатаДокумента,
| СУММА(ВТ.Количество) КАК Количество,
| ВТ.СтавкаНДС КАК СтавкаНДС,
| СУММА(ВТ.СуммаНДС) КАК СуммаНДС,
| СРЕДНЕЕ(ВТ.ЦенаСНДС) КАК ЦенаСНДС,
| СУММА(ВТ.СуммаСНДС) КАК СуммаСНДС,
| ВТ.КодТовара КАК КодТовара
|ИЗ
| ВТ КАК ВТ
|
|СГРУППИРОВАТЬ ПО
| ВТ.КодКонтрагента,
| ВТ.КодДокумента,
| ВТ.ДатаДокумента,
| ВТ.СтавкаНДС,
| ВТ.КодТовара
|ИТОГИ ПО
| КодДокумента";
Запрос.УстановитьПараметр("ТЗ", ТЗ);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаКодДокумента = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
НомерНакладной = "";
Пока ВыборкаКодДокумента.Следующий() Цикл
Если НомерНакладной <> ВыборкаКодДокумента.КодДокумента Тогда
НайденныйДокумент = Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру(Лев(ВыборкаКодДокумента.КодДокумента,11));
Если НайденныйДокумент = Документы.ПоступлениеТоваровУслуг.ПустаяСсылка() Тогда
Документ = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
Иначе
Документ = НайденныйДокумент.ПолучитьОбъект();
КонецЕсли;
Иначе
Документ = Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру(НомерНакладной).ПолучитьОбъект();
КонецЕсли;
Документ.Номер = Лев(ВыборкаКодДокумента.КодДокумента, 11);
Документ.НомерВходящегоДокумента = Лев(ВыборкаКодДокумента.КодДокумента, 11);
Документ.ВидОперации = Перечисления.ВидыОперацийПоступлениеТоваровУслуг.Товары;
Документ.Организация = Объект.Организация;
Документ.Склад = Объект.Склад;
ВыборкаДетальныеЗаписи = ВыборкаКодДокумента.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Документ.Контрагент = Справочники.Контрагенты.НайтиПоКоду(Лев(ВыборкаДетальныеЗаписи.КодКонтрагента,9));
Документ.Дата = ВыборкаДетальныеЗаписи.ДатаДокумента;
Документ.ДатаВходящегоДокумента = ВыборкаДетальныеЗаписи.ДатаДокумента;
СтрТЧ = Документ.Товары.Добавить();
СтрТЧ.Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Лев(ВыборкаДетальныеЗаписи.КодТовара,11));
СтрТЧ.Количество = ВыборкаДетальныеЗаписи.Количество;
СтрТЧ.Цена = ВыборкаДетальныеЗаписи.ЦенаСНДС;
СтрТЧ.Сумма = ВыборкаДетальныеЗаписи.СуммаСНДС;
СтрТЧ.СуммаНДС = ВыборкаДетальныеЗаписи.СуммаНДС;
Если ВыборкаДетальныеЗаписи.СтавкаНДС = "10" Тогда
СтавкаНДС = Перечисления.СтавкиНДС.НДС10;
ИначеЕсли ВыборкаДетальныеЗаписи.СтавкаНДС = "20" Тогда
СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
Иначе СтавкаНДС = Перечисления.СтавкиНДС.БезНДС;
КонецЕсли;
СтрТЧ.СтавкаНДС = СтавкаНДС;
НомерНакладной = Лев(ВыборкаКодДокумента.КодДокумента,11);
КонецЦикла;
СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаРасчетов(Документ);
СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаВТабличнойЧасти(Документ, "Товары");
Попытка
Документ.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Документ.Записать(РежимЗаписиДокумента.Запись);
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Собственно и все, получаем простейшую рабочую обработку по загрузке номенклатуры, контрагентов, поступлений товаров и услуг, отчетов о розничных продажах, доводим ее до красоты, и экономим время)) Надеюсь кому-нибудь пригодится