Top.Mail.Ru
Меню
Каталог Программы 1С Опыт и отзывы Услуги Компания Статьи Контакты

Как загрузить DBF в 1С: пошаговое руководство для начинающих

Основатель и генеральный директор компании MoscowSoft, Сорокин Сергей
Сорокин Сергей, Генеральный директор MoscowSoft  12.10.2025 Актуальность проверена: 12.10.2025   5 мин.
Подобрать перенос данных 1С

Специализируемся на переносах данных 1С с 2015г.

Подобрать перенос данных 1С >>

Интеграция 1С с маркетплейсами

Специализируемся на интеграциях 1С с маркетплейсами с 2021г.

Изучить продукты >>

Содержание

Главная мысль: в 1С:Предприятие 8 DBF-файлы удобно загружать через объекты ЧтениеDBF и ЗаписьDBF, либо косвенно через ТабличныйДокумент/ТаблицуЗначений с последующим маппингом в справочники и документы. Выбор подхода зависит от формата и объема данных, а также от требований к валидации и логированию. Ниже — практическая инструкция с кодом, типовыми ошибками и архитектурными шаблонами.

Введение: зачем и когда использовать DBF

DBF — «ветеран» обмена данными. Он часто встречается в интеграциях со старыми бухгалтерскими, складскими и отраслевыми системами. Новые проекты чаще используют XML/JSON/CSV/REST, но при поддержке «наследия» DBF неизбежен. Важно уметь:

  • Прочитать структуру полей DBF и корректно сопоставить их с реквизитами 1С.
  • Обработать кодировку, даты, числовые форматы, логические поля.
  • Выполнить валидацию, трансформацию, запись в справочники/документы с безопасной транзакцией.

Минимальные требования и окружение

  • Платформа 1С:Предприятие 8.3 (подход одинаков для большинства минорных версий 8.3).
  • Режим управляемого приложения (но примеры подходят и для обычного).
  • Права на файловую систему и доступ к каталогу DBF.
  • Знание основных объектов платформы: ТаблицаЗначений, Структура, Соответствие, Транзакции.

Быстрый обзор подходов к загрузке

  • Прямое чтение DBF: объект ЧтениеDBФ для построчного перебора и маппинга. Рекомендуется для строгих, повторяемых импортов.
  • Промежуточная ТаблицаЗначений: сначала читаем DBF в таблицу, затем валидируем и пишем в 1С. Удобно для контроля качества и логирования.
  • Обертывание в обработку (Обработка): UI для выбора файла, предварительный просмотр, правила сопоставления полей, лог ошибок, повторная загрузка.

Обзор формата DBF: типы и подводные камни

  • Типы DBF-полей: C (строка), N/F (число/число с плавающей точкой), D (дата), L (логический), M (мемо).
  • Ширина и точность числовых полей: важно корректно приводить к 1С-типам.
  • Кодировка: CP866/Windows-1251 — наиболее частые. Неправильная кодировка даст «кракозябры».
  • Дата: тип D — без времени; иногда дата хранится текстом, тогда нужна ручная конверсия.

Подготовка обработки: UI, выбор файла и настроек

Создайте обработку с формой, на которой:

  • Поле выбора файла DBF.
  • Переключатель кодировки (например, CP866/Windows-1251/UTF-8).
  • Таблица предварительного просмотра.
  • Кнопки: «Считать», «Проверить», «Загрузить», «Выгрузить лог».

Базовый пример чтения DBF построчно

Ниже — минимальный каркас чтения DBF и вывода в ТаблицуЗначений. Код 1С 8.3, модуль формы обработки.

&НаКлиенте
Процедура КомандаСчитать(Команда)
	Если ПустаяСтрока(ЭтотОбъект.ПутьКФайлу) Тогда
		Сообщить("Укажите путь к DBF-файлу.");
		Возврат;
	КонецЕсли;

	Таблица = ЧтениеDBFВТаблицу(ЭтотОбъект.ПутьКФайлу, ЭтотОбъект.Кодировка);
	ЭлементыФормы.ТаблицаПредпросмотра.Данные = Таблица;
	Сообщить("Прочитано строк: " + Строка(Таблица.Количество()));
КонецПроцедуры

