При импорте сведений из сторонних баз данных (например, файлов формата DBF, созданных в FoxPro) часто возникает ситуация, когда вместо одного итогового документа в 1С создается множество однотипных документов. Каждая строка исходного файла приводит к генерации нового объекта в системе. Разберем, как правильно переписать алгоритм обхода DBF-файла, вынести инициализацию документа за пределы цикла и корректно обработать специфические типы данных.
Проанализируем типовую ошибку в логике программного кода. Если вызов метода СоздатьДокумент() и управление транзакциями (НачатьТранзакцию(), ЗафиксироватьТранзакцию()) находятся внутри основного цикла обхода строк DBF (Пока ДБФ.ВКонце = 0 Цикл), система при каждом шаге итерации формирует новую ссылку на документ и записывает её в базу данных.
Дополнительно ситуацию усугубляет фиксация транзакции по счетчику Сч % 1 = 0 внутри итератора. Это разбивает обработку одного объекта на разные транзакции базы данных, приводит к конфликту версий объекта и плодит дубли документов.
Чтобы все строки из файла DBF попали в табличную часть одного и того же документа, рассмотрим пошаговый порядок действий:
ДокументСоздан = Ложь) или инициализируем объект документа до начала основного цикла.СоздатьДокумент() и устанавливаем флаг в значение Истина.Начисления созданного объекта.Док.Записать() только после завершения чтения всех строк из файла.НачатьТранзакцию() и ЗафиксироватьТранзакцию()) выносим за пределы цикла или оборачиваем им весь процесс целиком.Посмотрим на пример правильной организации структуры кода:
Док = Неопределено;
ДокументСоздан = Ложь;
ДБФ.Первая();
Попытка
НачатьТранзакцию();
Пока ДБФ.ВКонце() = 0 Цикл
Если Не ДокументСоздан Тогда
Док = Документы.НачислениеЗарплатыРаботникамОрганизаций.СоздатьДокумент();
Док.Дата = ТекущаяДата();
Док.ПериодНачисленияДатаОкончания = ДБФ.Dat_End;
ДокументСоздан = Истина;
КонецЕсли;
// Определение вида расчета по шифру
ВидОплаты = ДБФ.Shifr;
Расчет1 = ПланыВидовРасчета.ОсновныеНачисленияОрганизаций.ПустаяСсылка();
Если ВидОплаты = "001" Тогда
Расчет1 = ПланыВидовРасчета.ОсновныеНачисленияОрганизаций.НайтиПоНаименованию("Сдельные наряды(суммой)");
ИначеЕсли ВидОплаты = "005" Тогда
Расчет1 = ПланыВидовРасчета.ОсновныеНачисленияОрганизаций.НайтиПоНаименованию("Сверхурочные(суммой)");
КонецЕсли;
// Добавление строки в табличную часть документа
ТекСтрока = Док.Начисления.Добавить();
ТекСтрока.ВидРасчета = Расчет1;
Сотр1 = Справочники.СотрудникиОрганизаций.НайтиПоКоду(ДБФ.TabNom);
Если Не Сотр1.Пустая() Тогда
ТекСтрока.Сотрудник = Сотр1;
КонецЕсли;
ТекСтрока.Результат = ДБФ.Summa;
ТекСтрока.ДатаНачала = ДБФ.Dat_Beg;
ТекСтрока.ДатаНачалаСобытия = ДБФ.Dat_Beg;
ТекСтрока.ДатаОкончания = ДБФ.Dat_End;
ДБФ.Следующая();
КонецЦикла;
Если ДокументСоздан Тогда
Док.Записать();
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Сообщить(ОписаниеОшибки());
КонецПопытки;
Выясним причину второй частой проблемы, когда при загрузке из сторонней базы данных (например, FoxPro 2.6) поля ДатаНачала или ДатаОкончания остаются пустыми в табличной части 1С.
Объект XBase в 1С привязан к структуре типов, описанной в заголовке файла DBF. Существует несколько причин несоответствия данных:
"YYYYMMDD" или "DD.MM.YYYY". При попытке записать значение типа Строка в реквизит табличной части с типом Дата, платформа 1С не вызывает ошибку, но записывает пустую дату (01.01.0001 00:00:00).DBF Viewer 2000) и изучить структуру колонок.Рассмотрим, как правильно преобразовать строковую дату из DBF в полноценный тип Дата перед заполнением реквизита 1С:
// Если дата в DBF хранится в текстовом виде "YYYYMMDD"
ЗначениеДаты = Строка(ДБФ.Dat_Beg);
Если СтрДлина(СокрЛП(ЗначениеДаты)) = 8 Тогда
Год = Число(Лев(ЗначениеДаты, 4));
Месяц = Число(Сред(ЗначениеДаты, 5, 2));
День = Число(Прав(ЗначениеДаты, 2));
ТекСтрока.ДатаНачала = Дата(Год, Месяц, День);
Иначе
ТекСтрока.ДатаНачала = ДБФ.Dat_Beg; // Если тип поля в DBF изначально Date
КонецЕсли;
Таким образом, правильное проектирование цикла обхода файлов XBase и предварительная проверка типов данных через просмотрщик структуры гарантируют корректное создание единого документа и полное заполнение его табличной части.