Часто при переносе данных из внешних файлов формата DBF в справочники 1С начинающие разработчики сталкиваются с типичной архитектурной ошибкой. Проблема заключается в том, что в процессе перебора столбцов файла программа по ошибке создает новый элемент справочника для каждой колонки, вместо того чтобы собрать данные в один объект и записать его единожды. Давайте разберем, как исправить эту ситуацию и организовать код правильно.
Основная ошибка заключается в размещении метода СоздатьЭлемент() непосредственно внутри цикла, который перебирает поля текущей строки DBF-файла. Платформа 1С выполняет код последовательно: на каждом шаге цикла она видит команду на создание нового элемента и исполняет её. В результате вместо одного заполненного станка или оборудования мы получаем десятки пустых или частично заполненных элементов справочника.
Чтобы данные из всех колонок DBF-файла попали в нужные реквизиты одного элемента справочника, необходимо изменить порядок действий. Мы будем использовать Структура, чтобы временно накапливать значения, а создание элемента вынесем в область, где обрабатывается целая строка файла.
Рассмотрим пошаговое решение:
XBase на клиенте.Пока переходим по строкам файла.Вот пример того, как должен выглядеть код для реализации этой задачи:
&НаКлиенте
Процедура ИмпортДанных(Команда)
ПутьКФайлу = "C:\МойПроект\Data.DBF";
ФайлDBF = Новый XBase;
ФайлDBF.ОткрытьФайл(ПутьКФайлу,, Истина);
Если ФайлDBF.Открыта Тогда
ФайлDBF.Первая();
Пока Не ФайлDBF.ВКонце() Цикл
ДанныеСтроки = Новый Структура;
Для Каждого Поле Из ФайлDBF.Поля Цикл
ДанныеСтроки.Вставить(Поле.Имя, ФайлDBF.ПолучитьЗначениеПоля(Поле.Имя));
КонецЦикла;
// Вызываем серверный метод один раз на строку
ЗаписатьОборудованиеНаСервере(ДанныеСтроки);
ФайлDBF.Следующая();
КонецЦикла;
ФайлDBF.ЗакрытьФайл();
КонецЕсли;
КонецПроцедуры
Теперь рассмотрим реализацию серверной части, которая отвечает за корректную запись элемента:
&НаСервере
Процедура ЗаписатьОборудованиеНаСервере(ДанныеСтроки)
// Словарь соответствия полей DBF и реквизитов справочника
СоответствиеРеквизитов = Новый Структура("SYSNO, NAME", "Сис_N", "Наименование_");
НовыйЭлемент = Справочники.ЗаводскоеОборудование.СоздатьЭлемент();
Для Каждого КлючИЗначение Из ДанныеСтроки Цикл
Если СоответствиеРеквизитов.Свойство(КлючИЗначение.Ключ) Тогда
ИмяРеквизита = СоответствиеРеквизитов[КлючИЗначение.Ключ];
НовыйЭлемент[ИмяРеквизита] = КлючИЗначение.Значение;
КонецЕсли;
КонецЦикла;
Попытка
НовыйЭлемент.Записать();
Исключение
Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Когда вы разберетесь с базовой структурой, обратите внимание на следующие моменты для профессиональной разработки:
Пока создает лишнюю нагрузку на сеть. Если файл большой, лучше передать весь массив данных на сервер одним махом.НачатьТранзакцию() и ЗафиксироватьТранзакцию(). Если в процессе записи одного из элементов произойдет сбой, транзакция поможет избежать «битых» данных в справочнике.DBF хранят данные фиксированной длины, поэтому в строках могут присутствовать лишние пробелы. Всегда используйте функцию СокрЛП(), чтобы отсечь лишние пробелы при переносе данных в 1С.СправочникОбъект.СоздатьЭлемент() проверяйте, не существует ли уже такой объект, используя Справочники.ЗаводскоеОборудование.НайтиПоРеквизиту(). Это защитит ваш справочник от дублирования записей при повторном запуске обработки.Применяя этот подход, вы сможете эффективно и безопасно переносить любые объемы данных, избегая ошибок создания лишних элементов и обеспечивая целостность вашей базы данных.