&НаСервере
Функция ЧтениеDBFВТаблицу(ПутьКФайлу, Кодировка) Экспорт
	Таблица = Новый ТаблицаЗначений;
	Попытка
		Чтение = Новый ЧтениеDBФ(ПутьКФайлу, Кодировка);
		// Инициализация колонок по описанию DBF
		ОписаниеПолей = Чтение.ПолучитьОписаниеПолей();
		Для Каждого Поле Из ОписаниеПолей Цикл
			Таблица.Колонки.Добавить(Поле.Имя);
		КонецЦикла;

		Пока Чтение.Прочитать() Цикл
			Стр = Таблица.Добавить();
			Для Каждого Поле Из ОписаниеПолей Цикл
				Стр[Поле.Имя] = Чтение.ПолучитьЗначение(Поле.Имя);
			КонецЦикла;
		КонецЦикла;
	Исключение
		СообщениеПользователю(ОписаниеОшибки());
		Возврат Новый ТаблицаЗначений;
	КонецПопытки;
	Возврат Таблица;
КонецФункции

Детекция и установка кодировки

Кодировки DBF часто различаются. Хорошая практика — дать пользователю выбрать, а при ошибке — предложить альтернативу.

&НаСервере
Функция ПрочитатьСАвтоКодировкой(ПутьКФайлу) Экспорт
	Для Каждого Кодировка Из Новый Массив("CP866", "Windows-1251", "UTF-8") Цикл
		Попытка
			Возврат ЧтениеDBFВТаблицу(ПутьКФайлу, Кодировка);
		Исключение
			Продолжить;
		КонецПопытки;
	КонецЦикла;
	ВызватьИсключение "Не удалось прочитать DBF в распространённых кодировках.";
КонецФункции

Нормализация типов и приведение данных

DBF может хранить даты как строки, числа — как строки с разделителями. Введите слой нормализации.

&НаСервере
Функция НормализоватьСтрокуТаблицы(СтрокаТаблицы, КартаТипов) Экспорт
	// КартаТипов: Соответствие ИмяПоля -> Тип("Дата"), Тип("Число"), Тип("Строка"), Тип("Булево")
	Для Каждого Пара Из КартаТипов Цикл
		Имя = Пара.Ключ;
		ТипЦели = Пара.Значение;
		Знач = СтрокаТаблицы[Имя];

		Если ТипЦели=Тип("Дата") Тогда
			Если ТипЗнч(Знач)=Тип("Строка") Тогда
				// Попытка распознать форматы: YYYYMMDD, DD.MM.YYYY
				Если СтрДлина(Знач)=8 И ТолькоЦифры(Знач) Тогда
					Год = ЧИСЛО(Сред(Знач,1,4));
					Мес = ЧИСЛО(Сред(Знач,5,2));
					День = ЧИСЛО(Сред(Знач,7,2));
					Знач = Дата(Год,Мес,День);
				ИначеЕсли Найти(Знач,".")>0 Тогда
					Знач = Дата(Число(Сред(Знач,7,4)), Число(Сред(Знач,4,2)), Число(Лев(Знач,2)));
				КонецЕсли;
			КонецЕсли;
		ИначеЕсли ТипЦели=Тип("Число") Тогда
			Если ТипЗнч(Знач)=Тип("Строка") Тогда
				// Заменим запятую на точку и удалим пробелы
				Знач = Число(СтрЗаменить(СтрЗаменить(Знач, " ", ""), ",", "."));
			КонецЕсли;
		ИначеЕсли ТипЦели=Тип("Булево") Тогда
			Если ТипЗнч(Знач)=Тип("Строка") Тогда
				Знач = ВРег(Знач);
				Знач = (Знач="Y" ИЛИ Знач="T" ИЛИ Знач="1" ИЛИ Знач="TRUE");
			КонецЕсли;
		Иначе
			Знач = Строка(Знач);
		КонецЕсли;

		СтрокаТаблицы[Имя] = Знач;
	КонецЦикла;

	Возврат СтрокаТаблицы;
КонецФункции

Функция ТолькоЦифры(Т) Экспорт
	Для Номер=1 По СтрДлина(Т) Цикл
		Симв = Сред(Т, Номер, 1);
		Если Не (Симв>="0" И Симв<="9") Тогда
			Возврат Ложь;
		КонецЕсли;
	КонецЦикла;
	Возврат Истина;
КонецФункции

Сопоставление полей: карта соответствия

Часто имена полей в DBF не совпадают с именами реквизитов в 1С. Используйте карту маппинга.

&НаСервере
Функция ПостроитьКартуСопоставления() Экспорт
	// Пример: DBF поля -> Реквизиты справочника "Номенклатура"
	Карта = Новый Соответствие;
	Карта.Вставить("ARTICL", "Артикул");
	Карта.Вставить("NAME",   "Наименование");
	Карта.Вставить("UNIT",   "ЕдиницаХраненияОстатков");
	Карта.Вставить("PRICE",  "ЦенаЗакупки");
	Возврат Карта;
КонецФункции

Функция ПрименитьСопоставление(СтрокаТабл, КартаСопоставл) Экспорт
	Рез = Новый Структура;
	Для Каждого Пара Из КартаСопоставл Цикл
		ИсходноеПоле = Пара.Ключ;
		Реквизит      = Пара.Значение;
		Если СтрокаТабл.Свойство(ИсходноеПоле) Тогда
			Рез.Вставить(Реквизит, СтрокаТабл[ИсходноеПоле]);
		КонецЕсли;
	КонецЦикла;
	Возврат Рез;
КонецФункции

Загрузка в справочник: создание или поиск по ключу

При загрузке важно не плодить дублей. Определите ключ поиска (например, по Артикулу).

&НаСервереБезКонтекста
Функция НайтиИлиСоздатьНоменклатуру(Данные) Экспорт
	// Данные: Структура с реквизитами, напр. Артикул, Наименование, ЕдиницаХраненияОстатков, ЦенаЗакупки
	Артикул = Неопределено;
	Если Данные.Свойство("Артикул") Тогда Артикул = Данные.Артикул;

	Ссылка = Неопределено;
	Если ЗначениеЗаполнено(Артикул) Тогда
		Запрос = Новый Запрос(
			"ВЫБРАТЬ ПЕРВЫЕ 1
             Номенклатура.Ссылка КАК Ссылка
             ИЗ Справочник.Номенклатура КАК Номенклатура
             ГДЕ Номенклатура.Артикул = &Артикул");
		Запрос.УстановитьПараметр("Артикул", Артикул);
		Рез = Запрос.Выполнить().Выбрать();
		Если Рез.Следующий() Тогда
			Ссылка = Рез.Ссылка;
		КонецЕсли;
	КонецЕсли;

	Если Ссылка = Неопределено Тогда
		Э = Справочники.Номенклатура.СоздатьЭлемент();
		Если Данные.Свойство("Наименование") Тогда Э.Наименование = Данные.Наименование;
		Если Данные.Свойство("Артикул") Тогда Э.Артикул = Данные.Артикул;

		// Единица
		Если Данные.Свойство("ЕдиницаХраненияОстатков") И ЗначениеЗаполнено(Данные.ЕдиницаХраненияОстатков) Тогда
			Э.ЕдиницаХраненияОстатков = НайтиЕдиницу(Данные.ЕдиницаХраненияОстатков);
		КонецЕсли;

		Э.Записать();
		Ссылка = Э.Ссылка;
	Иначе
		Э = Ссылка.ПолучитьОбъект();
		// Обновление полей при необходимости
		Если Данные.Свойство("Наименование") И Э.Наименование <> Данные.Наименование Тогда
			Э.Наименование = Данные.Наименование;
		КонецЕсли;
		Э.Записать();
	КонецЕсли;

	Возврат Ссылка;
КонецФункции

Функция НайтиЕдиницу(КодИлиНаименование) Экспорт
	Запрос = Новый Запрос(
		"ВЫБРАТЬ ПЕРВЫЕ 1
        Ед.Ссылка
        ИЗ Справочник.ЕдиницыИзмерения КАК Ед
        ГДЕ Ед.Код = &Стр ИЛИ Ед.Наименование = &Стр");
	Запрос.УстановитьПараметр("Стр", КодИлиНаименование);
	Рез = Запрос.Выполнить().Выбрать();
	Если Рез.Следующий() Тогда Возврат Рез.Ссылка;
	Возврат Справочники.ЕдиницыИзмерения.ПустаяСсылка();
КонецФункции

Полный цикл: прочитать DBF, нормализовать, сопоставить, записать

&НаКлиенте
Процедура КомандаЗагрузить(Команда)
	Если ПустаяСтрока(ЭтотОбъект.ПутьКФайлу) Тогда
		Сообщить("Сначала укажите файл.");
		Возврат;
	КонецЕсли;

	Таблица = ЧтениеDBFВТаблицу(ЭтотОбъект.ПутьКФайлу, ЭтотОбъект.Кодировка);

	КартаТипов = Новый Соответствие;
	КартаТипов.Вставить("PRICE", Тип("Число"));
	КартаТипов.Вставить("DATEIN", Тип("Дата"));
	КартаТипов.Вставить("ACTIVE", Тип("Булево"));

	КартаСопоставл = ПостроитьКартуСопоставления();

	Ошибки = Новый Массив;
	Успешно = ЗагрузитьНоменклатуруИзТаблицы(Таблица, КартаТипов, КартаСопоставл, Ошибки);

	Если Не Успешно Тогда
		Сообщить("Загрузка завершена с ошибками. Количество: " + Строка(Ошибки.Количество()));
		ЭтотОбъект.Ошибки = Ошибки;
	Иначе
		Сообщить("Загрузка выполнена успешно.");
	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция ЗагрузитьНоменклатуруИзТаблицы(Таблица, КартаТипов, КартаСопоставл, Ошибки) Экспорт
	НачатьТранзакцию();
	Попытка
		Для Каждого Стр Из Таблица Цикл
			Лок = КопироватьСтроку(Стр);
			НормализоватьСтрокуТаблицы(Лок, КартаТипов);
			Модель = ПрименитьСопоставление(Лок, КартаСопоставл);

			// Валидация
			Сообщ = ПроверитьСтроку(Модель);
			Если Не ПустаяСтрока(Сообщ) Тогда
				Ошибки.Добавить("Строка: " + Строка(Стр) + " — " + Сообщ);
				Продолжить;
			КонецЕсли;

			НайтиИлиСоздатьНоменклатуру(Модель);
		КонецЦикла;

		ЗафиксироватьТранзакцию();
		Возврат Истина;
	Исключение
		ОтменитьТранзакцию();
		Ошибки.Добавить("Критическая ошибка: " + ОписаниеОшибки());
		Возврат Ложь;
	КонецПопытки;
КонецФункции

&НаСервереБезКонтекста
Функция КопироватьСтроку(СтрТабл) Экспорт
	Копия = Новый Структура;
	Для Каждого К Из СтрТабл.Поля Колонки Цикл
		ИмяКол = К.Имя;
		Копия.Вставить(ИмяКол, СтрТабл[ИмяКол]);
	КонецЦикла;
	Возврат Копия;
КонецФункции

&НаСервере
Функция ПроверитьСтроку(Модель) Экспорт
	Если Не Модель.Свойство("Наименование") ИЛИ ПустаяСтрока(Модель.Наименование) Тогда
		Возврат "Не заполнено Наименование";
	КонецЕсли;
	// Пример ограничений
	Если Модель.Свойство("Артикул") И СтрДлина(Модель.Артикул) > 50 Тогда
		Возврат "Слишком длинный Артикул";
	КонецЕсли;
	Возврат "";
КонецФункции

Обработка больших объемов: пакеты и контроль памяти

Для больших DBF лучше обрабатывать пакетами:

  • Считывать по N строк, валидировать и записывать, фиксировать транзакцию.
  • Использовать явный сборщик мусора редко требуется, но избегайте хранить весь файл в памяти, если он очень большой.
  • Включите прогресс-бар в форме, чтобы не казалось, что «зависло».
&НаСервере
Процедура ЗагрузитьПакетно(ПутьКФайлу, Кодировка, РазмерПакета, КартаТипов, КартаСопоставл, Ошибки) Экспорт
	Чтение = Новый ЧтениеDBФ(ПутьКФайлу, Кодировка);
	ОписаниеПолей = Чтение.ПолучитьОписаниеПолей();

	Пакет = Новый ТаблицаЗначений;
	Для Каждого Поле Из ОписаниеПолей Цикл
		Пакет.Колонки.Добавить(Поле.Имя);
	КонецЦикла;

	Счетчик = 0;
	Пока Чтение.Прочитать() Цикл
		Стр = Пакет.Добавить();
		Для Каждого Поле Из ОписаниеПолей Цикл
			Стр[Поле.Имя] = Чтение.ПолучитьЗначение(Поле.Имя);
		КонецЦикла;

		Счетчик = Счетчик + 1;
		Если Счетчик >= РазмерПакета Тогда
			ЗагрузитьНоменклатуруИзТаблицы(Пакет, КартаТипов, КартаСопоставл, Ошибки);
			Пакет.Очистить();
			Счетчик = 0;
		КонецЕсли;
	КонецЦикла;

	Если Пакет.Количество() > 0 Тогда
		ЗагрузитьНоменклатуруИзТаблицы(Пакет, КартаТипов, КартаСопоставл, Ошибки);
	КонецЕсли;
КонецПроцедуры

Логирование и повторная загрузка

Сохраняйте ошибки в РегистреСведений «ЛогИмпортаDBF» или во внешнем файле. Это упростит разбор проблем и повторный импорт.

	&НаСервере
	Процедура ЗаписатьЛог(ФайлDBF, ТекстОшибки, СтрокаНомер) Экспорт
		// Пример записи во внешний текстовый файл
		ПапкаЛога = ПолучитьКаталогВременныхФайлов();
		ИмяЛога = ПапкаЛога + "dbf_import.log";
		Текст = Новый ЗаписьТекста(ИмяЛога, КодировкаТекста.UTF8);
		Попытка
			Текст.ЗаписатьСтроку(ТекущаяДата() + " | " + ФайлDBF + " | Строка " + Строка(СтрокаНомер) + " | " + ТекстОшибки);
		Исключение
			// Игнорируем ошибку лога, чтобы не валить основной процесс
		КонецПопытки;
		Текст.Закрыть();
	КонецПроцедуры

Частые ошибки и их устранение

Расширенный сценарий: загрузка документов приходов

Если DBF — это табличные движения, можно формировать документы. Например, приходные накладные: «Шапка» и «Табличная часть».

&НаСервере
Процедура ЗагрузитьПриходы(Таблица, КартаТипов, КартаСопоставл, Ошибки) Экспорт
	// Предположим, что в DBF есть поля: NUMDOC, DATEDOC, SUPPLIER, ARTICL, QTY, PRICE
	// Сгруппируем по NUMDOC + DATEDOC + SUPPLIER
	Индекс = Новый Соответствие; // Ключ -> ДокументОбъект (в процессе формирования)
	Для Каждого Стр Из Таблица Цикл
		Лок = КопироватьСтроку(Стр);
		НормализоватьСтрокуТаблицы(Лок, КартаТипов);

		Ключ = Строка(Лок.NUMDOC) + "|" + Формат(Лок.DATEDOC, "ДЛФ=DD.MM.YYYY") + "|" + Строка(Лок.SUPPLIER);

		Если Не Индекс.Содержит(Ключ) Тогда
			Док = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
			Док.Номер = Неопределено; // авто-нумерация
			Док.Дата = Лок.DATEDOC;
			Док.Контрагент = НайтиКонтрагента(Лок.SUPPLIER);
			Индекс.Вставить(Ключ, Док);
		КонецЕсли;

		Док = Индекс.Получить(Ключ);

		СтрТЧ = Док.Товары.Добавить();
		Ном = НайтиИлиСоздатьНоменклатуру(ПрименитьСопоставление(Лок, КартаСопоставл));
		СтрТЧ.Номенклатура = Ном;
		СтрТЧ.Количество = Лок.QTY;
		СтрТЧ.Цена = Лок.PRICE;
	КонецЦикла;

	// Запись документов
	Для Каждого Пара Из Индекс Цикл
		Док = Пара.Значение;
		Попытка
			НачатьТранзакцию();
			Док.Записать(РежимЗаписиДокумента.Проведение);
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			Ошибки.Добавить("Документ не проведён: " + ОписаниеОшибки());
		КонецПопытки;
	КонецЦикла;
КонецПроцедуры

Функция поиска контрагента:

&НаСервереБезКонтекста
Функция НайтиКонтрагента(Идентификатор) Экспорт
	Запрос = Новый Запрос(
		"ВЫБРАТЬ ПЕРВЫЕ 1
       Контрагент.Ссылка
       ИЗ Справочник.Контрагенты КАК Контрагент
       ГДЕ Контрагент.Код = &ИД ИЛИ Контрагент.Наименование = &ИД");
	Запрос.УстановитьПараметр("ИД", Идентификатор);
	Рез = Запрос.Выполнить().Выбрать();
	Если Рез.Следующий() Тогда Возврат Рез.Ссылка;
	Э = Справочники.Контрагенты.СоздатьЭлемент();
	Э.Наименование = Идентификатор;
	Э.Записать();
	Возврат Э.Ссылка;
КонецФункции

Проверка структуры DBF и совместимость

Перед загрузкой полезно получить структуру полей DBF и сопоставить с ожидаемой моделью.

&НаСервере
Функция ПолучитьСтруктуруDBF(ПутьКФайлу, Кодировка) Экспорт
	Чтение = Новый ЧтениеDBФ(ПутьКФайлу, Кодировка);
	Описание = Чтение.ПолучитьОписаниеПолей();
	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Имя");
	Таблица.Колонки.Добавить("Тип");
	Таблица.Колонки.Добавить("Длина");
	Таблица.Колонки.Добавить("Точность");

	Для Каждого П Из Описание Цикл
		Стр = Таблица.Добавить();
		Стр.Имя = П.Имя;
		Стр.Тип = П.Тип; // "C","N","D","L","F","M"
		Стр.Длина = П.Длина;
		Стр.Точность = П.Точность;
	КонецЦикла;

	Возврат Таблица;
КонецФункции

Сравнение со схемой:

&НаСервере
Функция ПроверитьСовместимость(СтруктураDBF, ОжидаемаяСхема) Экспорт
	// ОжидаемаяСхема: Соответствие ИмяПоля -> Структура(Тип="C", Длина=20, Точность=0)
	Нарушения = Новый Массив;
	Для Каждого Стр Из СтруктураDBF Цикл
		Если Не ОжидаемаяСхема.Содержит(Стр.Имя) Тогда
			Нарушения.Добавить("Лишнее поле: " + Стр.Имя);
		Иначе
			Ож = ОжидаемаяСхема.Получить(Стр.Имя);
			Если Ож.Тип <> Стр.Тип Тогда
				Нарушения.Добавить("Несовпадение типа у " + Стр.Имя + ": ожидалось " + Ож.Тип + ", получено " + Стр.Тип);
			КонецЕсли;
			Если Стр.Длина > Ож.Длина Тогда
				Нарушения.Добавить("Длина поля " + Стр.Имя + " больше ожидаемой (" + Стр.Длина + " > " + Ож.Длина + ")");
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Возврат Нарушения;
КонецФункции

Работа с мемо-полями (M) и большими текстами

Мемо-поля в DBF могут храниться во внешнем файле .FPT/.DBT. Объект ЧтениеDBФ в большинстве случаев прозрачно вернет строку, но:

  • Проверяйте наличие парных файлов (DBF + FPT/DBT) в одной папке.
  • Для огромных текстов избегайте записи прямо в реквизит с ограничением длины — используйте ХранилищеЗначения, двоичные данные или отдельный регистр/каталог файлов.

Отладка: как понять, где ломается

  • Вставляйте целенаправленные Профилировать(), ЗамеритьВремя(), Сообщить() на этапах: чтение, нормализация, запись.
  • Логируйте «первые N ошибочных строк» и сохраняйте их в отдельный DBF/CSV для анализа.
  • Делайте «сухой прогон»: считывание и проверка без записи (флаг в форме).

Производительность и масштабирование

  • Пакеты по 1000–5000 строк обычно безопасны для транзакций на большинстве рабочих баз, но подбирайте эмпирически.
  • Индексированные поисковые запросы по ключевым реквизитам ускоряют upsert (добавление/обновление).
  • Используйте менеджер кэша (Соответствие) для повторно встречаемых значений (единицы, контрагенты) в рамках одной загрузки.

Безопасность и идемпотентность

  • Для повторных перезагрузок реализуйте идемпотентные ключи (например, ВнешнийКод документа или Хеш по набору полей).
  • Не записывайте документы дважды: проверяйте существование по уникальному признаку.
  • Ведите версионность маппинга, чтобы изменения схемы DBF не ломали старые загрузки.

Юнит-тесты сценариев загрузки (практика для начинающих)

  • Соберите тестовые DBF с минимальным набором строк, покрывающих разные кейсы: пустые даты, невалидные числа, экстремальные длины строк, отсутствующие FPT.
  • Напишите модульные тесты на функции нормализации и сопоставления, используя ОбщийМодуль с экспортными функциями. Это упростит поддержку.

Встраивание в план обмена или регламентное задание

  • Создайте РегламентноеЗадание, запускающее обработку загрузки по расписанию (например, каждую ночь).
  • Логируйте статистику: количество прочитанных строк, успешно загруженных, количество ошибок.
  • Уведомляйте ответственных через Встроенную почту/HTTP-hook/сообщения пользователям.

Пример регламентной обвязки:

&НаСервере
Процедура РегламентнаяЗагрузкаDBF() Экспорт
	Путь = ПолучитьНастройку("ПутьКDBF");
	Кодировка = ПолучитьНастройку("КодировкаDBF");
	Ошибки = Новый Массив;

	КартаТипов = Новый Соответствие; // заполните под свою схему
	КартаСоп = ПостроитьКартуСопоставления();

	Попытка
		ЗагрузитьПакетно(Путь, Кодировка, 2000, КартаТипов, КартаСоп, Ошибки);
	Исключение
		Ошибки.Добавить("Критическая ошибка регламентной загрузки: " + ОписаниеОшибки());
	КонецПопытки;

	Если Ошибки.Количество()>0 Тогда
		ОтправитьУведомление("DBF импорт: есть проблемы", СформироватьОтчетОшибок(Ошибки));
	Иначе
		ОтправитьУведомление("DBF импорт: успешно", "Ошибок не обнаружено");
	КонецЕсли;
КонецПроцедуры

Проверка и предварительный просмотр данных перед записью

Дайте пользователю кнопку «Проверить», которая:

  • Считает DBF,
  • Прогонит нормализацию,
  • Покажет подсветкой потенциальные проблемы,
  • Сформирует отчет о несоответствиях (например, отдельную вкладку с замечаниями).
&НаКлиенте
Процедура КомандаПроверить(Команда)
	Таблица = ЧтениеDBFВТаблицу(ЭтотОбъект.ПутьКФайлу, ЭтотОбъект.Кодировка);
	КартаТипов = ПолучитьКартуТипов(); // пользовательский пресет
	Нарушения = Новый Массив;

	Для Каждого Стр Из Таблица Цикл
		Лок = КопироватьСтроку(Стр);
		НормализоватьСтрокуТаблицы(Лок, КартаТипов);
		Ош = ПроверитьСтроку(Лок);
		Если Не ПустаяСтрока(Ош) Тогда
			Нарушения.Добавить(Ош);
		КонецЕсли;
	КонецЦикла;

	ЭтотОбъект.Нарушения = Нарушения;
	Сообщить("Проверка завершена. Обнаружено: " + Строка(Нарушения.Количество()) + " нарушений.");
КонецПроцедуры

Универсализация: правило-движок сопоставления

Чтобы не переписывать код под каждый DBF, вынесите правила в справочник «ПравилаИмпорта»:

  • Храните карту: ИмяПоляDBF -> РеквизитОбъекта.
  • Храните типы/валидаторы для каждого поля.
  • В обработке прочитайте правило по коду/версии и применяйте.
&НаСервере
Функция ЗагрузитьПравилоИмпорта(КодПравила) Экспорт
	// Возврат: Структура {КартаСопоставления=Соответствие, КартаТипов=Соответствие, ОбъектНазначения="Справочник.Номенклатура"}
	// Реализация индивидуальна для вашей БД: отбор из справочника с хранимыми JSON/ХранилищеЗначения.
КонецФункции

Экспорт в ТабличныйДокумент для аналитики

Иногда удобно показать пользователю «как интерпретировались» данные.

&НаКлиенте
Процедура ПоказатьПредпросмотр(Таблица)
	ТД = Новый ТабличныйДокумент;
	ТД.Вывести(Таблица);
	ТД.Показать();
КонецПроцедуры

Транслитерация и очистка строк

Убирайте лишние пробелы, неотпечатываемые символы, нормализуйте регистры.

&НаСервере
Функция ОчиститьСтроку(Текст) Экспорт
	Если Текст = Неопределено Тогда Возврат "";
	Т = СокрЛП(Текст);
	Т = СтрЗаменить(Т, Символы.ПС, " ");
	Т = СтрЗаменить(Т, Символы.ВК, " ");
	Возврат Т;
КонецФункции

Диагностика кодировки по сигнатуре

У DBF нет 100% надежной сигнатуры для кодировки, но можно ориентироваться на заголовок DBF/флаг языка. Практически — предложите выбор и сохраните последнюю успешную кодировку в настройках пользователя.

&НаСервере
Процедура СохранитьПоследнююКодировкуПользователя(Кодировка) Экспорт
	// Сохраните в хранилище настроек пользователя
КонецПроцедуры

Контроль качества: отчеты и KPI импорта

Создайте отчет «Качество импорта DBF»:

  • Доля строк с ошибками,
  • Топ-5 типов ошибок,
  • Средняя скорость обработки (строк/мин),
  • Время чтения vs время записи.

Это поможет аргументированно улучшать производительность и качество.

Вариант: Запись в DBF из 1С (для двусторонних обменов)

Иногда нужно не только читать, но и готовить DBF на выход. Объект ЗаписьDBФ:

&НаСервере
Процедура ЭкспортВDBF(ПутьКФайлу, Кодировка, Таблица) Экспорт
	Запись = Новый ЗаписьDBФ(ПутьКФайлу, Кодировка);
	// Создать описание полей
	Описание = Новый Массив;
	Для Каждого Кол Из Таблица.Колонки Цикл
		Поле = Новый ОписаниеПоляDBФ(Кол.Имя, "C", 100, 0); // примитивный пример
		Описание.Добавить(Поле);
	КонецЦикла;
	Запись.УстановитьОписаниеПолей(Описание);

	Для Каждого Стр Из Таблица Цикл
		Запись.ДобавитьСтроку();
		Для Каждого Кол Из Таблица.Колонки Цикл
			Запись.УстановитьЗначение(Кол.Имя, Стр[Кол.Имя]);
		КонецЦикла;
	КонецЦикла;

	Запись.Записать();
КонецПроцедуры

При реальной реализации задавайте корректные типы/длины полей и конвертируйте значения.

Чек-лист перед боевым запуском

  • Проверены кодировки на реальных файлах.
  • Настроены правила сопоставления и ключи для поиска/обновления.
  • Обеспечены транзакции и пакетная обработка.
  • Реализован лог ошибок и уведомления.
  • Есть «сухой режим» проверки без записи.
  • Тесты прошли на проблемных кейсах.

Заключение: архитектурный шаблон «Импорт DBF как сервис»

Лучший путь — вынести импорт в переиспользуемый сервисный модуль:

  • Интерфейсы: IReader (читает DBF -> ТаблицаЗначений), ITransformer (нормализует), IMapper (сопоставляет), IWriter (пишет в объектную модель 1С), ILogger (логирование).
  • Реализация этих слоев упрощает поддержку разных форматов DBF и быстрое изменение бизнес-логики.
  • Добавление новых источников сведется к настройке правил, а не к переписыванию кода.

Следуя этому руководству, начинающий специалист 1С уверенно организует надёжную загрузку данных из DBF: от простого чтения и нормализации до транзакционной записи в справочники и документы, с логами, проверками и возможностью масштабирования под большие объёмы.

MoscowSoft логотип

Нужна помощь?

Если не получается разобраться с вопросом самостоятельно, обратитесь к нам. Получите бесплатную консультацию эксперта!

Основатель и генеральный директор компании MoscowSoft, Сорокин Сергей
Сорокин Сергей, Генеральный директор MoscowSoft

Возврат к списку